As the book does not contain the Luxor code in AFL, I share it with the adaptations that I have been doing as I have been studying, in case it is useful for anyone who requires it.
Any comments or corrections are appreciated.
// Downloaded From
// Adapted by Santiago Vázquez
// including example code FX margin account by fxshrat@gmail.com
_SECTION_BEGIN( "GENERAL SETTINGS" );
//SETTINGS
SetChartOptions( 0, chartShowDates );
//OTHERS
SetOption( "FuturesMode", True );
SetOption( "Allowsamebarexit", True );
SetOption( "ReverseSignalForcesExit", False );
SetOption( "PriceBoundChecking", True );
SetOption( "ExtraColumnsLocation", 12 );// defines location of CBT columns in AA
report = ParamToggle("Report", "no, yes", 0);
SetOption( "GenerateReport", report ); // force generation of full report true/false, slower if set to true
SetOption( "PortfolioReportMode", 0 );// 0-Trade list, 1- Detailed Log, 2- Summary, 3- No output
//Reports, (deactivate reports section during optimization,
//if you don't wanna have generated reports for every optimization process because it slows it down quite a bit!)
SetBacktestMode( backtestRegular );// https://www.amibroker.com/guide/afl/setbacktestmode.html
// ....
// add other setoptions according to your system requirements ...
// https://www.amibroker.com/guide/afl/setoption.html
// or go to "Backtester settings" of analysis window
// in general: setoptions of code level override settings of "Backtester settings" window
// don't forget about the fact that you can save an analysis project file (.apx) that saves your AFL and backtest settings.
_SECTION_END();
_SECTION_BEGIN( "MONEY MANAGMENT SETTINGS" );
//INITIAL EQUITY, ,
basecurrency = ParamList("Base Currency", "USD,EUR");
Ini = Param( "Intial equity", 100000, 5000, 100000, 5000 );
SetOption( "InitialEquity", Ini ); // starting capital
//RISK AND POSITION
maxpositions = Param( "Simultaneous positions", 1, 1, 100 );
SetOption( "MaxOpenPositions", maxpositions );
lot = ParamList( "Lot size", "Lot (100k)|Mini (10k)|Micro (1k)" );
if( lot == "Lot (100k)" )
{
Lote = 100000;
}
if( lot == "Mini (10k)" )
{
Lote = 10000;
}
if( lot == "Micro (1k)" )
{
Lote = 1000;
}
SetOption( "UsePrevBarEquityForPosSizing", 0 );
SetPositionSize( lote, spsShares ); //i.e if trading standard lots
//
//SetPositionSize( 2, spsPercentOfEquity ); set percent of equity to use for position sizing
//This functions are used to determine the risk of each position.
//SetBacktestMode( backtestRegular ); https://www.amibroker.com/guide/afl/setbacktestmode.html
//COMISSIONS AND SLIPPAGE
Com = Param( "Commission and slipage", 0, 0, 150, 10 );
SetOption( "CommissionMode", 2 );
SetOption( "commissionamount", Com );
// FX Margin account settings ::::::::::::::::::::::::::::::::::
// these settings override settings of "Information" window
TickSize = IIf( StrFind( Name(), "JPY" ), 0.01, 0.0001 );
RoundLotSize = 1;
PointValue = 1;
Leverage = 40; // change to different leverage if using other broker i.e. IAB -> 40
MarginRate = 1 / Leverage; // dynamic calculation of margin
MarginDeposit = -100 * MarginRate; // here 100*0.025 = 2.5(%) 1:40
_SECTION_END();
_SECTION_BEGIN( "LUXOR" );
SmaPeriodFast = Param( "Fast Period ", 3, 1, 20, 2 );
SmaPeriodSlow = Param( "Slow Period", 30, 20, 200, 20 );
FastMA = MA( Close, SmaPeriodFast );
SlowMA = MA( Close, SmaPeriodSlow );
IsLong = FastMA > SlowMA;
IsShort = SlowMA > FastMA;
LongSignal = Cross( FastMA, SlowMA );
ShortSignal = Cross( SlowMA, FastMA );
LongConfirmPrice = ValueWhen( LongSignal, H );
ShortConfirmPrice = ValueWhen( ShortSignal, L );
Buy = IsLong AND H > LongConfirmPrice;
buyPrice = IIf(O > Ref(H, -1), O, LongConfirmPrice);//Avoid losing entries due to opening with a gap
Sell = IsShort AND L < ShortConfirmPrice;
SellPrice = ShortConfirmPrice;
Short = IsShort AND L < ShortConfirmPrice;
ShortPrice = IIf(O < Ref(L,-1), O, ShortConfirmPrice);//Avoid losing entries due to opening with a gap
Cover = IsLong AND H > LongConfirmPrice;
CoverPrice = LongConfirmPrice;
Buy = ExRem( Buy, Sell );
Sell = ExRem( Sell, Buy );
Short = ExRem( Short, Cover );
Cover = ExRem( Cover, Short );
intradeLong = Flip(Buy, Sell OR Short);
intradeshort = Flip(Short, Cover OR Buy);
LongConfirmPrice = IIf(intradeLong, 0, LongConfirmPrice);
ShortConfirmPrice = IIf(intradeshort, 0, ShortConfirmPrice);
Plot( C, "Close", colorBlack, styleBar );
Plot( FastMA, "Fast MA", colorRed, styleThick );
Plot( SlowMA, "Slow MA", colorBlue, styleThick );
_SECTION_END();
// PLOTTING ACTIVATION SIGNALS
distancia = 2.5 * ATR( 14 );
for( i = 0; i < BarCount; i++ )
{
if( Buy[i] ) PlotText( "buy\n" + BuyPrice[i], i, H[i] - distancia[i], colorGreen );
if( Sell[i] AND !Short[i] ) PlotText( "sell\n" + SellPrice[i], i, L[i] + distancia[i], colorRed );
if( Short[i] ) PlotText( "short\n" + ShortPrice[i], i, L[i] + distancia[i], colorRed );
if( Cover[i] AND !Buy[i] ) PlotText( "cover\n" + CoverPrice[i], i, H[i] - distancia[i], colorGreen );
}
//PLOTTIN SHAPES//
PlotShapes( IIf( LongSignal, shapeSmallCircle, shapeNone ), colorGreen, 0, LongConfirmPrice, 0 );
PlotShapes( IIf( ShortSignal, shapeSmallCircle , shapeNone ), colorRed, 0, ShortConfirmPrice, 0 );
PlotShapes( IIf( Buy, shapeUpArrow, shapeNone ), colorGreen, 0, L, -15 );
PlotShapes( IIf( Buy, shapeHollowCircle, shapeNone ), colorGreen, 0, BuyPrice, 0 );
PlotShapes( IIf( Sell AND !Short, shapeDownArrow, shapeNone ), colorRed, 0, H, -15 );
PlotShapes( IIf( Sell AND !Short , shapeHollowCircle, shapeNone ), colorRed, 0, SellPrice, 0 );
PlotShapes( IIf( Short, shapeDownArrow, shapeNone ), colorRed, 0, H, -15 );
PlotShapes( IIf( Short, shapeHollowCircle, shapeNone ), colorRed, 0, ShortPrice, 0 );
PlotShapes( IIf( Cover AND !Buy, shapeUpArrow, shapeNone ), colorGreen, 0, L, -15 );
PlotShapes( IIf( Cover AND !Buy, shapeHollowCircle, shapeNone ), colorGreen, 0, CoverPrice, 0 );
///////////////////////////////////////////////////////////////////////////////////////////////
// 2nd phase - Custom backtest start, here in example used to output a few additional columns//
///////////////////////////////////////////////////////////////////////////////////////////////
// store currency of Information window for CBT code below
StaticVarSetText( "Curr" + Name(), GetFnData( "Currency" ) );
SetCustomBacktestProc( "" );
if( Status( "action" ) == actionPortfolio )
{
bo = GetBacktesterObject();
bo.Backtest( 1 ); //high-level method performs default portfolio backtest to obtain custom metrics
st = bo.GetPerformanceStats( 0 ); // get stats for all trades
initialcap = st.GetValue( "InitialCapital" );
Sumprof = 0;
Sumpip = 0;
// iterate through closed trades and output some columns ////////////////////////////////
for( trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade() )
{
// equity at exit column
SumProf += trade.GetProfit();// cum. profit
EquityAtExit = initialcap + SumProf;
trade.AddCustomMetric( "Equity@Exit", EquityAtExit );
// base currency of tools-preferences-currencies
trade.AddCustomMetric( "BaseCurr", basecurrency );
// currency of information window
trade.AddCustomMetric( "Currency", StaticVarGetText( "Curr" + trade.Symbol ) );
// columns of conversion currency
trade.AddCustomMetric( "FXRate@Entry", trade.EntryFxRate, 5 );
trade.AddCustomMetric( "FXRate@Exit", trade.ExitFxRate, 5 );
// P/L in pips column
PLPips = IIf( trade.IsLong(),
/*Long*/ ( trade.ExitPrice - trade.EntryPrice ) / trade.TickSize,
/*Short*/ ( trade.EntryPrice - trade.ExitPrice ) / trade.TickSize );
trade.AddCustomMetric( "P/L Pips", PLPips, 1 );
// cummulated P/L pips column
Sumpip += PLPips;
trade.AddCustomMetric( "Cum.Pips", Sumpip, 1 );
}
// iterate through open trades and output some columns /////////////////////////////////
for( openpos = bo.GetFirstOpenPos(); openpos; openpos = bo.GetNextOpenPos() )
{
// equity at "exit" column
SumProf += openpos.GetProfit();// cum. profit
EquityAtExit = initialcap + SumProf;
openpos.AddCustomMetric( "Equity@Exit", EquityAtExit );
// base currency of tools-preferences-currencies
openpos.AddCustomMetric( "BaseCurr", basecurrency );
// currency of information window
openpos.AddCustomMetric( "Currency", StaticVarGetText( "Curr" + openpos.Symbol ) );
// columns of conversion currency
openpos.AddCustomMetric( "FXRate@Entry", openpos.EntryFxRate, 5 );
openpos.AddCustomMetric( "FXRate@Exit ", openpos.ExitFxRate, 5 );
// P/L in pips column
PLPips = IIf( openpos.IsLong(),
/*Long*/ ( openpos.ExitPrice - openpos.EntryPrice ) / openpos.TickSize,
/*Short*/ ( openpos.EntryPrice - openpos.ExitPrice ) / openpos.TickSize );
openpos.AddCustomMetric( "P/L Pips", PLPips, 1 );
// cummulated P/L pips column
Sumpip += PLPips;
openpos.AddCustomMetric( "Cum.Pips", Sumpip, 1 );
}
bo.ListTrades();
}
It does not allow me to include the original source code, so I have deleted it.