Topics
Replies
chatcpe
07 Aug 2023, 17:21
RE: cTrader calculate wrong Max equity drawdown
PanagiotisChar said:
Hi there,
Your drawdown calculation is wrong. The drawdown is calculated from the peak equity to the lowest equity after that.
Need help? Join us on Telegram
Where? THis is my code
private void CalculateDDForAccount()
{
try
{
var newDDdol = Account.Balance - Account.Equity;
if (newDDdol > MaxEquityDDInDol)
{
MaxEquityDDInDol = newDDdol;
}var newDDPercent = newDDdol / Account.Balance * 100;
if (newDDPercent > MaxEquityDDPercent)
{
MaxEquityDDPercent = newDDPercent;
}}
catch (Exception ex)
{
Print($"Error in CalculateDDForAccount : {ex.Message}");
}
}
@chatcpe
chatcpe
07 Jul 2020, 10:59
Example multi symbol
namespace cAlgo
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
public class EMA_2Cross_1Trend_RR : Robot
{
[Parameter("Fix Vol Trade", DefaultValue = true, Group = "Trade")]
public bool FixVolTrade { get; set; }
[Parameter("PerStart", DefaultValue = 1, Group = "Trade", MinValue = 1)]
public int PerStart { get; set; }
[Parameter("TradeWay", Group = "Trade", DefaultValue = TradeOnlyWay.Both)]
public TradeOnlyWay WantTradeWay { get; set; }
[Parameter("TP", Group = "Trade", DefaultValue = 50, MinValue = 1)]
public int TP { get; set; }
[Parameter("SL", Group = "Trade", DefaultValue = 25, MinValue = 1)]
public int SL { get; set; }
[Parameter("MaxOpen", Group = "Trade", DefaultValue = 1, MinValue = 1)]
public int MaxOpen { get; set; }
[Parameter("SymBol To Trade", Group = "Trade", DefaultValue = "AUDCAD,AUDCHF,AUDJPY,AUDNZD,AUDSGD,AUDUSD,CADCHF,CADJPY,CHFJPY,CHFSGD,EURAUD,EURCAD,EURCHF,EURGBP,EURJPY,EURNZD,EURSGD,EURUSD,GBPAUD,GBPCAD,GBPCHF,GBPJPY,GBPNZD,GBPSGD,GBPUSD,NZDCAD,NZDCHF,NZDJPY,NZDUSD,SGDJPY,USDCAD,USDCHF,USDJPY,USDSGD")]
public string SymBolToTrade { get; set; }
[Parameter("Strategies name", Group = "Trade", DefaultValue = "EMA_2Cross_1Trend_RR")]
public string StrategiesName { get; set; }
#region EMA
[Parameter("EMA 1 Source", Group = "EMA")]
public DataSeries EMA1Source { get; set; }
[Parameter("EMA 1 Periods", Group = "EMA", DefaultValue = 9)]
public int EMA1_Period { get; set; }
[Parameter("EMA 2 Source", Group = "EMA")]
public DataSeries EMA2Source { get; set; }
[Parameter("EMA 2 Periods", Group = "EMA", DefaultValue = 21)]
public int EMA2_Period { get; set; }
[Parameter("EMA 2 Source", Group = "EMA")]
public DataSeries EMA3Source { get; set; }
[Parameter("EMA 3 Periods", Group = "EMA", DefaultValue = 200)]
public int EMA3_Period { get; set; }
#endregion
List<Symbol> lsSymbol = new List<Symbol>();
Dictionary<Symbol, Bars> dicSymbolBar = new Dictionary<Symbol, Bars>();
Dictionary<Symbol, ExponentialMovingAverage> dicEMA1 = new Dictionary<Symbol, ExponentialMovingAverage>();
Dictionary<Symbol, ExponentialMovingAverage> dicEMA2 = new Dictionary<Symbol, ExponentialMovingAverage>();
Dictionary<Symbol, ExponentialMovingAverage> dicEMA3 = new Dictionary<Symbol, ExponentialMovingAverage>();
List<TradeLog> _tradeLogs = new List<TradeLog>();
double StartBalance = 0;
protected override void OnStart()
{
Print("Start OnStart");
StartBalance = Account.Balance;
Positions.Opened += PositionsOnOpened;
Positions.Closed += PositionsOnClosed;
LoadSymbolsDataAndIndi();
Print("End OnStart");
}
private void LoadSymbolsDataAndIndi()
{
try
{
//แยกคู่ที่ต้องการเทรดด้วย ,
var AllSymbol = SymBolToTrade.Split(',').ToList();
//List<Task> lsTask = new List<Task>();
foreach (var sSymbol in AllSymbol)
{
//Task aTask = new Task(() =>
//{
var bar = MarketData.GetBars(TimeFrame, sSymbol);
var aSymbolBars = MarketData.GetBars(TimeFrame, sSymbol);
var aSymbol = Symbols.GetSymbol(sSymbol);
lsSymbol.Add(aSymbol);
dicSymbolBar.Add(aSymbol, aSymbolBars);
dicEMA1.Add(aSymbol, Indicators.ExponentialMovingAverage(aSymbolBars.ClosePrices, EMA1_Period));
dicEMA2.Add(aSymbol, Indicators.ExponentialMovingAverage(aSymbolBars.ClosePrices, EMA2_Period));
dicEMA3.Add(aSymbol, Indicators.ExponentialMovingAverage(aSymbolBars.ClosePrices, EMA3_Period));
Print("Finished get data >> " + sSymbol);
//});
//lsTask.Add(aTask);
//aTask.Start();
}
//Task.WaitAll(lsTask.ToArray());
} catch (Exception ex)
{
Print("ERROR LoadSymbolsDataAndIndi : " + ex.Message);
}
}
protected override void OnBar()
{
try
{
List<Task> lsTask = new List<Task>();
foreach (var symbol in lsSymbol)
{
//แตก thread แยกตามคู่เงิน
Task aTask = new Task(() =>
{
//ema1 ตัด ema2 *ลง* && ย้อนหลังไปสองแท่งที่ยังไม่ตัดลง EMA1 ยังต้อง*มากกว่า* 2 ด้วย ไม่งั้นมันจะเข้าออเดอร์ทุกๆแท่งเอาได้ *หรือเราจะไปเช็คว่ามีออเดอร์เปิดแล้วก็ไม่ให้เปิดดีกว่านะ
if (dicEMA1.Where(x=>x.Key == symbol).First().Value.Result.Last(1) <= dicEMA2.Where(x => x.Key == symbol).First().Value.Result.Last(1) && dicEMA1.Where(x => x.Key == symbol).First().Value.Result.Last(2) > dicEMA2.Where(x => x.Key == symbol).First().Value.Result.Last(2))
{
//EMA 1 & 2 ต้องอยู่*ใต้* 3 ด้วย
if (dicEMA1.Where(x=>x.Key == symbol).First().Value.Result.Last(1) <= dicEMA3.Where(x=>x.Key == symbol).First().Value.Result.Last(1) && dicEMA2.Where(x=>x.Key == symbol).First().Value.Result.Last(1) <= dicEMA3.Where(x=>x.Key == symbol).First().Value.Result.Last(1))
{
//*ยังไม่เช็คว่ามีออเดอร์เปิดอยู่แล้ว เปิดเพิ่มได้ กรณียังไม่ tp หรือ SL แต่มันวกมาตัดขึ้น-ลงเพิ่มอีกก็เป็นไปได้
//เช็คกับการตั้งค่าว่าให้เล่นแต่ขาไหน จะเข้า *sell* แต่ถ้าจะเล่นแต่ขา *buy* เราก็จะไม่เปิด
if (WantTradeWay != TradeOnlyWay.Buy)
{
//เช็คกรณีว่าเปิดไปแล้วกี่ไม้ และจะไม่ให้เปิดอีก เช็คเฉพาะขานั้นด้วย เพราะมีสิทธิ์มีสองขาเปิดพร้อมกันอยู่
if (Positions.Where(x => x.TradeType == TradeType.Sell).Count() >= MaxOpen)
{
return;
}
ExecuteMarketOrder(TradeType.Sell, SymbolName, Symbol.NormalizeVolumeInUnits((FixVolTrade ? StartBalance : Account.Balance) * PerStart), StrategiesName, SL, TP, "");
}
}
}.......
@chatcpe
chatcpe
13 Jul 2015, 09:09
( Updated at: 21 Dec 2023, 09:20 )
RE:
chatcpe said:
I testing my bot. I have 2 problem, one is I cannot invest over 1000 million$ so I fix code to split to 999 with a lot of order, not problem.
Error is : 13/07/2015 04:01:00.000 | Crashed in OnBar with ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index\
I think that the environment of the cAlgo is int(32bit number cannot more than 2100billion) My next invest volumn is 21660000000$ so it is more than int32bit cannot contain. The system to 64bit int64 can contain 9,000,000,000,000,000,000.
@chatcpe
chatcpe
13 Jul 2015, 09:08
( Updated at: 21 Dec 2023, 09:20 )
RE:
chatcpe said:
I testing my bot. I have 2 problem, one is I cannot invest over 1000 million$ so I fix code to split to 999 with a lot of order, not problem.
Error is : 13/07/2015 04:01:00.000 | Crashed in OnBar with ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index\
I think that the environment of the cAlgo is int(32bit number cannot more than 2100billion) My next invest volumn is 21660000000$ so it is more than int32bit cannot contain. The system to 64bit int64 can contain 9,000,000,000,000,000,000.
@chatcpe
chatcpe
10 Aug 2023, 10:22
RE: RE: RE: cTrader calculate wrong Max equity drawdown
PanagiotisChar said:
I think it is already corrected.
@chatcpe