[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[amibroker] Re: How to add a column of MA30 of cum profit into the tradelist of the backtest



PureBytes Links

Trading Reference Links

Hi Mike

Thanks for the explanation of the procedure persisttrade, I replaced 
tradeprofit by cumprofit and now the backtest shows MA of cum.profit 
correctly. 

The next step , I want to use mid-level custom backtest to indicate 
either taking or neglecting a signal. ( something like 
if ( sign(Cumprofit-Avgtrades())) 
    possize=-10;
 else 
    possize=0;   )
 
I have two questions here:

1--Generally speaking, is it possible to do some calculation based 
on  metrics I got from trade object to filter the signals ? ( If some 
signals are filtered out, then the trades staying in the trade object 
will not be the same as the original ones on which the metrics of 
trade object was based )

2--Specific to my idea
 Signal object in amibroker seems to be engaging in a bar-to-bar 
checking of the signals.  And as you mentioned, my average of 
cum.proft in the previous code is  trade-by-trade statistics.  Is it 
possible to fill the gap between two. ( For example ,do a bar-to-bar 
iteration first , if MA_cumprofit does not exist, then assign it to 
be ref(MA_cumprofit ,-1)  ?


Or maybe from the start my idea is wrong, then is it possible to 
trade the equitry curve in some other way with custome backtester 
function of amibroker ?

Thanks for your help & best regards/ huanyan




--- In amibroker@xxxxxxxxxxxxxxx, "Mike" <sfclimbers@xxx> wrote:
>
> PersistTrade just just acts as a queue to keep track of the 
last 'n' 
> values, first in first out (FIFO). As new values get added, the 
oldest 
> values are dropped.
> 
>  http://en.wikipedia.org/wiki/Queue_(data_structure)
> 
> Since AmiBroker does not provide this type of structure natively, 
we 
> can instead leverage an AmiBroker feature called dynamic variables 
> (i.e.store values in variables named t1, t2, t3, ...tn).
> 
>  http://www.amibroker.com/guide/afl/afl_view.php?id=259
> 
> The approach is generic brute force in nature. To track the MA of 
> cumulative profit instead of trade profit, have your custom 
backtest 
> code pass cumProfit to PersistTrade instead of tradeProfit.
> 
> However, I believe that your intended usage is flawed.
> 
> Since you do not have a bar by bar collection of values, but rather 
a 
> trade by trade collection, once you stop trading the MA will never 
re-
> approach the equity curve. In the absence of any new trades, no new 
> values will be introduced and no existing values will get bumped 
out 
> of the queue, resulting in a stalled MA at the cumulative profit of 
> the last 'n' trades. In other words, your MA will no longer move 
> forward in time.
> 
> By contrast, in a true bar by bar MA, new (albeit unchanged) values 
> are still added to the queue, even though no new trade has taken 
> place, bumping out older values. Eventually, the queue would 
contain 
> 'n' identical values (the cumProfit of the last trade) and be equal 
to 
> the current equity curve. Your trade by trade approach will not do 
> this.
> 
> Mike
> 
> --- In amibroker@xxxxxxxxxxxxxxx, "huanyanlu" <huanyan2000@> wrote:
> >
> > Hi  Mike 
> > 
> > Thanks for the codes. I tested it , it displays the second 
metrics , 
> > but it seems to be the 30 unit average of the profit of the last 
30 
> > trades, rather than the 30 unit average of the cum.profit of the 
> last 
> > 30 trades.  ( The reason that I want to display the MA30 of the 
last 
> > cum.profit is that this is equivalent to the 30 unit average on 
the 
> > equity curve, then later I can trade the equity curve by only 
take 
> > those signals when the equity curve is above its own 30 unit 
> > average , and neglect the signals when the equity curve is below 
its 
> > 30 unit average , so here I need MA30 of cum.profit, not MA30 of 
> > profit ) .Would you please explain what does the procedure 
> > PersistTrade do here.
> > 
> > I replaced 30 by a variable "n " in your codes, and set the 
default 
> > lookback period as 10 ( which made it easier for me to realize 
the 
> > second metrics in your codes is actually average of trade 
profit. )
> > 
> > The code so far then is  as follows.  
> > 
> > 
> > 
> > 
> > ==========================================================
> > 
> > 
> > n=Param("Lookbackperiod for equity curve",10,1,200,1);
> > 
> > 
> > procedure PersistTrade( profit ) 
> > { 
> >     local t; 
> > 
> >     // Add to first open slot. 
> > 
> >     for ( t = 0; t < n; t++ ) 
> >     { 
> >         if ( IsNull( VarGet( "t" + t ) ) ) 
> >         { 
> >             VarSet( "t" + t, profit ); 
> >             break; 
> >         } 
> >     } 
> > 
> >     if ( t == n ) 
> >     { 
> >         // All slots currently occupied, need to bump oldest. 
> > 
> >         for ( t = 0; t < n-1; t++ ) 
> >         { 
> >             VarSet( "t" + t, VarGet( "t" + ( t + 1 ) ) ); 
> >         } 
> > 
> >         VarSet( "t" + t, profit ); 
> >     } 
> > } 
> > 
> > function AvgTrades() 
> > { 
> >     local cumProfit; 
> >     local t; 
> > 
> >     cumProfit = 0; 
> > 
> >     for ( t = 0; t < n; t++ ) 
> >     { 
> >         cumProfit += VarGet( "t" + t ); 
> >     } 
> > 
> >     return ( cumProfit / n ); 
> > } 
> > 
> > SetCustomBacktestProc( "" ); 
> > 
> > if ( Status( "action" ) == actionPortfolio ) 
> > { 
> >     for ( t = 0; t < n; t++ ) 
> >     { 
> >         VarSet( "t" + t, Null ); 
> >     } 
> > 
> >     bo = GetBacktesterObject(); 
> > 
> >     bo.Backtest( 1 ); // run default backtest at notradelist mode 
> > 
> >     cumProfit = 0; 
> >     numTrades = 0; 
> > 
> >     for ( trade = bo.GetFirstTrade(); trade; trade = 
bo.GetNextTrade
> > () ) 
> >     { 
> >         tradeProfit = trade.GetProfit(); 
> >         cumProfit += tradeProfit; 
> >         PersistTrade( tradeProfit ); 
> > 
> >         trade.AddCustomMetric( "custom cum profit", 
cumProfit ); // 
> > value of this metrics should be same as the built - 
in "cum.profit" 
> > 
> >         numTrades++; 
> > 
> >         if ( numtrades >= n ) 
> >         { 
> >             trade.AddCustomMetric( "MA of cum profit", AvgTrades
() 
> ); 
> >            
> >         } 
> >         else 
> >         { 
> >             trade.AddCustomMetric( "MA of cum profit", Null ); 
> >            
> >         } 
> >     } 
> > 
> >     bo.ListTrades(); 
> > } 
> > 
> > 
> > //===========a simple trading system ================ 
> > 
> > fast = Optimize( "fast", 12, 5, 20, 1 ); 
> > slow = Optimize( "slow", 26, 10, 25, 1 ); 
> > 
> > Buy = Cross( MACD( fast, slow ), Signal( fast, slow ) ); 
> > Sell = Cross( Signal( fast, slow ), MACD( fast, slow ) ); 
> > 
> > Short = Sell; 
> > Cover = Buy; 
> > 
> > 
> > 
> > 
> > --- In amibroker@xxxxxxxxxxxxxxx, "Mike" <sfclimbers@> wrote:
> > >
> > > 
> > > Hi,
> > > 
> > > The MA function returns an array, yet you are trying to store 
it 
> in 
> > a
> > > scaler (i.e. a non array variable). Similarly, MA expects an 
array 
> > as
> > > argument, but you are passing it a scaler.
> > > 
> > > You cannot use arrays to track the trades since you may have 
more 
> > trades
> > > than bars (array length is dictated by number of bars). 
Therefore, 
> > you
> > > will need to calculate the moving average yourself.
> > > 
> > > Run the following code and see if it does what you're after. I 
> have 
> > not
> > > tested it extensively, but it should at least get you started. 
To
> > > improve upon it, add a Parameter instead of hard coding the 
value 
> 30
> > > everywhere: http://www.amibroker.com/guide/afl/afl_view.php?
id=203
> > > <http://www.amibroker.com/guide/afl/afl_view.php?id=203>
> > > 
> > > Mike
> > > 
> > > procedure PersistTrade( profit )
> > > {
> > >      local t;
> > > 
> > >      // Add to first open slot.
> > > 
> > >      for ( t = 0; t < 30; t++ )
> > >      {
> > >          if ( IsNull( VarGet( "t" + t ) ) )
> > >          {
> > >              VarSet( "t" + t, profit );
> > >              break;
> > >          }
> > >      }
> > > 
> > >      if ( t == 30 )
> > >      {
> > >          // All slots currently occupied, need to bump oldest.
> > > 
> > >          for ( t = 0; t < 29; t++ )
> > >          {
> > >              VarSet( "t" + t, VarGet( "t" + ( t + 1 ) ) );
> > >          }
> > > 
> > >          VarSet( "t" + t, profit );
> > >      }
> > > }
> > > 
> > > function AvgTrades()
> > > {
> > >      local cumProfit;
> > >      local t;
> > > 
> > >      cumProfit = 0;
> > > 
> > >      for ( t = 0; t < 30; t++ )
> > >      {
> > >          cumProfit += VarGet( "t" + t );
> > >      }
> > > 
> > >      return ( cumProfit / 30 );
> > > }
> > > 
> > > SetCustomBacktestProc( "" );
> > > 
> > > if ( Status( "action" ) == actionPortfolio )
> > > {
> > >      for ( t = 0; t < 30; t++ )
> > >      {
> > >          VarSet( "t" + t, NULL );
> > >      }
> > > 
> > >      bo = GetBacktesterObject();
> > > 
> > >      bo.Backtest( 1 ); // run default backtest at notradelist 
mode
> > > 
> > >      cumProfit = 0;
> > >      numTrades = 0;
> > > 
> > >      for ( trade = bo.GetFirstTrade(); trade; trade = 
> > bo.GetNextTrade() )
> > >      {
> > >          tradeProfit = trade.GetProfit();
> > >          cumProfit += tradeProfit;
> > >          PersistTrade( tradeProfit );
> > > 
> > >          trade.AddCustomMetric( "custom cum profit", 
cumProfit ); 
> //
> > > value of this metrics should be same as the built - in 
> "cum.profit"
> > > 
> > >          numTrades++;
> > > 
> > >          if ( numtrades >= 30 )
> > >          {
> > >              trade.AddCustomMetric( "MA30 of cum profit", 
> AvgTrades
> > () );
> > >          }
> > >          else
> > >          {
> > >              trade.AddCustomMetric( "MA30 of cum profit", 
NULL );
> > >          }
> > >      }
> > > 
> > >      bo.ListTrades();
> > > }
> > > 
> > > 
> > > //===========a simple trading system ================
> > > 
> > > fast = Optimize( "fast", 12, 5, 20, 1 );
> > > slow = Optimize( "slow", 26, 10, 25, 1 );
> > > 
> > > Buy = Cross( MACD( fast, slow ), Signal( fast, slow ) );
> > > Sell = Cross( Signal( fast, slow ), MACD( fast, slow ) );
> > > 
> > > Short = Sell;
> > > Cover = Buy;
> > > 
> > > 
> > > --- In amibroker@xxxxxxxxxxxxxxx, "huanyanlu" <huanyan2000@> 
> wrote:
> > > >
> > > > Hi,
> > > >
> > > > After some reading, now I am able to put up some codes as 
> > attached. I
> > > > want to add two custom per-trade metrics. One is "custom cum 
> > profit",
> > > > this metrics already appear in the built-in backtester, I add 
> > this as
> > > > custom metrics in order to confirm that I am in the right 
> > direction.
> > > > The second custom metrics is what I really need to add, that 
> > is "MA30
> > > > of cum profit".
> > > >
> > > > I succeeded in adding the first custom metrics "custom cum 
> > profit",
> > > > but failed in getting the second done. The backtester shows 
zero
> > > > for "MA30 of cum profit"" the first 30 trades and blank from 
the
> > > > 31th trade. Did I miss something here, why I cannot use the 
> > function
> > > > MA() here correctly ?
> > > >
> > > > thanks for any help
> > > >
> > > > huanyan
> > > >
> > > > ==========================================================
> > > >
> > > > SetCustomBacktestProc("");
> > > >
> > > >
> > > > if( Status("action") == actionPortfolio )
> > > > {
> > > > bo = GetBacktesterObject();
> > > >
> > > > bo.Backtest(1); // run default backtest at notradelist mode
> > > >
> > > > Cumprofit = 0;
> > > > NumTrades = 0;
> > > > MA30_profit=0;
> > > >
> > > > // iterate through closed trades first
> > > > for( trade = bo.GetFirstTrade(); trade; trade = 
bo.GetNextTrade
> > > > () )
> > > > {
> > > >
> > > > Cumprofit = Cumprofit+ trade.Getprofit();
> > > >
> > > > trade.AddCustomMetric("custom cum profit",Cumprofit ); //
> > > > value of this metrics should be same as the built-in 
> "cum.profit"
> > > >
> > > >
> > > >
> > > > NumTrades++;
> > > >
> > > > if(numtrades>=30)
> > > > {MA30_profit=MA(Cumprofit,30);}
> > > >
> > > > trade.AddCustomMetric("MA30 of cum profit",MA30_profit );
> > > > }
> > > >
> > > > bo.ListTrades();
> > > >
> > > > }
> > > >
> > > >
> > > > //===========a simple trading system ================
> > > >
> > > > fast = Optimize("fast", 12, 5, 20, 1 );
> > > > slow = Optimize("slow", 26, 10, 25, 1 );
> > > > Buy=Cross(MACD(fast,slow),Signal(fast,slow));
> > > > Sell=Cross(Signal(fast,slow),MACD(fast,slow));
> > > >
> > > > Short=Sell;
> > > > Cover=Buy;
> > > >
> > > >
> > > >
> > > >
> > > >
> > > >
> > > > --- In amibroker@xxxxxxxxxxxxxxx, "Mike" sfclimbers@ wrote:
> > > > >
> > > > > Start with the document titled "AmiBroker Custom Backtester
> > > > > Interface.pdf" found in the Files section of this group 
> > published
> > > > by
> > > > > gp_sydney:
> > > > >
> > > > > http://f1.grp.yahoofs.com/v1/sPtkSfaX2ek2RCVbqqJOCJA2R_-
> > > > > armYEr2K2MmIWnAHp_8p2ZKxwE4WR0554peVNTIdd--
> > > > > CzFINIbYE5z51vkgAozgCxi0yI/AmiBroker%20Custom%20Backtester%
> > > > > 20Interface.pdf
> > > > >
> > > > > Mike
> > > > >
> > > > > --- In amibroker@xxxxxxxxxxxxxxx, "huanyanlu" <joesan99@> 
> wrote:
> > > > > >
> > > > > > Hi,
> > > > > > I have a simple question about custom backtesting.
> > > > > > I want to add a column of 30-trades average of the cum of 
> > profit
> > > > > into
> > > > > > the tradelist of the backtest result. How to implement 
this 
> in
> > > > AFL ?
> > > > > >
> > > > > > Thanks for any help
> > > > > >
> > > > > > huanlan
> > > > > >
> > > > >
> > > >
> > >
> >
>



------------------------------------

**** IMPORTANT ****
This group is for the discussion between users only.
This is *NOT* technical support channel.

*********************
TO GET TECHNICAL SUPPORT from AmiBroker please send an e-mail directly to 
SUPPORT {at} amibroker.com
*********************

For NEW RELEASE ANNOUNCEMENTS and other news always check DEVLOG:
http://www.amibroker.com/devlog/

For other support material please check also:
http://www.amibroker.com/support.html

*********************************
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/amibroker/

<*> Your email settings:
    Individual Email | Traditional

<*> To change settings online go to:
    http://groups.yahoo.com/group/amibroker/join
    (Yahoo! ID required)

<*> To change settings via email:
    mailto:amibroker-digest@xxxxxxxxxxxxxxx 
    mailto:amibroker-fullfeatured@xxxxxxxxxxxxxxx

<*> To unsubscribe from this group, send an email to:
    amibroker-unsubscribe@xxxxxxxxxxxxxxx

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/