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

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



PureBytes Links

Trading Reference Links

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@xxx> 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

<*> 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/
__._,_.___

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




Your email settings: Individual Email|Traditional
Change settings via the Web (Yahoo! ID required)
Change settings via email: Switch delivery to Daily Digest | Switch to Fully Featured
Visit Your Group | Yahoo! Groups Terms of Use | Unsubscribe

__,_._,___