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

[amibroker] Re: More on Database Structure and Local Storage



PureBytes Links

Trading Reference Links

Ken,

I see your point about the sums.  I wasn't thinking in terms of
summing, so the code I posted last doesn't do that.  Instead it gives
the user a choice of metrics, and sets the OI field according to the
ranking per the (single) chosen metric.

Sorry for any confusion caused by this.


--- In amibroker@xxxxxxxxxxxxxxx, Ken Close <ken45140@xxx> wrote:
>
> Progster:
> 
>  
> I like the way you comment the code to explain, in more detail, what
each
> line or at least selected lines are doing.  This is very helpful to
newbies
> in the custom backtester, like me, and will obviate the message I had
> planned asking for just such a thing from the experienced users.  Your
> comments have helped me a lot, so thanks.
>  
> As a partial test of my understanding of the code, I will attempt to
explain
> one of your comments/questions:
> this from your copied code (whew on word wrap)
> 
> // The index (k) into the sorted 'Signal' collection is the ordinal
ranking.
> 
>   if ( qt )
> 
>    {
> 
>      if ( run == 1 )
> 
> {   //  ROC case
> 
>        qt.OpenInt = k;
> 
> NoteSet(   sig.Symbol, sig.Symbol + " - OI displays: " + "ROC
ranking\n" +
> Announcement ) ;
> 
>     NoteSet(   sig.Symbol, NoteGet(sig.Symbol) + "\n" + "Highest
ROC(14) is
> lowest number.\n");
> 
>     }
> 
>         else if ( run == 2 )
> 
> {              //  RSI case
> 
>          // qt.OpenInt += k;          //  why?
> 
>  
> 
>     qt.OpenInt = k;
> 
>     NoteSet( sig.Symbol, sig.Symbol + " - OI displays: " + "RSI
ranking\n" +
> Announcement ) ;
> 
>     NoteSet(   sig.Symbol, NoteGet(sig.Symbol) + "\n" + "Highest
RSI(14) is
> lowest number.\n");
> 
>     }
> 
>         else{
> 
>         qt.OpenInt += k;          //  other cases (why?)
> 
>     }   
> 
>      }
> 
>  
> 
>             // target.isDirty = True;    //  not necessary
> 
> Now, my original specification to Paul Ho was that I wanted the sum
of the
> ordinals of the individual indicators to be the super ordinal or combo
> indicator.
> Thus, the 
>     qt.OpenInt += k;          //  other cases (why?)
> takes the ordinal from the first indicator (created in the first
qt.OpenInt
> = k; statement above, and adds the ordinal value of the second pass
to it,
> thus make the sum.
> From a previous message, Mike confirmed that qt.OpenInt += k; is the
same as
> qt.OpenInt = qt.OpenInt + k;
>  
> I hope/think this is right.
>  
> Of course, to add in challenge and complexity, what do the statement
loops
> look like when you want to sum three or four or more indicators.
>  
> Perhaps one just cascades the if statements, the run numbers and
still uses
> the += k construct.
>  
> So to add a third case to the initial switch statements in the ranking
> function, we might add
>  
>         case 3:
>             res = stochD( 14 );
>             break;
> 
> Later, we have to add a section
>      else if ( run == 3 )
>             {
>                 qt.OpenInt += k;
>             }
>  
> If my understanding of this is correct, for every additional
indicator added
> to the analysis, you add the same qt.OpenInt += k; statement (within the
> properly bracketed if else statements); the preprocessor has sorted
> everything for each indicator, so starting at the beginning, one
adds the
> ordinal values, then for each next step, one adds the ordinal values
of that
> step to the OpenInt from the previous step, resulting in the sum of
all the
> ordinals of the indicators in the analysis when all the loops or if/else
> steps are done.
>  
> Can someone confirm for me that this thinking is correct?  Please. 
If it is
> not, please take the time to explain how the += operator and previous
> preprocessor sorts are working to get the sum of all of the ordinals.  
>  
> If this is right (or is correctly explained another way), then this has
> increased my understanding of the custom backtester immensely.
>  
> Thanks for the added information in your modified code.
>  
> Ken
>  
>  
> 
> 
> -----Original Message-----
> From: amibroker@xxxxxxxxxxxxxxx [mailto:amibroker@xxxxxxxxxxxxxxx]
On Behalf
> Of progster01
> Sent: Wednesday, July 09, 2008 10:28 AM
> To: amibroker@xxxxxxxxxxxxxxx
> Subject: [amibroker] Re: More on Database Structure and Local Storage
> 
> --- In amibroker@xxxxxxxxxxxxxxx, "Paul Ho" <paul.tsho@> wrote:
> > Progster, you're correct in your interpretation. The only correction
> > needed is that Tomasz first posted the original code, I added the
> > storage part.
> 
> Paul - Thanks for the confirmation!
> 
> Below I add-on to this code a bit by making it write to the NotePad
a note
> which tells the observer what the OI field actually is showing.
> 
> I've also made the metric a parameter.
> 
> Something strange though - when I change the metric and re-run, all the
> symbols update OI to reflect the new metric _except_ for the one
which is
> currently displayed.  This is as observed in the NotePad.
> 
> Can anyone tell why that might be?
> (Tested in AB 5.14.0)
> 
> ___
> 
> 
> /*
>         OrdinalRankFast_01.afl
> 
>         Uses custom backtester to do very fast ordinal ranking,
writing the
> result
>         to the OI field.
> 
>         Demo ranking by ROC OR RSI is provided.
> 
>         Run this code as a Backtest.
> 
>         *** WARNING:    This code will change your database! ***
> 
>         Original code by:               Tomasz Janeczko and Paul Ho
>         Originally from:       
> http://finance.groups.yahoo.com/group/amibroker/message/126512
> 
>         7/9/2008        Progster        Added comments, and code to log
> actions by this AFL
> in the NotePad.
>         Made the ranking a parameter.  
>         Changed RSI case to behave like the ROC case.  This makes
the range
> of the OI field span the
>         # of stocks in the list to which this AFL is applied.
>         Observed that the symbol in the current chart does not
update (!?)
> 
> */
> 
> Announcement = "OI field has been set by OrdinalRankFast_01.afl" ;
> 
> run = Param( "run", 1, 1, 2, 1 );
> 
> function ranking( Ordinal )
> {
>     switch ( Ordinal )
>     {
>         case 1:
>             res = ROC( C, 14 ) + 1000;
>             break;
> 
>         case 2:
>             res = RSI( 14 );
>             break;
> 
>         default:
>             res = EMA( C, 50 );
>             break;
> 
>     }
>     return res;
> }
> 
> //      WHAT YOU WANT TO RANK
> //      Internally, AB will sort/order the backtester's 'Signal' objects
> according to
> //      absolute value of PositionScore.  Later in the code, we will
> retreive from these
> //      objects by stepping thru them sequentially.  Since the 'Signal'
> objects have already
> //      been sorted by AB into PositionScore order, the order in
which they
> will be
> // encountered when we step-thru them _is_ the ordinal order of the
ranking
> metric.
> PositionScore = ranking( run );                        
> 
> SetOption( "MaxOpenPositions", 50 );            //AB only keeps 2*
maxpos
> top
> rank signals
> 
> SetBacktestMode( backtestRegularRaw );
> 
> Buy = 1;                                                           
    //
> make a buy signal for every stock on every bar
> 
> Sell = Short = Cover = 0;
> 
> ab = CreateObject( "broker.Application" );
> 
> //      IsDirty flag tells AB that data has changed so when the user
press
> save, that area of the database is saved.
> //      Since this AFL will update the OI field, we mark the 'Stock' as
> changed.
> target = ab.Stocks( Name() );           //      select a single 'Stock'
> object from
> the 'Stocks' collection
> target.isDirty = True;
> 
> SetCustomBacktestProc( "" );            //      empty argument means use
> current AFL
> formula
> 
> if ( Status( "action" ) == actionPortfolio ) {
>     bo = GetBacktesterObject();
>     bo.PreProcess();
>     dt = DateTime();
> 
> //  fh = fopen("output.csv", "w"); uncomment these if you want to
save it to
> a csv file as well //  fputs("Symbol,Date,Rank\n", fh);
> 
>         //      On every bar
>     for ( i = 0; i < BarCount; i++ )
>     {
>                 // For every signal ... (one for each stock in this
case,
> based on Buy = 1, above)
>         k = 1;
>         for ( sig = bo.GetFirstSignal( i ); sig; sig =
bo.GetNextSignal( i )
> )
>         {
> //         Line = sig.Symbol + "," + DateTimeToStr(dt[i]) + "," + k +
> "\n";
> //         fputs(Line, fh);
> 
>             target = ab.Stocks( sig.Symbol );           //      select a
> 'Stock'
> object from the 'Stocks' collection
> 
>             qt = target.Quotations( DateTimeToStr( dt[i] ) );      
    //
> select a 'Quotation' object from the 'Quotations' collection
> 
>                         // The index (k) into the sorted 'Signal'
collection
> is the ordinal ranking.
>             if ( qt )
>             {
>                 if ( run == 1 ){                                // 
    ROC
> case
>                     qt.OpenInt = k;
>                                                 NoteSet(       
sig.Symbol,
> sig.Symbol + " - OI displays: " + "ROC
> ranking\n" + Announcement ) ;
>                                                 NoteSet(       
sig.Symbol,
> NoteGet(sig.Symbol) + "\n" +
>  
> "Highest ROC(14) is lowest number.\n"           );
>                                         }
>                 else if ( run == 2 ){                           // 
    RSI
> case
>                     // qt.OpenInt += k;                 //      why?
> 
>                                                 qt.OpenInt = k;
> 
>                                                 NoteSet( sig.Symbol,
> sig.Symbol + " - OI displays: " + "RSI ranking\n" + Announcement ) ;
>                                                 NoteSet(       
sig.Symbol,
> NoteGet(sig.Symbol) + "\n" +
>  
> "Highest RSI(14) is lowest number.\n"           );
>                                         }
>                 else{
>                     qt.OpenInt += k;                    //     
other cases
> (why?)
>                                         }      
>             }
> 
>             // target.isDirty = True;           //      not necessary
>             k++;
>         }
>     }
> 
>     bo.PostProcess();
> 
> //  if(fh)fclose(fh);
> 
> }       //      end of:         if ( Status( "action" ) ==
actionPortfolio )
> 
> 
> //      Try this at the end, to make OI for the currently displayed
symbol
> update.
> //      Not a fix.
> // target = ab.Stocks( Name() );                //      select a single
> 'Stock' object
> from the 'Stocks' collection
> // target.isDirty = True;
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> ------------------------------------
> 
> Please note that this group is for discussion between users only.
> 
> To get 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
>



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

Please note that this group is for discussion between users only.

To get 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/