Commit Graph

113 Commits

Author SHA1 Message Date
Stefano Raggi 4abc525a38 PortfolioTarget.Percent returns null if error 2018-08-21 18:10:51 +02:00
AlexCatarino 239a5a909e Fixes EqualWeightingPortfolioConstructionModel not flattening expired insights
- When there are or aren'tt new insights, the EqualWeightingPortfolioConstructionModel will creates a target to flatten delisted securities from the universe of expired insights.
- Helper methods were added to deal with removing expired insights and getting active ones and used in `EqualWeightingPortfolioConstructionModel`
- Adds unit test
- Updates framework algorithms
2018-08-13 19:45:25 +01:00
Michael Handschuh d5f88c6bb7 Add Insight.IsActive and Insight.IsExpired methods
Easily check if an insight is active or expired
2018-08-10 13:52:17 -04:00
Michael Handschuh 4fd16f6daf Fix resolution of insight close times, allow user defined close times
Fixes a bug where we were using the security's data resolution to compute
the insight's close time. This led a case such as insight.Period == 20days
to step 20days worth of tradable minutes (assuming minute data resolution),
yielding a close time that was very far in the future.

We also add different means of specifying an insight's period/close time:
1. Specify insight period as a TimeSpan and we compute close time
2. Specify insight period and a resolution and bar count and we compute close time
3. Specify insight close time local directly and we compute the insight period

The key here is maintaining consistency between the three different approaches
which is heavily validated with the corresponding unit tests.

Edits also made to trust the insight's close time as the analysis end time in
the case where the analysis period == insight period (extra analysis period = 0).
Given the current setup (extra analysis period == 0), this guarantees that close
and analysis end times are equivalent.

Regression statistics were updated and expectedly we get many more insights that
have completed analysis, and as such, average scores have also changed.
2018-08-07 11:21:11 -04:00
Martin Molinero 6da57a1e12 Improving GetMaximumOrderQuantityForTargetValue 2018-08-03 16:26:14 -03:00
Martin Molinero c73b7bb62f Adding smarter methods for PortfolioTargetCollection 2018-07-27 10:48:55 -03:00
Michael Handschuh d2c546e78e Make Insight.FromSerializedInsight public
This is needed elsewhere and seems less worse than exposing it
via InternalsVisibleTo
2018-07-19 13:46:11 -04:00
Stefano Raggi 7bc991a621 Update execution models to execute trades ordered by margin impact 2018-06-22 18:07:13 +02:00
AlexCatarino b15cfacff2 Insight.Group retuns the original Insight array with modified Insights
Use the new return type in PairsTradingAlphaModel.
2018-05-10 16:18:07 +01:00
AlexCatarino 659c64d5ce Adds single Insight overload to Insight.Group
pythonnet does not find the method overload when we only provide one `Insight` instance, that leads to a discrepancy from C# API.
2018-05-10 11:50:12 +01:00
AlexCatarino 62adc3a24b Changes Insight.Group return type to IEnumerable<Insight> from Guid 2018-05-09 14:49:00 +01:00
Michael Handschuh 2e0111b858 Handle null group-id in FromSerializedInsight
Also updates the insight serialization tests to exercse the null
group-id case to prevent future regressions.
2018-04-23 13:26:41 -04:00
Michael Handschuh b4902691ed Ignore null values of group-id and source-model
There's no need to transport these null values as it simply adds to
overhead and delays transmission of the insight.
2018-04-23 13:12:49 -04:00
Michael Handschuh 728868d46f Remove incorrect insight closing time approximation
The insight itself defines when it closes via the algorithm framework
and properly takes into account weekends and out of market hours. The
insight analysis was not respecting the insight's stated close time,
but instead was simply doing generated time + period, which doesn't
properly take into account market hours. This causes the number of
closed insights to decrease and due to the extra time for each insight,
the values of the insights have also increased.
2018-04-23 13:11:06 -04:00
Michael Handschuh 5f33d61220 Add Insight.GroupId and Insight.Group( insights )
Provides a means of grouping insights together.
This new value is serialized as 'group-id'.
2018-04-19 12:47:08 -04:00
Michael Handschuh c3c6a9aff8 Add Insight.SourceModel
This identifier is used to determine the alpha model that generated.
This is NOT ideal, since it requires users to specify the value, more
thought will be givent to how we can resolve this value automatically

Adds test for surviving roundtrip copy operation.
2018-04-17 16:36:47 -04:00
Michael Handschuh ef67abea7e Add InsightCollection
Provides a collection type for managing insights. Internally it uses
a dictionary Symbol->List<Insight> but does NOT implement the dictionary
interface due to potentially unexpected behavior when enumerating, i.e,
different behavior when enumerating if statically known as list vs statically
known as dictionary -- not sure how python would resposne to the ambiguity,
so best to leave well enough alone :)
2018-04-10 19:24:37 -04:00
Michael Handschuh dd764ad8e9 Rename InsightCollection->GeneratedInsightsCollection
This type is just used as a container for generatd insights. Renaming in
preparation for a new InsightCollection to mirror the PortfolioTargetCollection
2018-04-10 19:24:36 -04:00
AlexCatarino bf1aa7fa4c Implements Insight.Price helper method.
Implements `Insight.Price` method to make it easier to create new instances of `Insight` of `InsightType.Price`.
Standardize the parameter order to `Symbol`, `TimeSpan`, `InsightType`, `InsightDirection`, `Double`, `Double`.
2018-04-10 19:49:29 +01:00
Michael Handschuh af9202952e PortfolioTarget.ToString - <symbol>: <quantity>
IMO, this was backwards from the beginning. This ordering makes for
better, more intuitive logs.
2018-04-06 16:48:49 -04:00
Michael Handschuh 92c5e64024 Adds VWAP and STD execution models
VWAP will submit market orders while the current price is more favorable than VWAP.
STD will submit market orders while the current price is a configured number of
standard deviations away from the mean in the favorable direction.
2018-04-06 16:30:26 -04:00
Michael Handschuh f11acf1246 Remove Insight.Equals
This method is misleading at best and incorrect at worst.
Insight objects should use reference equality or compare ids to
perform equality checking. The only usage, in MacdAlphaModel,
was easily converted to not relying on this method.
2018-04-03 23:32:34 -04:00
Michael Handschuh b1e624dfdc Fixes bug in PortfolioTarget.Percent
Buying power model's GetMaximumOrderQuantityForTargetValue returns the
delta quantity needed to reach a particular position, so we need add
back in the existing quantity to get the total quantity required.
2018-04-02 11:30:13 -04:00
Michael Handschuh 48c691c2bb Use buying power model in PortfolioTarget.Percent
Also adds convenience ToString override
2018-03-26 16:42:25 -04:00
Michael Handschuh 708b0e91b8 Dispose of InsightManager extensions on exit
This isn't technically required, but it's best practice to explicitly
dispose of resources that require it.
2018-03-22 14:51:42 -04:00
Michael Handschuh 0d5fca0733 Add insight serialization tests
Moved costruction of insight from serialized insight to the insight
object so it could access private properties, such as the id
2018-03-12 16:28:41 -04:00
Michael Handschuh 6b239674e2 Renames Alpha -> Insight
The term 'alpha' is used to describe the entire algorithm. Therefore, 'alpha'
produces insights. From this we have things like IAlphaModel, which is the model
defining how insights are produced. We have IAlphaHandler, which defines how the
insights from a single 'alpha' (the algorithm) are managed, analyzed, and stored.
Types closer to the individual prediction level, such as InsightDirection, or
InsightScore relate directly to exactly 1 insight. The distinction between the
two became more clear as we developed the insights API, and from that effort it
was decided to harmonize alpha/insight terminology across the various QC systems.
2018-03-09 16:12:56 -05:00
Michael Handschuh e0f6365154 Move prediction serialization to dedicated DTO
As we strayed further from the serialization happy path, things started
getting unwieldy quickly. By defining a dedicated DTO to represent the
serialized type, we don't have to much around as much with json.net to
get it to transform/project our type to what we want. The projection is
handled completely within user code and json.net s used to serialize the
simple/flat result object.
2018-03-09 14:04:26 -05:00
Michael Handschuh 3f7b7702a4 Add Alpha.ReferenceValue
Gets the current value for the specified 'type'.
For example, this could be the price of the asset at the moment
the prediction was made.
2018-03-08 16:33:29 -05:00
Michael Handschuh 78c238a0e5 Add JsonConstructor and JsonProperty to Alpha
This resolves #1623 where we were unable to properly deserialize a
serialized alpha string. The issue was json.net didn't know what
constructor to use. In addition, json.net didn't know it was supposed
to set using the private property setters which isn't default behavior.
2018-02-27 15:08:10 -05:00
Michael Handschuh b35c0adab9 Add Alpha ctor that accepted GeneratedTimeUtc
When run in an algorithm this time is set by the algorithm. This constructor is added
to make testing alphas a little easier where we can't rely on the algorithm to set the
generated and close times properly.
2018-01-12 12:08:40 -05:00
Michael Handschuh d461544b21 Enforce deterministic scoring by using deterministic enumerables
This change fixes the non-determinism seen in the rolling averaged alpha scores. This was
caused by usage of ConcurrentDictionary coupled with the key being a new guid. The new guid
was the source of non-determinism as it caused the same conceptual alpha from backtest A to
end up in a different 'bucket' on backtest B due to a different guid. The concurrency isn't
actually needed or desirable in this context. The AlphaManager must be invoked synchronously
to avoid inconsistent/non-deterministic analysis. Given this, the collections were changed
to use HashSet<T> and now produces deterministic results independent of the alpha's id.
2018-01-12 12:08:40 -05:00
Michael Handschuh 69d3a10a93 Decompose DefaultAlphaHandler into IAlphaManagerExtension
The IAlphaManagerExtension defines a type that needs to react to events produced
by the AlphaManager. The actual events were removed in favor of a interface to
handle the events. This removes the need to wire events and instead just pass the
extensions to the alph manager and it will handle invoking the extensions at the
appropriate time.

This change removes all charting and statistics aggregation logic from the alpha
handler and moves it into dedicated types, AlphaChartingManagerExtension and
AlphaStatisticsManagerExtension. The resulting types are highly decoupled from the
LEAN ecosystem allowing them to be easily unit tested, whereas before the logic
was embedded in a handler with many many dependencies which would be very hard to
properly unit test.

As part of this change (and in preparation for moving scoring to the alpha thread)
the resolution of SecurityValues was removed from the alpha manager. In this new
pattern, the alpha manager is pushed generated alphas and security values at each
time step.
2018-01-12 12:08:40 -05:00
Michael Handschuh cfea54aecd Fixes average estimated value and delays avg score sampling 2017-12-28 12:24:59 -05:00
Michael Handschuh b07928bd58 Properly account for market hours in alpha prediction periods
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.
2017-12-28 11:27:41 -05:00
Michael Handschuh 45f97d38e9 Remove ConcurrentDictionary.IsEmpty call
It turns out that checking if it's empty is much more expensive than enumerating
an empty collection. This is because IsEmpty acquires all the locks in order to
give a 'snapshot' answer. Enumerating the dictionary directly (not .Keys or .Values)
instead acquires a single finer grained lock at a time. IIRC, one lock will manage a
few buckets internally.
2017-12-28 11:27:41 -05:00
Michael Handschuh b39fd19dc7 Remove Alpha.AlphaPeriodEndTimeUtc
The end time is a little more complicated than calendar math since we'll need to
account for weekends and market open/close hours
2017-12-28 11:27:40 -05:00
Michael Handschuh 3bfd567009 Properly seed ema of population scores
Not seeding this value cause a very heavy 0 starting value to keep the average
suppressed throughout the entire backtest, or until enough alphas are generated
to overcome the initial ema seed value.
2017-12-28 11:27:40 -05:00
Michael Handschuh dfce99f575 Sample alpha scores on next time step, ignore mag scores if mag=null 2017-12-28 11:27:40 -05:00
Michael Handschuh a2481387cd Directly enumerator concurrent dictonary instead of values
Enumerating the values directly requires the dictionary to acquire all global locks
vs enumerating the dictionary's key values pairs uses fine-grained locking at the
bucket level.
2017-12-20 10:44:56 -05:00
Michael Handschuh 2295e524f4 Add IAlphaRuntimeStatisticsGenerator and send to result handler
Provides estimates of alpha value as well as performs online computations of
alpha scores and other KPIs.

Sends alpha stats to result handler
Update live result with framework flag
2017-12-20 08:33:30 -05:00
Michael Handschuh 5a81bce5f6 Add volume and quote currency conversion to SecurityValues 2017-12-20 08:06:30 -05:00
Michael Handschuh 5337cb0b5e Fixes reporting of finalized alpha scores 2017-12-19 18:18:33 -05:00
Michael Handschuh b0032f2376 Range bound alpha scores to [0, 1]
These are intended to be percent-esque scores.
2017-12-17 05:19:15 -05:00
Michael Handschuh 3161fd600b Rename PercentChange -> Magnitude 2017-12-15 20:10:34 -05:00
Michael Handschuh b4b3aae112 Rename Signal -> Alpha
Whoa... I think I got everything :)
2017-12-15 18:24:58 -05:00
Michael Handschuh 2bc7905ea2 Add signal count and signal asset breakdown charts
Modifies the way we sample charts to be more like the equity sampling that we do.
In this case, we compute a sampling period based off of 1000 samples for the entire
backtest. In live mode, we'll just sample each minute.
2017-12-15 16:01:09 -05:00
Michael Handschuh f700bc0a6e Add Signal and Portoflio PercentChange convenience mehtods 2017-12-14 15:44:52 -05:00
Michael Handschuh 7af16009a8 Fixes bug in Signal.Clone/Force save all on handler exit
A bug in Signal.Clone caused some serious issues for the analysis engine since it thought
every signal was already past it's analysis period.

Added DefaultSignalHandler.OnExit so derived types can clean up before the thread exits.
2017-12-12 17:09:01 -05:00
Michael Handschuh c879f4ee83 Chart average signal scores daily 2017-12-12 15:57:00 -05:00