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;
	}
}