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