Ranking trade candidates
Author: maninjapan
Creation Date: 8/20/2013 10:38 AM
profile picture

maninjapan

#1
I am have a strategy to trade stocks which often produces more signals than my max no. of positions allow for. In this case I want to rank the stocks by a particular indicator value to select the stocks to trade.
I am aware of the PosSizer function and have had a brief look at them, I see I can manage max number of positions and position size here, but would I also manage the stock selection here? Or does this need to be done in the strategy itself? Its the first time I have attempted to do anything like this and have no idea where to begin here so any pointers or other threads looking to do something similar would be much appreciated.

Thank you
profile picture

Cone

#2
See Priority under the Position object in the QuickRef (F11). If you have any questions about it, just ask!
profile picture

maninjapan

#3
Thanks for the quick reply Cone, very much appreciated. Will take a look and see how I go!!
profile picture

maninjapan

#4
Cone, I was able to get the Priority function working as it is explained. However I have realized that this probably isn't what I am looking to do.
I am using limit orders and want to limit the number of orders to place each day. Not the number of executions after placing multiple orders.
I only want to submit a maximum of 10 orders a day. In the event more than 10 stocks produce signals I only want to place limit orders for the top 10 stocks (ranked per my selected indicator). From these stocks some or all may not be executed during the day.

Is there a way to do this?
profile picture

Eugene

#5
PosSizer: "Max Entries Per Day"
profile picture

maninjapan

#6
I may have misunderstood how that PosSizer works, I Does max entries refer to the number of orders placed, or the number of positions taken?
I am looking to limit the number of limit orders placed for the day. In real time I would scan for candidates after the close/before the open, and in the event there are more than my maximimum of 10, I take the top ten ranked by my indicator. I then only place limit orders for these 10. During the session anywhere between none or all may be filled.

Thanks again


profile picture

Eugene

#7
See if this is what you're after:

Position Options > "Reject on Alerts >: 10"

<<Reject a Position when candidate trade count (number of Alerts) is above or below some Alert cutoff threshold>>
profile picture

Cone

#8
I never noticed the Reject on Alerts option before, but I don't think it's what he's looking for. It appears to me that the option works like this:

All Alerts
Nothing is rejected on the basis of trade candidates (Alerts) on a particular bar (Date).

Reject on Alerts < n
All trade candidates are rejected if at least n Alerts did not occur.

Reject on Alerts > n
All trade candidates are rejected if more than n Alerts were present

Maninjapan is looking for a way to use a maximum of n (10) limit orders per day based on some priority. Setting Position.Priority (as I suggested) won't work because limit orders are not guaranteed to create positions.

The only way I can think to solve it is to use a DataSetSymbols loop-type simulation (you click on one symbol only). You would add your candidate orders to a list, rank it, and place the top n (10) orders much in the same way the Symbol Rotation script works.
profile picture

maninjapan

#9
Appreciate the assistance on this. Cone is correct. I need to prioritize the limit orders are placed at the beginning of the day. I am basically creating a new portfolio of stocks each day based on a ranking of my indicator, then running m strategy against that. With Cone's solution would I be able to run backtests easily enough?

Thanks
profile picture

maninjapan

#10
I had a look around and found a stock rotation script and have made some modifications. I have just attempted to run it on a dataset, but receiving an error. "Runtime Error: NullReferenceException"

To start testing I have tried to keep it simple and attempting to rank by lowest close, enter at market for symbols on the list and exiting at N number of days after entry.

Is there anything I need to be aware of when running this kind of script as opposed to a regular single symbol script? Am I doing anything majorly wrong with this code? (My programming skills consist of copy and paste so this wouldnt suprise me at all...)

Once again, appreciate the assistance

CODE:
Please log in to see this code.

profile picture

Eugene

#11
A lot of experience comes from reading those many dozens of discussions on symbol rotation strategies easily found on the forum, but this FAQ answers some essential questions and therefore is a must read:

FAQ | Strategies and WealthScript > Rotation strategies
profile picture

maninjapan

#12
Thanks for the tips Eugene, I have a basic rotation strategy working now. Currently I can rank them using the required indicator but what I need to do though is screen the data set first for a condition, rank them and then take the top 10 stocks of that list. For example, screen for stocks that are above their 50 moving average, then rank only the stocks that are above the 50 ma by indicator value. Are there any examples of how this would work?


Here is the section of code that I am using for the Ranking.

CODE:
Please log in to see this code.


profile picture

Eugene

#13
This question got also raised before on the forums. Follow my first reply (1/11/2013 3:37 AM) to OP in this thread:

Tactical Asset Allocation

This is exactly what you're looking for. If something is still not clear, it's explained in my post #28 in this thread: ROC Symbol Rotation - Modification of the Strategy
profile picture

maninjapan

#14
Eugene, I have been able to take your example and apply all my rules however I just realized it may be working in a different order to what I need If I understand it correctly then this won't be my solution...
1. It ranks the list based on indicator value
2. It creates a list of the top N symbols
3. These symbols are then checked for the extra conditions
4. Trades are then executed for symbols that are on the list and meet the extra conditions.


I am looking to first check for symbols that meet the conditions THEN rank them and put in limit orders for those products. I need to follow:
1. Filter Stocks based on condition (ie Close > Moving Average and Average Volume > Min_Volume).
2. Rank the filtered list by indicator value
3. Create list of top N symbols
4. Place limit orders for N Symbols

Perhaps I need to create a list of a list or something along those lines? First filter the data set based on a boolean then rank the remaining symbols by indicator value, finally keeping a list a of the top N symbols....


profile picture

Eugene

#15
If a stock does not qualify your "Above MA" criterion, then simply do not add that stock to the Top-N list. Voila.
profile picture

maninjapan

#16
Sorry Eugene, I'm sure it is quite easy, but I'm not sure I follow.... Below is the section of code that creates the list, correct? How do I 'not add a stock to the list?

CODE:
Please log in to see this code.



Is it just a case of adding the condition directly here?

CODE:
Please log in to see this code.
profile picture

Eugene

#17
I think so.
profile picture

maninjapan

#18
Ive been doing some testing with this, using Eugene's suggestion, however I still seem to be experiencing problems with this. I have created a small group of stocks to test this ( GOOG, AAPL, DIS, MCD, MSFT), using data from yahoo. however I am getting wildly different results depending on the stock I run it on ( i am running it on individiual stocks, not the group). I have read the link that was posted earlier regarding rotation strategies, and understand that results may vary, however depending on the stock the results, however the results are just way too different to be explained away by some differences in data ( in some cases only a single stocks trades are included in the trade list).
for testing purposes I have also set the cutoff number of stocks to a larger number of stocks than what is in the group so there shouldnt be any trades cut out due to this parameter.
Just to confirm I havent misunderstood this, the following code should run as follows
- loop through each stock in the list and check if it meets the criteria
- if the stock meets the criteria, it is added to the list
- once the script runs through all the stocks in the group, it then ranks the list by indictor
- the top number of stocks are kept and orders placed for these stocks

Thank you again for assistance with this!

CODE:
Please log in to see this code.
profile picture

Eugene

#19
I think you need to run it on the symbol with the longest data available.
profile picture

maninjapan

#20
I've checked all the data, I have years of data downloaded for all of them and only running on the last 15 months, so that shouldn't be an issue here.
profile picture

maninjapan

#21
Hi guys, I'm still not getting anyway, and I can't figure out what is causing the difference in results here. I have checked the data manually and it all matches up....
profile picture

Eugene

#22
As expected, I get absolutely no differences when running your code from post #10 on 15 months of Yahoo! Daily data of GOOG, AAPL, DIS, MCD, MSFT, using Percent Equity sizing (10-33%) and margin from 1.0 to 2.0. The results are consistent.

Using the Data Tool extension, try reloading the data by using the Data Tool's "Remove all data" feature and then updating the DataSet as usual.
profile picture

maninjapan

#23
Eugene, appreciate the assistance in trying to solve this, I too was able to get that version working correctly, however if you come a bit further further down the thread (posts #14 - #17) you can see that that what I am trying to achieve is slightly different. I was in the process of simplifying my strategy to provide a full version of the code posted in post #18, when I came across what seems to be the cause. I was using a DataSeries as my limit entry price, however after replacing the DataSeries directly with the formula, all the trades now match up. I'm assuming the location of this DataSeries in the code means it uses the prices from the selected stock, not each stock as it runs through. I don't know if this will help anyone going forward but here is a simplified version of the strategy showing the DataSeries as I was using it resulting in the incorrect results.
Replacing the DataSeries in the Limit order with the actual formula seems to have fixed it

So it wasn't related to the data at all.... Regardless, I wouldn't have figured it out without yours (and Cones) assistance on the thread. Thank you very much for your time.

CODE:
Please log in to see this code.
profile picture

Eugene

#24
This code will produce incorrect results:

CODE:
Please log in to see this code.


The placement of this DataSeries makes the value to be fixed depending on the clicked symbol e.g. AAPL. And then the script is referring to precisely same value on every other symbol in the DataSet (GOOG, DIS, MCD, MSFT). It should be moved on top of BuyAtLimit after SetContext.
profile picture

maninjapan

#25
Thank you for confirming that Eugene. One other thing I would like to confirm. I currently only have a time stop, however if I want to add profits and stop losses for each positions would the conditions of the exits check each open position with the code below? Or does the code need to be modified to correctly close each position individually. As you can see, time stop is using ActivePositions, while the other exit is using LastActivePosition. (I don't know the correct way to set this up, I am just taking a guess with what I have here).
I am trying to work through this with the same test group of stocks and comparing trade lists manually but I am finding some discrepencies. I just want to figure out if I am on the right track with these exits.

Thanks

CODE:
Please log in to see this code.
profile picture

Eugene

#26
Will you agree with me that exiting one position (i.e. LastActivePosition) because of another (i.e. ActivePositions[pos] was held less than N days) doesn't seem very sound because they can and usually will be different positions (as the system can hold up to 10). This is what your code is doing, and certainly it might cause discrepancies:

CODE:
Please log in to see this code.
profile picture

maninjapan

#27
Thanks Eugene, that makes sense. I guess my next question is, is there an easy way to rectify this? I'm trying a few different things here, I am yet to confirm what affect this has on my trades, but is it as simple as changing to the following?

CODE:
Please log in to see this code.



actually, update that to.... I've checked trades and the above code is still showing the same discrepancies in results. I tried changing every instance of Activepositions to LastActivePosition, but changing the following section returned an error so I left it as is. I'm sure I need this line for the timed exit though....
profile picture

Eugene

#28
From a logical standpoint, you'd want to do the opposite: when looping by ActivePositions and having already defined "p" as the current active Position, access that Position's properties as opposed to LastActivePosition.
profile picture

maninjapan

#29
Thank you again. All exits based on the above are matching across all symbols now. I still have one more entry that is causing me headaches though. from what I know now, it is basing its signal on the active chart, not that of the actual symbol with the position, but I am not sure what to do with this one. I want it to close the position if the symbol with the position closes up for the day.
I'm guessing I have to keep track of this for open positions and have tried adding a new holder.upday , but not been able to successfully reference this in the exit. Am I at least on the right track with this?
I can see from existing rotation strategies use something similar to exit if it is not in the list, however I don't think that exact format works here, as these positions are not necessarily in the list after entry. I haven't been able to find any other examples that cover this either. Still looking though....



CODE:
Please log in to see this code.


profile picture

Eugene

#30
QUOTE:
I'm guessing I have to keep track of this for open positions and have tried adding a new holder.upday , but not been able to successfully reference this in the exit.

Look at how the entry block operates to understand how accessing properties of the holder object is performed, then copy that. For example, after having defined the current active position while looping by ActivePositions, you create a new foreach loop by the List<iHolder> list, and then compare the current position's Bars property with each iHolder's Position object's property, and if they match, you finally query the new property you added to record Open/Close relationships.
profile picture

maninjapan

#31
Ok thanks Eugene, I will work on that. This is still all new to me and I probably don't completely understand this yet, or misunderstood your directions, but as the code currently stands it is creatin a list that only keeping the top ten symbols, and the symbol for an open position may be no longer on that list. Do I need to create a second list that keeps track of open positions?

Thanks
profile picture

Eugene

#32
You're making a good point Deane. Therefore my suggestion from reply #30 is most likely not going to work. But I think there's a super easy solution:

CODE:
Please log in to see this code.


This way you're querying the OHLC of the Bars object linked to the current Position "p", not the charted symbol. Hope this helps.
profile picture

maninjapan

#33
ah... Thanks Eugene!! I was thinking along these lines earlier but couldn't get the format correct. Just tested it and everything is now matching.

Thank you for helping get this completed!