I'm trying to implement some custom indicators, but I'm new to the platform so I don't have a full understanding of best practices and design patterns and how they will affect the overall development of my algorithm.
Say I have 3 indicators which are stateful and dependent upon each other:
Indicator A:
- uses a RollingWindow of TradeBars of the symbol
- generates a single value
Indicator B:
- uses a RollingWindow of TradeBars of the symbol
- uses a RollingWindow of Indicator A
- generates two separate values
- uses RollingWindows of both of its previous values
Indicator C:
- uses a RollingWindow of TradeBars of the symbol
- uses a RollingWindow of Indicator A
- uses RollingWindows of both values from Indicator B
- generates a single value
- uses a RollingWindow of its own previous value
(Note: I'm simplifying here with a hypothetical use case. My actual indicators could use more than two dependencies, that are shared by more than one other indicator, however I do know I won't have any circular dependencies)
The Alpha part of my algo uses the values generated by both B and C. I haven't decided whether to create multiple AlphaModels for each indicator and then distill the generated Insights downstream in Portfolio Construction, or just use a single AlphaModel that produces a single Insight.
For a multi-AlphaModel design, I'd have to create and register each of the indicators in the top-level algorithm, and pass the indicator instances as constructor args to the individual AlphaModels, and then to the indicators themselves. I like that it's composable, concerns are separated and it's easier to share, scaffold, and test. However, I'd be relying on the framework to call Update on each of them. Can I be sure in each iteration that Update will have been called in a reliable order (in this case A before B before C)? And are there any concerns about sharing stateful instances of indicators?
In a single-AlphaModel design I'd just create an Instance of C, which internally creates an instance of B, and B would create it's own internal instance of A. Each would call Update on its internal dependencies, and expose them as publicly accessible members to clients. This seems to be how some of the existing indicators work, but to be honest seems a little messy becuase it breaks the expected interface of the Indicator, and requires the clients to know about the internal dependencies. It could also be a performance concern because each indiicator would be storing redundanct copies of the data.
I'd like to do this in Python, as I've never worked with C#, but I'll learn it if it's better suited for a desgin like this (especially if I can just code the indicators in C# and the rest of the algo in Python). I see there are CompositeIndicator and FunctionalIndicator classes in C#.
Any guidance on my approach/methodology would be greatly appreciated!
Rahul Chowdhury
Hey Eric,
If you go for the multi-alpha approach, meaning you use AddAlpha and not SetAlpha, the Update method of each alpha will be called. Each AlphaModel can generate insights for the same symbol. You will also have to create a portfolio construction model that decides how to create portfolio targets based on those insights.
If you go for the single alpha approach, you can accomplish what you want to do without creating any indicators, but by using rolling windows. We can create a rolling window for trade bars and once that rolling window is ready we can calculate Indicator A and then update the rolling window for A. Once the rolling window for A is ready, we can calculate Indicator B, and so on.
I wrote a template for you to get started which has the structure layed out. We house all our data for each symbol in a SymbolData object. The rolling windows all reside in there.
Eric M
Simply amazing Rahul Chowdhury thank you!
I understand most of what you're doing here, with one quesiton: what is the role of the Consolidator here? Is this just functioning as a single unifying event that you can subscribe to so you can chain the updates from a single source?
Rahul Chowdhury
Hey Eric,
That's exactly it! The consolidators serve as a way to retrieve bar data for each of our symbols and the consolidator's event handler is used to update our rolling windows and our indicators with that bar data. We can also form consolidated bars of custom period by changing the resolution within our symbol data class. This allows us to experiment with different time scales.
Eric M
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!