[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

Answer 1: No. That would be putting the cart before the horse. You 
cannot have any trades until after the Signals have been processed.

Answer 2: You'll have to experiment. You would have to write the code 
such that it only ever pushed a repeat of the last trade's cumProfit 
once it was confirmed that you have stopped trading. Otherwise, you 
should continue waiting for the next trade.

Note; There is a lengthy thread in the forum regarding trading the 
equity curve. Perhaps you can get something of value from it:

http://finance.groups.yahoo.com/group/amibroker/message/127218?
o=0&var=1&l=1

Mike

--- In amibroker@xxxxxxxxxxxxxxx, "huanyanlu" <huanyan2000@xxx> wrote:
>
> 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@> 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/