public override void OnBar(Bar bar) { if (Bars.Count < length) { return; } highestHigh = Bars.HighestHigh(length); lowestLow = Bars.LowestLow(length); }
private void SetExit() { if (ExtremeExitEnabled) { if (exitExtremeOrder != null) { exitExtremeOrder.Cancel(); } if (Position.Side == PositionSide.Long) { exitExtremeOrder = SellStopOrder(Qty, Bars.LowestLow(ExitLength), "Exit (Extreme"); } else { exitExtremeOrder = BuyStopOrder(Qty, Bars.HighestHigh(ExitLength), "Exit (Extreme"); } exitExtremeOrder.OCAGroup = Instrument.Symbol + " OCA " + ocaCount; } if (VolatilityExitEnabled) { if (rangeSMA.Count > 0) { if (exitVolatilityOrder != null) { exitVolatilityOrder.Cancel(); } if (Position.Side == PositionSide.Long) { exitVolatilityOrder = SellStopOrder(Qty, series.HighestHigh(EntryLength) - rangeSMA.Last * VolatilitiesCount, "Exit (Volatility)"); } else { exitVolatilityOrder = BuyStopOrder(Qty, series.LowestLow(EntryLength) + rangeSMA.Last * VolatilitiesCount, "Exit (Volatility)"); } exitVolatilityOrder.OCAGroup = Instrument.Symbol + " OCA " + ocaCount; } } if (ExtremeExitEnabled) { exitExtremeOrder.Send(); } if (VolatilityExitEnabled) { exitVolatilityOrder.Send(); } ocaCount++; }
public override void OnBar(Bar bar) { if (entryEnabled) { if (Bars.Count > Length) { if (bar.High > highestHigh) { Buy(Qty, "Entry"); if (OCAExitEnabled) { limitOrder = SellLimitOrder(Qty, LimitOCALevel * bar.Close, "Limit OCA " + OCACount); limitOrder.OCAGroup = "OCA " + Instrument.Symbol + " " + OCACount; stopOrder = SellStopOrder(Qty, StopOCALevel * bar.Close, "Stop OCA " + OCACount); stopOrder.OCAGroup = "OCA " + Instrument.Symbol + " " + OCACount; limitOrder.Send(); stopOrder.Send(); OCACount++; } entryEnabled = false; barCount = 0; } } } else { barCount++; if (TimeExitEnabled && barCount > BarsToExit) { Sell(Qty, "Time Exit"); entryEnabled = true; } } if (Bars.Count >= Length) { highestHigh = Bars.HighestHigh(Length); } }
public override void OnBar(Bar bar) { if (sma.Count == 0) { return; } // if we are using a trend-following exit and have an open // positiong that we should close if (TrendFollowingExitEnabled && HasPosition && Bars.Count > TrendFollowingExitLength + 1) { // check if we are long and today's close is lower than // lowest low of the last "trendFollowingExitLength" bars. // If so, then exit on the next bar open if (Position.Side == PositionSide.Long) { double prevLow = Bars.LowestLow(Bars.Count - TrendFollowingExitLength - 1, Bars.Count - 2); if (bar.Close < prevLow) { exitOnBarOpen = true; } } // check if we are short and today's close is higher than // highest high of the last "trendFollowingExitLength" bars // If so, exit on the next bar open if (Position.Side == PositionSide.Short) { double prevHigh = Bars.HighestHigh(Bars.Count - TrendFollowingExitLength - 1, Bars.Count - 2); if (bar.Close > prevHigh) { exitOnBarOpen = true; } } } // look for N consecutive closes after a crossover Cross cross = Bars.Crosses(sma, bar); // if any cross occurred, reset the consecutive close count, // and copy the cross value so we can reset our copy of it // without wiping out the original indicator. if (cross != Cross.None) { smaCross = cross; ccCount = 0; } // if a cross occurred, increment the cc count, because the // first bar counts as the first consecutive close if (smaCross != Cross.None) { ccCount++; } // if we have enough consecutive closes, it's time to trade if (ccCount == ConsClosesCount) { // if we have no position open, or if we have a position // that is opposite the cross direction (ie, we need to // close the position) if (!HasPosition || (Position.Side == PositionSide.Long && smaCross == Cross.Below) || (Position.Side == PositionSide.Short && smaCross == Cross.Above)) { switch (FilterType) { // enter a trade if no filters are being used case FilterType.None: { entryEnabled = true; break; } // enter a trade if the RAVI filter says ok case FilterType.RAVI: { entryEnabled = FilterRAVI(); break; } // enable a trade if the ADX filter says ok case FilterType.ADX: { entryEnabled = FilterADX(); break; } } // if an entry was enabled, open a position on next bar open if (entryEnabled) { exitOnBarOpen = false; } // and reset our copy of the cross status to none smaCross = Cross.None; } // reset the consecutive close count too ccCount = 0; } }
protected override void OnBar(Instrument instrument, Bar bar) { // Add bar to bar series. Bars.Add(bar); // Add bar to group. Log(bar, barsGroup); // Add highest value to group. if (highest != 0) { Log(highest, highestGroup); } // Add lowest value to group. if (lowest != 0) { Log(lowest, lowestGroup); } // Calculate performance. Portfolio.Performance.Update(); // Add equity to group. Log(Portfolio.Value, equityGroup); // Check strategy logic. if (highest != 0 && lowest != 0) { if (!HasPosition(instrument)) { // Enter long/short. if (bar.Close > highest) { Order enterOrder = BuyOrder(Instrument, Qty, "Enter Long"); Send(enterOrder); } else if (bar.Close < lowest) { Order enterOrder = SellOrder(Instrument, Qty, "Enter Short"); Send(enterOrder); } } else { // Reverse to long/short. if (Position.Side == PositionSide.Long && bar.Close < lowest) { Order reverseOrder = SellOrder(Instrument, Math.Abs(Position.Amount) + Qty, "Reverse to Short"); Send(reverseOrder); } else if (Position.Side == PositionSide.Short && bar.Close > highest) { Order reverseOrder = BuyOrder(Instrument, Math.Abs(Position.Amount) + Qty, "Reverse to Long"); Send(reverseOrder); } } } // Calculate channel's highest/lowest values. if (Bars.Count > Length) { highest = Bars.HighestHigh(Length); lowest = Bars.LowestLow(Length); } }