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: [email protected] [mailto:[EMAIL PROTECTED] On Behalf
Of progster01
Sent: Wednesday, July 09, 2008 10:28 AM
To: [email protected]
Subject: [amibroker] Re: More on Database Structure and Local Storage
--- In [email protected], "Paul Ho" <[EMAIL PROTECTED]> 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