PureBytes Links
Trading Reference Links
|
Dang! I feel like kicking myself sometimes.
That's exactly the problem. Often I just copy and paste from my old code modules. I must have copied from one where Null was required. But in this case, it only screwed me up.
Thanks yet again.
--- In amibroker@xxxxxxxxxxxxxxx, "Mike" <sfclimbers@xxx> wrote:
>
> 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@> 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/
|