You are on page 1of 33

Advanced users workshop: Custom Backtester Interface

by Tomasz Janeczko, Amibroker.com

Custom backtester interface (CBI) - what for?


For everything that is not possible to do with standard backtester except.... making coffee (feat re not implemented, sorry!

Custom backtester interface (CBI) - what for?


S adding yo r c stom metrics position sizing based on portfolio"level e# ity S advanced scaling"in$"o t based on portfolio e# ity (for example rebalancing! and other r n" time stats S c stomized rotational trading systems S implementing c stom form las for slippage control S advanced systems sing %F"level stats on bar" by"bar basis to decide which trades to take

Purpose of this session


T T T T to explain some basic concepts to show a co ple of sage examples to answer # estions that yo may have it is NOT &"ho r programming co rse

Porto io backtest: ! passes


T first pass
S collecting trade signals, S ranking$sorting by position score (yo r AF' form la is exec ted once for every symbol nder test!

T second pass
S act al backtest (sim lation of trading on historical data sing signals collected in &st pass! (exec ted only once per backtest!

"irst backtester pass (re#u ar)

$econd backtester pass


This is where c stom backtester interface can be sed T For each bar the following things happen(
S Top ranked entry signals are checked and trades are entered (if f nds are available! S )xit$scale signals are matched against open positions and exec ted S *tops are applied and exec ted S All portfolio"level statistics$metrics are pdated
+ith ,-. yo can act ally change every aspect of this pass

%ow to enab e it ?
To enable c stom backtest, yo can se AA-> Settings, Portfolio tab (if yo do so, c stom code will be applied to A'' backtests!

%ow to enab e it ?
...or yo can enable it from the code( *et/ption(01se, stom-acktest%roc0, True !2 or *et, stom-acktest%roc( 0,(334y%ath334y, stom-acktest.afl0 !2 (if yo want to se se external file for it! .n this case c stom backtest will be applied to c rrent form la only.

&here to enter CB' code if it is enab ed inside formu a


To disting ish between normal r n (phase &! and final backtest r n (phase 5! yo need to se *tat s f nction(
SetCustomBacktestProc(""); if( Status("action") == actionPortfolio ) { ... YOUR CBT CO ! (P"#S! $)"!R!.... % ... YOUR R!&U'#R TR# ()& SYST!* (P"#S! +)

CBI - ( pro#rammin# eve s


T high-level - the easiest (allows simple implementation of c stom metrics! T medium-level (allows to modify signals, # ery open positions " good for advanced position sizing! T low-level approach (the most complex! " provides f ll control over entire backtest process for advanced programmers only

CBI pro#rammin# mode


T , stom backtester interface ses so called 6ob7ect oriented programming8 methodology (a.k.a. //%! T Don t be afraid " at basic level (only this level is re# ired to nderstand ,-.! //% is fairly simple

))P - ob*ect definition


T .n comp ter science an ob7ect is self" contained entity that encaps lates both data (so called properties! and proced res (so called methods! to manip late the data. T *o nds diffic lt.9 .... 4aybe b t it is act ally simple...

))P - simp e e+amp e


-efore we dig into ob7ects sed by ,-. one 6real"world8 example what ob7ect is and how to se(

T a %): " in programming co ld be represented as ob7ect having


S !ro!erties
R color, thickness

S methods that perform some actions


R ;raw'ine( x, y ! for example
,en = CreatePen(); -- o./ect creation ,en.t0ickness = $; -- ,ro,ert1 mo2ification ,en. ra3'ine( 456 $5 ); -- met0o2 call

))P vs functiona pro#rammin#


4any old"time programmers are afraid abo t //%, while they sed more or less the same idea witho t act ally realising that. )xample( F.') <A:;') "= /-J),T " in every programming lang age there is a concept of file handle that all file f nctions ("#T$ODS! re# ire to identify the file (O%&#'T! on which to operate.

CBI ob*ect hierarch,

CBI access to ob*ects


T -acktester ob7ect is available directly sing >et-acktester/b7ect(! AF' f nction. T All other ob7ects (*ignal$Trade$*tats! are accessible by calling appropriate methods of backtester ob7ect

%i#h eve mode


T The simplest. T 1ses only two ob7ects (%ac(tester and Stats! and only two methods (%ac(test(!$)etPerformanceStats(!! T how does it work9
S +e call defa lt %ac(test*+ proced re S and after that we are collecting statistics to calc late o r own fig res.

T what for9
S ser"defined portfolio"level metrics

-+ .: %i#h /eve - custom metrics


T .n the first example we will add simple new metric to backtest$optimization o tp t( #,!ectancy *-+ . /0inners 1 AvgProfit /2osers 1 Avg2oss

-+ .: %i#h eve - custom metrics - cont0


T SetCustomBacktestProc(""); -7 )o3 custom8.acktest ,roce2ure follo3s 7if( Status("action") == actionPortfolio ) { .o = &etBacktesterO./ect(); .o.Backtest(); -- run 2efault .acktest ,roce2ure st = .o.&etPerformanceStats(5); -- 9et stats for all tra2es e:,ectanc1 = st.&et;alue("<inners#=9Profit")7st.&et;alue("<innersPercent")-+55 > st.&et;alue("'osers#=9'oss")7st.&et;alue("'osersPercent")-+55; -- "ere 3e a22 custom metric to .acktest re,ort .o.#22Custom*etric( "!:,ectanc1 (?)"6 e:,ectanc1 ); %

-+ .: %i#h eve - custom metrics - resu ts

1edium eve
T *emi"advanced " ses all ob7ect classes T how does it work9
S for each bar(
R we can modify signals, check$modify open positions, retrieve per"trade statistics R then we call defa lt signal processing method

T what for9
S Advanced position sizing S %F"level signal control (c stom rotational trading! S Trade"based metrics

-+ !: 1id- eve - pos0 si2in# based on portfo io e30


if( Status("action") == actionPortfolio ) { .o = &etBacktesterO./ect(); .o.PreProcess(); for( .ar = 5; .ar @ BarCount; .ar>> ) { CurrentPortfolio!Auit1 = .o.!Auit1; for( si9 = .o.&etBirstSi9nal( .ar ); { if( CurrentPortfolio!Auit1 C D5555 if( CurrentPortfolio!Auit1 C F5555 if( CurrentPortfolio!Auit1 C G5555 % .o.ProcessTra2eSi9nals( .ar ); % .o.PostProcess(); %

si9; si9 = .o.&et)e:tSi9nal( .ar ) ) ) si9.PosSiEe = 8$5; ) si9.PosSiEe = 8+F; ) si9.PosSiEe = 8+$;

-+ (: 1id- eve - e+c 0 top-4 si#na s in rotationa mode


SetO,tion("UseCustomBacktestProc"6 True ); !:clu2eTo,) = +; -- 0o3 man1 to, ,ositions to e:clu2e if( Status("action") == actionPortfolio ) { .o = &etBacktesterO./ect(); .o.PreProcess(); for( .ar = 5; .ar @ BarCount; .ar>> ) { Cnt = 5; for( si9 = .o.&etBirstSi9nal( .ar ); si9; si9 = .o.&et)e:tSi9nal( .ar ) ) { if( Cnt @ !:clu2eTo,) ) si9.Price = 8+; -- e:clu2e Cnt>>; % .o.ProcessTra2eSi9nals( .ar ); % .o.PostProcess(); % !na.leRotationalTra2in9( True ); SetO,tion("*a:O,enPositions"6 D ); SetO,tion("<orstRank"el2"6 +5 );

/ow eve mode


T The most complex b t most powerf l T how does it work9
S for each bar
R we can check signals$open pos$%F"stats to decide what trades to enter$exit$scale R we can call )nterTrade$)xitTrade$*caleTrade for sing any parameters we want, we are not limited by signals R we need to handle stops and pdate portfolio statistics

T what for9
S rarely sed, only for very advanced pf systems

-+ 5: 1id6/ow- eve reba ancin#


if( Status("action") == actionPortfolio ) { .o = &etBacktesterO./ect(); .o.PreProcess(); -- (nitialiEe .acktester for(.ar=5; .ar@BarCount; .ar>>) { .o.ProcessTra2eSi9nals( .ar ); Cur!Auit1 = .o.!Auit1; for( ,os = .o.&etBirstO,enPos(); ,os; ,os = .o.&et)e:tO,enPos() ) { ,os=al = ,os.&etPosition;alue(); 2iff = ,os=al 8 5.5D 7 Cur!Auit1; -- re.alance to DI of ,f eAuit1 ,rice = ,os.&etPrice( .ar6 "O" ); if( 2iff J= 5 #) a.s( 2iff ) C 5.55D 7 Cur!Auit1 #) a.s( 2iff ) C ,rice ) { .o.ScaleTra2e( .ar6 ,os.S1m.ol6 2iff @ 56 ,rice6 a.s( 2iff ) ); % % % .o.PostProcess(); -- BinaliEe .acktester

$ome 3uestions I co ected before (.)


?( @ebalancing sample( can the weight also be an array, so the weights become dynamic9 A( Aes it can. .nstead of this line(
2iff = ,os=al 8 5.5D 7 Cur!Auit1;

1se this(
2iff = ,os=al 8 Borei9n("KTicker<it0<ei90ts"6 "C") 7 Cur!Auit1;

?(

<ow can . access percentage position size to make leverage ad7 stment for expectancy per B&CC invested A( Ao need to store original percent position size from appropriate *ignal ob7ect (if yo are sing reg lar mode!. To do so, yo can se *etDar f nction inside loop sing mid" level
for( sig = bo.GetFirstSignal( bar ); sig; sig = bo.GetNextSignal( bar ) ) VarSet("OrigSize" + sig.Symbol, sig.PosSize ); 'ater on yo wo ld need to read it back when yo iterate thro gh trades. -eca se of complexity . will post code sample a bit later to the E-.

$ome 3uestions I co ected before (!)

$ome 3uestions I co ected before (()


?( . have problem with sing AT, in ,proced re together with atcFlag)nable.n%ortfolio A( Aes there is a problem in c rrent beta, b t it will be fixed next week

$ome 3uestions I co ected before (5)


T ?( .s there already a way to a tomatically save the 0FFF)?1.TA0 to a different choosen name after a backtest9 .f not, wo ld yo consider introd cing this possibility9 T A( , rrently there are two ways(
S harder( writing e# ity to file and sing /') to re" import it at the end of ,- proced re. S easier( sing AT, and atcFlag)nable.n%ortfolio (b t as mentioned earlier it re# ires fix to the beta!

$ome 3uestions I co ected before (7)


T ?( +ill there be a link between the acco nt manager and the portfolio" -T$,-T T A( At some point in the f t re yes. First version of new acco nt manager that will appear within months probably will not have it.

An, more 3uestions?


T %lease feel free to ask any # estions...

'hank 8ou
"or more information visit: http:66www0amibroker0com

You might also like