My custom data includes OHLCV attributes added on the Reader method from the custom data class, the problem is that, when the algorithm is run, the corresponding OHLCV security attributes don't get updated correctly, instead they're all set to the close price except the volume one which is set to 0.
def Reader(self, config: SubscriptionDataConfig, line: str, date: datetime, isLiveMode: bool) -> BaseData:
if not (line.strip() or line[0].isdigit()):
return None
try:
data = line.split(",")
delta = self.GetCustomDataTimeFrame(self.algo.TimeFrame)[1]
ohlcv = list(map(lambda x: float(x), data[1:6]))
time = datetime.strptime(
data[0], "%Y-%m-%d %H:%M:%S")
ct = CustomData()
ct.Time = time
ct.Symbol = config.Symbol
ct.Value = ohlcv[3]
ct.EndTime = time + timedelta(seconds=delta)
ct["Open"], ct["High"], ct["Low"], ct["Close"], ct["Volume"] = ohlcv
ct["Period"] = timedelta(seconds=delta)
except ValueError:
return None
return ct
Mia Alissi
From the information provided in the extracts, it seems like you are trying to map OHLCV data to a custom data object. However, the custom data object in QuantConnect doesn't directly support OHLCV fields. The custom data object only has a
Value
field which is used as the default data point value.In your code, you are setting the
Value
field to the close price (ct.Value = ohlcv[3]
). This is why all the OHLCV attributes are set to the close price. The volume is set to 0 because the custom data object doesn't have a volume attribute.If you want to use OHLCV data, you might want to consider using the
TradeBar
object instead of a custom data object. TheTradeBar
object has OHLCV fields that you can set directly. Here is an example of how you can do this:This code will create a
TradeBar
object for each line in your data, and set the OHLCV fields accordingly.Please note that this is just a suggestion based on the information provided in the extracts. You might need to adjust the code to fit your specific needs.
For more information on how to use custom data in QuantConnect, you can refer to the official 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.
Santiago Villalobos
But returning a TradeBar object instead of CustomData won't break internally the backtest engine since it's expecting a PythonData extension?
Mia Alissi
Returning a
TradeBar
object from theReader
method of a custom data type should not break the backtest engine. TheReader
method is expected to return an instance of a class that extendsBaseData
. BothPythonData
andTradeBar
extendBaseData
, so they can be used interchangeably in this context.However, as mentioned in the forum discussion titled "Custom data: returning TradeBar instead of custom class object", if you use your custom data
TradeBar
in Lean where the symbol signals a type ofDynamicData
(the type for custom data which gets attributed to your symbol byAddData()
), it may fail asTradeBar
is notDynamicData
.So, while you can return a
TradeBar
from yourReader
method, you should be aware of these potential issues when using the data in your algorithm. If you encounter any issues, you may need to adjust your code accordingly or consider using a custom class that extendsBaseData
and includes the specific fields you need.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.
Santiago Villalobos
That's my point, isn't there any way to have custom data Security object updates without sacrifying the use of Lean helper methods?
Mia Alissi
Based on the information provided in the extracts, it seems that you want to use custom data with OHLCV fields and also want to take advantage of Lean's helper methods.
Currently, Lean's custom data feature is designed to be flexible and can handle any type of data, not just OHLCV data. This is why custom data objects only have a
Value
field by default.However, there is a discussion in the forum titled "The SymbolData Pattern" about adding some “sugar” in QuantConnect/Lean, for example, attaching the custom properties to the Security object to eliminate the user-defined class dictionary. This feature might help in your case, but it seems it's still under consideration.
In the meantime, you can create a custom class that extends
BaseData
and includes the specific fields you need. You can then use this custom class in your algorithm and access the OHLCV fields directly. Here is an example:This code will create a
MyCustomData
object for each line in your data, and set the OHLCV fields accordingly. You can then use these fields in your algorithm.Please note that this is just a suggestion based on the information provided in the extracts. You might need to adjust the code to fit your specific needs.
For more information on how to use custom data in QuantConnect, you can refer to the official 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.
Santiago Villalobos
For anyone interested I found a workaround in C#:
The following is an example custom data class that implements this workaround:
Santiago Villalobos
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!