The concept behind this strategy is that sometimes the market panics over some news, and hammers down a stock price for a short time. After a few minutes or hours, people recover from their panic, realize that the stock price is too low, and buy long to bid the price back up. At the end of each trading day (we assume daily bars here, like Altucher did in his book), this strategy receives the daily bar in the OnBar event handler. If no position is open, the strategy uses today’s closing price to calculate a new limit price that is 5% lower than today’s close, and issues a limit buy order to be executed at market open the following day. In contrast, if a position is open at the end of the day, it means that a 5% gap happened sometime during today, and so the strategy immediately closes the position with a market order (which will be executed at market open the next morning). The thinking here is that the panic prices would have been corrected upward during the day to something more reasonable. Notice how the timing of strategy decisions and actions is affected by when the bars arrive, and when the orders are executed. With daily bars, the strategy receives the daily bar at the end of each trading day, in the OnBar event handler. The OnBar event handler is executed on the trailing edge of each bar, at time that corresponds to the end of the trading day for daily bars. If you want to do something on the leading edge of a bar—meaning at the market open before the daily bar is constructed—then you should put your code in an OnBarOpen event handler.

using OpenQuant.API;

public class MyStrategy : Strategy
{
	[Parameter("Buy when a stock drops this number of percents in one day")]
	double Percent = 5;

	[Parameter("Order quantity (number of contracts to trade)")]
	double Qty = 100;

	Order buyOrder;

	public override void OnBar(Bar bar)
	{
		// if we do not have a position, update the limit buy order to be 5% above today's close
		if (!HasPosition)
		{
			// cancel the old limit order (it's out of date now)
			if (buyOrder != null)
				buyOrder.Cancel();

			// issue a new buy order at 5% below today's close this order will execute tomorrow 
			// if price is matched
			double buy_price = bar.Close * (1 - (Percent / 100));

			buyOrder = BuyLimitOrder(Qty, buy_price, "Entry");
			buyOrder.Send();
		}

		// else we opened a position today using our limit order from yesterday, so now close 
		// the position at the end of today. We expect that such a big drop was freaky, and that 
		// prices recovered during the day. If not, this order stops further losses.
		else
			Sell(Qty, "Exit");
	}
}