public override void OnBar(Bar bar) { // if we don't have a position and we have some bars // in the bollinger series, try to enter a new trade if (!HasPosition) { if (bbl.Count > 0) { // if the current bar is below the lower bollinger band // buy long to close the gap if (Bars.Crosses(bbl, bar) == Cross.Below) { buyOrder = MarketOrder(OrderSide.Buy, Qty, "Entry"); buyOrder.Send(); } } } else { // else if we DO have an existing position, and if // today's bar is above our entry price (profitable), // then close the position with a market order if (entryPrice < bar.Close) { barsFromEntry = 0; Sell(Qty, "Exit (Take Profit)"); } else { barsFromEntry++; } } }
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; } }