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

[amibroker] Re: Adding a Custom Metric to Backtest Report



PureBytes Links

Trading Reference Links

Ozzy,

Your immediate problem is that you are refering to the MarginDeposit 
*variable* in your backtester code, when what you actually want to do 
is refer to the MarginDeposit *property* of the trade object.

However, using MarginDeposit or PointValue, do not seem to work. So I 
would suggest not going with option e) of Thomasz's note unless 
overloading the Score property (which maps to PositionScore 
variable). I have provided an example below taking that approach, 
though I do not encourage it since PostionScore is used by the 
backtester when deciding which trades to take (in other words, don't 
mess with values that the backtester needs!).

A few other observations:

1) Your Buy logic appears buggy. As written, Buy will always be set 
to the value returned by Condition4 (i.e. you clobber the Buy value 
at each iteration of the loop, so the last iteration will always 
win). I suspect that you want an OR operation here to Buy whenever 
any of the conditions are met.

2) Same problem with your MarginDeposit calculation; It is 
destructive. If you want to keep the *first* condition that was true, 
do as is provided in the example. If you want to keep the *last* 
condition that was true, remove the "AND NOT PositionScore" clause. 
If you want to track *all* conditions, you'll need to use a bit flag.

3) Given that your Sell condition is a function of Buy, there is no 
need to keep recalculating it within the loop. Wait 'till Buy has 
finished being defined, then calculate Sell once after the fact.

4) If I understand your Sell intent correctly (i.e. hold for 12 days 
then sell), there is a better way to do it. See ExRemSpan usage in 
example below.

Mike

//--------------------------------------------------------------------
----
// SIMPLE TRADING SYSTEM BASED ON VARIOUS CONDITIONS
//--------------------------------------------------------------------
----

FastMA       =    MA( C, 10 );
SlowMA       =    MA( C, 200 );

Condition1   = Cross( FastMA, SlowMA );
Condition2   = Cross( SlowMA, FastMA );
Condition3   = Cross( C,      SlowMA );
Condition4   = Cross( SlowMA, C     );

Buy = Sell = Short = Cover = PositionScore = 0;
PositionSize = -10;

for ( a = 1; a < 5; a++ )
{
    Condition     = VarGet( "Condition" + NumToStr( a, 1.0, 0 ) );
    Buy           = Buy OR Condition;
    PositionScore = IIf( Condition AND NOT PositionScore, a, 
PositionScore );  // Reserved variable "PositionScore" is used to 
store the
    // Condition numbers whenever a Condition is True.
}

Buy = ExRemSpan(Buy, 12);
Sell = Ref(Buy, -12);

//--------------------------------------------------------------------
-------
// WANT TO ADD THE CUSTOM COLUMN, "CONDITION" TO BACKTEST REPORT
//--------------------------------------------------------------------
-------

SetCustomBacktestProc( "" );

if ( Status( "action" ) == actionPortfolio )
{
    bo = GetBacktesterObject();

    bo.Backtest( 1 ); // run default backtest procedure

    // iterate through closed trades first

    for ( trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade
() )
    {
        trade.AddCustomMetric( "Condition", trade.Score  );
    }

    bo.ListTrades();
}

--- In amibroker@xxxxxxxxxxxxxxx, "ozzyapeman" <zoopfree@xxx> wrote:
>
> Taking the suggestion from Tomasz, I use the reserved variable
> "MarginDeposit" to store my condition numbers, which I then feed 
back
> into the custom backtester. In my mind, the following code should 
do the
> trick. I don't get any syntax errors and I can't see any flaw in 
logic.
> Yet my "Condition" column in the backtest report contains no values.
> 
> In the code below, shouldn't the MarginDeposit array contain all 
values
> of "a" for each Buy? If not, why not, and what would be the right
> approach? Been pulling my hair out for a couple of days on this 
problem.
> And I know it has to be something simple:
> 
> 
> 
> //------------------------------------------------------------------
----\
> --
> // SIMPLE TRADING SYSTEM BASED ON VARIOUS CONDITIONS
> //------------------------------------------------------------------
----\
> --
> 
> FastMA       =    MA( C, 10 );
> SlowMA       =    MA( C, 20 );
> 
> Condition1   = Cross(FastMA, SlowMA);
> Condition2   = Cross(SlowMA, FastMA);
> Condition3   = Cross(C,      SlowMA);
> Condition4   = Cross(SlowMA, C     );
> 
> 
> for(a = 1; a < 5; a++)
> {
> Condition     = VarGet( "Condition" + NumToStr( a, 1.0, 0 ) );
> 
> Buy           = Condition;
> MarginDeposit = IIf(Condition, a, 0);    // Reserved variable
> "MarginDeposit" is used to store the
>                                           // Condition numbers 
whenever a
> Condition is True.
> 
> Sell          = BarsSince(Buy) > 12;
> }
> 
> 
> //------------------------------------------------------------------
----\
> -----
> // WANT TO ADD THE CUSTOM COLUMN, "CONDITION" TO BACKTEST REPORT
> //------------------------------------------------------------------
----\
> -----
> 
> SetCustomBacktestProc("");
> 
> if( Status("action") == actionPortfolio )
> {
>      bo = GetBacktesterObject();
> 
>      bo.Backtest(1); // run default backtest procedure
> 
>     // iterate through closed trades first
>     for( trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade
() )
>     {
>         trade.AddCustomMetric("Condition", MarginDeposit  );
>     }
> 
>      bo.ListTrades();
> }
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> --- In amibroker@xxxxxxxxxxxxxxx, "ozzyapeman" <zoopfree@> wrote:
> >
> > Thanks Tomasz. That's helpful. I had forgotten that we can use 
one of
> > the setoptions to store and recall data.
> >
> > One last key question (for anyone). And I feel like a klutz asking
> > something so simple, given that I've been doing AFL now for six
> months.
> > But sometimes these simple things can be elusive.
> >
> > How do I flag each "a" value every time there is a Buy, without 
going
> > into a Barcount loop? I find that Barcount loops always slow down 
my
> > AFLs.
> >
> > I can't just do:
> >
> > if(Buy)        {then do something}
> >
> > since if() does not work with arrays.
> >
> > Is there any way around this, so that I can dynamically pass "a"
> values
> > into a setoption or static var? Or is this simply a case where a
> > Barcount loop *must* be used?
> >
> >
> >
> >
> //------------------------------------------------------------------
----\
> \
> > --
> > // SIMPLE TRADING SYSTEM BASED ON VARIOUS CONDITIONS
> >
> //------------------------------------------------------------------
----\
> \
> > --
> >
> > FastMA       =    MA( C, 10 );
> > SlowMA       =    MA( C, 20 );
> >
> > Condition1   = Cross(FastMA, SlowMA);
> > Condition2   = Cross(SlowMA, FastMA);
> > Condition3   = Cross(C,      SlowMA);
> > Condition4   = Cross(SlowMA, C     );
> >
> > for(a = 1; a < 5; a++)
> > {
> > Condition    = VarGet( "Condition" + NumToStr( a, 1.0, 0 ) );
> > Buy          = Condition;
> > Sell         = BarsSince(Buy) > 12;
> > }
> >
> >
> >
> //------------------------------------------------------------------
----\
> \
> > -----
> > // WANT TO ADD THE CUSTOM COLUMN, "CONDITION" TO BACKTEST REPORT
> >
> //------------------------------------------------------------------
----\
> \
> > -----
> >
> > SetCustomBacktestProc("");
> >
> > if( Status("action") == actionPortfolio )
> > {
> >      bo = GetBacktesterObject();
> >
> >      bo.Backtest(1); // run default backtest procedure
> >
> >     // iterate through closed trades first
> >     for( trade = bo.GetFirstTrade(); trade; trade = 
bo.GetNextTrade()
> )
> >     {
> >         trade.AddCustomMetric("Condition", a  );
> >     }
> >
> >      bo.ListTrades();
> > }
> >
> >
> > --- In amibroker@xxxxxxxxxxxxxxx, "Tomasz Janeczko" groups@ wrote:
> > >
> > > You need to pass that in either
> > > a) series (set) of static variables
> > > or
> > > b) addtocomposite/foreign
> > > or
> > > c) files (fopen/fputs/fgets/fclose)
> > > or
> > > d) unused trade/position variable (can be for example 
margindeposit
> if
> > you don't use it).
> > >
> > > Best regards,
> > > Tomasz Janeczko
> > > amibroker.com
> > > ----- Original Message -----
> > > From: "ozzyapeman" zoopfree@
> > > To: amibroker@xxxxxxxxxxxxxxx
> > > Sent: Friday, December 26, 2008 5:50 PM
> > > Subject: [amibroker] Re: Adding a Custom Metric to Backtest 
Report
> > >
> > >
> > > > Thanks Mike. I eventually figured as much.
> > > >
> > > > Still trying to figure out a way to dynamically pass the 
correct
> "a"
> > > > value to the backtester.
> > > >
> > > > Any ideas on a general approach to this? I need to somehow 
collect
> > an
> > > > "a" value each time there is a Buy, and store those somewhere 
so
> > they
> > > > can be read back by the custom backtester code.
> > > >
> > > >
> > > > --- In amibroker@xxxxxxxxxxxxxxx, "Mike" sfclimbers@ wrote:
> > > >>
> > > >> Hi,
> > > >>
> > > >> Note that your loop will iterate until 'a' equals 5, at which
> point
> > > >> the looping will terminate. In your backtest code, you are
> > referring
> > > >> to the value of 'a' which we've just established will always 
be
> 5.
> > > >> The custom backtest code is run *after* the rest of the 
script
> code
> > > >> has been run for all symbols.
> > > >>
> > > >> Mike
> > > >>
> > > >> --- In amibroker@xxxxxxxxxxxxxxx, "ozzyapeman" <zoopfree@> 
wrote:
> > > >> >
> > > >> > Thank you for pointing out that specific example. That 
helps me
> > add
> > > >> the
> > > >> > column to the backtest report.
> > > >> >
> > > >> > But I am still at a loss in feeding back the 
actual "Condition"
> > > >> value to
> > > >> > the custom metric. If I was building that custom metric 
from
> > other
> > > >> > metrics already in the report, it would be easy (and I have
> done
> > so
> > > >> in
> > > >> > the past).
> > > >> >
> > > >> > But how do I pass back the value of an actual variable 
from my
> > > >> trading
> > > >> > AFL, each time a Buy is true?
> > > >> >
> > > >> > This is what I now have, but the Condition column always 
shows
> > "5"
> > > >> in
> > > >> > the backtest report :
> > > >> >
> > > >> >
> > > >> >
> > //----------------------------------------------------------------
--
> > > >> ----\
> > > >> > --
> > > >> > // SIMPLE TRADING SYSTEM BASED ON VARIOUS CONDITIONS
> > > >> >
> > //----------------------------------------------------------------
--
> > > >> ----\
> > > >> > --
> > > >> >
> > > >> > FastMA       =    MA( C, 10 );
> > > >> > SlowMA       =    MA( C, 20 );
> > > >> >
> > > >> > Condition1   = Cross(FastMA, SlowMA);
> > > >> > Condition2   = Cross(SlowMA, FastMA);
> > > >> > Condition3   = Cross(C,      SlowMA);
> > > >> > Condition4   = Cross(SlowMA, C     );
> > > >> >
> > > >> > for(a = 1; a < 5; a++)
> > > >> > {
> > > >> > Condition    = VarGet( "Condition" + NumToStr( a, 1.0, 
0 ) );
> > > >> > Buy          = Condition;
> > > >> > Sell         = BarsSince(Buy) > 12;
> > > >> > }
> > > >> >
> > > >> >
> > > >> >
> > //----------------------------------------------------------------
--
> > > >> ----\
> > > >> > -----
> > > >> > // WANT TO ADD THE CUSTOM COLUMN, "CONDITION" TO BACKTEST
> REPORT
> > > >> >
> > //----------------------------------------------------------------
--
> > > >> ----\
> > > >> > -----
> > > >> >
> > > >> > SetCustomBacktestProc("");
> > > >> >
> > > >> > if( Status("action") == actionPortfolio )
> > > >> > {
> > > >> >      bo = GetBacktesterObject();
> > > >> >
> > > >> >      bo.Backtest(1); // run default backtest procedure
> > > >> >
> > > >> >     // iterate through closed trades first
> > > >> >     for( trade = bo.GetFirstTrade(); trade; trade =
> > bo.GetNextTrade
> > > >> () )
> > > >> >     {
> > > >> >         trade.AddCustomMetric("Condition", a  );
> > > >> >     }
> > > >> >
> > > >> >      bo.ListTrades();
> > > >> > }
> > > >> >
> > > >> >
> > > >> >
> > > >> >
> > > >> >
> > > >> > --- In amibroker@xxxxxxxxxxxxxxx, "Tomasz Janeczko" 
<groups@>
> > wrote:
> > > >> > >
> > > >> > > Everything is explained with examples in the User's Guide
> > > >> > > http://www.amibroker.com/guide/a_custommetrics.html
> > > >> > >
> > > >> > > See example 3.
> > > >> > > ============
> > > >> > >
> > > >> > > Best regards,
> > > >> > > Tomasz Janeczko
> > > >> > > amibroker.com
> > > >> > >   ----- Original Message -----
> > > >> > >   From: ozzyapeman
> > > >> > >   To: amibroker@xxxxxxxxxxxxxxx
> > > >> > >   Sent: Friday, December 26, 2008 1:26 AM
> > > >> > >   Subject: [amibroker] Adding a Custom Metric to Backtest
> > Report
> > > >> > >
> > > >> > >
> > > >> > >   I have been able to add custom metrics to the 
Optimization
> > > >> Reports,
> > > >> > but for some reason can't add a column to the Trade List
> Backtest
> > > >> > report. Hoping someone might be able to chime in here, as 
the
> > custom
> > > >> > backtester confuses me.
> > > >> > >
> > > >> > >   What I want to do is fairly simple. In my actual 
trading
> > > >> system, I
> > > >> > cycle through hundreds of possible conditions per bar. If 
any
> one
> > > >> > condition is true, then I Buy. I want to add a custom 
metric to
> > the
> > > >> > backtest report that lists which condition generated the 
Buy
> > signal.
> > > >> > >
> > > >> > >   For the sake of debugging, below is a very simplified 
AFL
> > (not
> > > >> my
> > > >> > actual system). I simply want to feedback the condition 
number
> > into
> > > >> the
> > > >> > backtester. But it does not work. If I add an optimize
> statement
> > at
> > > >> the
> > > >> > top, it will add the custom metric to the Optimization 
report.
> > But
> > > >> even
> > > >> > then that column does not reflect correct values.
> > > >> > >
> > > >> > >   So how do I add the column to the Backtest report? I 
would
> > have
> > > >> > thought the below code would do the trick. And how do I
> feedback
> > the
> > > >> > correct values? Perhaps I need to FPUT each condition, 
during
> the
> > > >> loop,
> > > >> > to an external file, then FGET the file for every trade in 
the
> > > >> > backtester? That might work, but feels inefficient:
> > > >> > >
> > > >> > >
> > > >> > >
> > > >> >
> > //----------------------------------------------------------------
--
> > > >> ----\
> > > >> > --
> > > >> > >   // SIMPLE TRADING SYSTEM BASED ON VARIOUS CONDITIONS
> > > >> > >
> > > >> >
> > //----------------------------------------------------------------
--
> > > >> ----\
> > > >> > --
> > > >> > >
> > > >> > >   FastMA       =    MA( C, 10 );
> > > >> > >   SlowMA       =    MA( C, 20 );
> > > >> > >
> > > >> > >   Condition1   = Cross(FastMA, SlowMA);
> > > >> > >   Condition2   = Cross(SlowMA, FastMA);
> > > >> > >   Condition3   = Cross(C,      SlowMA);
> > > >> > >   Condition4   = Cross(SlowMA, C     );
> > > >> > >
> > > >> > >   for(a = 1; a < 5; a++)
> > > >> > >   {
> > > >> > >   Condition    = VarGet( "Condition" + NumToStr( a, 1.0, 
0 )
> );
> > > >> > >   Buy          = Condition;
> > > >> > >   Sell         = BarsSince(Buy) > 12;
> > > >> > >   }
> > > >> > >
> > > >> > >
> > > >> > >
> > > >> >
> > //----------------------------------------------------------------
--
> > > >> ----\
> > > >> > -----
> > > >> > >   // WANT TO ADD THE CUSTOM COLUMN, "CONDITION" TO 
BACKTEST
> > REPORT
> > > >> > >
> > > >> >
> > //----------------------------------------------------------------
--
> > > >> ----\
> > > >> > -----
> > > >> > >
> > > >> > >   SetCustomBacktestProc( "" );
> > > >> > >
> > > >> > >   if ( Status( "action" ) == actionPortfolio )
> > > >> > >   {
> > > >> > >   bo = GetBacktesterObject();
> > > >> > >   bo.Backtest( 1 );                                    //
> Call
> > > >> > Backtest but set NoTradeLists to true
> > > >> > >   bo.AddCustomMetric( "Condition", a, 
0,0,0 );         // Add
> > the
> > > >> > custom metric
> > > >> > >   bo.ListTrades
();                                     // Now
> > > >> generate
> > > >> > the backtest report with custom metric
> > > >> > >   }
> > > >> > >
> > > >> >
> > > >>
> > > >
> > > >
> > > >
> > > > ------------------------------------
> > > >
> > > > **** 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
> > > >
> > > >
> > > >
> > >
> >
>



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

**** 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/