**Backtesting Fuzzy Logic in Amibroker**
In pt.1 we backtested a “fuzzified” trading strategy in Matlab (read part 1):

Buy when RSI(3) is Low and it’s before Expiration week.

Although it was easy to develop this fuzzy model in Matlab, due to the intuitive GUI, it is difficult to get meaningful backtest results, visual signals, statistics and, of course, portfolio level backtesting. Everything is possible in Matlab but it takes considerable time and effort. I would rather backtest in Amibroker and get all my usual statistics, equity curves, visual arrows, as well as 1 click portfolio backtesting.

So how do we code this in Amibroker?

Again here’s the basic idea:

You can say buy when RSI(3)<25

Or you can say Buy when RSI(3) is fairly Low

You can say Buy on Monday of Expiration Week

Or Buy around the middle of the month.

I will be using some custom functions I developed:

//Let’s keep these for reference

indicators = “rsi3,Day_M”;

Property_ind1 = “Low,Neutral,High”;

Property_ind2 = “EarlyMonth,AroundExpirationWeek,EndMonth”;

Output = “Action”;

Property_Action = “Buy,Hold,Sell”;

RSI3 = RSI( 3 ); //0-100

Day_M = Day(); //1-31

SetMember( “rsi3”, “Low”, TRIMember( rsi3, -40.5, 0.475, 40.34 ) );

SetMember( “rsi3”, “Neutral”, TRIMember( rsi3, 10, 50, 90 ) );

SetMember( “rsi3”, “High”, TRIMember( rsi3, 60, 100, 140 ) );

SetMember( “Day_M”, “EarlyMonth”, GaussMember( Day_M, 5.27, -0.164 ) );

SetMember( “Day_M”, “AroundExpirationWeek”, GaussMember( Day_M, 3.94, 15.83 ) );

SetMember( “Day_M”, “EndMonth”, GaussMember( Day_M, 5.266, 31) );

Now, these are custom functions:

SetMember() creates an array named “rsi3Low”, and fills it with values from TRIMember() function.

TRIMember() function “transforms” the RSI(3) values to a membership function [0 1] of ‘Low” Rsi.

If the above make no sense, don’t worry, it’s much easier than you think.

Now, how did these numbers come up: TRIMember( rsi3, **-40.5, 0.475, 40.34 **).

Well if you look at the Matlab membership function we created in the last post, these are the numbers under “parameters”.

In other words

SetMember( “rsi3”, “Low”, TRIMember( rsi3, -40.5, 0.475, 40.34 ) );

SetMember( “rsi3”, “Neutral”, TRIMember( rsi3, 10, 50, 90 ) );

SetMember( “rsi3”, “High”, TRIMember( rsi3, 60, 100, 140 ) );

is basically this:

and

SetMember( “Day_M”, “EarlyMonth”, GaussMember( Day_M, 5.27, -0.164 ) );

SetMember( “Day_M”, “AroundExpirationWeek”, GaussMember( Day_M, 3.94, 15.83 ) );

SetMember( “Day_M”, “EndMonth”, GaussMember( Day_M, 5.266, 31) );

is this:

So now we’ll use two more custom functions that create the rules

1. FuzzyAndInf() – Stands for Fuzzy “AND” inference

2.FuzzyInf()

FuzzyAndInf( 0, “rsi3”, “Low”, “Day_M”, “AroundExpirationWeek”, “Action”, 1 );

FuzzyAndInf( 1, “rsi3”, “High”, “Day_M”, “EarlyMonth”, “Action”, -1 );

FuzzyInf( 2, “rsi3”, “High” , “Action”, -1 );

that roughly corresponds to these statements:

If RSI(3) is Low and it’s AroundExpirationWeek then Action is Buy

If RSI(3) is High and it’s EarlyMonth then Action is Sell

If RSI(3) is High then Sell

Then we have to weight the rules and defuzzify. Here I will simplify things since I cannot yet code a proper output membership function and de-fuzzify algorithm (help would be appreciated from math inclined people…).

Anyways, here are the reults. Remember this is a very simple concept of low RSI and expiration week positive bias…

1. SPY from 1995-August 2012

2. $0.006 commission per trade

3. Start with 100,000. Long only

Profit = 1359462.71 (1359.46%),

CAR = 16.37%,

MaxSysDD = -358582.04 (-43.88%),

CAR/MDD = 0.37,

# winners = 363 (68.75%),

# losers = 165 (31.25%)

So here’s the whole code:

indicators = “rsi3,Day_M”;

Property_ind1 = “Low,Neutral,High”;

Property_ind2 = “EarlyMonth,AroundExpirationWeek,EndMonth”;

Output = “Action”;

Property_Action = “Buy,Hold,Sell”;

RSI3 = RSI( 3 ); //0-100

Day_M = Day(); //1-31

SetMember( “rsi3”, “Low”, TRIMember( rsi3, -40.5, 0.475, 40.34 ) );

SetMember( “rsi3”, “Neutral”, TRIMember( rsi3, 10, 50, 90 ) );

SetMember( “rsi3”, “High”, TRIMember( rsi3, 60, 100, 140 ) );

SetMember( “Day_M”, “EarlyMonth”, GaussMember( Day_M, 5.27, -0.164 ) );

SetMember( “Day_M”, “AroundExpirationWeek”, GaussMember( Day_M, 3.94, 15.83 ) );

SetMember( “Day_M”, “EndMonth”, GaussMember( Day_M, 5.266, 31) );

FuzzyAndInf( 0, “rsi3”, “Low”, “Day_M”, “AroundExpirationWeek”, “Action”, 1 );

FuzzyAndInf( 1, “rsi3”, “High”, “Day_M”, “EarlyMonth”, “Action”, -1 );

FuzzyInf( 2, “rsi3”, “High” , “Action”, -1 );

//FuzzyAndInf( 3, “rsi3”, “Low”, “Day_M”, “EndMonth”, “Action”, 0 );

weight=0;

weight[0]=Param( “w0”, 1, 0.1, 1, 0.1 );

weight[1]=Param( “w1”, 1, 0.1, 1, 0.1 );

weight[2]=Param( “w2”, 1, 0.1, 1, 0.1 );

// weight[3]=Param( “w3”, 1, 0.1, 1, 0.1 );

Sellout = Holdout = Buyout = 0;

for ( k = 0;k <= 2;k++ )

{

Buyout = Buyout +( Nz( getRuleRes( 1, k ) ) ) * weight[k];

Holdout = Holdout +( Nz( getRuleRes( 0, k ) ) ) * weight[k];

Sellout = Sellout + (Nz( getRuleRes( -1, k ) ) )* weight[k];

}

decision = ( 0 * Sellout + 0.5 * Holdout + 1 * Buyout ) / ( Sellout + Holdout + Buyout );

decision=IIf( ( Sellout + Holdout + Buyout )==0,0 ,decision );

//Plot(decision,”decision”,colorRed);

Buy=decision>0.5;

Sell=decision<0.5;