// Downloaded From https://www.WiseStockTrader.com //---------------------------------------------------------------------- // e-ratio code aggregated by Jez Liberty // http://www.automated-trading-system.com // // The code is largely inspired from the ASX Gorilla blog // http://theasxgorilla.blogspot.com/2007/07/how-to-compute-edge-ratio-in-amibroker.html // // implementation of the Edge Ratio, included below, involves two profound Amibroker fudges. // The first is the use of the AddToComposite function to create a composite ticker symbol // in which to hold the ATR array of a given stock for later retrieval within the Custom Back Tester // via the Foreign function. // The second fudge is the use of the VarSet/VarGet function to create a quasi array. // This was necessary to overcome the limitation where array elements cannot exceed in number the value of barcount-1. //---------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------- // Options default reset (taken from boilerplate.afl on AmibrokerU.com // Should be included on all code files //--------------------------------------------------------------------------------------------------------- SetOption("InitialEquity",1000); SetOption("MinShares", .0001); SetOption("MinPosValue",0); SetOption("FuturesMode", False); SetOption("AllowPositionShrinking", True); SetOption("ActivateStopsImmediately",False); SetOption("ReverseSignalForcesExit", True); SetOption("AllowSameBarExit",True); SetOption("CommissionMode", 2); SetOption("CommissionAmount", 0); SetOption("InterestRate", 0); SetOption("MarginRequirement", 100); SetOption("PortfolioReportMode",0); SetOption("MaxOpenPositions", 1); SetOption("WorstRankHeld", 1);// Not in settings SetOption("PriceBoundChecking",False);// Not in settings SetOption("UsePrevBarEquityForPosSizing",True); SetOption("UseCustomBacktestProc",False); SetOption("DisableRuinStop",False);// Not in settings SetOption("EveryBarNullCheck",False);// Not in settings SetOption("HoldMinBars",0);// Not in settings SetOption("HoldMinDays",0);// Not in settings SetOption("EarlyExitBars",0);// Not in settings SetOption("EarlyExitDays",0);// Not in settings SetOption("EarlyExitFee",0);// Not in settings SetOption("SeparateLongShortRank",False);// Not in settings SetOption("MaxOpenLong",0);// Not in settings SetOption("MaxOpenShort",0);// Not in settings MaxPos= 100 * 100 / GetOption("MarginRequirement"); PositionSize = -MaxPos / GetOption("MaxOpenPositions"); RoundLotSize = 1; // 0 for Funds, 100 for Stocks TickSize= 0; // 0 for no min. size MarginDeposit = 10; PointValue= 1;// For futures ExitAtTradePrice = 0; ExitAtStop= 1; ExitNextBar= 2; ReEntryDelay= 0; //--------------------------------------------------------------------------------------------------------- // End of options reset - override options below //--------------------------------------------------------------------------------------------------------- //Override of options to enable e-ratio calc and multiple simultaneous positions PosQty = 5; // You can define here how many open positions you want SetOption("MaxOpenPositions", PosQty ); PositionSize = -100/PosQty; // invest 100% of portfolio equity divided by max. position count SetOption("InitialEquity",10000000); SetOption("FuturesMode", True); //------------------------------------------------------------------------------- //Actual System/Signal tested goes below: //------------------------------------------------------------------------------- //BUY RULES: implemented with a Buy Stop based Upper Donchian Channel(20) BuyStop = Ref(HHV(High, 20),-1); Buy = Cross( High, BuyStop ); BuyPrice = Max( BuyStop, Low ); // make sure buy price not less than Low //------------------------------------------------------------------------------ //e-ratio specific code //------------------------------------------------------------------------------ //eratio is the variable that we "optimise" (step from 1 to 100) eratio = Optimize("Eratio", 20, 1, 100, 1); //Never Sell so that the position is stopped out after N bar instead Sell = 3 > 5; //Stop the positon and close it after N bars (eratio = N that we step from 1 to 100 in optimisation) ApplyStop( stopTypeNBar, stopModeBars, eratio ); //AddToComposite function is used to create a composite ticker symbol. //In it we hold the ATR array of a given instrument //This is for later retrieval within the Custom Back Tester via the Foreign function Normaliser = ATR(20); AddToComposite(Normaliser, "~atr_"+Name(), "C", 1+2+8); SetCustomBacktestProc(""); //activate the custom backtester if(Status("action") == actionPortfolio) //called when backtesting/optimising { bo = GetBacktesterObject(); bo.PreProcess(); // run default backtest procedure TradeATR = NumTrades = ATRArr = 0; //init variables for( bar=0; bar < BarCount-1; bar++) { bo.ProcessTradeSignals(bar); for ( sig=bo.GetFirstSignal(bar); sig; sig=bo.GetNextSignal(bar) ) { if (sig.isEntry()) { NumTrades++; ATRArr = Foreign("~atr_"+sig.Symbol, "C"); VarSet("TradeATR" + NumTrades, ATRArr[bar]); _TRACE("Symbol " + sig.Symbol + " ATR: " + VarGet("TradeATR" + NumTrades)); } } } AvgMAE = AccumMAE = AvgMFE = AccumMFE = NumTrades = 0; // iterate through closed trades for( trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade() ) { NumTrades++; EntryATR = VarGet ("TradeATR" + NumTrades); if ( EntryATR != 0 ) { _TRACE("EntryATR: " + WriteVal(EntryATR)); _TRACE("AccumMAE : " + WriteVal(AccumMAE)); AccumMAE = AccumMAE + (trade.GetMAE()*trade.EntryPrice/(100*EntryATR)); AccumMFE = AccumMFE + (trade.GetMFE()*trade.EntryPrice/(100*EntryATR)); } trade.AddCustomMetric("My MAE", trade.GetMAE()*trade.EntryPrice/100); trade.AddCustomMetric("My MFE", trade.GetMFE()*trade.EntryPrice/100); trade.AddCustomMetric("Entry ATR", EntryATR*10000); } AvgMAE = AccumMAE / NumTrades; AvgMFE = AccumMFE / NumTrades; _TRACE(WriteVal(AccumMAE )); _TRACE(WriteVal(NumTrades)); _TRACE(WriteVal(AvgMAE)); Eratio = abs(AvgMFE/AvgMAE); _TRACE(WriteVal(Eratio)); bo.AddCustomMetric( "Avg MAE", AvgMAE ); bo.AddCustomMetric( "Avg MFE", AvgMFE ); bo.AddCustomMetric( "Eratio", Eratio); bo.PostProcess(); }