# Calculate MAE/MFE 30 Bars after A Signal

A very astute reader of this blog brought a snippet of code that looks like EasyLanguage and sort of behaves like it, but not exactly.  This code was presented on the exceptional blog of Quant Trader posted by Kahler Philipp.  He used some of the ideas from  Dave Bergstrom.

## Equilla Programming Language

The theory behind the code is quite interesting and I haven’t gotten into it thoroughly, but will do so in the next few days.  The code was derived from Trade-Signal’s Equilla Programming Language.  I looked at the website and it seems to leans heavily on an EasyLanguage like syntax, but unlike EZLang allows you to incorporate indicators right in the Strategy.  It also allows you, and I might be wrong, to move forward in time from a point in the past quite easily.  The code basically was fed a signal (+1,0,-1) and based on this value progressively moved forward one bar at a time  (over a certain time period) and calculated the MAE and MFE (max. adverse/favorable excursion for each bar.  The cumulative MAE/MFE were then stored in a BIN for each bar.  At the end of the data, a chart of the ratio between the MAE and MFE was plotted.

## EasyLanguage Version

I tried to replicate the code to the best of my ability by going back in time and recording a trading signal and then moving Back to The Future thirty bars, in this case, to calculated and store the MAE/MFE in the BINS.

### Simple Moving Average Cross Over Test

After 100 bars, I looked back 30 bars to determine if the price was either greater than or less than the 21 day moving average.   Let’s assume the close was greater than the 21 day moving average 30 days ago, I then kept going backward until this was not the case.  In other words I found the bar that crossed the moving average.  It could have been 5 or 18 or whatever bars further back.  I stored that close and then started moving forward calculating the MAE/MFE by keeping track of the Highest Close and Lowest Close made during 30 bar holding period.  You will see the calculation in the code.  Every time I got a signal I accumulated the results of the calculations for each bar in the walk forward period.  At the end of the chart or test I divided each bars MFE by its MAE and plotted the results.  A table was also created in the Print Log.  This code is barely beta, so let me know if you see any apparent errors in logic or calculations.

``inputs: ilb(30); //ilb - initial lookbackvars: lb(0),signal(0),btf(0),mf(0),ma(0),hh(0),ll(99999999),arrCnt(0),numSigs(0);arrays : mfe(0),mae(0);lb = ilb;if barNumber > 100 then begin	signal = iff(c[ilb] > average(c[ilb],21),1,-1);//	print(d," signal ",signal," ",ilb);	if  signal <> signal then	begin			numSigs = numSigs + 1; // keep track of number of signals//		print("Inside loop ", date[ilb]," ",c[ilb]," ",average(c[ilb],21));		if signal = 1 then // loop further back to get cross over		begin//			print("Inside signal = 1 ",date[lb]," ",c[lb]," ",average(c[lb],21));			while c[lb] > average(c[lb],21)			begin				lb = lb + 1;			end;//			print("lb = ",lb);		end;				if signal = -1 then // loop further back to get cross over		begin//			print("Inside signal = -1 ",date[lb]," ",c[lb]," ",average(c[lb],21));			while c[lb] < average(c[lb],21)			begin				lb = lb + 1;			end;		end;		lb = lb - 1;				hh = 0;		ll = 999999999;				arrCnt = 0;		for btf = lb downto (lb - ilb) //btf BACK TO FUTURE INDEX		begin			mf=0;			ma=0;			hh=maxList(c[btf],hh);//			print("inside inner loop ",btf," hh ",hh," **arrCnt ",arrCnt);			ll=minList(c[btf],ll);				if signal>0 then 			begin				mf=iff(hh>c[lb],(hh-c[lb])/c[lb],0); // mf long signal				ma=iff(ll<c[lb],(c[lb]-ll)/c[lb],0); // ma long signal			end;			if signal<0 then begin				ma=iff(hh>c[lb],(hh-c[lb])/c[lb],0); // ma after short signal				mf=iff(ll<c[lb],(c[lb]-ll)/c[lb],0); // mf after short signal			end;//			print(btf," signal ",signal," mf ",mf:0:5," ma ",ma:0:5," hh ",hh," ll ",ll," close[lb] ",c[lb]);			mfe[arrCnt]=mfe[arrCnt]+absValue(signal)*mf;			mae[arrCnt]=mae[arrCnt]+absValue(signal)*ma;			arrCnt = arrCnt + 1;		end;	end;end;if lastBarOnChart thenbegin    print(" ** MFE / MAE ** ");	for arrCnt = 1 to 30	begin		print("Bar # ",arrCnt:1:0," mfe / mae ",(mfe[arrCnt]/mae[arrCnt]):0:5);	end;		for arrCnt = 30 downto 1	begin		plot1[arrCnt](mfe[31-arrCnt]/mae[31-arrCnt]," mfe/mae ");	end;end;``
Back to The Future - going backward then forward

Here is an output at the end of a test on Crude Oil

`` ** MFE / MAE ** Bar # 1 mfe / mae 0.79828Bar # 2 mfe / mae 0.81267Bar # 3 mfe / mae 0.82771Bar # 4 mfe / mae 0.86606Bar # 5 mfe / mae 0.87927Bar # 6 mfe / mae 0.90274Bar # 7 mfe / mae 0.93169Bar # 8 mfe / mae 0.97254Bar # 9 mfe / mae 1.01002Bar # 10 mfe / mae 1.03290Bar # 11 mfe / mae 1.01329Bar # 12 mfe / mae 1.01195Bar # 13 mfe / mae 0.99963Bar # 14 mfe / mae 1.01301Bar # 15 mfe / mae 1.00513Bar # 16 mfe / mae 1.00576Bar # 17 mfe / mae 1.00814Bar # 18 mfe / mae 1.00958Bar # 19 mfe / mae 1.02738Bar # 20 mfe / mae 1.01948Bar # 21 mfe / mae 1.01208Bar # 22 mfe / mae 1.02229Bar # 23 mfe / mae 1.02481Bar # 24 mfe / mae 1.00820Bar # 25 mfe / mae 1.00119Bar # 26 mfe / mae 0.99822Bar # 27 mfe / mae 1.01343Bar # 28 mfe / mae 1.00919Bar # 29 mfe / mae 0.99960Bar # 30 mfe / mae 0.99915``
Ratio Values over 30 Bins

## Using Arrays for Bins

When  newcomers  start to program EasyLanguage and encounter arrays it sometimes scares them away.  They are really easy and in many cases necessary to complete a project.  In this code I used two 40 element or bins arrays MFE and MAE.  I only use the first 30 of the bins to store my information.  You can change this to 30 if you like, and when you start using a fixed array it is best to define them with the exact number you need, so that TradeStation will tell you if you step out of bounds (assign value to a bin outside the length of the array).  To learn more about arrays just search my blog.  The cool thing about arrays is  you control what data goes in and what you do with that data afterwards.  Anyways play with the code, and I will be back with a more thorough explanation of the theory behind it.

## 2 thoughts on “If You Can’t Go Forward, Then Go Backward [Back To The Future]”

1. Bruce says:

Hi George,

1. George Pruitt says: