protected override void Step() { // Look for trade entry var sets_count = PositionSets.Count + PendingOrders.Count(); if (sets_count < MaxPositionSets && EntryCooldown == 0) { // Wait for a sequence of candles entirely above or below the MA var price = Instrument.LatestPrice; var mcs = Instrument.MCS; // Look for a sequence of candles that are entirely above or below the MA var bulge = FindBulges(0, MA0).FirstOrDefault(); if (bulge.Sign != 0 && Instrument.IdxLast - bulge.Range.End <= NonIntersectingCount) { Debugging.AreaOfInterest(bulge.Range, append: false); // Decide the direction int sign = 0; //// Trade in the direction of the slow MA if it is trending strongly //var ma_slope = MA1.FirstDerivative(0) / Instrument.PipSize; //if (Math.Abs(ma_slope) > MATrendSlope) //{ // sign = Math.Sign(ma_slope); //} //else { // Using measured stats of bulge sequences, the probabilities are: // 0 = below the MA, 1 = above the MA var next_bulge_sign = new [] { -1, // 000: -0.168091168091168 (count=351) +1, // 001: 0.224489795918367 (count=245) -1, // 010: -0.069767441860465 (count=172) +1, // 011: 0.158730158730159 (count=252) -1, // 100: -0.195121951219512 (count=246) +1, // 101: 0.139664804469274 (count=179) -1, // 110: -0.217391304347826 (count=253) +1, // 111: 0.064102564102564 (count=312) }; // Include the current bulge because the trade triggers when this bulge closes var bulge_signs = new List <int>(); FindBulges(0, MA0).Take(3).ForEach(b => bulge_signs.Insert(0, b.Sign)); // Careful with order sign = next_bulge_sign[Bit.SignsToIndex(bulge_signs)]; } { // Create a pending order var ep = MA0[0]; var tt = CAlgo.SignToTradeType(sign); var sl = ep - sign * mcs * SLFrac; // Note: the SL needs to be big enough that a paired order is triggered before this trade is closed var tp = (QuoteCurrency?)null; var vol = Broker.ChooseVolume(Instrument, Math.Abs(ep - sl), risk: Risk); var trade = new Trade(Instrument, tt, Label, ep, sl, tp, vol, comment: Guid.NewGuid().ToString()) { Expiration = Instrument.ExpirationTime(1) }; Broker.CreatePendingOrder(trade); } EntryCooldown = 1; } } // Increase position size on winning positions //IncreasePosition(); // Break point helper if (Instrument.NewCandle) { Dump(); } }