Current location  Thread information  
OmniTrader 2017 Upgrade Forums
ATM A look inside the ATM ranking function 
Last Activity 2/13/2020 2:13 AM 0 replies, 258 viewings 


Printer friendly version 
^ Top  
SJ Member Posts: 30 Joined: 9/28/2012 Location: Olathe, KS User Profile  Popping the lid off the ATM/ATS composite ranking black box. (it’s not as dark as you think) While investigating an apparent problem with OT 2019, I uncovered the exact implementation of how multiple rankers are applied and, in fact, you can review the ranking formula if you wish. In the ATM Master Class, it was explained that ranker values are multiplied by their default weights, or if using optimization, their OptVal weights. When using multiple rankers, it is important to normalize the values to allow more of an applestoapples comparison. We do this by checking the Scale Indicator Values checkbox. It was said that this looked at the max and min value of the ranking formula over the backtest and used it to scale the value for any bar between 0 and 100. Let’s look at a real example. Just playing with the concept, I added 3 Rankers: Profit Zone, RSI and Vty Price Ratio. The first and last were in descending order, RSI in ascending order. All have equal weights. You can look at the ranking function formula by going to the VBA\ITS\(method name)\Ranks\ directory. The SubRanker files contain each of the long or short ranking formulas. Here is Profit Zone which returns the # of ATRs distance between the close and recent HHV. #Float Return (HHV(10)  C) / ATR(10) The Ranker files contain the composite formula. Here is the long formula. #Float #Param "RSIstd2_Weight", 100 #Param "VTY_PRICE_Weight", 100 #Param "ProfitZone_Weight", 100 Return RSIstd2_Weight*(1((RSIstd(2))0.00101934)/(1000.00101934))*0.3333333 +VTY_PRICE_Weight*(((VTY_PRICE(10,5))0.002019478)/(0.10295710.002019478))*0.3333333 +ProfitZone_Weight*((((HHV(10)  C) / ATR(10))0)/(9.9846360))*0.3333333 You can see that it is adding the three criteria together, each with a weighting factor of 0.333. Each factor is calculating the value at the current bar and normalizing it against the highest and lowest values found to give a value between 0 and 1. And that value is multiplied by the parameter assigned weights. I asked Jeff Drake for some clarification on how this worked. My question was “Are the min and max values based on signal bars or on every bar?” I gave the scenario of using RSI(3) as a ranker. In an RTM strategy, assume that RSI(3) is a signal generation criteria, values <= 10. If max and min were based on every bar, then max will be something near 100 and min will be something near 0. But if the assessment of max and min are based on signal days, then values are pinned to between 10 and something near zero. He responded that he checked with the programmer and it does use the max and min found across all bars in the evaluation period. So what is the implication of this? We know all of our signals will fall between 10 and zero, so if this was normalized as rank descending, every signal will normalize to approximately range (valuemin)/(maxmin) or (100)/(1000) = 0.1 to (00)/(1000) = 0. The same ranking calculated for ascending will result in the following: 1[(valuemin)/(maxmin)] or 1[(00)/(1000)] = 1 to 1[(100)/(1000)] = 0.9 Both give a 0.1 range and this works great if this ranker is used alone, but even if normalized in this manner, the ascending version contributes much more weight to a multiranked formula. Let's look at an example: In addition to RSI(3) we have another ranker that normalizes to between 1 and 0. We won’t make any suppositions about what values this ranker may assume on any given signal bar. Both rankers are initially given equal weight (100) as we hypothesize an outcome. At an analysis point, the mystery ranker has a value of 50 and the RSI ranker is also in the middle of its range for any given signal bar, a value of 5. If we combine the two, we get two decidedly different results if the RSI is sorted descending vs ascending: Formula: Ranker 1 normalized value * weight * 0.5 + RSI normalized value * weight * 0.5 = total Descending: (0.5 * 100 *0.5) + (0.05 * 100 * 0.5) = 27.5 Ascending: (0.5 * 100 * 0.5) + (0.95 * 100 * 0.5) = 72.5 The goal was for these to total 50 (a 50% contribution of each). The rankers have the exact same values, but sort direction has significantly changed the effective weights. Simply changing the weights, either manually or via optimization does not always fix this problem. In the descending equation, it looks like we could bump up the weight of RSI by a factor of 10 and now RSI is contributing equally with our other ranker. For descending, we now get: Descending min : (0.5 * 100 *0.5) + (0 * 1000 * 0.5) = 25 Descending mid: (0.5* 100 *0.5) + (0.05 * 1000 * 0.5) = 50 Descending max: (0.5 * 100 *0.5) + (.1 * 1000 * 0.5) = 75 But in the ascending equation, there is no RSI weight multiplier that will scale 10090 to a 1000 equivalent. If you start with the midpoint value of 95 and scale that to 50, you need a weight multiplier of 52.6 and you quickly see that: Ascending min : (0.5 * 100 *0.5) + (0.9 * 52.6 * 0.5) = 46.7 Ascending mid: (0.5 * 100 *0.5) + (0.95 * 52.6 * 0.5) = 50 Ascending max: (0.5 * 100 *0.5) + (1.0 * 52.6 * 0.5) = 51.3 The variability of RSI as a contributor is greatly diminished even though the midpoint values are now equivalent. The only way to fix this is to write the ranking formula so that it is constrained between the true max and min values for each valid signal bar. For our RSI example, we know the limit explicitly (10) as it is part of our system or filter criteria in the strategy itself. We might write a custom OL RSI indicator that contains logic “If RSI(x) value > 10 then RSI(x) = 10”. Easier Oscript formula: if(RSI(x) > 10, 10, RSI(x)) I tried the Oscript formula using a 2period standard (not the Nirvana version) RSI and it seems to work. The max value is 10 and the min value is 0.5. I can’t explain why just using my RSIstd(2) formula gave a min value of 0.001 and this formula discovered a minimum of 0.5. If anyone can find a flaw in the logic or try it against the OL version, let me know. I’m going to give it a rest for the moment. Here you can see part of formula in action: Return RSIstd2_Weight*(1((if(RSIstd(2) > 10, 10, RSIstd(2)))0.5211627)/(100.5211627)) These issues need to be considered when mixing in oversold and overbought indicators where all of the action of interest lies in a tight range at one extreme or the other. For other indicators, the range relationship may be much less obvious. For another popular ranker, VTY_PRICE, it seems intuitively more likely that signals occur over a broader range of its values. But to what extent? That is your assignment. Steve J [Edited by SJ on 3/6/2019 11:08 AM] Attached file : Ranker_Files.png (18KB  244 downloads) Attached file : Ranking_Settings.png (14KB  239 downloads) 


Legend  Action  Notification  
Administrator
Forum Moderator 
Registered User
Unregistered User 
EMail this thread to a friend 
Toggle email notification 