Ken
!isNull just mean that the element in the array is not
NULL ( i means is not)
You may also want to consider a number of things for
your code
1. As it is. The best stock is has a ranking of 0. if
you want the best to rank 1, simply initialise rocrank to 1 instead of 0 before
the loop.
2. You may want the best stock to have the highest
score, in this case, turn ">" to "<" e.g rocScore = iif(nz(mRoc) <
mOwnRoc, rocScore + n, rocScore);
3. You may want to normal your score, then make rocrank
= rocrank/(roccount - 1) after the loop, that will give you a score
between 0 and 1, multiply it by 100 will give you the percentile score.
otherwise, roccount is not really necessary in the loop.
4. you have the option of making a composite indicator
comprising Roc and RSI together before you rank, or add their ranking/scores
together afterwards like you are doing
5. this codes gives you rank per day. you can use
timeframeset etc for weekly score.
6. I'm partial to red, not much of a cigar fan though.
but I'll take making a donation to your local charity as an
equivalent.
Paul.
Paul:
Man oh
man, you are THE MAN!!
How
cool is that!! What a gigantic time saver. I am blown
away!
It
works just like I want and need, and just like you say. (Had to initialize a
few variables inside the loop but no problemo.)
Shows
how experience will reveal more than one way to do
something.
In
trying to understand it line by line (still don't quite understand its
workings but that is why I can't think of these on my own), I come across one
symbol I can not find explained in Help.
What does the ! do in front of
IsNull? Taking it out obviously wipes out the
calculation. Is it another way of writing "not equal
to"?
Never
knew the operator += existed, but now see it and understand
it.
I have
to see if I can add many more indicators vs just ROC and hope that it will
still perform as brilliantly as this concept code.
Name
the cigar you like or the case of wine you drink.
Ken
Ranking all bars at one time is not possible with
your ranking code, but is possible with a different type of
algorithm
for example
mOwnRoc = Roc(C, 14);
mRoc = 0;
list = categorygetsymbol(categorywathlist,
0);
for(i = 0; (sym = strextract(list, i)) != "";
i++)
{
setforeign(sym);
mRoc = Roc(c,
14);
restorepricearrays();
n =
!isnull(mRoc);
roccount += n;
rocrank = iif(nz(mRoc) >
mOwnRoc, Rocrank + n; rocrank);
}
that would rank all bars with all symbol on list, now
if you only want to do it monthly, then do a timeframeset(inMonthly) to
reduce the no of bars and it will run faster.
Paul:
Thanks for the first suggestion (determine i and just
put it in the two commands instead of looping). Obvious once pointed
out.
Ranking my system for all bars at one time is
impossible because the ranking code uses a large number of StaticSetVar
commands looped through all the members of a Watchlist, then extracts the
variables before summing them. I have tried all sorts of experiments and
recodings and it only works on last bar (ranks are the same for all other
earlier bars in a run).
Thanks for the first idea, though.
Ken
Ken since you're only doing one bar per run.
wouldnt it be easier if you just find out what the value of i is
and
do
qt =
qts.Item(i);
qt.OpenInt = Ranking[i];
directly
because i = lastvalue(datenum ==
DateEnd);
A better still alternative would be to rank your system
for all bars and stores all values
once.
Hi
Paul:
My
next challenge with the COM code is to put a value into a
single OI field for a specific date or bar.
I
stuck your code snippit (see below) onto the end of a complex
code that FTonetti gave me the idea for which is to assign ordinal ranks
to indicators, a number of which are used to create a ranked and summed
ordinal value. Actually, not a bad ranking methodology depending on
your choice of indicators on which to do the ordinal
ranking.
Being ordinal numbers, the final sum for a symbol is the same
for all bars, so my concept is to try and run the code, then modify the
main FOR loop in your code snippit to stick the value of the Ranking
variable into one and only one position (one single Bar/Date), then cycle
through my main code again with a different enddate, then stick that
new Ranking value into another corresponding bar
position.
Almost laughable (my attempt--not the concept), given my sparse
experience with looping, COM objects, and the like, but I am struggling
along. I actually got a value stuck into a single OI position by setting
things manually, now I have to figure our how to manipulate the
RangeToDate command in the Analysis object so that the code can be cycled
by some grand encompassing loop.
I
just know experts like yourself could throw something together to meet
this objective in a few minutes, but it is (I guess) a great
learning opportunity for me.
Thanks for your responses and help.
Ken
PS--If you have a moment, glance at this code. The
commented out RangeFromDate and RangeToDate never worked, perhaps because
the DateStart and DateEnd were not formatted correctly, so I played
manually with the n value and actually put the "Tot_Rank" value where
I wanted it to go (obviously ranked end of month).
What is the trick to making the RangeFromDate command
work? Anyone can comment--I am looking for advice from anyone who is
willing to help me.
Previous code will calculate sum of ordinal ranks and into
Tot_Rank variable
DateStart
= ParamDate("DateStart","06/30/2008");
DateEnd
= ParamDate("DateEnd","06/30/2008");
Mnth
= Month();
Nmnth
= Mnth != Ref(Mnth,-1);
Nmnth1
= Ref(Nmnth,1);
MnthStart =
IIf(Nmnth,1,0);
MnthEnd
= IIf(Nmnth1,1,0);
Ranking
= IIf(Nmnth1,Tot_Rank,0);
ab
=
CreateObject("broker.Application");
target
=
ab.Stocks(Name());
qts
=
target.Quotations;
aa
= ab.analysis;
aa.applyto =
2;
//aa.RangeFromDate = DateStart;// -
defines "From" Date
//aa.RangeToDate
= DateEnd;//- defines "To"
Date
n
= LastValue(BarCount -
ValueWhen(Nmnth1,BarIndex(),1));//< < < Set manually for single pass,
should stick the Rank value
// into the OI field on the proper end of month bar
m
= n ;
//Ranking
= 0;
for(i =
BarCount -
n ; i < BarCount - n +
1;
i++)
{
qt = qts.Item(i);
qt.OpenInt = Ranking[i];
}
target.IsDirty
= True;
/// MUST
SET
Hello Ken
It seems that everything was sorted while I was
hibernating down the deep south.
The isDirty flag just tells AB to data has
changed so when the user press save, that area of the database is saved.
On another note, I finally found out why I was
getting COM error 18. It was because I checked the pad and align box, When
AB tries to assign a value to a bar that isnt there. it
complains.
While I'm on this topic, and if Tomasz is reading
it. - Is there a way to trap the COM error in afl?
Thanks Tomasz: critical piece of information.
I assume you wanted to warn people (to remind themselves) when they are
using a data series with a value in one of the fields that is not truly
representative of what the field is supposed to hold. One wonders
how the IsDirty flag shows up. Did you set it up to show a warning
if anyone uses the OI field in some other calculation or indicator? (I
have been listing it with AddColumn to no effect). Or was it just
to remind the person at the time it was set up that they had done
something outside the "normal" use of the field
contents?
Anyway, thanks for sharing that
information.
Ken
Hello,
Of course the field WILL contain any value you put
into it...
BUT your changes will NOT be saved until you set dirty
flag.
ab = createobject( "broker.Application"); target =
ab.Stocks(name()); qts = target.Quotations;
AA = AB.Analysis;
AA.ApplyTo = 2; for(i = 0; i <
Barcount; i++) { qt =
qts.Item(i);
qt.OpenInt = Ranking[i]; }
target.IsDirty = True; /// MUST SET buy = sell = 0;
Best regards, Tomasz Janeczko amibroker.com
----- Original Message -----
Sent: Friday, July 04, 2008 8:13
PM
Subject: RE: Ah Tomasz: RE:
[amibroker] Ping Paul Ho---Re: Import Data into OI field? Using a
Watchlist
Tomasz:
Figured out the (now) simple looking commands to use the
Watchlist.
Ranking = C; // replace this with something you want to
store ab = createobject("broker.Application"); target
= ab.Stocks(name()); qts = target.Quotations;
AA = AB.Analysis;
AA.ApplyTo = 2; for(i = 0; i <
Barcount; i++) { qt =
qts.Item(i); qt.OpenInt =
Ranking[i]; } buy =
sell = 0;
I would still be
interested to know what happens to Amibroker operation if the IsDirty
Flag is NOT set, if the OI field now contains a value put there by
this OLE code.
Secondly, I can
"clear" the value by changing the Ranking value to 0 in the first line
above. This inserts a zero. Does this mean the symbol is
still "Dirty"?
Ken
Ah, Tomasz:
Couldn't you have also tossed in the
few statements I need to make it work with a Watchlist. And where do
you put the target.IsDirty = True statement. And what do you do
when you remove the value from the OI field? And what happens if you
forgot (or never knew) to set the IsDirty Flag to True? What
happens to program operation when that symbol is used by some other
code?
Thanks for adding some more
information.
Ken
Ranking = C; // replace this with something you want to
store ab = createobject("broker.Application"); target
= ab.Stocks(name()); qts = target.Quotations; for(i = 0; i
< Barcount; i++) { qt =
qts.Item(i); qt.OpenInt =
Ranking[i]; } buy =
sell = 0;
Hello,
You need to know that AB caches data.
If you are writing directly to quote array thru OLE
you need to
set "IsDirty" flag, after you are done with writing
to given symbol.
target.IsDirty = True;
Best regards, Tomasz
Janeczko amibroker.com
----- Original Message -----
Sent: Friday, July 04, 2008
5:47 PM
Subject: [amibroker] Ping Paul
Ho---Re: Import Data into OI field? Using a Watchlist
Paul:
Sorry to bother you
again.
I have proven that your small COM
object code stuck at the end of a very complex AFL will successfully
stuff the one parameter I want to save into the OI field.
Yea!
But, is a scan supposed to work on
all symbols within a Watchlist? I tried to run the code (scan)
against a three symbol watchlist but it did not work (only updated
the current symbol).
I see there is an Analysis object
Analysis.ApplyTo and there is
something called a SCAN Method, but by trial and error, I can not
come up with a statement(s) that works.
Would you be so kind to show me the
statement(s) that need to be added so that I can run through the
symbols in a watchlist, and stick the "Ranking" variable into the OI
field of each one of them?
It would get me so very close to a
major milestone in my quest.
Thank you so
much.
Ken
Ken
I presume you are using the latest version
of AB.
I have just tried it myself and I have come
back with a COM object error
run it in previous version and is working
fine.
Can you try it on an old version of AB, if
you have the same result. It is time to call on Tomasz to fix
it.
Paul:
I tried the code you shared below to see if I
could stick the "Ranking=C" value into the OI filed of a single
symbol, and I got nothing. I ran Scan over a short date range,
clicked "Refresh All", and then looked in the Quote Editor for
the change, but none was there.
What needs to be done to
make this work? Can the COM OBJECT application be put onto the
end of an AFL file (which generates the Ranking value), and
still be expected to work?
Need help. Thanks for any
suggestions. Ken
--- In amibroker@xxxxxxxxxps.com,
"Paul Ho" <paultsho@xx.> wrote: > >
Bob > You can't do it in Amiquote or fget, but you can do it
with COM objects. > The following example gives you a
means > Ranking = C; // replace this with something you want
to store > ab =
createobject("broker.Application"); > target =
ab.Stocks(name()); > qts = target.Quotations; >
for(i = 0; i < Barcount; i++) > { > qt =
qts.Item(i); > qt.OpenInt = Ranking[i]; > } >
buy = sell = 0; > > Run scan over tickers that you
want. and Remember to refresh all to see the >
changes > It is very important to know that AB does not
detect the OI field for > changes, so if there is no other
changes in your database, pressing save > doesnt save your
changes in OI (at least that was the case in the past),
To > force save, choose save database as, or make some sure
there are some other > changes in your database and press
save. Otherwise, the OI fields would be > blank next time
you open it. > Good luck. > > > >
_____ > > From: amibroker@xxxxxxxxxps.com
[mailto:amibroker@xxxxxxxxxps.com] On
Behalf > Of bjagow@xxx > Sent: Friday, 21 March 2008
10:38 AM > To: amibroker@xxxxxxxxxps.com >
Subject: [amibroker] Import Data into OI field? > >
> > > > Although I understand that
additional AB data arrays [and means of > populating them]
are planned for the future, I'd like to store a weekly >
value into the OI field.of existing tickers. > > Any
way to do this with AmiQuote? > If not, how about with fget,
etc? > > TIA, > Bob >
__._,_.___
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
__,_._,___
|