I have made this cBot to enter a buy market order when the oscillator turns green and sell market order when the oscillator turns red. However , when backtesting the cBot, the cBot seemed to exceute the code correctly at times and incorrectly at other times. As shown in the video, the first trade was executed correctly , the bot made a sell order when the oscillator was <0 and then changed to a buy order when the oscillator was >0. The second trade was not executed correctly, the cBot did not enter the sell trade at the first oscillator bar below 0 but at the second bar which is not correct as the bot should have entered a sell trade at the first trade. How can i ensure that the code executes correctly each time ? This is the video https://streamable.com/bm4yt2
This is the cBot's code :
`using cAlgo.API;
using cAlgo.API.Indicators;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class BBPbot14 : Robot
{
private double _volumeInUnits;
[Parameter(DefaultValue = 9)]
public int Periods { get; set; }
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
public double VolumeInLots { get; set; }
[Parameter("Stop Loss (Pips)", DefaultValue = 0, MaxValue = 400, MinValue = 0, Step = 1)]
public double StopLossInPips { get; set; }
[Parameter("Take Profit (Pips)", DefaultValue = 100, MaxValue = 1000, MinValue = 0, Step = 1)]
public double TakeProfitInPips { get; set; }
[Parameter("Label", DefaultValue = "BBPbot14")]
public string Label { get; set; }
private Bbpminussma _bbp;
public Position[] BotPositions
{
get
{
return Positions.FindAll(Label);
}
}
private const string label = "BBPbot14";
private int _lastSignal = 0; // 1 for long signal, -1 for short signal, 0 for no signal
protected override void OnStart()
{
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
_bbp = Indicators.GetIndicator<Bbpminussma>(Periods);
}
protected override void OnTick()
{
var longPosition = Positions.Find(label, SymbolName, TradeType.Buy);
var shortPosition = Positions.Find(label, SymbolName, TradeType.Sell);
var value = 0;
double currentHist = _bbp.Sum.Last(0);
double previousHist = _bbp.Sum.Last(1);
// Detect upward crossing (long signal)
if (_bbp.Sum.Last(0)>0 && _bbp.Sum.Last(1) <0 )
{
if (_lastSignal != 1) // only execute if last signal wasn't long
{
_lastSignal = 1; // update last signal
if (longPosition == null)
ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, label, StopLossInPips, TakeProfitInPips);
if (shortPosition != null)
ClosePosition(shortPosition);
}
}
// Detect downward crossing (short signal)
else if (_bbp.Sum.Last(0)<0 && _bbp.Sum.Last(1)>0)
{
if (_lastSignal != -1) // only execute if last signal wasn't short
{
_lastSignal = -1; // update last signal
if (shortPosition == null)
ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, label, StopLossInPips, TakeProfitInPips);
if (longPosition != null)
ClosePosition(longPosition);
}
}
else if(_bbp.Sum.Last(0)>0 && _bbp.Sum.Last(1)>0 && shortPosition!= null )
{
ClosePosition(shortPosition);
ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, label, StopLossInPips, TakeProfitInPips);
}
else if(_bbp.Sum.Last(0)<0 && _bbp.Sum.Last(1)<0 && longPosition != null )
{
ClosePosition(longPosition);
ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, label, StopLossInPips, TakeProfitInPips);
}
}
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
if (position.TradeType != tradeType) continue;
ClosePosition(position);
}
}
}
}