Hello everyone,
I need to use the average true range of the last ninety days for around 150 stocks in my algorithm. I'm doing it this way at the moment:
'in Initialize:'
self.equity_symbols = [
"AAPL", "FB", "TSLA", "AMD", "AMZN", "BABA", "BAC", "BYND", "MSFT", "NFLX", "MU", "NVDA", "SNAP", "GE", "DIS", "T", "BA", "ROKU", "UBER", "NIO",
"CRM", "INTC", "X", "TWTR", "QCOM", "CSCO", "JPM", "CZR", "WDC", "JD", "GOOGL", "TEVA", "F", "WMT", "PCG", "C", "SQ", "FCX", "ADBE", "LYFT", "CGC",
"ORCL", "OXY", "V", "PFE", "QSR", "S", "VZ", "LULU", "AVGO", "BMY", "MPC", "BB", "WFC", "CVS", "IQ", "BX", "BIDU", "GOLD", "KO", "SBUX", "ABBV", "ACB",
"PYPL", "CNC", "TWLO", "CRON", "FDX", "UNH", "NKE", "CMG", "MRK", "TLRY", "HAL", "GM", "HD", "GS", "SHOP", "GOOG", "CHK", "XOM", "MA", "AAL", "CAT",
"PBR", "RIG", "ZM", "CLF", "M", "WYNN", "JNJ", "KR", "IBM", "DISH", "MO", "TGT", "DELL", "DBX", "COST", "CMCSA", "KHC", "PG", "BHC", "EA", "OSTK",
"SLB", "TRP", "JCI", "LVS", "AMAT", "MCD", "CVX", "CELG", "TTD", "AGN", "QD", "DOCU", "CLDR", "BCE", "LEN", "EBAY", "GME", "APC", "DAL", "XLNX",
"AMGN", "AMRN", "NEM", "ATVI", "WBA", "OKTA", "KMI", "CTL", "SFIX", "LNG", "BP", "MDR", "GILD", "STZ", "UPS", "AXP", "GRUB", "BNS",
"HOME", "PWR", "NOK", "UNP", "ACN", "APA", "DHI"
]
self.high = dict()
self.low = dict()
self.atr = dict()
history = self.History(self.equity_symbols, 90, Resolution.Daily)
history = history.sort_values(by=["symbol", "high"], ascending=[1,0])
for ticker in self.equity_symbols:
self.high[ticker] = history.loc[ticker]["high"][0]
history = history.sort_values(by=["symbol", "low"], ascending=[1,1])
for ticker in self.equity_symbols:
self.low[ticker] = history.loc[ticker]["low"][0]
self.atr[self.Symbol(ticker)] = self.high[ticker] - self.low[ticker]
This is working fine in backtesting but in live trading the server can't handle it and I get the "Algorithm took longer than 10 minutes on a single time loop" error. I think it might be more efficient to use an indicator even if I only need the values once and not being updated. How to do this?
Best regards,
Christian
Apollos Hill
I can't understand why you have all the extra sorting. Arey you trying to seperate out the top 3 highest ATr and the lowest 3 ATR values?
for ticker in self.equity_symbols: self.low[ticker] = history.loc[ticker]["low"][0] self.atr[self.Symbol(ticker)] = self.high[ticker] - self.low[ticker]
This is a for loop where you are setting 2 new variables for every ticker. You have over a dozen tickers. That is a large computation load. Look at my attached algorithm. i copied QC's Momentum forex algorithm and changed it into a ATR based algo that picks the top 3 and lowest 3. (disclaimer: its not profitable and not sure the trading works out right but the code should be solid enough to give you an idea) maybe that will help you .
i see you also set the history variable like 3 times before your for loop. that is a serious overload.
Christian Lauer
Hello Apollos,
thank you very much for your answer! Let me try to explain myself. To calculate the average true range of ninety days, I needed the highest and the lowest value for each stock over that period. I had to do all of this sorting to get those out of the history data frame. So first I sorted by stock and by high in order to have each stock's high at the first position in the data frame and to be able to acces it by history.loc[ticker]["high"][0]. Without sorting this wouldn't be possible as I got 90 values per stock for each daily high and history.loc[ticker]["high"][0] wouldn't access the right one. For the lows I had to do the same thing.
I know that this is a lot of computing and that this is the reason for the algorithm to crash.
I chose this approach though as I didn't manage to do it the right way using an indicator. I guess in your example I woudn't get the correct values either as by
self.data[symbol] = self.MOM(symbol, period, Resolution.Hour)
would give you the average of the ATR (MOM in this case, I suppose you forgot to change that) calculated for each hour over the defined period separately instead of once for the entire period.
Best regards,
Christian
Daniel Chen
Hi Christian,
Thank you for hard work! We recommend you use ATR indicator provided by QC, since it is less time-consuming and more convenient to implement. There are basically two steps to do: 1. use AddEquity() to add the equity data; 2. Use self.ATR() indicator to calculate the ATR values for your symbols. Here is the backtest I made, you can see the ATR values of each stock from the Log, please check.
Besides, QC also provides many other indicators for users (e.g NormalizedAverageTrueRange and TrueRange that are both relative to ATR), so we recommend you first consider using indicators provided by our platform, which is more efficient in most cases. For more information, please visit here. Thank you for your support to QuantConnect!
Christian Lauer
Hello Daniel,
thank you for your answer. I see now that I used the wrong term for my question. What I need, is the true range, not the average true range. I need the whole price range from those past ninety days. For example, if I run the algorithm in July and a stock had a high of 200 dollars in June and a low of 150 in May, I need 50 as an output. But with your code, I'd get 5 for example because that's the average daily range. So how to use the true range indicator to achieve what I need?
Best regards,
Christian
Daniel Chen
Hi Christian,
Thank you for your follow-up question. This can be easily done by replacing the ATR indicator to the TR (TrueRange) one which is also provided by QC. I've modified the example and attach my backtest here. Now I am glad to say that True Ranges of your list of stocks are offered to you!
Besides, there are more than 100 technical indicators in QC. If you need another indicator in the future, please search in the reference table on this page, the indicator you need is already provided by QC. Thank you again, and we hope you enjoy using QC!
Christian Lauer
Hello Daniel,
thank you for your answer. Unfortunately, this is still not what I need. I know that these indicators are offered by QC but my problem is that I don't know how to modify them to achieve what I have in mind. By Resolution.Daily the TR is calculated per day and not by ninety days. The warm-up period doesn't change that. As I tried to explain above, I should get values of 50 or more for certain stocks for those ninety days. In your example AAPL is only at around five. I think I'd need something like a custom resolution here but I don't know how that is done correctly.
Best regards,
Christian
Daniel Chen
Hi Christian,
I am really sorry that I misunderstand your meanings. For each stock, the True Value for the previous 90 days = Max(Highs of Previous 90 days) - Min(Lows of Previous 90 days). Therefore, we can use self.History() to get the historical Highs and Lows, and hence get the TR for each stock using the formula above.
Please see the following backtest for details. Particularly, I log the TR of AAPL for validation. As you can see, the Daily TRs are over 50, which indicates a reasonable result for this method.
Thank you for the follow-up and your patience!
Christian Lauer
Hello Daniel,
thank you very much. This is exactly what I needed. My own approach doesn't seem too bad but .max() and .min() is more efficient of course than my sorting.
Best regards,
Christian
Christian Lauer
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!