A Seasonal System For Soybean Futures
The article by Markos Katsanos in this issue, “A Seasonal System For Soybean Futures”, has demonstrated the correlation between the soybean historical average seasonal prices and the dollar index to develop a trading system that exploits historical seasonal patterns to trade soybean futures.
First of all, one needs to create the SOYBEAN SEASONAL-CHANNEL BREAKOUT STRATEGY using Tradecision’s Strategy Builder. You need to specify the following strategy rules:
Entry Long:
{LENGTH=Channel length in days,
D1DXY=Days for the Dollar Index linear regression
slope calculation
D2SNL=Days for the Seasonal data linear regression
slope calculation
LRSNLSELL= Seasonal data linear regression slope per day
LRSDXYSELL=Dollar index linear regression slope per day
MASNL=Days for the seasonal exponential moving average sell/
buytocover conditions
MASELL=Days for the Soybean exponential moving average sell/
buytocover conditions
MADXY=Days for the Dollar Index moving average sell/
buytocover conditions}
VARIABLES
LENGTH:=4;
D1DXY:=25;
D2SNL:=12;
SELLMONTH:=6;
BUYMONTH:=9;
LRSNLSELL:=-0.8;
LRSDXYSELL:=0.3;
MASNL:=15;
MASELL:=15;
MADXY:=50;
RS:=0;
LRSNL:=0;
S2:=0;
STOPL:=0;
SEASONALBUY:=FALSE;
SEASONALSHORT:=FALSE;
LRSDXY:=0;
END_VARIABLES
IF BARNUMBER>3 THEN BEGIN
RS:=EMA((Close / External("Close","SNL")), 3);
END;
IF BARNUMBER >D2SNL + 3 THEN BEGIN
LRSNL:=(LRL(RS, D2SNL, 0) - LRL(RS, D2SNL, D2SNL)) /
LRL(RS, D2SNL, D2SNL) / D2SNL * 100;
END;
IF BARNUMBER >D1DXY THEN BEGIN
LRSDXY:=(LRL(External("Close","DXY"),D1DXY,0) -
LRL(External("Close","DXY"),D1DXY,D1DXY)) /
LRL(External("Close","DXY"),D1DXY,D1DXY) / D1DXY * 100;
END;
SEASONALBUY:= Month < SELLMONTH OR Month > BUYMONTH;
SEASONALSHORT:= Month > SELLMONTH AND Month < BUYMONTH+1;
{Buy condition}
IF SEASONALBUY AND LRSDXY < LRSDXYSELL AND C >
(HIGHEST(Close\1\,LENGTH)+2)
AND LRSNL > LRSNLSELL THEN return TRUE;
return FALSE;
Exit Long:
{LENGTH=Channel length in days,
D1DXY=Days for the Dollar Index linear regression
slope calculation
D2SNL=Days for the Seasonal data linear regression
slope calculation
LRSNLSELL= Seasonal data linear regression slope per day
LRSDXYSELL=Dollar index linear regression slope per day
MASNL=Days for the seasonal exponential moving average sell/
buytocover conditions
MASELL=Days for the Soybean exponential moving average sell/
buytocover conditions
MADXY=Days for the Dollar Index moving average sell/
buytocover conditions}
VARIABLES
LENGTH:=4;
D1DXY:=25;
D2SNL:=12;
SELLMONTH:=6;
BUYMONTH:=9;
LRSNLSELL:=-0.8;
LRSDXYSELL:=0.3;
MASNL:=15;
MASELL:=15;
MADXY:=50;
RS:=0;
LRSNL:=0;
S2:=0;
STOPL:=0;
SEASONALBUY:=FALSE;
SEASONALSHORT:=FALSE;
LRSDXY:=0;
END_VARIABLES
IF BARNUMBER>3 THEN BEGIN
RS:=EMA((Close / External("Close","SNL")), 3);
END;
IF BARNUMBER >D2SNL + 3 THEN BEGIN
LRSNL:=(LRL(RS, D2SNL, 0) - LRL(RS, D2SNL, D2SNL)) /
LRL(RS, D2SNL, D2SNL) / D2SNL * 100;
END;
IF BARNUMBER >D1DXY THEN BEGIN
LRSDXY:=(LRL(External("Close","DXY"),D1DXY,0) -
LRL(External("Close","DXY"),D1DXY,D1DXY)) /
LRL(External("Close","DXY"),D1DXY,D1DXY) / D1DXY * 100;
END;
SEASONALBUY:= Month < SELLMONTH OR Month > BUYMONTH;
SEASONALSHORT:= Month > SELLMONTH AND Month < BUYMONTH+1;
IF {IsLongPosition() AND }BarsSinceEntry > 1 THEN BEGIN
IF Close < EMA(Close, MASELL) AND LRSNL < LRSNLSELL THEN
return TRUE;
IF Close < EMA(Close, MASELL)
AND EMA(External("Close","DXY"),MADXY) >
EMA(External("Close","DXY"),MADXY)\1\
AND LRSDXY>LRSDXYSELL THEN
return TRUE;
END;
return FALSE;
Entry Short:
{LENGTH=Channel length in days,
D1DXY=Days for the Dollar Index linear regression
slope calculation
D2SNL=Days for the Seasonal data linear regression
slope calculation
LRSNLSELL= Seasonal data linear regression slope per day
LRSDXYSELL=Dollar index linear regression slope per day
MASNL=Days for the seasonal exponential moving average sell/
buytocover conditions
MASELL=Days for the Soybean exponential moving average sell/
buytocover conditions
MADXY=Days for the Dollar Index moving average sell/
buytocover conditions}
VARIABLES
LENGTH:=4;
D1DXY:=25;
D2SNL:=12;
SELLMONTH:=6;
BUYMONTH:=9;
LRSNLSELL:=-0.8;
LRSDXYSELL:=0.3;
MASNL:=15;
MASELL:=15;
MADXY:=50;
RS:=0;
LRSNL:=0;
S2:=0;
STOPL:=0;
SEASONALBUY:=FALSE;
SEASONALSHORT:=FALSE;
LRSDXY:=0;
END_VARIABLES
IF BARNUMBER>3 THEN BEGIN
RS:=EMA((Close / External("Close","SNL")), 3);
END;
IF BARNUMBER >D2SNL + 3 THEN BEGIN
LRSNL:=(LRL(RS, D2SNL, 0) - LRL(RS, D2SNL, D2SNL)) /
LRL(RS, D2SNL, D2SNL) / D2SNL * 100;
END;
IF BARNUMBER >D1DXY THEN BEGIN
LRSDXY:=(LRL(External("Close","DXY"),D1DXY,0) -
LRL(External("Close","DXY"),D1DXY,D1DXY)) /
LRL(External("Close","DXY"),D1DXY,D1DXY) / D1DXY * 100;
END;
SEASONALBUY:= Month < SELLMONTH OR Month > BUYMONTH;
SEASONALSHORT:= Month > SELLMONTH AND Month < BUYMONTH+1;
{Sell condition}
IF SEASONALSHORT AND C < LOWEST(C,LENGTH)\1\ -
2 AND LRSDXY > -LRSDXYSELL
AND LRSNL < -LRSNLSELL THEN
return TRUE;
return FALSE;
Exit Short:
{LENGTH=Channel length in days,
D1DXY=Days for the Dollar Index linear regression
slope calculation
D2SNL=Days for the Seasonal data linear regression
slope calculation
LRSNLSELL= Seasonal data linear regression slope per day
LRSDXYSELL=Dollar index linear regression slope per day
MASNL=Days for the seasonal exponential moving average sell/
buytocover conditions
MASELL=Days for the Soybean exponential moving average sell/
buytocover conditions
MADXY=Days for the Dollar Index moving average sell/
buytocover conditions}
VARIABLES
LENGTH:=4;
D1DXY:=25;
D2SNL:=12;
SELLMONTH:=6;
BUYMONTH:=9;
LRSNLSELL:=-0.8;
LRSDXYSELL:=0.3;
MASNL:=15;
MASELL:=15;
MADXY:=50;
RS:=0;
LRSNL:=0;
S2:=0;
STOPL:=0;
SEASONALBUY:=FALSE;
SEASONALSHORT:=FALSE;
LRSDXY:=0;
END_VARIABLES
IF BARNUMBER>3 THEN BEGIN
RS:=EMA((Close / External("Close","SNL")), 3);
END;
IF BARNUMBER >D2SNL + 3 THEN BEGIN
LRSNL:=(LRL(RS, D2SNL, 0) - LRL(RS, D2SNL, D2SNL)) /
LRL(RS, D2SNL, D2SNL) / D2SNL * 100;
END;
IF BARNUMBER >D1DXY THEN BEGIN
LRSDXY:=(LRL(External("Close","DXY"),D1DXY,0) -
LRL(External("Close","DXY"),D1DXY,D1DXY)) /
LRL(External("Close","DXY"),D1DXY,D1DXY) / D1DXY * 100;
END;
SEASONALBUY:= Month < SELLMONTH OR Month > BUYMONTH;
SEASONALSHORT:= Month > SELLMONTH AND Month < BUYMONTH+1;
IF BarsSinceEntry > 1 THEN BEGIN
IF Close > EMA(Close, MASELL) AND LRSNL > -LRSNLSELL THEN
return TRUE;
IF Close > EMA(Close, MASELL)
AND EMA(External("Close","DXY"),MADXY) <
EMA(External("Close","DXY"),MADXY)\1\
AND External("Close","SNL") >
EMA(External("Close","SNL"),MASNL) THEN
return TRUE;
END;
return FALSE;
Then one needs to create the SOYBEAN SIMLE DATE SEASONAL STRATEGY:
Entry Long:
VARIABLES
SELLMONTH:=6;
BUYMONTH:=9;
SEASONALBUY:= FALSE;
END_VARIABLES
SEASONALBUY:= Month < SELLMONTH OR Month > BUYMONTH;
IF SEASONALBUY THEN return TRUE;
return FALSE;
Entry Short:
VARIABLES
SELLMONTH:=6;
BUYMONTH:=9;
SEASONALSHORT:=FALSE;
END_VARIABLES
SEASONALSHORT:= MONTH > SELLMONTH AND MONTH < BUYMONTH+1;
IF SEASONALSHORT THEN return TRUE;
return FALSE;
Finally, one needs to create the Simple moving average crossover strategy:
Entry Long:
VARIABLES
FastLength:=18;
SlowLength:=120;
MAS:=0;
MAL:=0;
AverageFC:=0;
End_var
MAS:= AverageFC( C, FastLength ) ;
MAL:= AverageFC( C, SlowLength ) ;
IF BarNumber > SLOWLENGTH THEN BEGIN
IF CrossAbove(MAS,MAL) THEN return TRUE;
END;
return FALSE;
Entry Short:
VARIABLES
FastLength:=18;
SlowLength:=120;
MAS:=0;
MAL:=0;
AverageFC:=0;
End_var
MAS:= AverageFC( C, FastLength ) ;
MAL:= AverageFC( C, SlowLength ) ;
IF BarNumber > SLOWLENGTH THEN BEGIN
IF CrossBelow(MAS,MAL) THEN return TRUE;
END;
return FALSE;
Also, one needs to create the AverageFC function using Tradecision’s Function Builder:
function (Price:NUMERIC=C, Length:NUMERIC=18):Numeric;
return CumSum( Price, Length ) / Length;
|