cAlgo 1% Risk Based Lot Size HELP
cAlgo 1% Risk Based Lot Size HELP
10 Apr 2019, 14:20
Hey guys,
Okay, so I do not claim to be programmer, so I would like some help please :)
I have created an algo using FXPro Quant strategy builder and I would like to change the coding to allow for the lot size to be set automatically by setting a risk percentage. For example if my account was 10,000 I would only be risking £100 on a trade if I wanted to only risk 1%.
So, my lot size will be adjusted accordingly based on my 1% risk per trade.
Code is below :)
//+------------------------------------------------------------------+ //+ Code generated using FxPro Quant 2.1.4 | //+------------------------------------------------------------------+ using System; using System.Threading; using cAlgo.API; using cAlgo.API.Indicators; using cAlgo.API.Internals; using cAlgo.API.Requests; using cAlgo.Indicators; namespace cAlgo.Robots { [Robot(TimeZone = TimeZones.UTC)] public class Prototype : Robot { [Parameter("SL_Points", DefaultValue = 100)] public int _SL_Points { get; set; } [Parameter("Lots", DefaultValue = 0.1)] public double _Lots { get; set; } [Parameter("Candle_Points", DefaultValue = 500)] public int _Candle_Points { get; set; } [Parameter("TP_Points", DefaultValue = 200)] public int _TP_Points { get; set; } //Global declaration double _Open; double _Close; double _Transform; DateTime LastTradeExecution = new DateTime(0); protected override void OnStart() { } protected override void OnTick() { if (Trade.IsExecuting) return; //Local declaration TriState _Sell = new TriState(); TriState _Buy = new TriState(); //Step 1 _Open = MarketSeries.Open.Last(1); _Close = MarketSeries.Close.Last(1); _Transform = Transform(_Candle_Points, 3); //Step 2 //Step 3 //Step 4 //Step 5 if ((((_Open - (_Close)) >= _Transform) && (MarketSeries.TickVolume.LastValue == 1))) _Sell = Sell(0, _Lots, 1, _SL_Points, 1, _TP_Points, 10, 1, 0, ""); if ((((_Close - (_Open)) >= _Transform) && (MarketSeries.TickVolume.LastValue == 1))) _Buy = Buy(0, _Lots, 1, _SL_Points, 1, _TP_Points, 10, 1, 0, ""); } bool NoOrders(string symbolCode, double[] magicIndecies) { if (symbolCode == "") symbolCode = Symbol.Code; string[] labels = new string[magicIndecies.Length]; for (int i = 0; i < magicIndecies.Length; i++) { labels[i] = "FxProQuant_" + magicIndecies[i].ToString("F0"); } foreach (Position pos in Positions) { if (pos.SymbolCode != symbolCode) continue; if (labels.Length == 0) return false; foreach (var label in labels) { if (pos.Label == label) return false; } } foreach (PendingOrder po in PendingOrders) { if (po.SymbolCode != symbolCode) continue; if (labels.Length == 0) return false; foreach (var label in labels) { if (po.Label == label) return false; } } return true; } TriState _OpenPosition(double magicIndex, bool noOrders, string symbolCode, TradeType tradeType, double lots, double slippage, double? stopLoss, double? takeProfit, string comment) { Symbol symbol = (Symbol.Code == symbolCode) ? Symbol : MarketData.GetSymbol(symbolCode); if (noOrders && Positions.Find("FxProQuant_" + magicIndex.ToString("F0"), symbol) != null) return new TriState(); if (stopLoss < 1) stopLoss = null; if (takeProfit < 1) takeProfit = null; if (symbol.Digits == 5 || symbol.Digits == 3) { if (stopLoss != null) stopLoss /= 10; if (takeProfit != null) takeProfit /= 10; slippage /= 10; } int volume = Convert.ToInt32(lots * 100000); if (!ExecuteMarketOrder(tradeType, symbol, volume, "FxProQuant_" + magicIndex.ToString("F0"), stopLoss, takeProfit, slippage, comment).IsSuccessful) { Thread.Sleep(400); return false; } return true; } TriState _SendPending(double magicIndex, bool noOrders, string symbolCode, PendingOrderType poType, TradeType tradeType, double lots, int priceAction, double priceValue, double? stopLoss, double? takeProfit, DateTime? expiration, string comment) { Symbol symbol = (Symbol.Code == symbolCode) ? Symbol : MarketData.GetSymbol(symbolCode); if (noOrders && PendingOrders.__Find("FxProQuant_" + magicIndex.ToString("F0"), symbol) != null) return new TriState(); if (stopLoss < 1) stopLoss = null; if (takeProfit < 1) takeProfit = null; if (symbol.Digits == 5 || symbol.Digits == 3) { if (stopLoss != null) stopLoss /= 10; if (takeProfit != null) takeProfit /= 10; } int volume = Convert.ToInt32(lots * 100000); double targetPrice; switch (priceAction) { case 0: targetPrice = priceValue; break; case 1: targetPrice = symbol.Bid - priceValue * symbol.TickSize; break; case 2: targetPrice = symbol.Bid + priceValue * symbol.TickSize; break; case 3: targetPrice = symbol.Ask - priceValue * symbol.TickSize; break; case 4: targetPrice = symbol.Ask + priceValue * symbol.TickSize; break; default: targetPrice = priceValue; break; } if (expiration.HasValue && (expiration.Value.Ticks == 0 || expiration.Value == DateTime.Parse("1970.01.01 00:00:00"))) expiration = null; if (poType == PendingOrderType.Limit) { if (!PlaceLimitOrder(tradeType, symbol, volume, targetPrice, "FxProQuant_" + magicIndex.ToString("F0"), stopLoss, takeProfit, expiration, comment).IsSuccessful) { Thread.Sleep(400); return false; } return true; } else if (poType == PendingOrderType.Stop) { if (!PlaceStopOrder(tradeType, symbol, volume, targetPrice, "FxProQuant_" + magicIndex.ToString("F0"), stopLoss, takeProfit, expiration, comment).IsSuccessful) { Thread.Sleep(400); return false; } return true; } return new TriState(); } TriState _ModifyPosition(double magicIndex, string symbolCode, int slAction, double slValue, int tpAction, double tpValue) { Symbol symbol = (Symbol.Code == symbolCode) ? Symbol : MarketData.GetSymbol(symbolCode); var pos = Positions.Find("FxProQuant_" + magicIndex.ToString("F0"), symbol); if (pos == null) return new TriState(); double? sl, tp; if (slValue == 0) sl = null; else { switch (slAction) { case 0: sl = pos.StopLoss; break; case 1: if (pos.TradeType == TradeType.Buy) sl = pos.EntryPrice - slValue * symbol.TickSize; else sl = pos.EntryPrice + slValue * symbol.TickSize; break; case 2: sl = slValue; break; default: sl = pos.StopLoss; break; } } if (tpValue == 0) tp = null; else { switch (tpAction) { case 0: tp = pos.TakeProfit; break; case 1: if (pos.TradeType == TradeType.Buy) tp = pos.EntryPrice + tpValue * symbol.TickSize; else tp = pos.EntryPrice - tpValue * symbol.TickSize; break; case 2: tp = tpValue; break; default: tp = pos.TakeProfit; break; } } if (!ModifyPosition(pos, sl, tp).IsSuccessful) { Thread.Sleep(400); return false; } return true; } TriState _ModifyPending(double magicIndex, string symbolCode, int slAction, double slValue, int tpAction, double tpValue, int priceAction, double priceValue, int expirationAction, DateTime? expiration) { Symbol symbol = (Symbol.Code == symbolCode) ? Symbol : MarketData.GetSymbol(symbolCode); var po = PendingOrders.__Find("FxProQuant_" + magicIndex.ToString("F0"), symbol); if (po == null) return new TriState(); double targetPrice; double? sl, tp; if (slValue == 0) sl = null; else { switch (slAction) { case 0: sl = po.StopLoss; break; case 1: if (po.TradeType == TradeType.Buy) sl = po.TargetPrice - slValue * symbol.TickSize; else sl = po.TargetPrice + slValue * symbol.TickSize; break; case 2: sl = slValue; break; default: sl = po.StopLoss; break; } } if (tpValue == 0) tp = null; else { switch (tpAction) { case 0: tp = po.TakeProfit; break; case 1: if (po.TradeType == TradeType.Buy) tp = po.TargetPrice + tpValue * symbol.TickSize; else tp = po.TargetPrice - tpValue * symbol.TickSize; break; case 2: tp = tpValue; break; default: tp = po.TakeProfit; break; } } switch (priceAction) { case 0: targetPrice = po.TargetPrice; break; case 1: targetPrice = priceValue; break; case 2: targetPrice = po.TargetPrice + priceValue * symbol.TickSize; break; case 3: targetPrice = po.TargetPrice - priceValue * symbol.TickSize; break; case 4: targetPrice = symbol.Bid - priceValue * symbol.TickSize; break; case 5: targetPrice = symbol.Bid + priceValue * symbol.TickSize; break; case 6: targetPrice = symbol.Ask - priceValue * symbol.TickSize; break; case 7: targetPrice = symbol.Ask + priceValue * symbol.TickSize; break; default: targetPrice = po.TargetPrice; break; } if (expiration.HasValue && (expiration.Value.Ticks == 0 || expiration.Value == DateTime.Parse("1970.01.01 00:00:00"))) expiration = null; if (expirationAction == 0) expiration = po.ExpirationTime; if (!ModifyPendingOrder(po, targetPrice, sl, tp, expiration).IsSuccessful) { Thread.Sleep(400); return false; } return true; } TriState _ClosePosition(double magicIndex, string symbolCode, double lots) { Symbol symbol = (Symbol.Code == symbolCode) ? Symbol : MarketData.GetSymbol(symbolCode); var pos = Positions.Find("FxProQuant_" + magicIndex.ToString("F0"), symbol); if (pos == null) return new TriState(); TradeResult result; if (lots == 0) { result = ClosePosition(pos); } else { int volume = Convert.ToInt32(lots * 100000); result = ClosePosition(pos, volume); } if (!result.IsSuccessful) { Thread.Sleep(400); return false; } return true; } TriState _DeletePending(double magicIndex, string symbolCode) { Symbol symbol = (Symbol.Code == symbolCode) ? Symbol : MarketData.GetSymbol(symbolCode); var po = PendingOrders.__Find("FxProQuant_" + magicIndex.ToString("F0"), symbol); if (po == null) return new TriState(); if (!CancelPendingOrder(po).IsSuccessful) { Thread.Sleep(400); return false; } return true; } bool _OrderStatus(double magicIndex, string symbolCode, int test) { Symbol symbol = (Symbol.Code == symbolCode) ? Symbol : MarketData.GetSymbol(symbolCode); var pos = Positions.Find("FxProQuant_" + magicIndex.ToString("F0"), symbol); if (pos != null) { if (test == 0) return true; if (test == 1) return true; if (test == 3) return pos.TradeType == TradeType.Buy; if (test == 4) return pos.TradeType == TradeType.Sell; } var po = PendingOrders.__Find("FxProQuant_" + magicIndex.ToString("F0"), symbol); if (po != null) { if (test == 0) return true; if (test == 2) return true; if (test == 3) return po.TradeType == TradeType.Buy; if (test == 4) return po.TradeType == TradeType.Sell; if (test == 5) return po.OrderType == PendingOrderType.Limit; if (test == 6) return po.OrderType == PendingOrderType.Stop; } return false; } int TimeframeToInt(TimeFrame tf) { if (tf == TimeFrame.Minute) return 1; else if (tf == TimeFrame.Minute2) return 2; else if (tf == TimeFrame.Minute3) return 3; else if (tf == TimeFrame.Minute4) return 4; else if (tf == TimeFrame.Minute5) return 5; else if (tf == TimeFrame.Minute10) return 10; else if (tf == TimeFrame.Minute15) return 15; else if (tf == TimeFrame.Minute30) return 30; else if (tf == TimeFrame.Hour) return 60; else if (tf == TimeFrame.Hour4) return 240; else if (tf == TimeFrame.Daily) return 1440; else if (tf == TimeFrame.Weekly) return 10080; else if (tf == TimeFrame.Monthly) return 43200; return 1; } DateTime __currentBarTime = DateTime.MinValue; bool __isNewBar(bool triggerAtStart) { DateTime newTime = MarketSeries.OpenTime.LastValue; if (__currentBarTime != newTime) { if (!triggerAtStart && __currentBarTime == DateTime.MinValue) { __currentBarTime = newTime; return false; } __currentBarTime = newTime; return true; } return false; } TriState Sell(double magicIndex, double Lots, int StopLossMethod, double stopLossValue, int TakeProfitMethod, double takeProfitValue, double Slippage, double MaxOpenTrades, double MaxFrequencyMins, string TradeComment) { double? stopLossPips, takeProfitPips; int numberOfOpenTrades = 0; var res = new TriState(); foreach (Position pos in Positions.FindAll("FxProQuant_" + magicIndex.ToString("F0"), Symbol)) { numberOfOpenTrades++; } if (MaxOpenTrades > 0 && numberOfOpenTrades >= MaxOpenTrades) return res; if (MaxFrequencyMins > 0) { if (((TimeSpan)(Server.Time - LastTradeExecution)).TotalMinutes < MaxFrequencyMins) return res; foreach (Position pos in Positions.FindAll("FxProQuant_" + magicIndex.ToString("F0"), Symbol)) { if (((TimeSpan)(Server.Time - pos.EntryTime)).TotalMinutes < MaxFrequencyMins) return res; } } int pipAdjustment = Convert.ToInt32(Symbol.PipSize / Symbol.TickSize); if (stopLossValue > 0) { if (StopLossMethod == 0) stopLossPips = stopLossValue / pipAdjustment; else if (StopLossMethod == 1) stopLossPips = stopLossValue; else stopLossPips = (stopLossValue - Symbol.Bid) / Symbol.PipSize; } else stopLossPips = null; if (takeProfitValue > 0) { if (TakeProfitMethod == 0) takeProfitPips = takeProfitValue / pipAdjustment; else if (TakeProfitMethod == 1) takeProfitPips = takeProfitValue; else takeProfitPips = (Symbol.Bid - takeProfitValue) / Symbol.PipSize; } else takeProfitPips = null; Slippage /= pipAdjustment; long volume = Symbol.NormalizeVolume(Lots * 100000, RoundingMode.ToNearest); if (!ExecuteMarketOrder(TradeType.Sell, Symbol, volume, "FxProQuant_" + magicIndex.ToString("F0"), stopLossPips, takeProfitPips, Slippage, TradeComment).IsSuccessful) { Thread.Sleep(400); return false; } LastTradeExecution = Server.Time; return true; } double Transform(double Value, int Transformation) { switch (Transformation) { case 0: return (Value / Symbol.TickSize); case 1: return (Value / Symbol.PipSize); case 2: return (Value * Symbol.TickSize); case 3: return (Value * Symbol.PipSize); default: return (0); } } TriState Buy(double magicIndex, double Lots, int StopLossMethod, double stopLossValue, int TakeProfitMethod, double takeProfitValue, double Slippage, double MaxOpenTrades, double MaxFrequencyMins, string TradeComment) { double? stopLossPips, takeProfitPips; int numberOfOpenTrades = 0; var res = new TriState(); foreach (Position pos in Positions.FindAll("FxProQuant_" + magicIndex.ToString("F0"), Symbol)) { numberOfOpenTrades++; } if (MaxOpenTrades > 0 && numberOfOpenTrades >= MaxOpenTrades) return res; if (MaxFrequencyMins > 0) { if (((TimeSpan)(Server.Time - LastTradeExecution)).TotalMinutes < MaxFrequencyMins) return res; foreach (Position pos in Positions.FindAll("FxProQuant_" + magicIndex.ToString("F0"), Symbol)) { if (((TimeSpan)(Server.Time - pos.EntryTime)).TotalMinutes < MaxFrequencyMins) return res; } } int pipAdjustment = Convert.ToInt32(Symbol.PipSize / Symbol.TickSize); if (stopLossValue > 0) { if (StopLossMethod == 0) stopLossPips = stopLossValue / pipAdjustment; else if (StopLossMethod == 1) stopLossPips = stopLossValue; else stopLossPips = (Symbol.Ask - stopLossValue) / Symbol.PipSize; } else stopLossPips = null; if (takeProfitValue > 0) { if (TakeProfitMethod == 0) takeProfitPips = takeProfitValue / pipAdjustment; else if (TakeProfitMethod == 1) takeProfitPips = takeProfitValue; else takeProfitPips = (takeProfitValue - Symbol.Ask) / Symbol.PipSize; } else takeProfitPips = null; Slippage /= pipAdjustment; long volume = Symbol.NormalizeVolume(Lots * 100000, RoundingMode.ToNearest); if (!ExecuteMarketOrder(TradeType.Buy, Symbol, volume, "FxProQuant_" + magicIndex.ToString("F0"), stopLossPips, takeProfitPips, Slippage, TradeComment).IsSuccessful) { Thread.Sleep(400); return false; } LastTradeExecution = Server.Time; return true; } } } public struct TriState { public static readonly TriState NonExecution = new TriState(0); public static readonly TriState False = new TriState(-1); public static readonly TriState True = new TriState(1); sbyte value; TriState(int value) { this.value = (sbyte)value; } public bool IsNonExecution { get { return value == 0; } } public static implicit operator TriState(bool x) { return x ? True : False; } public static TriState operator ==(TriState x, TriState y) { if (x.value == 0 || y.value == 0) return NonExecution; return x.value == y.value ? True : False; } public static TriState operator !=(TriState x, TriState y) { if (x.value == 0 || y.value == 0) return NonExecution; return x.value != y.value ? True : False; } public static TriState operator !(TriState x) { return new TriState(-x.value); } public static TriState operator &(TriState x, TriState y) { return new TriState(x.value < y.value ? x.value : y.value); } public static TriState operator |(TriState x, TriState y) { return new TriState(x.value > y.value ? x.value : y.value); } public static bool operator true(TriState x) { return x.value > 0; } public static bool operator false(TriState x) { return x.value < 0; } public static implicit operator bool(TriState x) { return x.value > 0; } public override bool Equals(object obj) { if (!(obj is TriState)) return false; return value == ((TriState)obj).value; } public override int GetHashCode() { return value; } public override string ToString() { if (value > 0) return "True"; if (value < 0) return "False"; return "NonExecution"; } } public static class PendingEx { public static PendingOrder __Find(this cAlgo.API.PendingOrders pendingOrders, string label, Symbol symbol) { foreach (PendingOrder po in pendingOrders) { if (po.SymbolCode == symbol.Code && po.Label == label) return po; } return null; } }
Your comments will be deeply appreciated,
Samuel
Replies
samuelbreezey
05 May 2019, 14:32
RE:
Jonkey said:
https://ctrader.com/forum/cbot-support/1573
The code you need is in here. But coupling it into your code is the fun bit (friendly sarcasm)... It's just a time thing... that I don't have right now to do it for you... and even then it might be buggy... and id have to spend time debugging it ... hope this helps but im sorry I can't be of more help.
Coding is a source, it will change your life... swear to God. : )
Thank you
I have now been able to do this thanks to the thread you gave me.
Much appreciated :)
@samuelbreezey
Jonkey
24 Apr 2019, 08:54
https://ctrader.com/forum/cbot-support/1573
The code you need is in here. But coupling it into your code is the fun bit (friendly sarcasm)... It's just a time thing... that I don't have right now to do it for you... and even then it might be buggy... and id have to spend time debugging it ... hope this helps but im sorry I can't be of more help.
Coding is a source, it will change your life... swear to God. : )
@Jonkey