3.2 How to Create a .NET Strategy

The indicator, which shows the strength trend has been created and defined. Now, on the basis of this indicator, we will build a strategy that will open a position at the beginning of a strong trend and close the position when the trend weakens.


In the PowerLanguage .NET Editor main menu, select File, then select New, then click New Signal and create a new signal with the name TrendPower. Next, copy the trend strength calculation logic with inputs from the previous indicator. As a result, the following signal will be created:

public class TrendPower : SignalObject {
	public TrendPower(object _ctx):base(_ctx)
	{
		fastLength = 7;
		slowLength = 14;
		strongLevel = 0.9;
	}
 
	[Input]
	public int fastLength { get; set; }
 
	[Input]
	public int slowLength { get; set; }
 
	[Input]
	public double strongLevel { get; set; }
 
	protected override void Create() {
	}
 
	private double AvgVal( int length )
	{
		double aval = 0.0;
		for (int i = 0; i < length; ++i)
			aval += Bars.AvgPrice(i);
		return aval / length;
	}
 
	protected override void StartCalc() {
 
	}
	protected override void CalcBar(){
		double afast = AvgVal(fastLength);
		double aslow = AvgVal(slowLength);
		double power = Math.Abs(100*(afast - aslow /Bars.Close[0]);
	}
}

Add strong trend direction definition method. The method returns:

  • 1 if High and Low of the current bar are higher. In this case, the trend is considered to be an uptrend,
  • -1 if High and Low of the current bar are lower. In this case the trend is considered to be a downtrend.
  • 0 if the trend is not specified.
private int TrendDir(){
	if ((Bars.Low[0] < Bars.Low[1])&&(Bars.High[0] < Bars.High[1])) return -1;
	if ((Bars.Low[0] > Bars.Low[1])&&(Bars.High[0] > Bars.High[1])) return 1;
	return 0;
}

A long position will be opened by trend_LE market order, a short position by trend_SE market order. The position will be closed by one of the following orders: long position by trend_LX, short position by trend_SX.


Let’s create these objects in our signal:

private IOrderMarket trend_LE;
private IOrderMarket trend_SE;
private IOrderMarket trend_LX;
private IOrderMarket trend_SX;
 
protected override void Create() {
	trend_LE = OrderCreator.MarketNextBar(new SOrderParameters(Contracts.Default, "Tend LE", EOrderAction.Buy));
	trend_SE = OrderCreator.MarketNextBar(new SOrderParameters(Contracts.Default, "Tend SE", EOrderAction.SellShort));
	trend_LX = OrderCreator.MarketNextBar(new SOrderParameters(Contracts.Default, "Tend LX", EOrderAction.Sell));
	trend_SX = OrderCreator.MarketNextBar(new SOrderParameters(Contracts.Default, "Tend SX", EOrderAction.BuyToCover));
}

The logic of this signal should be written in the CalcBar() method. If the trend is weak and becomes strong or if the trend is strong and becomes weak a long or short position will be opened depending upon the direction of the trend with the option to close any position. A Local variable should be created to save the previous strength trend value and its value will be reset before the beginning of every calculation of the strategy:

double old_power;
protected override void StartCalc() {
	old_power = 0;			
}
protected override void CalcBar(){
	double afast = AvgVal(fastLength);
	double aslow = AvgVal(slowLength);
	double power = 	Math.Abs(100*(afast - aslow)/Bars.Close[0]);
	if ( (power >= strongLevel)&&(old_power < strongLevel) ){
		switch(TrendDir()){
			case -1:
				trend_SE.Send();
				break;
			case 1:
				trend_LE.Send();
				break;
		}
	}
	if ((CurrentPosition.Side != EMarketPositionSide.Flat)
		&&(old_power >= strongLevel)
		&&(power < strongLevel))
		{
			trend_LX.Send();
			trend_SX.Send();
		}
	old_power = power;
}


To compile the signal, press F7. Once this is complete you can apply the signal to the chart. After the calculation you will see the order markers on the chart. Chart3.png

The results of the strategy can be seen in Strategy Performance Report by selecting View in the main menu and clicking on the Strategy Performance Report.