Profitable cBot apart from one rogue parameter!!
Profitable cBot apart from one rogue parameter!!
15 Sep 2015, 16:54
Hi All,
I've been getting some good results with the robot below, however I have a parameter that doesn't seem to act as it should...
I'm counting up the total pips of a position with this:
int totalPips = (int)(Positions[y].Pips - Positions[y].EntryPrice);
and then using totalPips to delay when a martingale strategy is called with this
if ( totalPips <= MartingaleTrigger * Symbol.PipSize)
The problem is that this MartingaleTrigger value isn't doing anything related to the Symbol.Pipsize. In fact, back test results remain the same regardless of the MartingaleTrigger value. However, if I remove the parameter all together the backtest results do change!?!?
Any help or advice would be greatly appreciated...
(Backtest with EURGBP, m1)
using System; using System.Linq; using System.Collections.Generic; using cAlgo.API; using cAlgo.API.Requests; using cAlgo.API.Indicators; using cAlgo.API.Internals; using cAlgo.Indicators; namespace cAlgo { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class BolliBot : Robot { [Parameter("Source")] public DataSeries SourceSeries { get; set; } [Parameter("Stop Loss (pips)", DefaultValue = 1000, MinValue = 1)] private int StopLossInPips { get; set; } [Parameter("Take Profit (pips)", DefaultValue = 1000, MinValue = 1)] private int TakeProfitInPips { get; set; } [Parameter("Volume", DefaultValue = 1000, MinValue = 1000)] public int Volume { get; set; } [Parameter("RSI High Trigger", DefaultValue = 60)] public int highRSI { get; set; } [Parameter("RSI Low Trigger", DefaultValue = 40)] public int lowRSI { get; set; } [Parameter("Bollinger Bands Deviations", DefaultValue = 2.5)] public double Deviations { get; set; } [Parameter("Periods", DefaultValue = 20)] public int Periods { get; set; } [Parameter("Fast MA", DefaultValue = 1)] public int FastPeriods { get; set; } [Parameter("MA Type")] public MovingAverageType MAType { get; set; } [Parameter("Mid MA", DefaultValue = 200)] public int MidPeriods { get; set; } [Parameter("Slow MA", DefaultValue = 1000)] public int SlowPeriods { get; set; } [Parameter("Martingale Trigger", DefaultValue = -5)] public int MartingaleTrigger { get; set; } [Parameter("Overall Profit Take Profit", DefaultValue = 10)] public int OverAllProfitTP { get; set; } [Parameter("Overall Loss Stop Loss", DefaultValue = -10000)] public int OverAllLossSL { get; set; } [Parameter("MartinGale Volume Multiplied By", DefaultValue = 32)] public int martingaleMultiplier { get; set; } private RelativeStrengthIndex rsi; private MovingAverage fastMa; private MovingAverage midMa; private MovingAverage slowMa; Dictionary<int, int> dic = new Dictionary<int, int>(); BollingerBands bollingerBands; string label = "BolliBot"; protected override void OnStart() { bollingerBands = Indicators.BollingerBands(SourceSeries, Periods, Deviations, MAType); rsi = Indicators.RelativeStrengthIndex(SourceSeries, Periods); fastMa = Indicators.MovingAverage(SourceSeries, FastPeriods, MAType); midMa = Indicators.MovingAverage(SourceSeries, MidPeriods, MAType); slowMa = Indicators.MovingAverage(SourceSeries, SlowPeriods, MAType); } private void ExecuteOrder(int volume, TradeType tradeType) { ExecuteMarketOrder(tradeType, Symbol, volume, label, StopLossInPips, TakeProfitInPips); } protected override void OnBar() { var top = bollingerBands.Top.Last(1); var bottom = bollingerBands.Bottom.Last(1); var longPosition = Positions.Find(label, Symbol, TradeType.Buy); var shortPosition = Positions.Find(label, Symbol, TradeType.Sell); var FastMa = fastMa.Result.Last(0); var MidMa = midMa.Result.Last(0); var SlowMa = slowMa.Result.Last(0); var high = rsi.Result.Last(0); var low = rsi.Result.Last(0); var shortPositionsCount = Positions.Count(p => p.TradeType == TradeType.Sell); var longPositionsCount = Positions.Count(p => p.TradeType == TradeType.Buy); if (Symbol.Bid > top && high > highRSI && FastMa < MidMa && MidMa < SlowMa) { ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, label, StopLossInPips, TakeProfitInPips); Print("Short Position. Num positions : " + Positions.Count + " Split long : " + longPositionsCount + " short : " + shortPositionsCount); } if (Symbol.Ask < bottom && low < lowRSI && FastMa > MidMa && MidMa > SlowMa) { ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, label, StopLossInPips, TakeProfitInPips); Print("Long Position. Num positions : " + Positions.Count + " Split long : " + longPositionsCount + " short : " + shortPositionsCount); } } protected override void OnTick() { var top = bollingerBands.Top.Last(1); var bottom = bollingerBands.Bottom.Last(1); var longPosition = Positions.Find(label, Symbol, TradeType.Buy); var shortPosition = Positions.Find(label, Symbol, TradeType.Sell); var FastMa = fastMa.Result.Last(0); var MidMa = midMa.Result.Last(0); var SlowMa = slowMa.Result.Last(0); var high = rsi.Result.Last(0); var low = rsi.Result.Last(0); var shortPositionsCount = Positions.Count(p => p.TradeType == TradeType.Sell); var longPositionsCount = Positions.Count(p => p.TradeType == TradeType.Buy); var symbolSearch = Positions.FindAll(label, Symbol); int posCount = Positions.Count; foreach (Position position in symbolSearch) for (int y = posCount - 1; y >= 0; y--) { int totalPips = (int)(Positions[y].Pips - Positions[y].EntryPrice); int test = 0; if (!dic.TryGetValue(Positions[y].Id, out test)) { dic[Positions[y].Id] = 0; } if (Positions[y].TradeType == TradeType.Sell && totalPips <= MartingaleTrigger * Symbol.PipSize && test == 0 && Positions[y].Volume < Volume * martingaleMultiplier && Symbol.Bid > top && high > highRSI && FastMa < MidMa && MidMa < SlowMa) { dic[Positions[y].Id] = 1; ExecuteOrder((int)Positions[y].Volume * 2, Positions[y].TradeType); Print("Martingale SHORT!!. Num positions : " + Positions.Count + " Split... long : " + longPositionsCount + " short : " + shortPositionsCount); } if (Positions[y].TradeType == TradeType.Buy && totalPips <= MartingaleTrigger * Symbol.PipSize && test == 0 && Positions[y].Volume < Volume * martingaleMultiplier && Symbol.Ask < bottom && low < lowRSI && FastMa > MidMa && MidMa > SlowMa) { dic[Positions[y].Id] = 1; ExecuteOrder((int)Positions[y].Volume * 2, Positions[y].TradeType); Print("Martingale LONG!!. Num positions : " + Positions.Count + " Split... long : " + longPositionsCount + " short : " + shortPositionsCount); } } double overallProfit = 0; foreach (Position position in symbolSearch) { overallProfit += position.GrossProfit; } if (overallProfit >= OverAllProfitTP) { Print("OVERALL Profit TOTAL = " + overallProfit + " Closing All Positions. Num positions: " + Positions.Count); foreach (Position position in symbolSearch) { ClosePosition(position); } } if (overallProfit <= OverAllLossSL) { Print("OVERALL Loss TOTAL = " + overallProfit + " Closing All Positions. Num positions: " + Positions.Count); foreach (Position position in symbolSearch) { ClosePosition(position); } } } } }
moneybiz
15 Sep 2015, 22:45
RE:
9718853 said:
Positions[y].Pips is already gibing you the profit or loss in pips.
Subtracting Positions[y].EntryPrice from pips is not logical. One is a value like 10 (pips) and the other is a value like 1.12345.
int totalPips = Positions[y].Pips is enough.
What does the MartingaleTrigger represent, pips or price? If pips then totalPips <= MartingaleTrigger is enough.
You use multiplication with Symbol.PipSize only when you want to add/subtract some pips from a price value.
Say you want to set a take profit price position as 10 pips from the entry price.
var takeProfit = Positions[y].EntryPrice + (TakeProfitPips * Symbol.PipSize);
var takeProfit = 1.12345 + (10 * 0.0001) = 1.12445
@moneybiz