{"id":426,"date":"2014-09-30T15:21:42","date_gmt":"2014-09-30T20:21:42","guid":{"rendered":"http:\/\/www.amibroker.com\/kb\/?p=426"},"modified":"2018-02-27T11:06:01","modified_gmt":"2018-02-27T10:06:01","slug":"gen-backtest-from-a-file","status":"publish","type":"post","link":"https:\/\/www.amibroker.com\/wordpress\/kb\/2014\/09\/30\/gen-backtest-from-a-file\/","title":{"rendered":"How generate backtest statistics from a list of historical trades stored in a file"},"content":{"rendered":"

Apart from testing mechanical rules based on indicator readings, backtester can also be used to generate all statistics based on a list of pre-defined trades, list of our real trades from the past or a list of trades generated from another software.<\/p>

To achieve that, first we need to create an input information for AmiBroker where it could read the trades from. A convenient way would be to use an input file in text format, which could store information about trades, including the type of transaction (buy or sell), dates and position sizes. A sample input file may look like this:
Symbol,Trade,Date,Price,Shares
AAME,Buy,2000-04-06,2.66,375.94
AAME,Buy,2000-04-10,2.66,378.922
AAPL,Buy,2000-04-27,31.23,32.0862
AAON,Buy,2000-04-06,3.19,313.48
ABAX,Buy,2000-04-26,7.67,132.101
AB,Buy,2000-04-25,20.23,50.0337
A,Buy,2000-04-27,84.66,11.8362
AAME,Buy,2000-05-10,2.6,373.627
ABCB,Buy,2000-05-11,6.08,159.406
A,Buy,2000-05-15,82.27,11.736
AAON,Buy,2000-05-18,3.84,246.242
AB,Buy,2000-05-15,20.84,46.3303
ABAX,Buy,2000-05-18,5.84,161.913
ABCB,Buy,2000-05-15,6.08,158.803
AAME,Buy,2000-05-19,2.6,363.763
AB,Buy,2000-06-05,22.78,43.3501
ABC,Buy,2000-05-18,4.49,210.595
<\/code><\/p>

We can read and backtest such input with the formula presented below. It is important to remember that this particular code can work with input files of identical format (columns in identical order, signals specified with exact Buy \/ Sell words, position sizes specified as shares). Changing the input format would also require to update the formula to match the input.<\/p>

Path to the file is specified in the very first line (note that double backslashes need to be used).<\/p>

The formula reads the file line by line, then on a bar with matching date\/time it generates a new Buy or Sell signal that is then combined with existing signals (coming from other bars).<\/p>file <\/span>= <\/span>"C:\\\\TEMP\\\\trades.csv"<\/span>; <\/span>\/\/ change this to real location of your data file
<\/span>dt <\/span>= <\/span>DateTime<\/span>();
<\/span>\/\/
\/\/ Initialize variables
<\/span>Buy <\/span>= <\/span>Sell <\/span>= <\/span>possize <\/span>= <\/span>0<\/span>;
<\/span>\/\/
<\/span>fh <\/span>= <\/span>fopen<\/span>( <\/span>file<\/span>, <\/span>"r" <\/span>);
<\/span>\/\/
<\/span>if( <\/span>fh <\/span>)
 {
     while( ! <\/span>feof<\/span>( <\/span>fh <\/span>) )
     {
         <\/span>line <\/span>= <\/span>fgets<\/span>( <\/span>fh <\/span>);
         <\/span>\/\/ get the ticker symbol from the file
         <\/span>sym <\/span>= <\/span>StrExtract<\/span>( <\/span>line<\/span>, <\/span>0 <\/span>);
         <\/span>\/\/ if ticker matches current symbol
         <\/span>if ( <\/span>Name<\/span>() == <\/span>sym <\/span>)
         {
             <\/span>\/\/ extract data from line of text
             <\/span>trade <\/span>= <\/span>StrExtract<\/span>( <\/span>line<\/span>, <\/span>1 <\/span>);
             <\/span>trade_datetime <\/span>= <\/span>StrToDateTime<\/span>( <\/span>StrExtract<\/span>( <\/span>line<\/span>, <\/span>2 <\/span>) );
             <\/span>price <\/span>= <\/span>StrToNum<\/span>( <\/span>StrExtract<\/span>( <\/span>line<\/span>, <\/span>3 <\/span>) );
             <\/span>shares <\/span>= <\/span>StrToNum<\/span>( <\/span>StrExtract<\/span>( <\/span>line<\/span>, <\/span>4 <\/span>) );
             <\/span>\/\/
             <\/span>if ( <\/span>trade <\/span>== <\/span>"Buy" <\/span>)
             {
                 <\/span>newbuy <\/span>= <\/span>dt <\/span>== <\/span>trade_datetime<\/span>;
                 <\/span>Buy <\/span>= <\/span>Buy <\/span>OR <\/span>newbuy<\/span>; <\/span>\/\/ combine previous buy signals with new
                 <\/span>BuyPrice <\/span>= <\/span>IIf<\/span>( <\/span>newbuy<\/span>, <\/span>price<\/span>, <\/span>BuyPrice <\/span>);
                 <\/span>possize <\/span>= <\/span>IIf<\/span>( <\/span>newbuy<\/span>, <\/span>shares<\/span>, <\/span>possize <\/span>);
             }
             <\/span>\/\/
             <\/span>if ( <\/span>trade <\/span>== <\/span>"Sell" <\/span>)
             {
                 <\/span>newsell <\/span>= <\/span>dt <\/span>== <\/span>trade_datetime<\/span>;
                 <\/span>Sell <\/span>= <\/span>Sell <\/span>OR <\/span>newsell<\/span>; <\/span>\/\/ combine previous sell signals with new
                 <\/span>SellPrice <\/span>= <\/span>IIf<\/span>( <\/span>newsell<\/span>, <\/span>price<\/span>, <\/span>SellPrice <\/span>);
             }
         }
     }
     <\/span>\/\/
     <\/span>fclose<\/span>( <\/span>fh <\/span>);
 }
 else
 {
     <\/span>Error<\/span>( <\/span>"ERROR: file can not be open" <\/span>);
 }
<\/span>\/\/
<\/span>SetPositionSize<\/span>( <\/span>possize<\/span>, <\/span>spsShares <\/span>)<\/code>","protected":false},"excerpt":{"rendered":"

Apart from testing mechanical rules based on indicator readings, backtester can also be used to generate all statistics based on a list of pre-defined trades, list of our real trades from the past or a list of trades generated from another software.To achieve that, first we need to create an input information for AmiBroker where […]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[7],"tags":[53,14,15],"_links":{"self":[{"href":"https:\/\/www.amibroker.com\/wordpress\/kb\/wp-json\/wp\/v2\/posts\/426"}],"collection":[{"href":"https:\/\/www.amibroker.com\/wordpress\/kb\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.amibroker.com\/wordpress\/kb\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.amibroker.com\/wordpress\/kb\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.amibroker.com\/wordpress\/kb\/wp-json\/wp\/v2\/comments?post=426"}],"version-history":[{"count":2,"href":"https:\/\/www.amibroker.com\/wordpress\/kb\/wp-json\/wp\/v2\/posts\/426\/revisions"}],"predecessor-version":[{"id":1519,"href":"https:\/\/www.amibroker.com\/wordpress\/kb\/wp-json\/wp\/v2\/posts\/426\/revisions\/1519"}],"wp:attachment":[{"href":"https:\/\/www.amibroker.com\/wordpress\/kb\/wp-json\/wp\/v2\/media?parent=426"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.amibroker.com\/wordpress\/kb\/wp-json\/wp\/v2\/categories?post=426"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.amibroker.com\/wordpress\/kb\/wp-json\/wp\/v2\/tags?post=426"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}