/// <summary>Strategy step</summary> protected override void Step() { // Look for trade entry var sets_count = PositionSets.Count + PendingOrders.Count(); if (sets_count < MaxPositionSets && EntryCooldown == 0) { var mcs = Instrument.MCS; { var sign = -1; var ep = Donchian[0, Bot]; var tt = CAlgo.SignToTradeType(sign); var sl = ep - sign * mcs * SLFrac; 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); } { var sign = +1; var ep = Donchian[0, Top]; var tt = CAlgo.SignToTradeType(sign); var sl = ep - sign * mcs * SLFrac; 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; } }
protected override void Step() { // Look for trade entry var sets_count = PositionSets.Count + PendingOrders.Count(); if (sets_count < MaxPositionSets && EntryCooldown == 0) { var mcs = Instrument.MCS; var price = Instrument.LatestPrice; var trend_sign = Math.Sign(MA0[0].CompareTo(MA1[0])); for (;;) { if (Math.Abs(MA1[0] - MA0[0]) < 0.5 * mcs) { break; } { var sign = trend_sign; var ep = MA1[0]; var tt = CAlgo.SignToTradeType(sign); var sl = ep - sign * mcs * SLFrac; var tp = MA0[0]; //(QuoteCurrency?)null; var vol = Broker.ChooseVolume(Instrument, Math.Abs(ep - sl), risk: Risk); var trade = new Trade(Instrument, tt, Label, ep, sl, tp, vol) { Expiration = Instrument.ExpirationTime(1) }; Broker.CreatePendingOrder(trade); break; } } //var dist_ask = MA0[0] - price.Ask; //var dist_bid = price.Bid - MA0[0]; //var trend0 = ((Monic)MA0.Extrapolate(1, 5).Curve).A; //var trend1 = Instrument.EMASlope(0); // //((Monic)MA1.Extrapolate(1, 5).Curve).A; //// Bias the price distance from the MA by the trend //dist_ask += trend0 * TrendWeight; //dist_bid -= trend0 * TrendWeight; //if (dist_ask > OpenDistance*mcs && Math.Sign(trend1) > 0) //{ // var sign = +1; // var ep = price.Ask; // var tt = TradeType.Buy; // var sl = ep - sign * mcs * SLFrac; // var tp = (QuoteCurrency?)null; // var vol = Broker.ChooseVolume(Instrument, Math.Abs(ep - sl), risk:Risk); // var trade = new Trade(Instrument, tt, Label, price.Ask, sl, tp, vol); // Broker.CreateOrder(trade); //} //if (dist_bid > OpenDistance*mcs && Math.Sign(trend1) < 0) //{ // var sign = -1; // var ep = price.Bid; // var tt = TradeType.Sell; // var sl = ep - sign * mcs * SLFrac; // var tp = (QuoteCurrency?)null; // var vol = Broker.ChooseVolume(Instrument, Math.Abs(ep - sl), risk:Risk); // var trade = new Trade(Instrument, tt, Label, price.Bid, sl, tp, vol); // Broker.CreateOrder(trade); //} } // Break point helper if (Instrument.NewCandle) { Dump(); } }
protected override void Step() { if (!Instrument.NewCandle) { return; } // Look for trade entry var sets_count = PositionSets.Count + PendingOrders.Count(); if (sets_count < MaxPositionSets && EntryCooldown == 0) { // Wait for a Doji candle var mcs = Instrument.MCS; var A = Instrument[-1]; var a_type = A.Type(mcs); if (!a_type.IsIndecision()) { return; } // Look for strong trade direction indications var trade_sign = (int?)null; for (;;) { // Divergent extrapolation var q0 = (Quadratic)MA0.Future.Curve; var q1 = (Quadratic)MA1.Future.Curve; var intersect = Maths.Intersection(q0, q1); if (Math.Sign(q0.A) != Math.Sign(q1.A) || intersect.Length == 0) // || intersect.FirstOrDefault() >= 0) { break; } trade_sign = Math.Sign(q0.A); break; } // Look for Marubozu followed by doji for (;;) { // Find the preceding non-doji var i = -2; var B = Instrument[i]; var b_type = B.Type(mcs); for (; i > Instrument.IdxFirst && b_type.IsIndecision(); --i, B = Instrument[i], b_type = B.Type(mcs)) { } if (!b_type.IsTrend()) { break; } { var sign = trade_sign ?? -B.Sign; var ep = A.Close; var tt = CAlgo.SignToTradeType(sign); var sl = ep - sign * mcs * SLFrac; var tp = ep + sign * mcs * SLFrac * 4; //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) { Expiration = Instrument.ExpirationTime(1) }; Broker.CreateOrder(trade); Debugging.Trace(" -Doji followed by Marubozu"); return; } } // Look for a strong candle trend followed by a hammer or inverted hammer for (;;) { // Get the candle trend leading up to 'A' var candle_trend = Instrument.MeasureTrendFromCandles(-3, -1); if (Math.Abs(candle_trend) < 0.8) { break; } // Look for a hammer pattern if (a_type == Candle.EType.Hammer && Math.Sign(candle_trend) > 0) { break; } if (a_type == Candle.EType.InvHammer && Math.Sign(candle_trend) < 0) { break; } { var sign = trade_sign ?? -Math.Sign(candle_trend); var ep = A.Close; var tt = CAlgo.SignToTradeType(sign); var sl = ep - sign * mcs * SLFrac; var tp = ep + sign * mcs * SLFrac * 4; //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) { Expiration = Instrument.ExpirationTime(1) }; Broker.CreateOrder(trade); Debugging.Trace(" -{0} pattern".Fmt(a_type)); return; } } //var trend_sign = Math.Sign(MA0[0].CompareTo(MA1[0])); //var price_range = Instrument.PriceRange(i, 1).Inflate(1.05); } }
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(); } }