Welcome Features News Download Registration Support FAQ Wish list Links
Advanced stock charting and analysis program

AFL Library

This is read-only version of AFL library entry. Ability to add user formulas and comment is only available from members-only area.

Details:

Formula name: Ed Seykota's TSP: EMA Crossover System
Author/Uploader: Mark H. - (email hidden)
Date/Time added: 2006-09-15 11:12:58
Origin:
Keywords: Seykota EMA Crossover
Level: basic
Flags: system

DISCLAIMER: Most formulas present in AFL on-line library are submitted by the users and are provided here on an "as is" and "as available" basis. AmiBroker.com makes no representations or warranties of any kind to the contents or the operation of material presented here. We do not maintain nor provide technical support for 3rd party formulas.
Description:

This is the code for the EMA Crossover System of Ed Seykota's Trading System Project at
http://www.seykota.com/tribe/TSP/index.htm.

I have tested it and got identical results to the dime compared to those at Seykota's website. I can't get it identical to cents due to rounding errors.

Formula:

/*==============================================================================
	Global Settings
==============================================================================*/
SetOption("InitialEquity", 1000000);
SetOption("MinShares", 50);
SetOption("NoDefaultColumns", True );
SetOption("CommissionMode", 2); //$$ per trade
SetOption("CommissionAmount", 0); // commission is accounted for in skid
SetOption("MarginRequirement", 10);
SetOption("UsePrevBarEquityForPosSizing", True);
SetOption("UseCustomBacktestProc", True );

SetTradeDelays( 1, 1, 1, 1 );

/*==============================================================================
	User-defined Functions
==============================================================================*/
function EMA0(A, p)
{
	r[0] = a[0];
	ep = 2/(p+1);
	for(i = 1; i < BarCount; i++)
	{
		r[i] = r[i-1] + (a[i] - r[i-1]) * ep;
	}
	return r;
}

function OptimizeNot(a1, a2, a3, a4, a5)
{
	return a2;
}

/*==============================================================================
	Entry and Exit Rules
==============================================================================*/
tr = Max(H-L, Max(abs(H-Ref(C, -1)), abs(Ref(C, -1)-L)));
tr[0] = H[0] - L[0];

fast = EMA0(C, Optimize("FastEMA", 15, 20, 140, 5));
slow = EMA0(C, Optimize("SlowEMA", 150, 150, 1000, 10));
Buy = Cross(fast, slow);
Sell = Cross(slow, fast);
Buy[1] = 0; // to avoid false signal at the beginning
//ApplyStop(stopTypeLoss, stopModePoint, ATR_multi*Ref(ATR0, -1), True, True
);

/*==============================================================================
	Skid of Executions
==============================================================================*/
BuyPrice = (H+O)/2;
SellPrice = (L+O)/2;

/*==============================================================================
	Position Sizing
==============================================================================*/
ATR_multi = OptimizeNot("ATP Multi", 5, 1, 9, 1);
ATR0 = EMA0(tr, 20);

Risk_Per_Share = Ref(ATR0, -1) * ATR_multi;
Heat = OptimizeNot("Heat", 0.10, 0.01, 0.50, 0.01);

PosSizeFactor = Heat / Risk_Per_Share; 
// the real position size value is calculated within CBT
SetPositionSize(PosSizeFactor, spsValue);

/*==============================================================================
	Automatic Analysis Action Options
==============================================================================*/
AAAction = Status("action");
if(AAAction == actionIndicator)
{
	Plot(fast, "FastEMA", colorRed);
	Plot(slow, "SlowEMA", colorYellow);
}
else if(AAAction == actionExplore)
{
	Filter = 1;
	AddColumn( DateTime(), "Date", formatDateTime ); 
	//AddColumn(DayOfWeek(), "DayOfWeek", 1);
	AddColumn(O, "Open");
	AddColumn(H, "High");
	AddColumn(L, "Low");
	AddColumn(C, "Close");
	//AddColumn(Avg, "AVG");
	AddColumn(fast, "FastEMA", 1.3);
	AddColumn(slow, "SlowEMA", 1.3);
	AddColumn(ATR0, "ATR", 1.3);
	//AddColumn(Risk_Per_Share, "Risk/Share");
	AddColumn(IIf(Buy, 111, IIf(Sell, 222, 0)) , "Buy1Sell2", 1);
	AddColumn(PosSize, "PosSize%Eq");
	AddColumn(Equity() , "Equity");
}	
else if(AAAction == actionPortfolio)
{
	bo = GetBacktesterObject();
	bo.PreProcess(); // Initialize backtester
	for( bar=0; bar < BarCount; bar++)
	{
		eq =  bo.Equity;
		for ( sig=bo.GetFirstSignal(bar); sig; sig=bo.GetNextSignal(bar) )
		{
			if (sig.isExit())
			{
            	if(bo.ExitTrade(bar,sig.symbol,sig.Price))
				{ 
					_TRACE("EXIT: " + sig.symbol + "@" + sig.Price);
				}
			}
		}

        // update stats after closing trades
     	bo.UpdateStats(bar, 1 );
       
     	for ( sig=bo.GetFirstSignal(bar); sig; sig=bo.GetNextSignal(bar)) 
     	{ 
			if (sig.isEntry()) 
			{ 
				// sig.PosSize is passed from Phase I.
				ps = Round(( eq * sig.PosSize)/250)*250 * sig.Price; 

				if(bo.EnterTrade(bar, sig.symbol, True, sig.Price, ps,
sig.PosScore,sig.RoundLotSize)) 
				{
					_TRACE("ENTRY: " + sig.symbol + " @" + sig.Price + " PosScore=" +
sig.PosScore + " PosSize=" + ps);
            	}
			}
		}

		//bo.HandleStops(bar); // MUST BE PLACED HERE TO WORK FOR N-BAR STOPS (not
before enter/exit trades)
		bo.UpdateStats(bar,1); // MAE/MFE is updated when timeinbar is set to 1.
		bo.UpdateStats(bar,2);
   	}
	bo.PostProcess(); // Finalize backtester
		
}
/*==============================================================================
	End of Formula
==============================================================================*/

Comments:

JoeMama
joemama.com
2006-09-15 17:21:31
Interesting but the optimization does not work.

Thanks!
Mark H.

2006-09-15 17:35:07
Which variables you can't optimize?
You may need to rename OptimizeNot to Optimize for some of the variables. OptimizeNot is just a shortcut when you don't want to optimize a variable at that run. (i.e. Rename Optimize to OptimizeNot to avoid optimizing that variable)
john norquay
john (dot) norquay (at) gmail (dot) com
2006-09-18 14:12:56
Hi Mark.
I use eod data. I have a watchlist of about 39 funds I tested this on. I backtested the system exactly as written, and it is taking positions sizes that are larger than the beginning equity amount. Could you see if there is an easy explanation for this?
Thanks.
Mark H.

2006-09-19 15:34:55
See statement:
SetOption("MarginRequirement", 10);
That's 10% margin requirement. So you can buy 10 times of starting equity of funds.
Change it to 100 if you don't want to use margin.

By the way, this formula was written specifically for Seykota's project, and supports trading on one fund only. If you want to test it on a portfolio of funds/stocks, you need to modify it, adding position scoring (ranking) and position sizing methods, etc.
Markus Witzler
funnybiz [at] web.de
2008-09-17 15:14:39
Hello Mark,

Iīm doing Edīs MA crossover excercise of which you provided the code above.

since iīm still a newbie to coding in AB, I would have a question or two on your code.

Would you mind providing your email address so that i could contact you if I donīt understand something in your code?

for instance, I donīt have a clue what you want to accomplish by ep = 2/(p+1.

Thanks

Markus

Markus Witzler
funnybiz [at] web.de
2008-09-17 15:34:20
Hello Mark,

Iīm doing Edīs MA crossover excercise of which you provided the code above.

since iīm still a newbie to coding in AB, I would have a question or two on your code.

Would you mind providing your email address so that i could contact you if I donīt understand something in your code?

for instance, I donīt have a clue what you want to accomplish by ep = 2/(p+1.

Thanks

Markus


About | Privacy | Terms of Use | Contact information
Copyright © 2001 AMIBROKER.COM