_SECTION_BEGIN( "Price" );
SetChartOptions( 0, chartShowArrows | chartShowDates );
_N( Title = StrFormat( "{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ) );
Plot( C, "Close", ParamColor( "Color", colorDefault ), styleNoTitle | ParamStyle( "Price Style" ) | GetPriceStyle() );
_SECTION_END();
//Trading System
TradeDelay = Param( "Trade Delay", 0, 1, 1 );
SetTradeDelays( TradeDelay, TradeDelay, TradeDelay, TradeDelay );
SetBacktestMode ( backtestregular );
SetOption( "InitialEquity", 20000 );
posqty = Param( "PosQty", 20, 1, 20, 1 );
SetOption( "MaxOpenPositions", posqty );
SetOption( "PriceBoundChecking", 1 ); // trade only within the chart bar's price range
SetOption( "CommissionMode", 2 ); // set commissions AND costs as $ per trade
SetOption( "CommissionAmount", 22.95 ); // commissions AND cost
SetOption( "UsePrevBarEquityForPosSizing", 1 ); // set the use of last bars Equity for trade size
SetOption( "EveryBarNullCheck", True ); //For graphing stop losses
RoundLotSize = 10;
PositionSize = -100 / posqty; // desired position size is 100% portfolio Equity
//PositionScore = Random(); Not necessary for this purpose // Set the order for which stock trades when get mulitple signals in one bar in backtesting
BuyPrice = IIf( TradeDelay > 0, O, C );;
SellPrice = O; //Exit on stops only
Buy = Cross( EMA( C, 9 ), EMA( C, 28 ) ); //This is arbitrary - I just want to plot stop lines that match ApplyStop
Sell = 0;
Buy = ExRem( Buy, Sell );
Sell = ExRem( Sell, Buy );
ExitAtStop = IIf( TradeDelay > 0, 2, 1 ); //0 for ??, 1 for Intraday on Signal, 2 for open on next day
//StopLoss = Param( "Max loss %", 10, 2, 30, 1 );
//ApplyStop( stopTypeLoss, stopModePercent, StopLoss, ExitAtStop, False ); //Fixed % Stop Loss
//PercentTrailingStopLevel = Param( "Trailing %", 23, 23, 30, 1 );
//ApplyStop( stopTypeTrailing, stopModePercent, PercentTrailingStopLevel, ExitAtStop, False ); //Trailing % Stop Loss
ATRTrailingStopLevel = Param( "ATR Factor", 3, 0.5, 5, 0.5 ) * Ref( ATR( Param( "ATR Periods", 10, 2, 30, 1 ) ), -TradeDelay );
ApplyStop( stopTypeTrailing, stopModePoint, ATRTrailingStopLevel, ExitAtStop, True ); //Dynamic ATR Stop Loss
Equity( 1, 0 ); // evaluate stops, all quotes
InTrade = Flip( Ref( Buy, -TradeDelay ), Ref( Sell, -TradeDelay ) );
StopStyle = ParamStyle( "Stop Style", styleDots | styleNoLine, maskDefault | styleDots | styleNoLine );
//StopLossLine = IIf( InTrade OR Ref(Sell,-TradeDelay), ValueWhen( Ref( Buy, -TradeDelay ), BuyPrice ) * ( 1 - StopLoss / 100 ), Null );
//Plot( StopLossLine, "Stop Loss", colorRed, StopStyle );
//PercentTrailingStopLine = IIf( InTrade OR Ref(Sell,-TradeDelay), HighestSince( Buy, Ref( H, -TradeDelay ) - ( Ref( H, -TradeDelay ) * PercentTrailingStopLevel / 100 ) ), Null );
//Plot( PercentTrailingStopLine, "Percent Trailing Stop Line", colorRed, StopStyle );
ATRTrailingStopLine = IIf( InTrade OR Ref( Sell, -TradeDelay ), HighestSince( Buy, Ref( H, -TradeDelay ) - ATRTrailingStopLevel ), Null );
Plot( ATRTrailingStopLine, "ATR Trailing Stop Line", colorRed, StopStyle );
PlotShapes( Buy*shapeUpArrow, colorBrightGreen, 0, Low );
PlotShapes( Sell*shapeDownArrow, colorRed, 0, High );
I am always happy to help anyone with writing AFL for AB. I am a regular in the AB yahoo group, AB website forum, RC and other places.
Hi MattyMac --
You have set the tests to return "levels" by making your statement "C> MA 200 and RSI2 < 10," rather than "impulses" which come from tests that are true for only a single bar, such as "Cross(C,MA 200)." What you have done is the correct way to get a signal for every bar that meets the conditions.
You are getting a Buy only on the first bar where conditions are true because of the default system settings.
To enable multiple positions from any issues:
The default number for Maximum positions is one. Set the maximum positions greater than one -- like this:
MaxPos = 10;
SetOption("MaxOpenPositions",MaxPos);
Add a statement allowing AmiBroker to hold more than one position in the same issue -- like this:
SetBacktestMode( backtestRegularRawMulti );
I also recommend setting the size of each position to a fixed dollar amount. This removes the distortion caused by compounding and leverage:
SetOption("InitialEquity",100000);
SetPositionSize(10000,spsValue);
Put all of these statements at the beginning of your afl.
Regards,
Howard
gringotts,
I am an amibroker user of exactly one days experience, so dont take what i say too seriously, but this may help;
1. the code as written is not producing any short trades on my system, so its missing half the action. dont know why, but i am still on the free trial version, perhaps that is sonmething to do with it.
2. the code says the test was on 20 ETFs, not just SPY, and the position size 10000 is only 1/10 of the account size. with total exposure of 1.7%, even a great system is going to struggle to make 300k. The posted results panel shows 18% exposure, presumably filled out by the 19 other ETFs.
but strangely enough I get (just on SPY) exactly the same number of long trades as the posted results, so dont know whats going on there
You need to make sure the positions is on both Long and Short
To do this you need to go to Setting > General > Positions make sure you select both long and short
gringotts,
I am an amibroker user of exactly one days experience, so dont take what i say too seriously, but this may help;
1. the code as written is not producing any short trades on my system, so its missing half the action. dont know why, but i am still on the free trial version, perhaps that is sonmething to do with it.
2. the code says the test was on 20 ETFs, not just SPY, and the position size 10000 is only 1/10 of the account size. with total exposure of 1.7%, even a great system is going to struggle to make 300k. The posted results panel shows 18% exposure, presumably filled out by the 19 other ETFs.
but strangely enough I get (just on SPY) exactly the same number of long trades as the posted results, so dont know whats going on there
Thanks village. That's strange because up the top it says "Daily data for SPY for a period of about twelve years are used".
But it explains the difference I guess. I'll try it again with the top 20 EFTs by liquidity.
i just tried it and got a very similar result and equity curve to the one published on Howard's site, if I changed the initial position size to $20000 . Using $10000 i get a simar shape curve but scaled down. Definately not a loss though
Slippage = 0.0002;
//Start of Custom Backtest Interface
SetCustomBacktestProc("");
if ( Status( "action" ) == actionPortfolio )
{
bo = GetBacktesterObject();
bo.PreProcess(); // Initialize backtester
for ( bar = 0; bar < BarCount; bar++ )
{
for( sig = bo.GetFirstSignal( bar ); sig; sig = bo.GetNextSignal( bar ) )
{
sig.Price = sig.Price + IIf( sig.IsEntry(), Slippage, -Slippage );
}
bo.ProcessTradeSignals( bar );
}
bo.PostProcess(); // Finalize backtester
}
Again: if you don't know what you are coding it is STRONGLY encouraged to use
COMMISSION table instead. Just set custom commission table to implement slippage.
It is way easier and more straightforward than any other method. I completelly don't understand
the insistency of copy-paste artists on making it hard way while way easier method (no coding at all) is available.
As to the problem itself, there is NO need for loops or custom backtester.
Correct and fastest way to do this is:
SetOption("PriceBoundChecking",False); // make sure that AB will NOT trim at high/low
BuyPrice += Slippage; // add slippage to entries
SellPrice -= Slippage; // and subtract from exits
ShortPrice -= Slippage;
CoverPrice += Slippage;
Best regards,
Tomasz Janeczko
amibroker.com
SetOption("PriceBoundChecking",False);
slipfactor=0;
if (Name()=="+CL#" OR Name()=="QCL#" OR Name()=="+NG#")
{
BuyPrice=(BuyPrice+TickSize*slipfactor)+(1/PointValue)*2.32;
SellPrice=(SellPrice-TickSize*slipfactor)-(1/PointValue)*2.32;
CoverPrice=(CoverPrice+TickSize*slipfactor)+(1/PointValue)*2.32;
ShortPrice=(ShortPrice-TickSize*slipfactor)-(1/PointValue)*2.32;
}
else if (Name()=="@ES#" OR Name()=="@YM#")
{
BuyPrice=(BuyPrice+TickSize*slipfactor)+(1/PointValue)*2.01;
SellPrice=(SellPrice-TickSize*slipfactor)-(1/PointValue)*2.01;
CoverPrice=(CoverPrice+TickSize*slipfactor)+(1/PointValue)*2.01;
ShortPrice=(ShortPrice-TickSize*slipfactor)-(1/PointValue)*2.01;
}
else if (Name() == "@NQ#" )
{
BuyPrice=(BuyPrice+TickSize*slipfactor)+(1/PointValue)*2.01;
SellPrice=(SellPrice-TickSize*slipfactor)-(1/PointValue)*2.01;
CoverPrice=(CoverPrice+TickSize*slipfactor)+(1/PointValue)*2.01;
ShortPrice=(ShortPrice-TickSize*slipfactor)-(1/PointValue)*2.01;
}
else if (Name() == "@TFS#" )
{
BuyPrice=(BuyPrice+TickSize*slipfactor)+(1/PointValue)*2.01;
SellPrice=(SellPrice-TickSize*slipfactor)-(1/PointValue)*2.01;
CoverPrice=(CoverPrice+TickSize*slipfactor)+(1/PointValue)*2.01;
ShortPrice=(ShortPrice-TickSize*slipfactor)-(1/PointValue)*2.01;
}
Hello,
As documented, slippage may be simply added to commission, that is fully
customizable (see
tiered commission editor).
If you want extra setting just for ApplyStops -
for some reason, no one placed such suggestion in proper place, i.e.
http://www.amibroker.com/feedback/
Remember: if you want something use feedback center as it is the only way to get
your suggestion registered/read/categorized and eventually implemented.
Best regards,
Tomasz Janeczko
amibroker.com
There are different possibilities. Custom Backtester, commission table, or adding commission and slippage to buyprice, sellprice, shortprice,coverprice.
Hi,
Is anyone having trouble with latest 5.60.3, 64 bit version crashing after backtesting analysis?...i have it on 2 pcs and its crashing on both..
cheers
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?