Topics
Forum Topics not found
Replies
cAlgo_Fanatic
26 Apr 2013, 15:01
You can copy the line (select the lline and press CTR + C) and paste it in a text editor like Notepad to see the whole error message. We are aware of this issue. There is no log file.
@cAlgo_Fanatic
cAlgo_Fanatic
26 Apr 2013, 11:31
Please see this sample for Max DrawDown.
In the example this is the function that calculates it which is called when the position closes, in the OnPositionClosed event:
private void GetMaxDrawDown() { peak = Math.Max(peak, Account.Balance); Array.Resize(ref drawdown, drawdown.Length + 1); int i = drawdown.Length - 1; drawdown[i] = (peak - Account.Balance) / peak * 100; for (i = 0; i < drawdown.Length; i++) maxDrawdown = Math.Max(maxDrawdown, drawdown[i]); Print("Max DrawDown = {0}", Math.Round(maxDrawdown, 2)); }
@cAlgo_Fanatic
cAlgo_Fanatic
26 Apr 2013, 11:26
This is the sample martingale robot included in the cAlgo with the calculation of Max Draw Down.
using System; using System.Collections.Generic; using cAlgo.API; namespace cAlgo.Robots { [Robot] public class MaxDrawdown:Robot { [Parameter("Position Label", DefaultValue = "Martingale MaxDrawDown")] public string MyLabel { get; set; } [Parameter("Initial Volume", DefaultValue = 10000, MinValue = 0)] public int InitialVolume { get; set; } [Parameter("Stop Loss", DefaultValue = 40)] public int StopLoss { get; set; } [Parameter("Take Profit", DefaultValue = 40)] public int TakeProfit { get; set; } private Random random = new Random(); private double peak; private List<double> drawdown = new List<double>(); private double maxDrawdown; protected override void OnStart() { Positions.Closed += PositionsOnClosed; ExecuteOrder(InitialVolume, GetRandomTradeCommand()); } private void PositionsOnClosed(PositionClosedEventArgs args) { var position = args.Position; if (position.Label != MyLabel) return; Print("Position labeled {0} has closed", position.Label); if (position.NetProfit > 0) { ExecuteOrder(InitialVolume, GetRandomTradeCommand()); } else { ExecuteOrder((int)position.Volume * 2, position.TradeType); } GetMaxDrawDown(); } private void ExecuteOrder(int volume, TradeType tradeType) { ExecuteMarketOrder(tradeType, Symbol, volume, MyLabel, StopLoss, TakeProfit); } private void GetMaxDrawDown() { peak = Math.Max(peak, Account.Balance); drawdown.Add((peak - Account.Balance) / peak * 100); drawdown.Sort(); maxDrawdown = drawdown[drawdown.Count - 1]; Print("Max DrawDown = {0}", Math.Round(maxDrawdown, 2)); } protected override void OnError(Error error) { if (error.Code == ErrorCode.BadVolume) Stop(); } private TradeType GetRandomTradeCommand() { return random.Next(2) == 0 ? TradeType.Buy : TradeType.Sell; } } }
@cAlgo_Fanatic
cAlgo_Fanatic
26 Apr 2013, 09:28
This issue has been fixed with the new update which if is not available to you yet it will be by Monday. You can test it with a demo account on Spotware cTrader and cAlgo. If you have not received the update yet, please sign out and sign back in again and see if the position remains.
@cAlgo_Fanatic
cAlgo_Fanatic
25 Apr 2013, 15:05
( Updated at: 21 Dec 2023, 09:20 )
Unfortunately, we cannot add those buttons but you can easily use the Price DOM to make Stop Orders.
@cAlgo_Fanatic
cAlgo_Fanatic
25 Apr 2013, 14:48
Thank you for your suggestions. We will consider adding hot keys to the platform.
@cAlgo_Fanatic
cAlgo_Fanatic
24 Apr 2013, 17:57
Please reinstall cTrader and see if the problem persists. If it does please let us know and we will investigate promptly.
@cAlgo_Fanatic
cAlgo_Fanatic
24 Apr 2013, 10:23
Yes, MarketSeries.Close[MarketSeries.Close.Count - 2]; represents the second from the end close price.
MarketSeries.Close is a DataSeries which is a collection of data like an array. An array, can be thought of as a container that has a list of storage locations. These locations are accessed by their index (position). Indexing starts from zero. For example if the values contained in the MarketSeries.Close are {5,1,9} then MarketSeries.Close[0] = 5, MarketSeries.Close[1] = 1 and MarketSeries.Close[2] = 9.
MarketSeries.Close.Count is the size of the collection. In the above example it is equal to 3. So at the last location, the index is 2.
So, MarketSeries.Close.Count - 1 gives you the last index. The value at that last location is accessed like this: MarketSeries.Close.Count[MarketSeries.Close.Count - 1 ].
To make it more clear to read you can break it into two lines:
var lastIndex = MarketSeries.Close.Count - 1;
var lastValue = MarketSeries.Close.Count[lastIndex];
To show the last 3 closing prices:
protected override void OnTick() { var lastIndex = MarketSeries.Close.Count - 1; for (int i = 0; i < 3; i++) { var index = lastIndex - i; var price = MarketSeries.Close[index]; Print("Closing Price at index {0} is {1}", lastIndex - i, price); } }
@cAlgo_Fanatic
cAlgo_Fanatic
24 Apr 2013, 09:30
We are already considering or working on all of your suggestions. Thank you for your input.
@cAlgo_Fanatic
cAlgo_Fanatic
24 Apr 2013, 09:22
Yes, the OnPositionOpened event is raised when a position is created. So, you can control/monitor the flow with this event.
@cAlgo_Fanatic
cAlgo_Fanatic
23 Apr 2013, 15:09
For the time being you cannot access the Account Interface so it would not be possible to access any position of the account but there are plans to implement this.
@cAlgo_Fanatic
cAlgo_Fanatic
23 Apr 2013, 15:01
You can find the code for the momentum oscillator here: Momentum Oscillator.
@cAlgo_Fanatic
cAlgo_Fanatic
23 Apr 2013, 15:00
Momentum Oscillator :
using cAlgo.API; namespace cAlgo.Indicators { [Indicator("Momentum Oscillator")] public class MomentumOscillatorIndicator : Indicator { [Parameter] public DataSeries Source { get; set; } [Parameter(DefaultValue = 14, MinValue = 1)] public int Periods { get; set; } [Output("Main")] public IndicatorDataSeries Result { get; set; } public override void Calculate(int index) { Result[index] = 100 * Source[index] / Source[index - Periods]; } } }
@cAlgo_Fanatic
cAlgo_Fanatic
23 Apr 2013, 14:31
To hedge all positions in the Account:
[Parameter(DefaultValue = 100000)] public int Volume { get; set; } protected override void OnStart() { foreach (var position in Account.Positions) { if (position.TradeType == TradeType.Buy) { Trade.CreateSellMarketOrder(Symbol, Volume); //break; // optional break to hedge only one position } else { Trade.CreateBuyMarketOrder(Symbol, Volume); //break; // optional break to hedge only one position } } }
@cAlgo_Fanatic
cAlgo_Fanatic
23 Apr 2013, 14:14
You can set it to double.NaN for each value you want to hide.
@cAlgo_Fanatic
cAlgo_Fanatic
23 Apr 2013, 11:34
You can reference the Keltner Channels Indicator (need to download and build) and the Bollinger Bands (build in) Indicator. The Momentum Oscillator oscillates to 100, so you would have to scale it down if you want your signal output to oscillate between 1 and 0. Also you may want to oscillate between 1 and 0.99 instead of zero so that you can see the momentum histogram properly.
//#reference: KeltnerChannels.algo using cAlgo.API; using cAlgo.API.Indicators; //... /////////////////////////////////////////// // Bollinger Bands private BollingerBands bollingerBands; [Parameter(DefaultValue = MovingAverageType.Simple)] public MovingAverageType BBMaType { get; set; } [Parameter(DefaultValue = 2)] public double BBStdev { get; set; } [Parameter(DefaultValue = 14)] public int BBPeriod { get; set; } [Parameter] public DataSeries BBSource { get; set; } /////////////////////////////////////////// // Keltner Channels private KeltnerChannels keltnerChannels; [Parameter(DefaultValue = 1.5)] public double BandDistance { get; set; } [Parameter(DefaultValue = 20)] public int KeltnerPeriod { get; set; } [Parameter(DefaultValue = MovingAverageType.Simple)] public MovingAverageType KeltnerMaType { get; set; } /////////////////////////////////////////// //... protected override void Initialize() { _momentum = Indicators.MomentumOscillator(MarketSeries.Close, 14); bollingerBands = Indicators.BollingerBands(BBSource, BBPeriod, BBStdev, BBMaType); keltnerChannels = Indicators.GetIndicator<KeltnerChannels>(KeltnerPeriod, BandDistance, KeltnerMaType); } public override void Calculate(int index) { double momentum = _momentum.Result[index]; Result[index] = momentum/100; // scale it down // which is 1 when the bollinger upper band is lower than the keltner upper band, // and the boll low is higher than the keltner low; otherwise the signal is 0. if( bollingerBands.Top[index] < keltnerChannels.ChannelUp[index] && bollingerBands.Bottom[index] > keltnerChannels.ChannelLow[index]) { Result2[index] = 1; } else { Result2[index] = 0.98; } } } }
@cAlgo_Fanatic
cAlgo_Fanatic
22 Apr 2013, 18:10
( Updated at: 23 Jan 2024, 13:16 )
[Today High and Low Indicator]
@cAlgo_Fanatic
cAlgo_Fanatic
22 Apr 2013, 18:01
using System ; using cAlgo.API; namespace cAlgo.Indicators { [Indicator(IsOverlay = true)] public class TodayHighLow : Indicator { private Timeframe _timeframe = Timeframe.Na; private double high = double.MinValue; private double low = double.MaxValue; [Output("High", Color = Colors.Lime)] public IndicatorDataSeries High { get; set; } [Output("Low", Color = Colors.Red)] public IndicatorDataSeries Low { get; set; } public override void Calculate(int index) { if (index < 1) return; if (_timeframe == Timeframe.Na) { _timeframe = GetTimeFrame(index); if (_timeframe == Timeframe.Na) { const string naText = "Timeframe Not Applicable"; ChartObjects.DrawText("object1", naText, StaticPosition.TopLeft, Colors.Red); return; } } if (_timeframe == Timeframe.D1) { High[index] = MarketSeries.High[index - 1]; Low[index] = MarketSeries.Low[index - 1]; return; } DateTime currentOpenTime = MarketSeries.OpenTime[index]; bool isToday = currentOpenTime.Date == DateTime.Now.Date; if (isToday) { if (MarketSeries.High[index] > high) high = MarketSeries.High[index]; if (MarketSeries.Low[index] < low) low = MarketSeries.Low[index]; } if (IsRealTime) { for (int i = 0; i <= index; i++) { High[i] = high; Low[i] = low; } } } /// <summary> /// Get the current chart timeframe /// </summary> private Timeframe GetTimeFrame(int index) { DateTime currentOpenTime = MarketSeries.OpenTime[index]; DateTime previousOpenTime = MarketSeries.OpenTime[index - 1]; if (currentOpenTime.DayOfWeek == DayOfWeek.Monday && previousOpenTime.DayOfWeek != DayOfWeek.Monday) { currentOpenTime = previousOpenTime; previousOpenTime = MarketSeries.OpenTime[index - 2]; } TimeSpan barTimeDiff = currentOpenTime - previousOpenTime; var totalMin = (int) barTimeDiff.TotalMinutes; switch (totalMin) { case 1: return Timeframe.m1; case 2: return Timeframe.m2; case 3: return Timeframe.m3; case 4: return Timeframe.m4; case 5: return Timeframe.m5; case 10: return Timeframe.m10; case 15: return Timeframe.m15; case 30: return Timeframe.m30; case 60: return Timeframe.h1; case 240: return Timeframe.h4; case 720: return Timeframe.h12; case 1440: return Timeframe.D1; default: return Timeframe.Na; } } private enum Timeframe { m1, m2, m3, m4, m5, m10, m15, m30, h1, h4, h12, D1, Na } } }
@cAlgo_Fanatic
cAlgo_Fanatic
26 Apr 2013, 15:44
@cAlgo_Fanatic