PendingOrder gets cancelled (Reason: Cancelled) without having called CancelPendingOrder()
Created at 20 Sep 2022, 17:31
EM
PendingOrder gets cancelled (Reason: Cancelled) without having called CancelPendingOrder()
20 Sep 2022, 17:31
Like the title says I have (at least) one instance where my PendingOrder gets cancelled for no apparent reason, since I do not call the Cancel Pending Order method (checked with breakpoints that are not getting hit).
I have no idea how to debug this or where to look after having gone tick by tick, explored the call stack and having logged most of the things.
So what the bot does before the order gets cancel is:
1) Place Pending Order
2) Modify it once
3) check for every tick if the setup gets broken (it does not)
4) suddenly cancels the order
namespace cAlgo.Robots
{
[Robot(AccessRights = AccessRights.FullAccess)]
public class Abot : Robot
{
static string dumb = @"C:\Recycle Bin";
static string logs = @"C:\Users\d\Documents\TradingEngineLogs\";
TextLogger logger = new EmtpyLogger(logs);
BollingerBands bb;
ExponentialMovingAverage ema8;
ExponentialMovingAverage ema21;
AverageTrueRange atr14;
Ticks _ticks;
ExponentialMovingAverage m5ema8;
ExponentialMovingAverage m5ema21;
ExponentialMovingAverage m10ema8;
ExponentialMovingAverage m10ema21;
BollingerBands m5BB;
BollingerBands m10BB;
AverageTrueRange m5atr14;
AverageTrueRange m10atr14;
IMeanReversion twoMinuteSetup;
IBollingerTouch fiveMinuteTouch;
IBollingerTouch tenMinuteTouch;
IDecreasingVolatilityMode dvmode;
Dictionary<PendingOrder, decimal> breakUpPoints;
Queue<Candle> candleQueue;
protected override void OnStart()
{
System.Diagnostics.Debugger.Launch();
var m2bar = MarketData.GetBars(TimeFrame.Minute2);
var m5bar = MarketData.GetBars(TimeFrame.Minute5);
var m10bar = MarketData.GetBars(TimeFrame.Minute10);
var m2 = m2bar.ClosePrices;
var m5 = m5bar.ClosePrices;
var m10 = m10bar.ClosePrices;
bb = Indicators.BollingerBands(m2, 20, 2.0, MovingAverageType.Simple);
ema8 = Indicators.ExponentialMovingAverage(m2, 8);
ema21 = Indicators.ExponentialMovingAverage(m2, 21);
atr14 = Indicators.AverageTrueRange(MarketData.GetBars(TimeFrame.Minute2), 14, MovingAverageType.WilderSmoothing);
m5BB = Indicators.BollingerBands(m5, 20, 2.0, MovingAverageType.Simple);
m10BB = Indicators.BollingerBands(m10, 20, 2.0, MovingAverageType.Simple);
m5ema8 = Indicators.ExponentialMovingAverage(m5, 8);
m5ema21 = Indicators.ExponentialMovingAverage(m5, 21);
m10ema8 = Indicators.ExponentialMovingAverage(m10, 8);
m10ema21 = Indicators.ExponentialMovingAverage(m10, 21);
m5atr14 = Indicators.AverageTrueRange(MarketData.GetBars(TimeFrame.Minute5), 14, MovingAverageType.WilderSmoothing);
m10atr14 = Indicators.AverageTrueRange(MarketData.GetBars(TimeFrame.Minute10), 14, MovingAverageType.WilderSmoothing);
_ticks = MarketData.GetTicks(this.SymbolName);
twoMinuteSetup = new NoSetup();
fiveMinuteTouch = new NoTouch();
tenMinuteTouch = new NoTouch();
dvmode = new NormalMode();
m2bar.BarOpened += NewTwoMinuteBar;
m5bar.BarOpened += NewFiveMinuteBar;
m10bar.BarOpened += NewTenMinutebar;
PendingOrders.Cancelled += PendingOrdersOnCancelled;
breakUpPoints = new();
candleQueue = new();
}
protected override void OnTick()
{
var t = _ticks.Last(0);
MarketTick tick = new MarketTick();
tick.Ask = (decimal)t.Ask;
tick.Bid = (decimal)t.Bid;
logger.LogTick($"{t.Time};{t.Ask};{t.Bid}");
twoMinuteSetup = twoMinuteSetup.TickTransition(tick);
fiveMinuteTouch = fiveMinuteTouch.TickTransition(tick);
tenMinuteTouch = tenMinuteTouch.TickTransition(tick);
foreach(var porder in PendingOrders)
{
if (porder.TradeType.Equals(API.TradeType.Buy))
{
if(breakUpPoints.GetValueOrDefault(porder, decimal.MaxValue) >= (decimal) t.Ask)
{
CancelPendingOrder(porder);
}
}
if (porder.TradeType.Equals(API.TradeType.Sell))
{
if(breakUpPoints.GetValueOrDefault(porder, decimal.MinValue) <= (decimal) t.Bid)
{
CancelPendingOrder(porder);
}
}
}
}
private void NewTwoMinuteBar(BarOpenedEventArgs args)
{
var c = BarToCandle(args.Bars.Last(1));
var i = GetIndicators();
foreach(var porder in PendingOrders)
{
if (porder.TradeType.Equals(API.TradeType.Buy))
{
var newEntry = (double)RoundingCalculator.RoundToNearestHalfPipUp(c.High);
var distanceInPips = (porder.TargetPrice - newEntry) * 10000;
if ((double) RoundingCalculator.RoundToNearestHalfPipUp(c.High) < (double) porder.TargetPrice)
{
ModifyPendingOrder(porder, (double) (RoundingCalculator.RoundToNearestHalfPipUp(c.High)), porder.StopLossPips - distanceInPips, porder.TakeProfitPips + distanceInPips);
}
}
if (porder.TradeType.Equals(API.TradeType.Sell))
{
var newEntry = (double)RoundingCalculator.RoundToNearestHalfPipDown(c.Low);
var distanceInPips = Math.Abs(porder.TargetPrice - newEntry) * 10000;
if ((double) RoundingCalculator.RoundToNearestHalfPipDown(c.Low) > (double) porder.TargetPrice)
{
ModifyPendingOrder(porder, (double) RoundingCalculator.RoundToNearestHalfPipDown(c.Low), porder.StopLossPips - distanceInPips, porder.TakeProfitPips + distanceInPips);
}
}
}
twoMinuteSetup = twoMinuteSetup.CandleTransition(c, i);
dvmode = dvmode.Transition(c, i);
if (candleQueue.Count > 25)
candleQueue.Dequeue();
candleQueue.Enqueue(c);
logger.LogSetup($"{c.OpenTime};{twoMinuteSetup}");
logger.LogM2($"{c.OpenTime};{c.Open};{c.High};{c.Low};{c.Close};{i}");
if(c.OpenTime.Hour >= 6 && c.OpenTime.Hour <= 16)
PlaceTrade();
}
private void NewFiveMinuteBar(BarOpenedEventArgs args)
{
var c = BarToCandle(args.Bars.Last(1));
var i = GetFiveMinutesIndicators();
fiveMinuteTouch = fiveMinuteTouch.Transition(c, i);
dvmode.NewFiveMinute(c, i);
logger.LogM5($"{c.OpenTime};{c.Open};{c.High};{c.Low};{c.Close};{i}");
logger.M5BB($"{c.OpenTime};{fiveMinuteTouch}");
}
private void NewTenMinutebar(BarOpenedEventArgs args)
{
var c = BarToCandle(args.Bars.Last(1));
var i = GetTenMinutesIndicators();
tenMinuteTouch = tenMinuteTouch.Transition(c, i);
dvmode.NewTenMinute(c, i);
logger.LogM10($"{c.OpenTime};{c.Open};{c.High};{c.Low};{c.Close};{i}");
logger.M10BB($"{c.OpenTime};{tenMinuteTouch}");
}
private void PlaceTrade()
{
if (PendingOrders.Count != 0)
return;
if (Positions.Count != 0)
return;
if (twoMinuteSetup is ShortSetupRTC)
{
var s = (ShortSetupRTC)twoMinuteSetup;
PlaceShortOrder(s.Low, s.High);
return;
}
if (twoMinuteSetup is ShortSetupRTV)
{
var s = (ShortSetupRTV)twoMinuteSetup;
PlaceShortOrder(s.Low, s.High);
return;
}
if (twoMinuteSetup is LongSetupRTC)
{
var s = (LongSetupRTC)twoMinuteSetup;
PlaceLongOrder(s.High, s.Low);
return;
}
if (twoMinuteSetup is LongSetupRTV)
{
var s = (LongSetupRTV)twoMinuteSetup;
PlaceLongOrder(s.High, s.Low);
return;
}
}
private void PlaceLongOrder(decimal entry, decimal stoploss)
{
if (!(fiveMinuteTouch is TouchLow && tenMinuteTouch is TouchLow))
return;
if (dvmode is DecreasingVolatilityModeDowntrend)
return;
var e = RoundingCalculator.RoundToNearestHalfPipUp(entry);
var s = RoundingCalculator.RoundToNearestHalfPipDown(stoploss);
var t = TargetCalculator.LongScalp(e, s);
var r = Math.Abs(e - s);
if (r < 0.0003m)
r = 0.0003m;
var p = (100) / r;
if (t > candleQueue.Max(c => c.High))
return;
var res = PlaceStopLimitOrder(API.TradeType.Buy, SymbolName, Symbol.NormalizeVolumeInUnits((double)p), (double) e, 0.1, "LONG", (double)Math.Abs(e - s) * 10000, (double)Math.Abs(e - t) * 10000);
breakUpPoints.Add(res.PendingOrder, stoploss);
}
private void PlaceShortOrder(decimal entry, decimal stoploss)
{
if (!(fiveMinuteTouch is TouchHigh && tenMinuteTouch is TouchHigh))
return;
if (dvmode is DecreasingVolatilityModeUptrend)
return;
var e = RoundingCalculator.RoundToNearestHalfPipDown(entry);
var s = RoundingCalculator.RoundToNearestHalfPipUp(stoploss);
var t = TargetCalculator.ShortScalp(e, s);
var r = Math.Abs(e - s);
if (r < 0.0003m)
r = 0.0003m;
var p = (100) / r;
if (t < candleQueue.Min(c => c.Low))
return;
var res = PlaceStopLimitOrder(API.TradeType.Sell, SymbolName, Symbol.NormalizeVolumeInUnits((double)p), (double)e, 0.1, "SHORT", (double)Math.Abs(e - s) * 10000, (double)Math.Abs(e - t) * 10000);
breakUpPoints.Add(res.PendingOrder, stoploss);
}
protected override void OnStop()
{
}
private MarketStateMachines.Common.Indicators GetIndicators()
{
var i = new MarketStateMachines.Common.Indicators();
i.BollingerBandTop = (decimal)bb.Top.Last(1);
i.BollingerBandBottom = (decimal)bb.Bottom.Last(1);
i.Ema8 = (decimal)ema8.Result.Last(1);
i.Ema21 = (decimal)ema21.Result.Last(1);
i.Atr14 = (decimal)atr14.Result.Last(1);
return i;
}
private Candle BarToCandle(Bar bar)
{
var c = new Candle();
c.OpenTime = (DateTime)bar.OpenTime;
c.Open = (decimal)bar.Open;
c.High = (decimal)bar.High;
c.Low = (decimal)bar.Low;
c.Close = (decimal)bar.Close;
return c;
}
private MarketStateMachines.Common.Indicators GetFiveMinutesIndicators()
{
var i = new MarketStateMachines.Common.Indicators();
i.BollingerBandTop = (decimal)m5BB.Top.Last(1);
i.BollingerBandBottom = (decimal)m5BB.Bottom.Last(1);
i.Ema8 = (decimal)m5ema8.Result.Last(1);
i.Ema21 = (decimal)m5ema21.Result.Last(1);
i.Atr14 = (decimal)m5atr14.Result.Last(1);
return i;
}
private MarketStateMachines.Common.Indicators GetTenMinutesIndicators()
{
var i = new MarketStateMachines.Common.Indicators();
i.BollingerBandTop = (decimal)m10BB.Top.Last(1);
i.BollingerBandBottom = (decimal)m10BB.Bottom.Last(1);
i.Ema8 = (decimal)m10ema8.Result.Last(1);
i.Ema21 = (decimal)m10ema21.Result.Last(1);
i.Atr14 = (decimal)m10atr14.Result.Last(1);
return i;
}
private void PendingOrdersOnCancelled(PendingOrderCancelledEventArgs args)
{
Print("Pending order with id {0} was cancelled. Reason: {1}", args.PendingOrder.Id, args.Reason);
}
}
}
PanagiotisCharalampous
21 Sep 2022, 08:34
Hi there,
Unfortunately I cannot build this code since it seems you are using some external libraries which I do not have.
Best Regards,
Panagiotis
Join us on Telegram and Facebook
@PanagiotisCharalampous