Hi all,
I'm attempting to develop a risk management module that sets a static stop loss based on the ATR of the security at its purchase date. I've attempted to put it together something like this, but is currently returning errors:
class ATRRiskManagementModel(RiskManagementModel):
'''Provides an implementation of IRiskManagementModel that limits drawdown based upon 2 x 20 Day ATR'''
def __init__(self, atrPeriod = 20):
'''Initializes a new instance of the ATRRiskManagementModel class
Args:
ATRPeriod: 20'''
self.atrPeriod = atrPeriod
def ManageRisk(self, algorithm, targets):
'''Manages the algorithm's risk at each time step
Args:
algorithm: The algorithm instance
targets: The current portfolio targets to be assessed for risk'''
targets = []
# check if security is long/short
# get the value of the security
# subtract/add 2*ATR
# append targets/liquidate
# dont forget history request for the indicator
for kvp in algorithm.Securities:
self.symbolData[added.Symbol] = SymbolData(algorithm, kvp, self.atrPeriod)
if not security.Invested:
continue
if algorithm.Securities.IsLong:
lossLevel = security.Price - (2*self.atr.Current.Value)
if lossLevel == security.Price:
# liquidate
targets.append(PortfolioTarget(security.Symbol, 0))
if algorithm.Securities.IsShort:
lossLevel = security.Price + (2*self.atr.Current.Value)
if lossLevel == security.Price:
# liquidate
targets.append(PortfolioTarget(security.Symbol, 0))
return targets
class SymbolData:
def __init__(self, algorithm, security, atrPeriod):
self.Security = security
self.atr = AverageTrueRange(atrPeriod, MovingAverageType.Simple)
history = algorithm.History(security.Symbol, 20, Resolution.Daily)
for bar in history.itertuples():
tradeBar = TradeBar(bar.Index[1], bar.Index[0], bar.open, bar.high, bar.low, bar.close, bar.volume, timedelta(1))
self.momentum.Update(bar.Index[1], bar.close)
Is anyone familiar with setting stop losses according to indicator values? Some suggestions would be greatly appreciated.
Regards,
Nick
Varad Kabade
Hi Nicholas Fitzgerald,
Would you mind attaching a backtest highlighting the error? We recommend implementing the OnSecuritiesChanged event handler to initialize the SymbolData objects for securities in the universe and checking the risk conditions inside the ManageRisk method. Also, inside the SymbolData method, we are updating the momp variable, but we have not initialized the variable inside the __init__ method of SymbolData class.
Best,
Varad Kabade
Nicholas Fitzgerald
Hi Varad,
The current error I am experiencing is:
Runtime Error: NameError : name 'security' is not defined at OnSecuritiesChanged if not security.Invested: continue === at Python.Runtime.PyObject.Invoke(PyTuple args in RiskManagement.py: line 46
Attached is a backtest with the risk management model commented out in the main.py module so that I can upload the code for you.
Suggestions on how to implement this stop loss would be greatly appreciated.
Thanks,
Nick
Varad Kabade
Hi Nicholas,
In the OnSecuritiesChanged method inside the RiskManagement model, we are iterating the changes object by the variable name added/removed but we are trying to access the object using the variable name security hence the above error. To resolve this, we recommend changing to the following code snippet:
We strongly recommend all the QuantConnect Community using the debugger (see video) to solve runtime errors.
Best,
Varad Kabade
Nicholas Fitzgerald
Hi Varad,
I've made the changes you suggested, which has cleared up the issue. I'm not having problems with the average true range calculations.
AttributeError : 'ATRRiskManagementModel' object has no attribute 'atr' at ManageRisk lossLevel = security.Price - (2*self.atr.Current.Value) === at Python.Runtime.PyObject.Invoke(PyTuple args in RiskManagement.py: line 32
I've commented out the risk module so that I can upload the backtest with the new code.
My other concern is that instead of a static ATR figure being attached to the security at the time of purchase, a dynamic atr may be continually updated. Is there a way to access or create order tickets for new stocks entering the portfolio to ensure the ATR used is that from the time of purchase?
Thank you for your continued assistance!
Nick
Varad Kabade
Hi Nicholas Fitzgerald,
the atr is the attribute of the SymbolData class and not of the RiskManagementModel class to resolve the error we recommend:
instead of:
My other concern is that instead of a static ATR figure being attached to the security at the time of purchase, a dynamic atr may be continually updated. Is there a way to access or create order tickets for new stocks entering the portfolio to ensure the ATR used is that from the time of purchase?
We could delete the SymbolData object from our dictionary if the particular symbol is liquidated. This way, when we add the security again we will create a fresh ATR.
Best,
Varad Kabade
Nicholas Fitzgerald
Hi Varad,
I've made some significant changes to the code, which is attached below. My current issue is that targets are not being made with the log command returning only a blank list. I believe this may have something to do with the definition of:
security = kpv.value
symbol = kpv.key
,leading to the symbolData class creating no values. The backtest for this is attached below. I also performed a backtest using your suggested code, which is contained in the RiskManagement3 module, but yields the same result.
I have attempted to log the values of the sd.atr.Current.Value, which results in the error:
Runtime Error: UnboundLocalError : local variable 'sd' referenced before assignment at ManageRisk algorithm.Log(sd.atr.Current.Value) === at Python.Runtime.PyObject.Invoke(PyTuple args in RiskManagement.py: line 45
I'm currently working through the Python documentation as I have been advised this results from a coding error rather than a Quantconnect issue. If you have any suggestions that would be great.
Regards,
Nick
Louis Szeto
Hi Nicholas
We cannot retrieve the RiskManagement3.py file, nor identifying the location where the error message came from. Please attach the backtest with that information for further assistance. Thank you!
Best
Louis
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.
Nicholas Fitzgerald
Hi Louis,
I have responded to you in this thread about these issues and will close this one so as not to duplicate responses and take more of your time.
Sincere regards,
Nick
Nicholas Fitzgerald
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!