from AlgorithmImports import *
from collections import deque
class RushStrategy(QCAlgorithm):
def Initialize(self):
# Backtest period
self.SetStartDate(2022, 1, 1)
self.SetEndDate(2023, 12, 1)
# Starting cash
self.SetCash(1000)
# Simulate a backtest with a margin account at Binance, so fees ... are include
self.SetBrokerageModel(BrokerageName.Binance, AccountType.Margin) #Simulate the broker component of trading
self.symbol = self.AddCrypto("BTCUSDT", Resolution.Daily).Symbol #BTCUSDT symbol for daily resolution
# ADX in Quantconnect include the +DI and -DI, that can be retrived
self.adx = self.ADX(self.symbol, 14)
self.diplus = self.adx.PositiveDirectionalIndex
self.diminus = self.adx.NegativeDirectionalIndex
#increase the indicators' number of stored value
self.adx.Window.Size = 7
self.diplus.Window.Size = 7
self.diminus.Window.Size = 7
# Keltner Channels
self.kc = self.KCH(self.symbol, 20, 2, MovingAverageType.Simple)
# Retreive bands from KC.
self.upperband = self.kc.UpperBand
self.lowerband = self.kc.LowerBand
# Compute again the Keltner Channels but this time with 2.5 stdev
self.kcUP = self.KCH(self.symbol, 20, 2.5, MovingAverageType.Simple)
# create a void SMA
self.volume_sma = SimpleMovingAverage('Volume SMA', 10)
# fill the SMA with volume for inputs
# Register the indicator for automatic update
self.RegisterIndicator(self.symbol, self.volume_sma, Resolution.Daily, Field.Volume)
self.SetWarmUp(30)
self.PlotIndicator("Volume SMA", self.volume_sma)
self.PlotIndicator("adx", self.adx)
# compute the fast ADX based on an 7 period average
# with DI+ and DI- computed on 14 periods
self.fast_adx = FastADX('Fast ADX', 7)
self.RegisterIndicator(self.symbol, self.fast_adx, Resolution.Daily)
self.PlotIndicator('Fast ADX', self.fast_adx)
def OnData(self, data):
# Check if data for "Crypto" is available
if not data.Bars.ContainsKey(self.symbol):
return
# Don't run if the indicators aren't ready
if self.IsWarmingUp: return
class FastADX(PythonIndicator):
def __init__(self, name, period):
super().__init__()
self.Name = name
self.Value = None
self.Time = datetime.now()
self.current = IndicatorDataPoint()
self.adxf = AverageDirectionalIndex(period)
# double queue
self.queue = deque(maxlen=period)
def Update(self, input):
self.adxf.Update(input)
if self.adxf.IsReady:
diplusf = self.adxf.PositiveDirectionalIndex.Current.Value
diminusf = self.adxf.NegativeDirectionalIndex.Current.Value
# compute DX
DX = (100 * abs((diplusf) - (diminusf))) / ((diplusf) + (diminusf))
# Store the last 7 value of DX in an array (add new to the left, get rid old value to the right)
self.queue.appendleft(DX)
# count number of value in the array
count = len(self.queue)
if count == self.queue.maxlen:
# compute the 7 period ADX base on the values include in the array
self.Value = np.sum(self.queue) / count
self.current = IndicatorDataPoint(input.EndTime, self.Value)
return self.current
I'm trying to build a fast adx that is an average of 7 DX periods, but the +DI and -DI are computed on a 14 basis period.
(I know I could aslo build a fast adx by taking self.ADX(self.symbol, 7) = fast adx, and doing an IndicatorExtension that compute the SMA of this adx, to obtain the slow adx. But i don't want this and i also want to learn how to create a custom indicator on the basis of another indicator as well)
Thank you :)))
Trader Benedict
I've been trying to build this for 72 hours, and i decided it is time to seek helpÂ
Mia Alissi
Your code for creating a custom indicator based on another indicator seems correct. You've created a
FastADX
class that inherits fromPythonIndicator
, and within itsUpdate
method, you're updating theAverageDirectionalIndex
and calculating theDX
value. You're then storing theseDX
values in a deque with a maximum length equal to the period you want to average over. Once the deque is full, you're calculating the average of theseDX
values to get yourFastADX
value.However, it's important to note that the
AverageDirectionalIndex
(ADX) in QuantConnect includes the Positive Directional Index (+DI) and Negative Directional Index (-DI), which are calculated over a specified period. In your case, you're initializingAverageDirectionalIndex
with a period of 14, so the +DI and -DI values will be calculated over 14 periods. If you want to calculate them over a different period, you would need to adjust the period when initializingAverageDirectionalIndex
.Also, remember to call the
IsReady
property of your custom indicator in your algorithm to ensure it's ready before using its value.Here are the relevant extracts that might help:
TradeBar
object, which might be useful if you need to update your custom indicator with specific data.FastADX
indicator.Remember, creating custom indicators can be complex, and it's important to thoroughly test your indicator to ensure it's calculating the values you expect.
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.
Trader Benedict
This AI is not helping and don't understand the problem, anyone Human available for help ?Â
Mia Alissi
I'm sorry to hear that you're having trouble. If you need further assistance, you can escalate your support ticket to a human on the Support Team. To do this, after submitting your ticket, click "No, I'd like a human response" when prompted by Mia, the AI assistant. You can also reach out to the QuantConnect team via email at support@quantconnect.com or through the community forum or Discord for additional help.
For more information, please refer to the QuantConnect Support Documentation.
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.
Trader Benedict
Mia Alissi
Your code for creating a custom indicator
Volatility_ADX
that calculates the difference between a 7-period and 14-period ADX seems correct. You're correctly initializing theAverageDirectionalIndex
with a period of 14, and in theUpdate
method, you're updating theAverageDirectionalIndex
and calculating theDX
value. You're then storing theseDX
values in two deques with maximum lengths equal to the fast and slow periods you want to average over. Once both deques are full, you're calculating the averages of theseDX
values to get your fast and slow ADX values, and then calculating the difference between these to get yourVolatility_ADX
value.However, there are a few things to note:
You're registering your custom indicator for automatic updates with
self.RegisterIndicator(self.symbol, self.custom)
. This means that theUpdate
method of your custom indicator will be called automatically whenever new data for your symbol is available. If you want to manually update your custom indicator instead, you can comment out this line and uncomment the code in theOnData
method that manually updates the custom indicator.You're setting a warm-up period with
self.SetWarmUp(50)
. This means that your algorithm will not start trading until 50 days of data have been processed. This is to ensure that your indicators are ready before you start trading. However, since your slow ADX is calculated over a period of 14 days, you might want to consider reducing your warm-up period to 14 days.You're plotting your custom indicator with
self.PlotIndicator('ADX: Fast - Slow', self.custom)
. This will plot the value of your custom indicator on a chart in your backtest results. This can be useful for visualizing the behavior of your custom indicator over time.Here is the relevant extract that might help:
Update
method, which is what you've done in yourVolatility_ADX
class.Remember, creating custom indicators can be complex, and it's important to thoroughly test your indicator to ensure it's calculating the values you expect.
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.
Trader Benedict
After spending many hours working on this problem, I've finally found a solution. The code I'm sharing is the very first template designed to calculate a custom indicator using a pre-existing indicator as a base.
I hope sharing this will save someone else the six full days of hard work and effort I put into solving it myself :))
Â
Trader Benedict
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!