The concept of this strategy is to open a long position after a major market index has had 4 down days in a row. The theory is that 4 days of market momentum in a major market index is hard to maintain, and that an up day is soon to follow. You might have to wait a day or two for it to show up, but it will show up eventually. This implementation buys at the market open on day 5 after 4 down days, and doesn’t wait around for multiple days for an up day. It just automatically issues a market sell order at the end of day 6 (when day 6 bar is received). The sell order will actually be executed by the exchange when the market opens on day 7. 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("Order quantity (number of contracts to trade)")] double Qty = 100; [Parameter("Number of consecutive down closes")] int ConsClosesCount = 4; int count; double prevClose; public override void OnStrategyStart() { prevClose = -1; count = 0; } public override void OnBar(Bar bar) { // we need at least one bar to go by before we do anything if (prevClose != -1) { // if we don't have a position open, increment the count of down days (or reset it to zero) if (!HasPosition) { if (prevClose > bar.Close) count++; else count = 0; // if this is the fourth (consClosesCount is equal to 4 by default) down day, // issue a market order to open a long position tomorrow morning, on day 5 if (count == ConsClosesCount) Buy(Qty, "Entry"); } // else if we have a position open, close it now (today is the day after the trade was // entered), so now is actually end of day 6, and the trade will be executed by the market // on open day 7. else Sell(Qty, "Exit"); } // today's close now becomes the previous close for the down day calculation prevClose = bar.Close; } }