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

[amibroker] Re: BarCount Loop with Log File Dump Does not Work



PureBytes Links

Trading Reference Links

ProfitSum is never being initialized beyond Null. You use the += operator to add to it, but that operator may not be valid on Nulls. Why are you initializing to Null anyway? Why not 0? I did not notice anywhere that you were explicitly checking for IsNull or anything like that.

Mike

--- In amibroker@xxxxxxxxxxxxxxx, "ozzyapeman" <zoopfree@xxx> wrote:
>
> Thanks, Mike. I spent the better part of the morning playing with
> formatting and doing various other experiments. Turns out formatting is
> not the issue.
> 
> I was able to isolate the problem down to this single line:  " ProfitSum
> += ProfitLevel;"
> 
> For whatever reason, ProfitSum is not being indexed correctly, and any
> calculations based on it gets dumped to the log file as:
> 
> -10000000000
> 
> Consider the following somewhat simplified code. Everything works except
> for the ProfitAvg calculation which depends on the above mentioned
> indexing. Any other suggestions of what to try, given the isolation of
> the above line? :
> 
> 
> 
> //-----------------------------------------------------------------
> //      Variables for Optimization
> //-----------------------------------------------------------------
> 
> 
> LongOrShort = Optimize("LongOrShort", 1, 1, 2, 1);
> EntryNum    = Optimize("EntryNum",    1, 1, 3, 1);
> ExitNum     = Optimize("ExitNum",     1, 1, 3, 1);
> 
> 
> //-----------------------------------------------------------------
> //      Set up Range Tests for Entries and Exits
> //-----------------------------------------------------------------
> 
> 
> Entry1 = Close > Ref(Close, -1);
> Entry2 = Close > Ref(Close, -10);
> Entry3 = Close > Ref(Close, -20);
> 
> Exit1  = Close < Ref(Close, -1);
> Exit2  = Close < Ref(Close, -1);
> Exit3  = Close < Ref(Close, -1);
> 
> 
> Entry       = VarGet("Entry" + EntryNum);
> Exit        = VarGet("Exit"  + ExitNum );
> 
> 
> //-----------------------------------------------------------------
> //      Trading System with BarCount Loop
> //-----------------------------------------------------------------
> 
> 
> FileName     = "F:\\Stats Log File.csv";
> 
> wasLong      = wasShort       = BuySignal    = Temp =
> ShortSignal  = SellSignal     = CoverSignal  =
> SoldCount    = CoverCount     = EntryFreq    = 0;
> 
> ValueAtBuy   = ValueAtShort   = ProfitLevel  =
> ProfitSum    = ProfitAvg      = Null;
> 
> LongContractCount  = 0;
> ShortContractCount = 0;
> 
> InRange  = Status("barinrange");
> 
> for (i = 0; i < BarCount; i++)
> {
>    if (!InRange[i]) { continue;}
> 
>    wasLong  =  LongContractCount  > 0;
>    wasShort =  ShortContractCount > 0;
> 
>    // Long Exit
>    if (wasLong && Exit[i])
>    {
>       SellSignal[i] = 1;
>       LongContractCount = 0;
>       SoldCount++;
>       ProfitLevel = 10000*(SellPrice[i] - ValueAtBuy);
>       ProfitSum += ProfitLevel;
>     }
> 
>     // Short Exit
>     if (wasShort && Exit[i])
>     {
>       CoverSignal[i] = 1;
>       ShortContractCount = 0;
>       CoverCount++;
>       ProfitLevel = 10000*(ValueAtShort - SellPrice[i]);
>       ProfitSum += ProfitLevel;
>      }
> 
> 
>    // Long entry
>     if ( Entry[i] && LongOrShort == 1 )
>     {
>        BuySignal[i] = 1;
>        EntryFreq++;
>        LongContractCount = 1;
>        ValueAtBuy = BuyPrice[i];
>      }
> 
>    // Short entry
>     if ( Entry[i] && LongOrShort == 2 )
>     {
>        ShortSignal[i] = 1;
>        EntryFreq++;
>        ShortContractCount = 1;
>        ValueAtShort = ShortPrice[i];
>      }
> }
> 
> Sell  = SellSignal;
> Cover = CoverSignal;
> Buy   = BuySignal;
> Short = ShortSignal;
> 
> 
> //-----------------------------------------------------------------
> //      Calculate Some Basic Stats
> //-----------------------------------------------------------------
> 
> 
> if(LongOrShort == 1)
> {
>     if(SoldCount > 0)
>     ProfitAvg = ProfitSum/SoldCount;
> 
>     if(SoldCount == 0)
>     ProfitAvg = 0;
>    }
> 
> 
> if(LongOrShort == 2)
> {
>     if(CoverCount > 0)
>     ProfitAvg = ProfitSum/CoverCount;
> 
>     if(CoverCount == 0)
>     ProfitAvg = 0;
>    }
> 
> 
> 
> 
> //-----------------------------------------------------------------
> //      Create a Text Header Row for the Log File
> //-----------------------------------------------------------------
> 
> //SetCustomBacktestProc( "" );
> 
> if ( Status( "ActionEx" ) == actionExOptimizeSetup )
> {
>      _TRACE( "Optimize Begin" );
>      fh = fopen( FileName, "w" );
> 
>      if ( fh )
>      {
>         fputs( "LongOrShort, Entry, Exit, EntryFreq, ProfitAvg,
> ProfitSum, ProfitLevel, SoldCount, CoverCount\n", fh );
>         fclose( fh );
>      }
> }
> 
> 
> //-----------------------------------------------------------------
> //      Dump the Stats Values to the Log File
> //-----------------------------------------------------------------
> 
> 
> fh = fopen( FileName, "a" );
> 
> if ( fh )
> {
>     fputs( StrFormat( "%.0f,%.0f,%.0f,%.0f,%.0f%,%.0f,%.0f,%.0f,%.0f\n",
>                      LongOrShort, Entry, Exit, EntryFreq, ProfitAvg,
> ProfitSum, ProfitLevel, SoldCount, CoverCount), fh );
>     fclose( fh );
>    }
> 
> 
> 
> 
> 
> --- In amibroker@xxxxxxxxxxxxxxx, "Mike" <sfclimbers@> wrote:
> >
> > Unexpected log output is very often the result of incorrect
> formatting. Strip out your formatting and see if the results get written
> properly, then retry the formatting 'till you get it right.
> >
> > Mike
> >
> > --- In amibroker@xxxxxxxxxxxxxxx, "ozzyapeman" zoopfree@ wrote:
> > >
> > > Mike - great catch on the SetCustomCacktestProc. A bit of legacy
> code that I didn't even realize was still there. And I reviewed the code
> dozens and dozens of times! Guess I was so used to seeing it in my other
> AFL modules, that it passed under my radar.
> > >
> > > Thanks also for the observations on the barcount loop. I will
> implement those changes.
> > >
> > > Now the only remaining bug is that my stat of ProfitAvg dumped to
> the log file is showing up as  -10000000000.00000 for all instances.
> > >
> > > Yet if I printf to the interpretation window, I can see the correct
> values are being calculated for ProfitAvg, e.g. 0.0026
> > >
> > > I've dumped stats to log files many times before and they always
> dump correctly. Any idea why this is screwed up? I'm sure again it's
> something simple, but I still can't track down the disconnect.
> > >
> > >
> > >
> > > --- In amibroker@xxxxxxxxxxxxxxx, "Mike" <sfclimbers@> wrote:
> > > >
> > > > First, a word of caution; You really should only be running your
> loop over the period for which the bar is in range. Starting from zero
> *will* misalign your signals and your results will *not* be accurate.
> > > >
> > > > One simple way to do this is to set an InRange array before the
> loop:
> > > >
> > > >   InRange = Status("barinrange");
> > > >
> > > > Then inside your loop, if InRange is false, go to next bar.
> > > >
> > > >   if (!InRange[i]) {
> > > >     continue;
> > > >   }
> > > >
> > > > As to your question; You have set the code to use an in-file
> custom backtest procedure, but have not provided one. Comment out the
> following line and I believe that you will get the results you're
> looking for:
> > > >
> > > > SetCustomBacktestProc( "" );
> > > >
> > > > Alternatively, do as it would appear you intended and add custom
> backtester handling for your custom metrics.
> > > >
> > > > Mike
> > > >
> > > > P.S. Why are you looping to < BarCount - 1? You are skipping the
> last bar by doing so. Normally we loop to < BarCount (i.e. for BarCount
> bars using a zero based index, that should generally be index 0 to
> BarCount - 1 *inclusive*).
> > > >
> > > >
> > > > --- In amibroker@xxxxxxxxxxxxxxx, "ozzyapeman" <zoopfree@> wrote:
> > > > >
> > > > > Thanks Mike, I have some systems like that too, based on that KB
> code.
> > > > >
> > > > > But do you have any idea why my current code does not work? What
> puzzles me is that I've already built these types of barcount stats
> dumps before, and they always worked. In fact, looking at this current
> system vs my previous ones, I don't see any difference. In fact, the
> current one is simpler yet just does not work.
> > > > >
> > > > > I'm sure it's something simple that I am overlooking. I need to
> do it the way I am doing it, vs using the CBT, for reasons that have to
> do with my trading system. So I need to get this strategy to work.
> > > > >
> > > > >
> > > > >
> > > > > --- In amibroker@xxxxxxxxxxxxxxx, "Mike" <sfclimbers@> wrote:
> > > > > >
> > > > > > Ozzy,
> > > > > >
> > > > > > You can probably do what you want from within custom
> backtester code. You can track single bar values bar by bar, or
> construct a running tally bar by bar, storing the results in a composite
> symbol.
> > > > > >
> > > > > >
> http://www.amibroker.com/kb/2008/05/19/historical-portfolio-backtest-met\
> rics/
> > > > > >
> > > > > > Paolo recently posted something similar here:
> > > > > > http://finance.groups.yahoo.com/group/amibroker/message/137124
> > > > > >
> > > > > > Mike
> > > > > >
> > > > > > --- In amibroker@xxxxxxxxxxxxxxx, "ozzyapeman" <zoopfree@>
> wrote:
> > > > > > >
> > > > > > > Hello,
> > > > > > >
> > > > > > > Hoping someone can help with debugging this trading system
> code.
> > > > > > > I'vebeen building BarCount loops for the better part of 9
> months now,
> > > > > > > andthought I had the hang of it. Yet this simple problem
> seems to have
> > > > > > > thebetter of me!
> > > > > > >
> > > > > > > First, a simple test trading code that does work. The
> followingcode
> > > > > > > tests some entry and exit ranges, and takes a position when
> agiven range
> > > > > > > is true. I optimize over the various ranges, as well
> asLong/Short to see
> > > > > > > what works best. I am testing Forex, and left out
> thebacktester settings
> > > > > > > for simplicity here.
> > > > > > >
> > > > > > > If you optimize or backtest this code, over any given month,
> you will
> > > > > > > see output as expected:
> > > > > > >
> > > > > > >
> //-----------------------------------------------------------------
> > > > > > > //      Variables for Optimization
> > > > > > >
> //-----------------------------------------------------------------
> > > > > > >
> > > > > > >
> > > > > > > LongOrShort = Optimize("LongOrShort", 1, 1, 2, 1);
> > > > > > > EntryNum    = Optimize("EntryNum",    1, 1, 3, 1);
> > > > > > > ExitNum     = Optimize("ExitNum",     1, 1, 3, 1);
> > > > > > >
> > > > > > >
> > > > > > >
> //-----------------------------------------------------------------
> > > > > > > //      Set up Range Tests for Entries and Exits
> > > > > > >
> //-----------------------------------------------------------------
> > > > > > >
> > > > > > > myMA1       = MA(Close, 7);
> > > > > > >
> > > > > > > Entry1      = Close >= myMA1 + 0.0001  && Close < myMA1 +
> 0.0003;
> > > > > > > Entry2      = Close >= myMA1 + 0.0003  && Close < myMA1 +
> 0.0005;
> > > > > > > Entry3      = Close >= myMA1 + 0.0005;
> > > > > > >
> > > > > > > Exit1       = Close >= myMA1 + 0.0002  && Close < myMA1 +
> 0.0006;
> > > > > > > Exit2       = Close >= myMA1 + 0.0006  && Close < myMA1 +
> 0.0010;
> > > > > > > Exit3       = Close >= myMA1 + 0.0010;
> > > > > > >
> > > > > > >
> > > > > > > Entry       = VarGet("Entry" + EntryNum);
> > > > > > > Exit        = VarGet("Exit"  + ExitNum );
> > > > > > >
> > > > > > >
> > > > > > >
> //-----------------------------------------------------------------
> > > > > > > //      Trading System
> > > > > > >
> //-----------------------------------------------------------------
> > > > > > >
> > > > > > > Buy  = Short = 0;
> > > > > > >
> > > > > > >     if(LongOrShort == 1)
> > > > > > >
> > > > > > >           Buy   = Entry;
> > > > > > >
> > > > > > >     else
> > > > > > >
> > > > > > >         Short = Entry;
> > > > > > >
> > > > > > >
> > > > > > > Cover = Sell = Exit;
> > > > > > >
> > > > > > > So now all I want to do is run the exact same code as above,
> but with
> > > > > > > aBarCount loop, so that I can calculate some basic
> statistics for
> > > > > > > eachtrade over the optimization parameters. For example, I
> might want
> > > > > > > tofind out the average profit for trades, the frequency of
> which
> > > > > > > rangeswere used for entries, etc. While these trivial
> examples may
> > > > > > > beavailable in the AB optimization report, my real-world use
> involves
> > > > > > > allsorts of different stats that are not available.
> > > > > > >
> > > > > > > After I calculate the stats, I want to dump them to a log
> file. Pretty
> > > > > > > simple in theory.
> > > > > > >
> > > > > > > But the following code suffers from these problems:
> > > > > > >
> > > > > > >
> > > > > > >     1. If you run an optimization, all results are zero,
> instead of being
> > > > > > > identical to the above code.
> > > > > > >     2. If you run a backtest, no trades are ever taken,
> instead of
> > > > > > > behaving identical to the above code
> > > > > > >     3. The log file contains repeated rows. It should only
> contain one
> > > > > > > row per optimization sweep
> > > > > > >     4. The ProfitAvg stat is not calculated correctly.
> Entries are all
> > > > > > > -10 Billion or so (!)
> > > > > > >
> > > > > > > Can anyone spot why this is not working? I get no errors,
> and
> > > > > > > tracesindicate that my loops are being correctly processed.
> Any input
> > > > > > > muchappreciated!
> > > > > > >
> > > > > > >
> > > > > > >
> //-----------------------------------------------------------------
> > > > > > > //      Variables for Optimization
> > > > > > >
> //-----------------------------------------------------------------
> > > > > > >
> > > > > > >
> > > > > > > LongOrShort = Optimize("LongOrShort", 1, 1, 2, 1);
> > > > > > > EntryNum    = Optimize("EntryNum",    1, 1, 3, 1);
> > > > > > > ExitNum     = Optimize("ExitNum",     1, 1, 3, 1);
> > > > > > >
> > > > > > >
> > > > > > >
> //-----------------------------------------------------------------
> > > > > > > //      Set up Range Tests for Entries and Exits
> > > > > > >
> //-----------------------------------------------------------------
> > > > > > >
> > > > > > > myMA1       = MA(Close, 7);
> > > > > > >
> > > > > > > Entry1      = Close >= myMA1 + 0.0001  && Close < myMA1 +
> 0.0003;
> > > > > > > Entry2      = Close >= myMA1 + 0.0003  && Close < myMA1 +
> 0.0005;
> > > > > > > Entry3      = Close >= myMA1 + 0.0005;
> > > > > > >
> > > > > > > Exit1       = Close >= myMA1 + 0.0002  && Close < myMA1 +
> 0.0006;
> > > > > > > Exit2       = Close >= myMA1 + 0.0006  && Close < myMA1 +
> 0.0010;
> > > > > > > Exit3       = Close >= myMA1 + 0.0010;
> > > > > > >
> > > > > > >
> > > > > > > Entry       = VarGet("Entry" + EntryNum);
> > > > > > > Exit        = VarGet("Exit"  + ExitNum );
> > > > > > >
> > > > > > >
> > > > > > >
> //-----------------------------------------------------------------
> > > > > > > //      Trading System with BarCount Loop
> > > > > > >
> //-----------------------------------------------------------------
> > > > > > >
> > > > > > >
> > > > > > > FileName     = "F:\\Stats Log File.csv";
> > > > > > >
> > > > > > > wasLong      = wasShort       = BuySignal    =
> > > > > > > ShortSignal  = SellSignal     = CoverSignal  =
> > > > > > > SoldCount    = CoverCount     = EntryFreq    = 0;
> > > > > > >
> > > > > > > ValueAtBuy   = ValueAtShort   = ProfitLevel  =
> > > > > > > ProfitSum    = ProfitAvg      = Null;
> > > > > > >
> > > > > > > LongContractCount  = 0;
> > > > > > > ShortContractCount = 0;
> > > > > > >
> > > > > > >
> > > > > > > for (i = 0; i < BarCount-1; i++)
> > > > > > > {
> > > > > > >    wasLong  =  LongContractCount  > 0;
> > > > > > >    wasShort =  ShortContractCount > 0;
> > > > > > >
> > > > > > >    // Long Exit
> > > > > > >    if (wasLong && Exit[i])
> > > > > > >    {
> > > > > > >       SellSignal[i] = 1;
> > > > > > >       LongContractCount = 0;
> > > > > > >       SoldCount++;
> > > > > > >       ProfitLevel = SellPrice[i] - ValueAtBuy;
> > > > > > >       ProfitSum  += ProfitLevel;
> > > > > > >     }
> > > > > > >
> > > > > > >     // Short Exit
> > > > > > >     if (wasShort && Exit[i])
> > > > > > >     {
> > > > > > >       CoverSignal[i] = 1;
> > > > > > >       ShortContractCount = 0;
> > > > > > >       CoverCount++;
> > > > > > >       ProfitLevel = ValueAtShort - SellPrice[i];
> > > > > > >       ProfitSum  += ProfitLevel;
> > > > > > >      }
> > > > > > >
> > > > > > >
> > > > > > >    // Long entry
> > > > > > >     if ( Entry[i] && LongOrShort == 1 )
> > > > > > >     {
> > > > > > >        BuySignal[i] = 1;
> > > > > > >        EntryFreq++;
> > > > > > >        LongContractCount = 1;
> > > > > > >        ValueAtBuy = BuyPrice[i];
> > > > > > >      }
> > > > > > >
> > > > > > >    // Short entry
> > > > > > >     if ( Entry[i] && LongOrShort == 2 )
> > > > > > >     {
> > > > > > >        ShortSignal[i] = 1;
> > > > > > >        EntryFreq++;
> > > > > > >        ShortContractCount = 1;
> > > > > > >        ValueAtShort = ShortPrice[i];
> > > > > > >      }
> > > > > > > }
> > > > > > >
> > > > > > > Sell  = SellSignal;
> > > > > > > Cover = CoverSignal;
> > > > > > > Buy   = BuySignal;
> > > > > > > Short = ShortSignal;
> > > > > > >
> > > > > > >
> > > > > > >
> //-----------------------------------------------------------------
> > > > > > > //      Calculate Some Basic Stats
> > > > > > >
> //-----------------------------------------------------------------
> > > > > > >
> > > > > > >
> > > > > > > if(LongOrShort == 1)
> > > > > > >
> > > > > > >     ProfitAvg = ProfitSum/SoldCount;
> > > > > > >
> > > > > > > else
> > > > > > >
> > > > > > >     ProfitAvg = ProfitSum/CoverCount;
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >
> //-----------------------------------------------------------------
> > > > > > > //      Create a Text Header Row for the Log File
> > > > > > >
> //-----------------------------------------------------------------
> > > > > > >
> > > > > > > SetCustomBacktestProc( "" );
> > > > > > >
> > > > > > > if ( Status( "ActionEx" ) == actionExOptimizeSetup )
> > > > > > > {
> > > > > > >      _TRACE( "Optimize Begin" );
> > > > > > >      fh = fopen( FileName, "w" );
> > > > > > >
> > > > > > >      if ( fh )
> > > > > > >      {
> > > > > > >         fputs( "LongOrShort, Entry, Exit, EntryFreq,
> ProfitAvg\n", fh );
> > > > > > >         fclose( fh );
> > > > > > >      }
> > > > > > > }
> > > > > > >
> > > > > > >
> > > > > > >
> //-----------------------------------------------------------------
> > > > > > > //      Dump the Stats Values to the Log File
> > > > > > >
> //-----------------------------------------------------------------
> > > > > > >
> > > > > > >
> > > > > > > fh = fopen( FileName, "a" );
> > > > > > >
> > > > > > > if ( fh )
> > > > > > > {
> > > > > > >     fputs( StrFormat( "%.0f,%.0f,%.0f,%.0f,%.5f\n",
> > > > > > >                      LongOrShort, Entry, Exit, EntryFreq,
> ProfitAvg), fh
> > > > > > > );
> > > > > > >     fclose( fh );
> > > > > > >    }
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>




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

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

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

TO SUBMIT SUGGESTIONS please use FEEDBACK CENTER at
http://www.amibroker.com/feedback/
(submissions sent via other channels won't be considered)

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

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/