When focusing on generating alpha signals we don't need t both with execution or
portfolio construction models. Instead we can judge how well we do based on our
generated alphas. By not submitting orders, backtests and live performance is
greatly improved.
In this update, methods overloads with decimal parameters accept python float.
- Fixes FractionalQuantityRegressionAlgorithm:
With the pythonnet update we can pass a python float where a decimal is required.
If we make a prediction for 1 day in the future, we actually mean 1 trading day.
This change updates the alpha analysis logic to take into account the security's
market hours.
This PR is an attempt to reduce contention in concurrent dictionaries, replacing method calls using full locks with lock-free equivalents:
- dictionary.Count -> dictionary.Skip(0).Count()
- dictionary.Keys -> dictionary.Select(x => x.Key)
- dictionary.Values -> dictionary.Select(x => x.Value)
The most frequent usages of these methods are: CashBook, SecurityManager, UniverseManager and indirectly, SecurityPortfolioManager.
The reasons for this update are explained very clearly in this article:
https://arbel.net/2013/02/03/best-practices-for-using-concurrentdictionary/
This is to prevent derived types from overriding these implementation as
they're critical to the proper function of the class. This removes the
existing reflection checks that would accomplish the same thing, but at
runtime instead of compile time.
Internally we're materializing the symbols enumerable from the signal model and then
passing that into the portoflio construction model. So we already have the list. In
addition, a common task is to check the count of the signals for use in further math,
such as determining weighting percentages, ect...
This abstraction point is completely unwarranted. The signal object is really
just a DTO and it's extensible as it is currently defined. This also allows us
to enforce certain behaviors, such as internal set of GeneratedTimeUtc.
Removes GeneratedTimeUtc from the result object as it's now directly on the signal.
Requiring a period here forces signal models to place a time frame on
when their signal is valid. This also allows consumers of signals to
have some expectation of when a prediction should come to fruition.
It's not unreasonable to think users will provide their own ISignal implementation
and we'll want them all behaving by the same serialization rules to make consumption
much easier.
Since these are really just data structures they belon in the common library. Also,
it stands to reason that we'll want to reuse them in other components, such as the
result handler.
IAlgorithm.FrameworkOnData is used to pulse models with new data each time step
IAlgorithm.FrameworkOnSecuritiesChanged is used to pulse models with security changes
These two functions need to be separate to ensure that if we add an indicator during
the securities changed event that it will get the data from the current time step.
This forces us to call the securities changed event before we invoke the consolidators
for the current time step.
This forces the quantity computation to be performed from the portfolio construction model.
As a result of this change, we've removed the Percent and Quantity implementations and
replaced them with just a PortfolioTarget implementation that is equivalent to the previous
Quantity implementation. Users can still use the static Percent method to generate the
correct quantities for a target for the common case of a percent weighted portfolio.
The risk management model is intended to check the algorithm's positions
at the end of each time step to potentially exit positions that are losing
too much.
Framework algorithms are expected to set these models. All of these models
should be user specified. The execution model could be defaulted to the immediate
model, but perhaps it's best that users are explicit
This change includes a check to prevent users from overriding methods required
by the framework. This is non-ideal and we should perhaps look into alternatives
to this approach, which could involve additional methods on IAlgorithm. In order
to not lose access to these events at the algorithm level, we could expose them
as C# events (not sure python compatibility?)