Writing Strategies
In Tradesignal, many strategies are available, either delivered with the software or offered for download from the website.
However, wishes may remain unfulfilled or you may have new ideas that need to be tested. You can always use the
Trading Strategy Wizard to design a new strategy. You can also program new strategies (or edit available ones) in Tradesignal by using the Equilla language.
In the following you will find an example showing how to write a strategy using Equilla. It is only intended to give you a basic introduction. For details on Equilla, please refer to articles in the
Equilla Basics category.
Programming a Bollinger Band - RSI System

Writing a new strategyThe strategy calculates the Relative Strength Index for an instrument. Based on these values, Bollinger Bands are then constructed. The crossings between the RSI and the Bollinger Bands are used as trading signals. In addition, Stop Loss and Trailing Stop are calculated. The idea behind this setup is to substitute the static extremes of the Relative Strength Index with more flexible zones that adapt to the movements of the indicator.
Creating the Strategy
- In the toolbox, click on the Strategies button.
- In the Related Tasks area, select New Strategy.
- In the next dialog, select the option Use the Equilla Formula Language to write the strategy.
- Select a folder, e.g. "tradesignal Files".
- Type the name "Bollinger-RSI-Bands".
- Click on Done.
Now you can enter the source code of the strategy in the
Equilla Editor. The areas are described in the following sections. The complete code can be found at the end of this article. In the header area, the input parameters of the used indicators and necessary variables are declared. In addition, we enter the meta information for the subchart creation.
Meta:
SubChart( true );
Inputs:
PeriodAvg( 20 , 1 ),
PeriodStd( 10 , 1 ),
FactorStd( 2.0 , 0.0 ),
PeriodRSI( 14 , 1 ),
PeriodATR( 10, 1 ),
FactorAtr( 1.5, 0.0 ),
PeriodTrail( 20 , 1 ),
TradeMode( outsideIn, insideOut );
Variables:
avgValue, upperBand, lowerBand, rsiValue, stdValue, atrValue,
stopValue, trailValue, activeStop;
Programming the Calculations for the Indicators and Stops
In this part, the indicator calculations are entered. For most of them, we will use available
Equilla Functions. However, a new calculation is written for the Bollinger Bands, as we want to use the RSI as their basis.
rsiValue = RSI( Close, PeriodRSI );
avgValue = Average( rsiValue, PeriodAvg );
stdValue = StdDeviation( rsiValue, PeriodStd );
upperBand = avgValue + ( FactorStd * stdValue );
lowerBand = avgValue - ( FactorStd * stdValue );
atrValue = Average( TrueRange, PeriodAtr );
trailValue = XAverage( Close, PeriodTrail );
Defining Trading Conditions and Programming Order Generation
In this part, the conditions for trading signals are defined and the orders are generated. Two modes are defined:
- The mode outsideIn is designed so that the RSI has to cut the Bollinger Bands from outside in for signal generation. This mode is preferable for correction movements.
- The mode insideOut is designed so that the RSI has to cut the Bollinger Bands from inside out, i.e. in trend direction. This mode is optimal for strong trends.
If TradeMode = 0 Then
Begin
If rsiValue crosses over lowerBand Then
Begin
Buy("LongIn") Next Bar at Market;
stopValue = Close - ( FactorAtr * atrValue );
End;
If rsiValue crosses under upperBand Then
Begin
Short("ShortIn") Next Bar at Market;
stopValue = Close + ( FactorAtr * atrValue );
End;
End
Else
Begin
If rsiValue crosses over upperBand Then
Begin
Buy("LongOut") Next Bar at Market;
stopValue = Close - ( FactorAtr * atrValue );
End;
If rsiValue crosses under lowerBand Then
Begin
Short("ShortOut") Next Bar at Market;
stopValue = Close + ( FactorAtr * atrValue );
End;
End;
Handling of the Stop Loss Prices
For the Stop Loss, the
Average True Range (ATR) is calculated. The value for the initial stop results from the ATR multiplied with a factor. As Trailing Stop, the
Exponential Moving Average based on the instrument is calculated. If the price cuts this average inverse to the trade, the trade is closed. The program uses both stop values and compares which one is better positioned and more protective of the trade. That value is finally output as a stop order for the next trading period.
If MarketPosition = MarketPositionLong Then
Begin
If ( stopValue > trailValue ) Then
Sell("Stop Loss") Next Bar at stopValue Stop;
If ( trailValue > stopValue ) And ( trailValue < Close ) Then
Sell("Trail") Next Bar at trailValue Stop;
End;
If MarketPosition = MarketPositionShort Then
Begin
If ( stopValue < trailValue ) Then
Cover("Stop Loss") Next Bar at stopValue Stop;
If ( trailValue < stopValue ) And ( trailValue > Close ) Then
Cover("Trail") Next Bar at trailValue Stop;
End;
Displaying the Indicators in Subcharts
This is the easiest part. Only the indicators that are used for signal generation are displayed here.
DrawLine( rsiValue, "RSI", StyleSolid, 1, blue );
DrawLIne( upperBand, "Upper Band", StyleSolid, 1, darkGreen );
DrawLIne( lowerBand, "Lower Band", StyleSolid, 1, red );
Applying the Strategy
Compile the code either by pressing
F7 or by clicking on the button
Compile Script in the
Equilla Editor group. The code is checked for errors, saved and then available in the list of strategies in the toolbox by the name "Bollinger-RSI-Bands".
You can now apply it to a chart it as described in
Using Strategies, for example with drag and drop.
The Complete Code
Meta:
SubChart( true );
Inputs:
PeriodAvg( 20 , 1 ),
PeriodStd( 10 , 1 ),
FactorStd( 2.0 , 0.0 ),
PeriodRSI( 14 , 1 ),
PeriodATR( 10, 1 ),
FactorAtr( 1.5, 0.0 ),
PeriodTrail( 20 , 1 ),
TradeMode( outsideIn, insideOut );
Variables:
avgValue, upperBand, lowerBand, rsiValue, stdValue, atrValue,
stopValue, trailValue, activeStop;
rsiValue = RSI( Close, PeriodRSI );
avgValue = Average( rsiValue, PeriodAvg );
stdValue = StdDeviation( rsiValue, PeriodStd );
upperBand = avgValue + ( FactorStd * stdValue );
lowerBand = avgValue - ( FactorStd * stdValue );
atrValue = Average( TrueRange, PeriodAtr );
trailValue = XAverage( Close, PeriodTrail );
If TradeMode = 0 Then
Begin
If rsiValue crosses over lowerBand Then
Begin
Buy("LongIn") Next Bar at Market;
stopValue = Close - ( FactorAtr * atrValue );
End;
If rsiValue crosses under upperBand Then
Begin
Short("ShortIn") Next Bar at Market;
stopValue = Close + ( FactorAtr * atrValue );
End;
End
Else
Begin
If rsiValue crosses over upperBand Then
Begin
Buy("LongOut") Next Bar at Market;
stopValue = Close - ( FactorAtr * atrValue );
End;
If rsiValue crosses under lowerBand Then
Begin
Short("ShortOut") Next Bar at Market;
stopValue = Close + ( FactorAtr * atrValue );
End;
End;
If MarketPosition = MarketPositionLong Then
Begin
If ( stopValue > trailValue ) Then
Sell("Stop Loss") Next Bar at stopValue Stop;
If ( trailValue > stopValue ) And ( trailValue < Close ) Then
Sell("Trail") Next Bar at trailValue Stop;
End;
If MarketPosition = MarketPositionShort Then
Begin
If ( stopValue < trailValue ) Then
Cover("Stop Loss") Next Bar at stopValue Stop;
If ( trailValue < stopValue ) And ( trailValue > Close ) Then
Cover("Trail") Next Bar at trailValue Stop;
End;
DrawLine( rsiValue, "RSI", StyleSolid, 1, blue );
DrawLIne( upperBand, "Upper Band", StyleSolid, 1, darkGreen );
DrawLIne( lowerBand, "Lower Band", StyleSolid, 1, red );