This example is like the basic Bollinger Band example above, but it adds three refinements. First, it demands that prices really punch through the lower Bollinger limit before buying. If 0 is the low limit, and 100 the high limit, this strategy buys only if prices are 20% of the band width below the lower limit. Second, it exits when a profit target of 15% is reached. Third, it exits after 4 days if the profit target has not been reached.
using OpenQuant.API; using OpenQuant.API.Indicators; using System.Drawing; public class MyStrategy : Strategy { [Parameter("Order quantity (number of contracts to trade)")] double Qty = 100; [Parameter("Bollinger Band level to go long")] double BLevel = -20; [Parameter("Percent profit target")] double ProfitPercent = 15; [Parameter("Max number of bars, while position is active")] int MaxDuration = 4; [Parameter("Length of Bollinger Band")] int BLength = 10; [Parameter("Order of Bollinger Band")] double BOrder = 1.5; B b; int barsFromEntry = 0; double exitPrice; Order sellOrder; Order buyOrder; public override void OnStrategyStart() { // set up bollinger bands BBL bbl = new BBL(Bars, BLength, BOrder, Color.Pink); // set up a series for B (breakout force) value b = new B(Bars, BLength, BOrder, Color.Yellow); Draw(bbl, 0); Draw(b, 2); } public override void OnBar(Bar bar) { // good practice to check if a series has the date you are interested in before you try // to use it if (b.Contains(bar)) { // if we don't have a position and prices are below the lower band, open a long position if (!HasPosition) { if (b[bar.DateTime] * 100 <= BLevel) { buyOrder = BuyOrder(Qty, "Entry"); buyOrder.Send(); } } else { barsFromEntry++; // if we _have_ reached the exit day (4 days after entry), cancel the profit target // sell order, and issue a new market order to close the position now. if (barsFromEntry == MaxDuration) { barsFromEntry = 0; // cancel existing sell order if there is one if (sellOrder != null) sellOrder.Cancel(); Sell(Qty, "Exit (Max Duration)"); } } } } public override void OnPositionOpened() { // when a position is opened, calculate profit target exitPrice = buyOrder.AvgPrice * (1 + ProfitPercent / 100); // cancel existing sell order if there is one if (sellOrder != null) sellOrder.Cancel(); // issue a new sell limit order at the profit target price sellOrder = SellLimitOrder(Qty, exitPrice, "Exit (Profit Target)"); sellOrder.Send(); } public override void OnPositionClosed() { barsFromEntry = 0; } }