Compare commits

...

61 Commits

Author SHA1 Message Date
Riley Shea
2b7372783a Fix column headings in Data/equity/readme.md (#5125)
* Swapped incorrect column heading postions
2021-01-07 11:01:51 -03:00
Adalyat Nazirov
54fce3f666 FillForward enumerator does not loop infinitely if fillforward resolution is different from data resolution (#5118)
* change filename template. add fillforward resolution suffix

* replicate GH issue 5116 on master

it's easy to reproduce on FXCM market by using data resolution different from fillforward resolution.
in this cases daily vs hour/minute were added

* change priorities of Time & EndTime values.

it's necessary to calculate EndTime  properly, and then we can align Time to it.
potential end time should be also calculated using ptoper TZ. Because of we store open hours without TZ movement TZ in market-hours it's necessary to reapply TZ

fix tests

* Miss 2AM bar on Sunday of DST; FF 2AM bar on Sunday ST

* use UTC TimeZone as baseline during comparison
2021-01-06 20:18:08 -03:00
Colton Sellers
12db2261dc Allow Saving of Octet Stream in API (#5130)
* Allow downloading of octet stream

* Refactor solution

* Match lowercase ContentType
2021-01-06 19:46:09 -03:00
Alexandre Catarino
c6d4888e70 Refactors Market Fill of Equity Fill Model (#5114)
* Refactors Market Fill Model

Create `GetBidPrice` and `GetAskPrice` methods to request the most suitable price to fill market orders.

Fix unit tests to show that new implementation prevents using non-market data to fill the order.

* Addresses Peer Review …

Modifies EquityTickQuoteAdjustedModeRegressionAlgorithm to reflect changes in the market fill method. The previous implementation only looks for the last tick when it should look for the last tick of quote type, so current implementation is an improvement.
2021-01-06 12:35:33 -03:00
Martin-Molinero
33b58b0dbc Fixes for IB malformed symbols (#5127)
* Fixes for IB malformed symbols

- Add handling for IB future malformed symbols. Adding unit test
- Fix IB option malformed symbols which had more whitespaces than
  expected. Adding unit test

* Address review
2021-01-06 11:59:22 -03:00
Martin-Molinero
56cb9fbec5 IB will wait for connection response (#5124)
- IB.Connect() will wait for connection response before starting reader
2021-01-05 19:44:04 -03:00
Jared
194e6f6b58 Update benchmark algorithm to include disabling (#5115)
* Update benchmark algorithm to include disabling

* Update C# benchmark example algo

Co-authored-by: Martin Molinero <martin.molinero1@gmail.com>
2021-01-04 18:11:18 -03:00
Martin-Molinero
612c4f8b66 Fix BTC future price multiplier (#5113) 2021-01-04 15:44:38 -03:00
Martin-Molinero
d3b9f8bc7a Protobuf OpenInterest (#5107)
- Add OpenInterest protobuf support. Adding unit test
- Use composer for future and option chain provider
2021-01-04 10:40:35 -03:00
Gerardo Salazar
c4a1c245a7 Adds data parsing for malformed option contracts for InteractiveBrokers (#5101)
* Adds data parsing for malformed option contracts in IBBrokerage

  * Some contracts come in malformed from IB when downloading our
    account holdings. We attempt to detect whenever this happens with
    our options Symbols and try to recover the contract.

* Addresses review and fixes bug

  * Uses contract currency for the new contract created from the
    malformed contract.

  * Bug fix: Sets ibSymbol to new Symbol of the contract once the
    malformed contract has been parsed.

  * Adds support for Futures and FOPs

  * Refactoring code and cleanup

* Addresses review: code cleanup and refactoring

* Addresses review: remove redundant logging of contract in log statement
2020-12-30 16:28:33 -08:00
Martin-Molinero
050dadc21f Increase low resolution cache size (#5105)
- Increasing low resolution cache size so it can hold QC500
2020-12-30 20:59:36 -03:00
Colton Sellers
7b0ea0982e Update ExpectedStatistics (#5094) 2020-12-29 12:04:36 -03:00
Adalyat Nazirov
f8cf923d7b upload SHY quote bars (#5097) 2020-12-29 11:58:13 -03:00
Colton Sellers
14b44bbe17 Reduce Travis Logs v2 (#5049)
* Silence DotNet in building stubs

* Reapply silence to stub publishing

* Have QuantBook store and restore initial LogHandler

* Add assembly action to maintain LogHandler

* Allow AlgorithmRunner to use ConsoleLogHandler

* Use MaintainLogHandlerAttribute to provide current test logger

* Refactor LogHandler creation
2020-12-28 21:10:21 -03:00
Colton Sellers
2ed221b623 Linux PyCharm Docker Debugger Fix (#5092)
* Map host.docker.internal to host ip

* Typo fix

* Only add host in Linux environment
2020-12-28 21:08:34 -03:00
Gerardo Salazar
3f1c33e1c5 Fixes DockerfileLeanFoundation build and adds/updates new packages (#5036)
* Fixes DockerfileLeanFoundation build

  * Updates DockerfileLeanFoundation packages and adds new packages
  * apt-get performance improvements

* Moves packages to CDN and install packages from CDN

  * Updates all CDN downloads to HTTPS

* Removes interactive `rm` command arg in DockerfileLeanFoundation cleanup
2020-12-28 18:22:15 -03:00
Adalyat Nazirov
017b464e21 Map legacy symbols using map file (#5017)
* map IB brokerage symbol

* map Alpaca symbols

* improve empty symbol checking
2020-12-28 17:54:00 -03:00
Gerardo Salazar
4dec21ccc0 Fixes failing option chain provider test for futures options (#5088)
* The test didn't take into account that the contract expiring on
    December would mean that there would temporarily be no Dec. FOP
    contract. We fix this by looking for the Mar. contract instead
    if the december contract has expired.
2020-12-28 16:28:41 -03:00
Martin-Molinero
529d0a3634 Fix low resolution cache (#5080)
* Replace cache size for MB

* Remove setting capacity

* Custom cache implementation

* Reduce locks in custom cache

* Add cache performance unit test
2020-12-28 16:27:11 -03:00
Martin-Molinero
9c89e8d403 Fix backtest result packet deserializing (#5084)
* added test covering minValue / maxValue issue with JsonRoundingConverter

* change namespaces

* JsonRoundingConverter fix decimal.Min and MaxValues (cannot deserialize)

* remove dependency on 3rd party library

* c# 6 compatible code (remove pattern matching)

* Fixes BacktestResultPacket deserializing

- Serializing decimals as strings to avoid precision loss, since json
  convert will use floating point precision. Updating unit tests.
- Fix logging unit test failing to delete file being used.

Co-authored-by: Mark Virchenko <mark.virchenko@calienteam.com>
2020-12-28 16:26:40 -03:00
Adalyat Nazirov
1988ad1ae5 Bug 4925 daylight out of order bar (#4941)
* test

* wip

* Revert "Fix duplicated history entries when contains daylight saving time change (#4700)"

Use proper rounding down

* regression test

* remove unused parameters

* more tests

* fix name and comment

* improve regression test

* more tests: oanda market hours

* re-apply Exchange TZ to bar EndTime

* fix expected results

* we can't substract minute because it can harm algorithm on minute resolution; so we could use tick?

* rename prop: conflict with QCAlgorithm.StartDate

* do not log messages to pass travis ci log limit

* assign loghandler in AlgorithmSetupHandler

* reference to PR for more description

* due to https://github.com/QuantConnect/Lean/pull/5039 we don't need to override it manually
2020-12-28 16:24:33 -03:00
Martin-Molinero
3658fb1405 Update config.json (#5086) 2020-12-28 13:06:07 -03:00
Colton Sellers
0ac79487d7 IB Brokerage Restore Subscriptions Fix (#5078)
* Return true after all symbols have been processed

* Continue on Canonical Future Symbols
2020-12-23 20:56:07 -03:00
Gerardo Salazar
38120a3217 Converts QuantConnect.Common.csproj file to .NET Sdk format (#5071) 2020-12-23 13:15:29 -03:00
Martin-Molinero
01a13a095a Remove cloud-api-url config setting (#5073) 2020-12-22 22:51:00 -03:00
Colton Sellers
704a5cb00e Pycharm Docker Debugging Fix (#5069)
* Move PyCharm Debugger to port 6000 and expose it

* Change PyCharm default configurations to port 6000
2020-12-22 15:22:46 -03:00
Martin-Molinero
490ad08c89 Optimization handling of failed backtest init (#5068)
- Optimizer will increment failed count and notify the strategy of
  failed backtest initialization
2020-12-21 19:27:27 -03:00
Martin-Molinero
a60cd95611 Optimizer will clean lean before last update (#5063)
- LeanOptimizer will clean up any lean instance before calling the last
  udpate, so that runtime stats are correct.
2020-12-21 15:17:44 -03:00
Colton Sellers
eed8e9c763 Improve IBBrokerage Symbol Mapping Error Message (#5051)
* Improve IBBrokerage Error Message

* Add exception message to catch statement

* Address review

* Address review edits
2020-12-21 13:04:05 -03:00
Marco Grassi
365f53dfc7 Fix the missed rename of OptimizationStatus.Ended to Completed (#5060) 2020-12-19 19:06:09 -03:00
Martin-Molinero
48a86c2626 Rename OptimizationStatus from Ended to Completed (#5059) 2020-12-18 16:53:29 -08:00
Martin-Molinero
2de9c21b6d Optimization tweaks (#5056)
* Add progress for runtimeStats

- Add optimization progress runtimestats
- Add ServerStatistics for the last backtesting package

* Add StaticOptimizationParameter

- Add StaticOptimizationParameter. Updating unit tests
2020-12-18 16:01:44 -08:00
Martin-Molinero
649aafc952 Adding Api.ReadBacktest optional getCharts (#5054)
* Adding Api.ReadBacktest optional getCharts

- Optionally allow users not to fetch backtest charts when reading a
  backtest, it can be slow

* Fix null reference for deleted/cancelled backtests

* Get Leaky bucket config settings once
2020-12-18 14:17:40 -03:00
Gerardo Salazar
25fa4c6fb6 Adds holidays to ES futures (#5045)
* Adds holidays to ES futures

* Adds CME equity product market hours and holidays (ES, NQ, YM)
2020-12-17 21:12:20 -03:00
Martin-Molinero
d1b35f7974 Optimization status update (#5050) 2020-12-17 17:09:01 -03:00
Colton Sellers
4006ba01e4 Reduce Travis Log (#5039)
* Reduce Travis setup verbosity

* Introduce ConsoleErrorLogHandler

* Change Console.WriteLine to Log statements

* Quiet wget

* Route build stubs stdout to null

* Fix Quantbook history test

* Silence stub packages directly

* Use parameterized log-handler for testing

* Rename AssemblyInitialize Setup

* Fix AlgorithmRunner file logging

* Drop all overriden LogHandlers in tests

* Change to OneTimeSetup to maintain LogHandlers

* Permit any ILogHandler to be defined in params

* Fix for AlgorithmRunner Handlers V2
2020-12-17 12:59:13 -03:00
Martin-Molinero
6d824b40a6 Add handling for custom host name (#5043)
* Add handling for custom host name

* Credit cost as decimal
2020-12-16 21:54:00 -03:00
Colton Sellers
8e410fcaf1 Update old Hourly/Daily data for ApiDataProvider (#5034)
* Update old Hourly/Daily data for ApiDataProvider

* Add unit test for IsOutOfDate

* Address review

* Fix reference to static function in test
2020-12-16 19:04:06 -03:00
Adalyat Nazirov
d136428556 ignore *.DotSettings files (#5035)
This layer is designated for common settings that enforce your team preferences for the current solution.
Since we don't have specific resharper settings we want to share within the team we ignore this file
2020-12-16 12:38:01 -03:00
Gerardo Salazar
40d81965be Adds debug logging for MapSymbol(...) method in IB Brokerage (#5040) 2020-12-15 17:44:00 -08:00
Aaron Janeiro Stone
c650eb6c1c Adds DeM indicator (#5002)
* Adds DeM indicator

* Added reference to param movingaverage type

* Fixed variable declarations

* Added nameless initialize

* Missing DeM "type" args added

* Missing DeM "type" args added

* refactor

* Undid _previousInput → protected

* Demarker symbol: DeM →DEM

* Symbol change: DeM → DEM

* Updated symbols

TestDivByZero originally had dem as cmf.

* Symbol: DeM →DEM

Co-authored-by: Alexandre Catarino <AlexCatarino@users.noreply.github.com>
2020-12-15 08:29:55 -03:00
Charles Naccio
aa2f9f927a Fixed QuantBook import path for CSharp example (#5028)
Now requires a relative path for loading QuantBook.csx
2020-12-14 21:22:22 -03:00
Charles Naccio
c698a65a84 Replaced obsolete Gitter badge with Slack (#5031) 2020-12-14 12:55:35 -03:00
Charles Naccio
181283a4cd Noted Polygon downloaded in Readme (#5025) 2020-12-11 16:55:58 -08:00
Martin-Molinero
b247724a34 Improve Optimizer runtime statistics (#5024)
- Adding optimization Id to backtests packets
- SeriesSampler will allow truncating the samples
- Removing OptimizationEstimate, simplifying getting estimate and
  runtime stats separatly
2020-12-11 16:39:13 -08:00
Gerardo Salazar
dde3576161 Fixes intraday delistings not occurring before contract expiry for Futures and FOPs (#5007)
* Fixes intraday delistings not occurring for Futures and FOPs

  * Previously, we would wait until the next market open to
    liquidate futures and futures options contracts. Since these
    contracts can not be traded at the next market open and require
    intraday delisting, changes were made to liquidate at the first
    available place where we know the market is open. This means
    we now liquidate futures and FOPs intraday as a market order.

  * Maintains backwards compatability with equities and equity options
    delisting behavior

* Addresses review: adds additional protections for ProcessDelistedSymbols

  * We choose to adjust the delisting date to the next market open only
    if the market is not open at the current time, otherwise the time
    would have been adjusted to the market open of the next trading day

* Addresses review: reverts changes and fixes error message in regression algo
2020-12-11 20:46:56 -03:00
Gerardo Salazar
e8734a0797 Adds/Fixes Futures Options History Research Support (#5013)
* Adds Futures Options History Research Support

* Address review: make canonical future throw when calling GetOptionHistory

* Improve error message, recommending users to user FutureChainProvider
2020-12-11 20:46:41 -03:00
Aaron Janeiro Stone
7f5d69bbec Adds the Awesome Oscillator (#5005)
* Adds the awesome oscillator.

* added missing type hint for AO

* cleaned initializations

* refactor in call for AO(fast,slow,type)

* added missing type parameter for AO

* Changes AO sub-indicators to public.

Co-authored-by: Alexandre Catarino <AlexCatarino@users.noreply.github.com>
2020-12-11 20:46:07 -03:00
Colton Sellers
f6be7a41a5 Bug python runtime issue with local report generation (#5014)
* Fixed Python runtime issue that was occurring when trying to generate reports locally on OSX/mono, but assume the issue impacts all configurations.

* Move Python.Runtime config to common

* Remove duplicate files

* Update readme

* Typo

* Change destination in build directory

Co-authored-by: Charles Naccio <cnaccio@gmail.com>
2020-12-11 20:45:26 -03:00
Stefano Raggi
7f30c0cd00 Downgrade IB error codes from Warning to Information (#5015) 2020-12-11 18:53:25 -03:00
Colton Sellers
6694fe01f8 Api Chart Hotfix (#5023)
* Api Chart Hotfix

* Use IsNullOrEmpty
2020-12-11 18:43:18 -03:00
Aaron Janeiro Stone
32ab4fdea1 Adds ChaikinMoneyFlow indicator (#4986)
* Added CMF indicator

CMF is a volume-weighted average of accumulation and distribution over a period.

* Added initializer for CMF

Registration for ChaikinMoneyFlow implemented.

* Added CMF tests.

* Added CMF tests.

* spy_cmf.txt changed to external indicator data.

* Implement suggestions of @AlexCatarino

* added sum terms as subindicators.

* added sum terms as subindicators.

* Removal of vestigial rolling window

* Minor nit changes

Co-authored-by: Martin Molinero <martin.molinero1@gmail.com>
2020-12-11 18:04:17 -03:00
Colton Sellers
fc81f606e4 Reserve Names for Pandas Mapper (#4978)
* Fix for #4886 and unit test

* Fix test function

* Address review

* Clarify comments
2020-12-11 16:39:13 -03:00
Stefano Raggi
ec74abd4d0 Fix Bitfinex brokerage currency mapping (#5011) 2020-12-11 16:12:57 -03:00
Colton Sellers
bd3ead3480 ApiDataProvider Zip Download Fixes (#5020)
* Stop non zip responses from being saved as a zip

* Capture and log message

* Log as Error
2020-12-11 16:01:57 -03:00
Colton Sellers
45849962a3 Readme expansion and additional VS build tasks (#5018) 2020-12-11 14:49:29 -03:00
Gerardo Salazar
8279cf7eac Improve exception message for indicators using Update(DateTime, decimal) (#5019) 2020-12-11 14:36:42 -03:00
Colton Sellers
4c4a699cb0 Stop Emitting Insights on Delisted Securities (#4997)
* Verify insights are valid before emitting

* nit

* Address review

* Address review and unit tests

* nit - remove extra lines

* Address review

* Initialize insight fields
2020-12-10 11:44:37 -03:00
Colton Sellers
31a2c31c0a Api Update November 2020 (#4981)
* WIP Backtest adjustments

* Workaround awaiting changes

* Adjustments to API Changes

* Nit fix

* Custom Newtonsoft Deserializer for AlphaRuntimeStatistics

* Workaround Travis build error

* Drop AlphaRuntimeStatistics converter; use Decimal converter

* Use StringDecimalJsonConverter

* Undo set properties

* Add more members to de-serializer class
2020-12-09 16:51:58 -03:00
Jared
877a123276 Update readme.md 2020-12-08 12:26:21 -08:00
Gerardo Salazar
4134b05bfd Fixes options order crash in ReportGenerator/PortfolioLooper (#4992) 2020-12-07 12:39:53 -03:00
196 changed files with 9345 additions and 1822 deletions

1
.gitignore vendored
View File

@@ -144,6 +144,7 @@ $tf/
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings
*.DotSettings.user
# JustCode is a .NET coding addin-in

4
.idea/workspace.xml generated
View File

@@ -3,7 +3,7 @@
<component name="RunManager" selected="Python Debug Server.Debug in Container">
<configuration name="Debug Local" type="PyRemoteDebugConfigurationType" factoryName="Python Remote Debug">
<module name="LEAN" />
<option name="PORT" value="5678" />
<option name="PORT" value="6000" />
<option name="HOST" value="localhost" />
<PathMappingSettings>
<option name="pathMappings">
@@ -16,7 +16,7 @@
</configuration>
<configuration name="Debug in Container" type="PyRemoteDebugConfigurationType" factoryName="Python Remote Debug">
<module name="LEAN" />
<option name="PORT" value="5678" />
<option name="PORT" value="6000" />
<option name="HOST" value="localhost" />
<PathMappingSettings>
<option name="pathMappings">

View File

@@ -5,7 +5,7 @@ mono:
solution: QuantConnect.Lean.sln
before_install:
- export PATH="$HOME/miniconda3/bin:$PATH"
- wget https://cdn.quantconnect.com/miniconda/Miniconda3-4.5.12-Linux-x86_64.sh
- wget -q https://cdn.quantconnect.com/miniconda/Miniconda3-4.5.12-Linux-x86_64.sh
- bash Miniconda3-4.5.12-Linux-x86_64.sh -b
- rm -rf Miniconda3-4.5.12-Linux-x86_64.sh
- sudo ln -s $HOME/miniconda3/lib/libpython3.6m.so /usr/lib/libpython3.6m.so
@@ -17,10 +17,10 @@ before_install:
- conda install -y scipy=1.4.1
- conda install -y wrapt=1.12.1
install:
- nuget restore QuantConnect.Lean.sln
- nuget restore QuantConnect.Lean.sln -v quiet
- nuget install NUnit.Runners -Version 3.11.1 -OutputDirectory testrunner
script:
- msbuild /p:Configuration=Release /p:VbcToolExe=vbnc.exe QuantConnect.Lean.sln
- mono ./testrunner/NUnit.ConsoleRunner.3.11.1/tools/nunit3-console.exe ./Tests/bin/Release/QuantConnect.Tests.dll --where "cat != TravisExclude" --labels=Off
- msbuild /p:Configuration=Release /p:VbcToolExe=vbnc.exe /v:quiet /p:WarningLevel=1 QuantConnect.Lean.sln
- mono ./testrunner/NUnit.ConsoleRunner.3.11.1/tools/nunit3-console.exe ./Tests/bin/Release/QuantConnect.Tests.dll --where "cat != TravisExclude" --labels=Off --params:log-handler=ConsoleErrorLogHandler
- chmod +x ci_build_stubs.sh
- sudo -E ./ci_build_stubs.sh -d -t -g -p

15
.vscode/readme.md vendored
View File

@@ -13,7 +13,7 @@ Before anything we need to ensure a few things have been done:
1. Get [Visual Studio Code](https://code.visualstudio.com/download)
* Get the Extension [Mono Debug](https://marketplace.visualstudio.com/items?itemName=ms-vscode.mono-debug) for C# Debugging
* Get the Extension [Mono Debug **15.8**](https://marketplace.visualstudio.com/items?itemName=ms-vscode.mono-debug) for C# Debugging
* Get the Extension [Python](https://marketplace.visualstudio.com/items?itemName=ms-python.python) for Python Debugging
2. Get [Docker](https://docs.docker.com/get-docker/):
@@ -35,7 +35,8 @@ Before anything we need to ensure a few things have been done:
* Download the repo or clone it using: _git clone[ https://github.com/QuantConnect/Lean](https://github.com/QuantConnect/Lean)_
* Open the folder using VS Code
**NOTES**:
- Mono Extension Version 16 and greater fails to debug the docker container remotely, please install **Version 15.8**. To install an older version from within VS Code go to the extensions tab, search "Mono Debug", and select "Install Another Version...".
<br />
<h1>Develop Algorithms Locally, Run in Container</h1>
@@ -112,6 +113,12 @@ In VS Code click on the debug/run icon on the left toolbar, at the top you shoul
As defaults these are all great! Feel free to change them as needed for your setup.
**NOTE:** VSCode may try and throw errors when launching this way regarding build on `QuantConnect.csx` and `Config.json` these errors can be ignored by selecting "*Debug Anyway*". To stop this error message in the future select "*Remember my choice in user settings*".
If using C# algorithms ensure that msbuild can build them successfully.
<br />
<h3>Option 2</h3>
@@ -194,4 +201,6 @@ _Figure 2: Python Debugger Messages_
<h1>Common Issues</h1>
Here we will cover some common issues with setting this up. This section will expand as we get user feedback!
* Error messages about build in VSCode points to comments in JSON. Either select **ignore** or follow steps described [here](https://stackoverflow.com/questions/47834825/in-vs-code-disable-error-comments-are-not-permitted-in-json) to remove the errors entirely.
* Any error messages about building in VSCode that point to comments in JSON. Either select **ignore** or follow steps described [here](https://stackoverflow.com/questions/47834825/in-vs-code-disable-error-comments-are-not-permitted-in-json) to remove the errors entirely.
* `Errors exist after running preLaunchTask 'run-docker'`This VSCode error appears to warn you of CSharp errors when trying to use `Debug in Container` select "Debug Anyway" as the errors are false flags for JSON comments as well as `QuantConnect.csx` not finding references. Neither of these will impact your debugging.
* `The container name "/LeanEngine" is already in use by container "****"` This Docker error implies that another instance of lean is already running under the container name /LeanEngine. If this error appears either use Docker Desktop to delete the container or use `docker kill LeanEngine` from the command line.

28
.vscode/tasks.json vendored
View File

@@ -20,6 +20,34 @@
},
"problemMatcher": "$msCompile"
},
{
"label": "rebuild",
"type": "shell",
"command": "msbuild",
"args": [
"/p:Configuration=Debug",
"/p:DebugType=portable",
"/t:rebuild",
],
"group": "build",
"presentation": {
"reveal": "silent"
},
"problemMatcher": "$msCompile"
},
{
"label": "clean",
"type": "shell",
"command": "msbuild",
"args": [
"/t:clean",
],
"group": "build",
"presentation": {
"reveal": "silent"
},
"problemMatcher": "$msCompile"
},
{
"label": "force build linux",
"type": "shell",

View File

@@ -38,6 +38,10 @@ namespace QuantConnect.Algorithm.CSharp
// Find more symbols here: http://quantconnect.com/data
AddSecurity(SecurityType.Equity, "SPY", Resolution.Second);
// Disabling the benchmark / setting to a fixed value
// SetBenchmark(time => 0);
// Set the benchmark to AAPL US Equity
SetBenchmark("AAPL");
}

View File

@@ -100,25 +100,25 @@ namespace QuantConnect.Algorithm.CSharp
{"Drawdown", "1.300%"},
{"Expectancy", "0"},
{"Net Profit", "1.634%"},
{"Sharpe Ratio", "2.476"},
{"Probabilistic Sharpe Ratio", "92.194%"},
{"Sharpe Ratio", "2.495"},
{"Probabilistic Sharpe Ratio", "92.298%"},
{"Loss Rate", "0%"},
{"Win Rate", "100%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "0.006"},
{"Beta", "0.158"},
{"Annual Standard Deviation", "0.032"},
{"Annual Standard Deviation", "0.033"},
{"Annual Variance", "0.001"},
{"Information Ratio", "-4.89"},
{"Information Ratio", "-4.942"},
{"Tracking Error", "0.08"},
{"Treynor Ratio", "0.509"},
{"Treynor Ratio", "0.517"},
{"Total Fees", "$3.70"},
{"Fitness Score", "0.019"},
{"Kelly Criterion Estimate", "0"},
{"Kelly Criterion Probability Value", "0"},
{"Sortino Ratio", "1.362"},
{"Return Over Maximum Drawdown", "9.699"},
{"Portfolio Turnover", "0.022"},
{"Portfolio Turnover", "0.023"},
{"Total Insights Generated", "0"},
{"Total Insights Closed", "0"},
{"Total Insights Analysis Completed", "0"},
@@ -132,7 +132,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Mean Population Magnitude", "0%"},
{"Rolling Averaged Population Direction", "0%"},
{"Rolling Averaged Population Magnitude", "0%"},
{"OrderListHash", "-1252326142"}
{"OrderListHash", "490786648"}
};
}
}

View File

@@ -85,11 +85,11 @@ namespace QuantConnect.Algorithm.CSharp
{
{"Total Trades", "2"},
{"Average Win", "0%"},
{"Average Loss", "-0.01%"},
{"Compounding Annual Return", "-0.500%"},
{"Drawdown", "0.000%"},
{"Average Loss", "-0.12%"},
{"Compounding Annual Return", "-9.062%"},
{"Drawdown", "0.100%"},
{"Expectancy", "-1"},
{"Net Profit", "-0.006%"},
{"Net Profit", "-0.121%"},
{"Sharpe Ratio", "0"},
{"Probabilistic Sharpe Ratio", "0%"},
{"Loss Rate", "100%"},
@@ -103,12 +103,12 @@ namespace QuantConnect.Algorithm.CSharp
{"Tracking Error", "0.22"},
{"Treynor Ratio", "0"},
{"Total Fees", "$6.41"},
{"Fitness Score", "0.248"},
{"Fitness Score", "0.249"},
{"Kelly Criterion Estimate", "0"},
{"Kelly Criterion Probability Value", "0"},
{"Sortino Ratio", "79228162514264337593543950335"},
{"Return Over Maximum Drawdown", "-82.815"},
{"Portfolio Turnover", "0.497"},
{"Return Over Maximum Drawdown", "-79.031"},
{"Portfolio Turnover", "0.498"},
{"Total Insights Generated", "0"},
{"Total Insights Closed", "0"},
{"Total Insights Analysis Completed", "0"},
@@ -122,7 +122,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Mean Population Magnitude", "0%"},
{"Rolling Averaged Population Direction", "0%"},
{"Rolling Averaged Population Magnitude", "0%"},
{"OrderListHash", "1213851303"}
{"OrderListHash", "-1760998125"}
};
}
}

View File

@@ -0,0 +1,123 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Interfaces;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression test algorithm simply fetch and compare data of minute resolution around daylight saving period
/// reproduces issue reported in GB issue GH issue https://github.com/QuantConnect/Lean/issues/4925
/// related issues https://github.com/QuantConnect/Lean/issues/3707; https://github.com/QuantConnect/Lean/issues/4630
/// </summary>
public class FillForwardEnumeratorOutOfOrderBarRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private decimal _exptectedClose = 84.09m;
private DateTime _exptectedTime = new DateTime(2008, 3, 10, 9, 30, 0);
private Symbol _shy;
/// <summary>
/// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.
/// </summary>
public override void Initialize()
{
SetStartDate(2008, 3, 7);
SetEndDate(2008, 3, 10);
_shy = AddEquity("SHY", Resolution.Minute).Symbol;
// just to make debugging easier, less subscriptions
SetBenchmark(time => 1);
}
public override void OnData(Slice slice)
{
var trackingBar = slice.Bars.Values.FirstOrDefault(s => s.Time.Equals(_exptectedTime));
if (trackingBar != null)
{
if (!Portfolio.Invested)
{
SetHoldings(_shy, 1);
}
if (trackingBar.Close != _exptectedClose)
{
throw new Exception(
$"Bar at {_exptectedTime.ToStringInvariant()} closed at price {trackingBar.Close.ToStringInvariant()}; expected {_exptectedClose.ToStringInvariant()}");
}
}
}
/// <summary>
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
/// </summary>
public bool CanRunLocally { get; } = true;
/// <summary>
/// This is used by the regression test system to indicate which languages this algorithm is written in.
/// </summary>
public Language[] Languages { get; } = { Language.CSharp };
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
/// </summary>
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Trades", "1"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "0%"},
{"Drawdown", "0%"},
{"Expectancy", "0"},
{"Net Profit", "0%"},
{"Sharpe Ratio", "0"},
{"Probabilistic Sharpe Ratio", "0%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "0"},
{"Beta", "0"},
{"Annual Standard Deviation", "0"},
{"Annual Variance", "0"},
{"Information Ratio", "0"},
{"Tracking Error", "0"},
{"Treynor Ratio", "0"},
{"Total Fees", "$5.93"},
{"Fitness Score", "0.499"},
{"Kelly Criterion Estimate", "0"},
{"Kelly Criterion Probability Value", "0"},
{"Sortino Ratio", "79228162514264337593543950335"},
{"Return Over Maximum Drawdown", "-105.726"},
{"Portfolio Turnover", "0.998"},
{"Total Insights Generated", "0"},
{"Total Insights Closed", "0"},
{"Total Insights Analysis Completed", "0"},
{"Long Insight Count", "0"},
{"Short Insight Count", "0"},
{"Long/Short Ratio", "100%"},
{"Estimated Monthly Alpha Value", "$0"},
{"Total Accumulated Estimated Alpha Value", "$0"},
{"Mean Population Estimated Insight Value", "$0"},
{"Mean Population Direction", "0%"},
{"Mean Population Magnitude", "0%"},
{"Rolling Averaged Population Direction", "0%"},
{"Rolling Averaged Population Magnitude", "0%"},
{"OrderListHash", "-850144190"}
};
}
}

View File

@@ -124,30 +124,30 @@ namespace QuantConnect.Algorithm.CSharp
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Trades", "6"},
{"Average Win", "2.94%"},
{"Average Win", "2.93%"},
{"Average Loss", "-4.15%"},
{"Compounding Annual Return", "-5.601%"},
{"Drawdown", "5.600%"},
{"Expectancy", "-0.146"},
{"Net Profit", "-2.771%"},
{"Sharpe Ratio", "-0.49"},
{"Probabilistic Sharpe Ratio", "10.583%"},
{"Compounding Annual Return", "-5.663%"},
{"Drawdown", "5.700%"},
{"Expectancy", "-0.148"},
{"Net Profit", "-2.802%"},
{"Sharpe Ratio", "-0.495"},
{"Probabilistic Sharpe Ratio", "10.470%"},
{"Loss Rate", "50%"},
{"Win Rate", "50%"},
{"Profit-Loss Ratio", "0.71"},
{"Profit-Loss Ratio", "0.70"},
{"Alpha", "-0.043"},
{"Beta", "-0.001"},
{"Annual Standard Deviation", "0.087"},
{"Annual Variance", "0.008"},
{"Information Ratio", "0.96"},
{"Information Ratio", "0.957"},
{"Tracking Error", "0.192"},
{"Treynor Ratio", "58.394"},
{"Treynor Ratio", "57.633"},
{"Total Fees", "$14.80"},
{"Fitness Score", "0.018"},
{"Kelly Criterion Estimate", "0"},
{"Kelly Criterion Probability Value", "0"},
{"Sortino Ratio", "-0.096"},
{"Return Over Maximum Drawdown", "-0.993"},
{"Sortino Ratio", "-0.097"},
{"Return Over Maximum Drawdown", "-0.999"},
{"Portfolio Turnover", "0.043"},
{"Total Insights Generated", "0"},
{"Total Insights Closed", "0"},
@@ -162,7 +162,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Mean Population Magnitude", "0%"},
{"Rolling Averaged Population Direction", "0%"},
{"Rolling Averaged Population Magnitude", "0%"},
{"OrderListHash", "-290004562"}
{"OrderListHash", "-1863159170"}
};
}
}

View File

@@ -132,12 +132,10 @@ namespace QuantConnect.Algorithm.CSharp
private void AssertFutureOptionOrderExercise(OrderEvent orderEvent, Security future, Security optionContract)
{
// We expect the liquidation to occur on the day of the delisting (while the market is open),
// but currently we liquidate at the next market open (AAPL open) which happens to be
// at 9:30:00 Eastern Time. For unknown reasons, the delisting happens two minutes after the
// market open.
// Read more about the issue affecting this test here: https://github.com/QuantConnect/Lean/issues/4980
var expectedLiquidationTimeUtc = new DateTime(2020, 6, 22, 13, 32, 0);
// For unknown reasons, the delisting happens two minutes after the market open. Most likely
// stems from the placement of the ProcessDelistedSymbols and HandleDelistedSymbols methods in relation
// to the algorithm time update and the brokerage ProcessSynchronousEvents.
var expectedLiquidationTimeUtc = new DateTime(2020, 6, 19, 13, 32, 0);
if (orderEvent.Direction == OrderDirection.Sell && future.Holdings.Quantity != 0)
{
@@ -214,13 +212,13 @@ namespace QuantConnect.Algorithm.CSharp
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Trades", "3"},
{"Average Win", "1.25%"},
{"Average Win", "1.22%"},
{"Average Loss", "-7.42%"},
{"Compounding Annual Return", "-12.413%"},
{"Compounding Annual Return", "-12.461%"},
{"Drawdown", "6.300%"},
{"Expectancy", "-0.416"},
{"Net Profit", "-6.257%"},
{"Sharpe Ratio", "-1.325"},
{"Expectancy", "-0.417"},
{"Net Profit", "-6.282%"},
{"Sharpe Ratio", "-1.324"},
{"Probabilistic Sharpe Ratio", "0.004%"},
{"Loss Rate", "50%"},
{"Win Rate", "50%"},
@@ -229,14 +227,14 @@ namespace QuantConnect.Algorithm.CSharp
{"Beta", "-0.003"},
{"Annual Standard Deviation", "0.076"},
{"Annual Variance", "0.006"},
{"Information Ratio", "0.673"},
{"Information Ratio", "0.671"},
{"Tracking Error", "0.188"},
{"Treynor Ratio", "33.559"},
{"Treynor Ratio", "33.52"},
{"Total Fees", "$7.40"},
{"Fitness Score", "0.008"},
{"Kelly Criterion Estimate", "0"},
{"Kelly Criterion Probability Value", "0"},
{"Sortino Ratio", "-0.205"},
{"Sortino Ratio", "-0.204"},
{"Return Over Maximum Drawdown", "-1.983"},
{"Portfolio Turnover", "0.023"},
{"Total Insights Generated", "0"},
@@ -252,7 +250,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Mean Population Magnitude", "0%"},
{"Rolling Averaged Population Direction", "0%"},
{"Rolling Averaged Population Magnitude", "0%"},
{"OrderListHash", "23301049"}
{"OrderListHash", "1442219241"}
};
}
}

View File

@@ -166,31 +166,31 @@ namespace QuantConnect.Algorithm.CSharp
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Trades", "3"},
{"Average Win", "28.04%"},
{"Average Win", "27.44%"},
{"Average Loss", "-62.81%"},
{"Compounding Annual Return", "-78.165%"},
{"Drawdown", "52.400%"},
{"Expectancy", "-0.277"},
{"Net Profit", "-52.379%"},
{"Sharpe Ratio", "-0.865"},
{"Compounding Annual Return", "-78.376%"},
{"Drawdown", "52.600%"},
{"Expectancy", "-0.282"},
{"Net Profit", "-52.604%"},
{"Sharpe Ratio", "-0.864"},
{"Probabilistic Sharpe Ratio", "0.019%"},
{"Loss Rate", "50%"},
{"Win Rate", "50%"},
{"Profit-Loss Ratio", "0.45"},
{"Alpha", "-0.596"},
{"Beta", "-0.031"},
{"Annual Standard Deviation", "0.681"},
{"Annual Variance", "0.463"},
{"Profit-Loss Ratio", "0.44"},
{"Alpha", "-0.598"},
{"Beta", "-0.032"},
{"Annual Standard Deviation", "0.684"},
{"Annual Variance", "0.467"},
{"Information Ratio", "-0.514"},
{"Tracking Error", "0.703"},
{"Treynor Ratio", "18.748"},
{"Tracking Error", "0.706"},
{"Treynor Ratio", "18.718"},
{"Total Fees", "$66.60"},
{"Fitness Score", "0.157"},
{"Fitness Score", "0.158"},
{"Kelly Criterion Estimate", "0"},
{"Kelly Criterion Probability Value", "0"},
{"Sortino Ratio", "-0.133"},
{"Return Over Maximum Drawdown", "-1.492"},
{"Portfolio Turnover", "0.411"},
{"Return Over Maximum Drawdown", "-1.489"},
{"Portfolio Turnover", "0.413"},
{"Total Insights Generated", "0"},
{"Total Insights Closed", "0"},
{"Total Insights Analysis Completed", "0"},
@@ -204,7 +204,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Mean Population Magnitude", "0%"},
{"Rolling Averaged Population Direction", "0%"},
{"Rolling Averaged Population Magnitude", "0%"},
{"OrderListHash", "151392833"}
{"OrderListHash", "891799117"}
};
}
}

View File

@@ -26,11 +26,13 @@ namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// This regression algorithm tests Out of The Money (OTM) future option expiry for calls.
/// We expect 1 order from the algorithm, which are:
/// We expect 2 orders from the algorithm, which are:
///
/// * Initial entry, buy ES Call Option (expiring OTM)
/// - contract expires worthless, not exercised, so never opened a position in the underlying
///
/// * Liquidation of worthless ES call option (expiring OTM)
///
/// Additionally, we test delistings for future options and assert that our
/// portfolio holdings reflect the orders the algorithm has submitted.
/// </summary>
@@ -219,7 +221,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Mean Population Magnitude", "0%"},
{"Rolling Averaged Population Direction", "0%"},
{"Rolling Averaged Population Magnitude", "0%"},
{"OrderListHash", "-1116221764"}
{"OrderListHash", "1061918870"}
};
}
}

View File

@@ -132,12 +132,10 @@ namespace QuantConnect.Algorithm.CSharp
private void AssertFutureOptionOrderExercise(OrderEvent orderEvent, Security future, Security optionContract)
{
// We expect the liquidation to occur on the day of the delisting (while the market is open),
// but currently we liquidate at the next market open (AAPL open) which happens to be
// at 9:30:00 Eastern Time. For unknown reasons, the delisting happens two minutes after the
// market open.
// Read more about the issue affecting this test here: https://github.com/QuantConnect/Lean/issues/4980
var expectedLiquidationTimeUtc = new DateTime(2020, 6, 22, 13, 32, 0);
// For unknown reasons, the delisting happens two minutes after the market open. Most likely
// stems from the placement of the ProcessDelistedSymbols and HandleDelistedSymbols methods in relation
// to the algorithm time update and the brokerage ProcessSynchronousEvents.
var expectedLiquidationTimeUtc = new DateTime(2020, 6, 19, 13, 32, 0);
if (orderEvent.Direction == OrderDirection.Buy && future.Holdings.Quantity != 0)
{
@@ -214,24 +212,24 @@ namespace QuantConnect.Algorithm.CSharp
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Trades", "3"},
{"Average Win", "4.18%"},
{"Average Win", "4.15%"},
{"Average Loss", "-8.27%"},
{"Compounding Annual Return", "-8.879%"},
{"Drawdown", "4.400%"},
{"Expectancy", "-0.247"},
{"Net Profit", "-4.432%"},
{"Sharpe Ratio", "-1.391"},
{"Compounding Annual Return", "-8.928%"},
{"Drawdown", "4.500%"},
{"Expectancy", "-0.249"},
{"Net Profit", "-4.457%"},
{"Sharpe Ratio", "-1.389"},
{"Probabilistic Sharpe Ratio", "0.002%"},
{"Loss Rate", "50%"},
{"Win Rate", "50%"},
{"Profit-Loss Ratio", "0.51"},
{"Profit-Loss Ratio", "0.50"},
{"Alpha", "-0.073"},
{"Beta", "-0.002"},
{"Annual Standard Deviation", "0.052"},
{"Annual Variance", "0.003"},
{"Information Ratio", "0.863"},
{"Information Ratio", "0.861"},
{"Tracking Error", "0.179"},
{"Treynor Ratio", "38.46"},
{"Treynor Ratio", "38.365"},
{"Total Fees", "$7.40"},
{"Fitness Score", "0.008"},
{"Kelly Criterion Estimate", "0"},
@@ -252,7 +250,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Mean Population Magnitude", "0%"},
{"Rolling Averaged Population Direction", "0%"},
{"Rolling Averaged Population Magnitude", "0%"},
{"OrderListHash", "-675079082"}
{"OrderListHash", "-1705374528"}
};
}
}

View File

@@ -26,11 +26,13 @@ namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// This regression algorithm tests Out of The Money (OTM) future option expiry for puts.
/// We expect 1 order from the algorithm, which are:
/// We expect 2 orders from the algorithm, which are:
///
/// * Initial entry, buy ES Put Option (expiring OTM)
/// - contract expires worthless, not exercised, so never opened a position in the underlying
///
/// * Liquidation of worthless ES Put OTM contract
///
/// Additionally, we test delistings for future options and assert that our
/// portfolio holdings reflect the orders the algorithm has submitted.
/// </summary>
@@ -218,7 +220,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Mean Population Magnitude", "0%"},
{"Rolling Averaged Population Direction", "0%"},
{"Rolling Averaged Population Magnitude", "0%"},
{"OrderListHash", "515984318"}
{"OrderListHash", "-312857564"}
};
}
}

View File

@@ -194,29 +194,29 @@ namespace QuantConnect.Algorithm.CSharp
{
{"Total Trades", "3"},
{"Average Win", "10.05%"},
{"Average Loss", "-5.60%"},
{"Compounding Annual Return", "8.121%"},
{"Average Loss", "-5.63%"},
{"Compounding Annual Return", "8.067%"},
{"Drawdown", "0.500%"},
{"Expectancy", "0.396"},
{"Net Profit", "3.880%"},
{"Sharpe Ratio", "1.192"},
{"Probabilistic Sharpe Ratio", "58.203%"},
{"Expectancy", "0.393"},
{"Net Profit", "3.855%"},
{"Sharpe Ratio", "1.191"},
{"Probabilistic Sharpe Ratio", "58.149%"},
{"Loss Rate", "50%"},
{"Win Rate", "50%"},
{"Profit-Loss Ratio", "1.79"},
{"Alpha", "0.069"},
{"Alpha", "0.068"},
{"Beta", "0.003"},
{"Annual Standard Deviation", "0.057"},
{"Annual Variance", "0.003"},
{"Information Ratio", "1.641"},
{"Information Ratio", "1.64"},
{"Tracking Error", "0.18"},
{"Treynor Ratio", "22.101"},
{"Treynor Ratio", "22.061"},
{"Total Fees", "$7.40"},
{"Fitness Score", "0.021"},
{"Kelly Criterion Estimate", "0"},
{"Kelly Criterion Probability Value", "0"},
{"Sortino Ratio", "79228162514264337593543950335"},
{"Return Over Maximum Drawdown", "17.255"},
{"Return Over Maximum Drawdown", "17.142"},
{"Portfolio Turnover", "0.021"},
{"Total Insights Generated", "0"},
{"Total Insights Closed", "0"},
@@ -231,7 +231,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Mean Population Magnitude", "0%"},
{"Rolling Averaged Population Direction", "0%"},
{"Rolling Averaged Population Magnitude", "0%"},
{"OrderListHash", "1118389718"}
{"OrderListHash", "-991138464"}
};
}
}

View File

@@ -26,11 +26,13 @@ namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// This regression algorithm tests Out of The Money (OTM) future option expiry for short calls.
/// We expect 1 order from the algorithm, which are:
/// We expect 2 orders from the algorithm, which are:
///
/// * Initial entry, sell ES Call Option (expiring OTM)
/// - Profit the option premium, since the option was not assigned.
///
/// * Liquidation of ES call OTM contract on the last trade date
///
/// Additionally, we test delistings for future options and assert that our
/// portfolio holdings reflect the orders the algorithm has submitted.
/// </summary>
@@ -212,7 +214,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Mean Population Magnitude", "0%"},
{"Rolling Averaged Population Direction", "0%"},
{"Rolling Averaged Population Magnitude", "0%"},
{"OrderListHash", "1364902860"}
{"OrderListHash", "1847291350"}
};
}
}

View File

@@ -191,29 +191,29 @@ namespace QuantConnect.Algorithm.CSharp
{
{"Total Trades", "3"},
{"Average Win", "10.18%"},
{"Average Loss", "-8.02%"},
{"Compounding Annual Return", "2.773%"},
{"Average Loss", "-8.05%"},
{"Compounding Annual Return", "2.721%"},
{"Drawdown", "0.500%"},
{"Expectancy", "0.135"},
{"Net Profit", "1.343%"},
{"Sharpe Ratio", "0.939"},
{"Probabilistic Sharpe Ratio", "46.842%"},
{"Expectancy", "0.133"},
{"Net Profit", "1.318%"},
{"Sharpe Ratio", "0.934"},
{"Probabilistic Sharpe Ratio", "46.618%"},
{"Loss Rate", "50%"},
{"Win Rate", "50%"},
{"Profit-Loss Ratio", "1.27"},
{"Alpha", "0.023"},
{"Beta", "0.002"},
{"Annual Standard Deviation", "0.025"},
{"Annual Standard Deviation", "0.024"},
{"Annual Variance", "0.001"},
{"Information Ratio", "1.45"},
{"Information Ratio", "1.448"},
{"Tracking Error", "0.173"},
{"Treynor Ratio", "14.62"},
{"Treynor Ratio", "14.482"},
{"Total Fees", "$7.40"},
{"Fitness Score", "0.021"},
{"Kelly Criterion Estimate", "0"},
{"Kelly Criterion Probability Value", "0"},
{"Sortino Ratio", "79228162514264337593543950335"},
{"Return Over Maximum Drawdown", "5.815"},
{"Return Over Maximum Drawdown", "5.706"},
{"Portfolio Turnover", "0.022"},
{"Total Insights Generated", "0"},
{"Total Insights Closed", "0"},
@@ -228,7 +228,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Mean Population Magnitude", "0%"},
{"Rolling Averaged Population Direction", "0%"},
{"Rolling Averaged Population Magnitude", "0%"},
{"OrderListHash", "980293281"}
{"OrderListHash", "777632049"}
};
}
}

View File

@@ -26,11 +26,13 @@ namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// This regression algorithm tests Out of The Money (OTM) future option expiry for short puts.
/// We expect 1 order from the algorithm, which are:
/// We expect 2 order from the algorithm, which are:
///
/// * Initial entry, sell ES Put Option (expiring OTM)
/// - Profit the option premium, since the option was not assigned.
///
/// * Liquidation of ES put OTM contract on the last trade date
///
/// Additionally, we test delistings for future options and assert that our
/// portfolio holdings reflect the orders the algorithm has submitted.
/// </summary>
@@ -211,7 +213,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Mean Population Magnitude", "0%"},
{"Rolling Averaged Population Direction", "0%"},
{"Rolling Averaged Population Magnitude", "0%"},
{"OrderListHash", "-418839052"}
{"OrderListHash", "1003680014"}
};
}
}

View File

@@ -0,0 +1,202 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using QuantConnect.Data;
using QuantConnect.Interfaces;
using QuantConnect.Orders;
using QuantConnect.Securities;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Tests delistings for Futures and Futures Options to ensure that they are delisted at the expected times.
/// </summary>
public class FuturesAndFuturesOptionsExpiryTimeAndLiquidationRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private bool _invested;
private int _liquidated;
private int _delistingsReceived;
private Symbol _esFuture;
private Symbol _esFutureOption;
private readonly DateTime _expectedExpiryWarningTime = new DateTime(2020, 6, 19);
private readonly DateTime _expectedExpiryDelistingTime = new DateTime(2020, 6, 20);
private readonly DateTime _expectedLiquidationTime = new DateTime(2020, 6, 19, 9, 32, 0);
public override void Initialize()
{
SetStartDate(2020, 1, 5);
SetEndDate(2020, 12, 1);
SetCash(100000);
// To ensure that the expiry liquidations are ran for the Futures and FOPs, we
// add AAPL to pump a data point through on liquidation date so that the liquidation goes through
// at AAPL market open. See issue for more details: https://github.com/QuantConnect/Lean/issues/4872
AddEquity("AAPL", Resolution.Daily);
var es = QuantConnect.Symbol.CreateFuture(
Futures.Indices.SP500EMini,
Market.CME,
new DateTime(2020, 6, 19));
var esOption = QuantConnect.Symbol.CreateOption(
es,
Market.CME,
OptionStyle.American,
OptionRight.Put,
3400m,
new DateTime(2020, 6, 19));
_esFuture = AddFutureContract(es, Resolution.Minute).Symbol;
_esFutureOption = AddFutureOptionContract(esOption, Resolution.Minute).Symbol;
}
public override void OnData(Slice data)
{
foreach (var delisting in data.Delistings.Values)
{
// Two warnings and two delisted events should be received for a grand total of 4 events.
_delistingsReceived++;
if (delisting.Type == DelistingType.Warning &&
delisting.Time != _expectedExpiryWarningTime)
{
throw new Exception($"Expiry warning with time {delisting.Time} but is expected to be {_expectedExpiryWarningTime}");
}
if (delisting.Type == DelistingType.Warning && delisting.Time != Time.Date)
{
throw new Exception($"Delisting warning received at an unexpected date: {Time} - expected {delisting.Time}");
}
if (delisting.Type == DelistingType.Delisted &&
delisting.Time != _expectedExpiryDelistingTime)
{
throw new Exception($"Delisting occurred at unexpected time: {delisting.Time} - expected: {_expectedExpiryDelistingTime}");
}
if (delisting.Type == DelistingType.Delisted &&
delisting.Time != Time.Date)
{
throw new Exception($"Delisting notice received at an unexpected date: {Time} - expected {delisting.Time}");
}
}
if (!_invested &&
(data.Bars.ContainsKey(_esFuture) || data.QuoteBars.ContainsKey(_esFuture)) &&
(data.Bars.ContainsKey(_esFutureOption) || data.QuoteBars.ContainsKey(_esFutureOption)))
{
_invested = true;
MarketOrder(_esFuture, 1);
MarketOrder(_esFutureOption, 1);
}
}
public override void OnOrderEvent(OrderEvent orderEvent)
{
if (orderEvent.Direction != OrderDirection.Sell || orderEvent.Status != OrderStatus.Filled)
{
return;
}
// * Future Liquidation
// * Future Option Exercise
// * Underlying Future Liquidation
_liquidated++;
if (orderEvent.Symbol.SecurityType == SecurityType.FutureOption && _expectedLiquidationTime != Time)
{
throw new Exception($"Expected to liquidate option {orderEvent.Symbol} at {_expectedLiquidationTime}, instead liquidated at {Time}");
}
if (orderEvent.Symbol.SecurityType == SecurityType.Future && _expectedLiquidationTime.AddMinutes(-1) != Time && _expectedLiquidationTime != Time)
{
throw new Exception($"Expected to liquidate future {orderEvent.Symbol} at {_expectedLiquidationTime} (+1 minute), instead liquidated at {Time}");
}
}
public override void OnEndOfAlgorithm()
{
if (!_invested)
{
throw new Exception("Never invested in ES futures and FOPs");
}
if (_delistingsReceived != 4)
{
throw new Exception($"Expected 4 delisting events received, found: {_delistingsReceived}");
}
if (_liquidated != 3)
{
throw new Exception($"Expected 3 liquidation events, found {_liquidated}");
}
}
/// <summary>
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
/// </summary>
public bool CanRunLocally { get; } = true;
/// <summary>
/// This is used by the regression test system to indicate which languages this algorithm is written in.
/// </summary>
public Language[] Languages { get; } = { Language.CSharp, Language.Python };
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
/// </summary>
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Trades", "4"},
{"Average Win", "0.13%"},
{"Average Loss", "-11.33%"},
{"Compounding Annual Return", "-2.634%"},
{"Drawdown", "2.400%"},
{"Expectancy", "-0.494"},
{"Net Profit", "-2.399%"},
{"Sharpe Ratio", "-0.933"},
{"Probabilistic Sharpe Ratio", "0.003%"},
{"Loss Rate", "50%"},
{"Win Rate", "50%"},
{"Profit-Loss Ratio", "0.01"},
{"Alpha", "-0.017"},
{"Beta", "-0.001"},
{"Annual Standard Deviation", "0.018"},
{"Annual Variance", "0"},
{"Information Ratio", "0.886"},
{"Tracking Error", "0.127"},
{"Treynor Ratio", "30.534"},
{"Total Fees", "$9.25"},
{"Fitness Score", "0.007"},
{"Kelly Criterion Estimate", "0"},
{"Kelly Criterion Probability Value", "0"},
{"Sortino Ratio", "-0.177"},
{"Return Over Maximum Drawdown", "-1.098"},
{"Portfolio Turnover", "0.018"},
{"Total Insights Generated", "0"},
{"Total Insights Closed", "0"},
{"Total Insights Analysis Completed", "0"},
{"Long Insight Count", "0"},
{"Short Insight Count", "0"},
{"Long/Short Ratio", "100%"},
{"Estimated Monthly Alpha Value", "$0"},
{"Total Accumulated Estimated Alpha Value", "$0"},
{"Mean Population Estimated Insight Value", "$0"},
{"Mean Population Direction", "0%"},
{"Mean Population Magnitude", "0%"},
{"Rolling Averaged Population Direction", "0%"},
{"Rolling Averaged Population Magnitude", "0%"},
{"OrderListHash", "542517089"}
};
}
}

View File

@@ -142,12 +142,14 @@
<Link>Properties\SharedAssemblyInfo.cs</Link>
</Compile>
<Compile Include="AddAlphaModelAlgorithm.cs" />
<Compile Include="FillForwardEnumeratorOutOfOrderBarRegressionAlgorithm.cs" />
<Compile Include="CustomBuyingPowerModelAlgorithm.cs" />
<Compile Include="AddFutureOptionContractDataStreamingRegressionAlgorithm.cs" />
<Compile Include="AddFutureOptionSingleOptionChainSelectedInUniverseFilterRegressionAlgorithm.cs" />
<Compile Include="AddOptionContractExpiresRegressionAlgorithm.cs" />
<Compile Include="AltData\QuiverWallStreetBetsDataAlgorithm.cs" />
<Compile Include="FutureOptionCallITMGreeksExpiryRegressionAlgorithm.cs" />
<Compile Include="FuturesAndFuturesOptionsExpiryTimeAndLiquidationRegressionAlgorithm.cs" />
<Compile Include="OnOrderEventExceptionRegression.cs" />
<Compile Include="FutureOptionCallITMExpiryRegressionAlgorithm.cs" />
<Compile Include="FutureOptionCallOTMExpiryRegressionAlgorithm.cs" />

View File

@@ -35,7 +35,11 @@ class CustomBenchmarkAlgorithm(QCAlgorithm):
self.SetCash(100000) #Set Strategy Cash
# Find more symbols here: http://quantconnect.com/data
self.AddEquity("SPY", Resolution.Second)
# Disabling the benchmark / setting to a fixed value
# self.SetBenchmark(lambda x: 0)
# Set the benchmark to AAPL US Equity
self.SetBenchmark(Symbol.Create("AAPL", SecurityType.Equity, Market.USA))
def OnData(self, data):
@@ -46,4 +50,4 @@ class CustomBenchmarkAlgorithm(QCAlgorithm):
tupleResult = SymbolCache.TryGetSymbol("AAPL", None)
if tupleResult[0]:
raise Exception("Benchmark Symbol is not expected to be added to the Symbol cache")
raise Exception("Benchmark Symbol is not expected to be added to the Symbol cache")

View File

@@ -107,7 +107,7 @@ class FutureOptionCallITMExpiryRegressionAlgorithm(QCAlgorithm):
# at 9:30:00 Eastern Time. For unknown reasons, the delisting happens two minutes after the
# market open.
# Read more about the issue affecting this test here: https://github.com/QuantConnect/Lean/issues/4980
expectedLiquidationTimeUtc = datetime(2020, 6, 22, 13, 32, 0)
expectedLiquidationTimeUtc = datetime(2020, 6, 19, 13, 32, 0)
if orderEvent.Direction == OrderDirection.Sell and future.Holdings.Quantity != 0:
# We expect the contract to have been liquidated immediately

View File

@@ -28,11 +28,13 @@ from QuantConnect import Market
### <summary>
### This regression algorithm tests Out of The Money (OTM) future option expiry for calls.
### We expect 1 order from the algorithm, which are:
### We expect 2 orders from the algorithm, which are:
###
### * Initial entry, buy ES Call Option (expiring OTM)
### - contract expires worthless, not exercised, so never opened a position in the underlying
###
### * Liquidation of worthless ES call option (expiring OTM)
###
### Additionally, we test delistings for future options and assert that our
### portfolio holdings reflect the orders the algorithm has submitted.
### </summary>

View File

@@ -106,7 +106,7 @@ class FutureOptionPutITMExpiryRegressionAlgorithm(QCAlgorithm):
# at 9:30:00 Eastern Time. For unknown reasons, the delisting happens two minutes after the
# market open.
# Read more about the issue affecting this test here: https://github.com/QuantConnect/Lean/issues/4980
expectedLiquidationTimeUtc = datetime(2020, 6, 22, 13, 32, 0)
expectedLiquidationTimeUtc = datetime(2020, 6, 19, 13, 32, 0)
if orderEvent.Direction == OrderDirection.Buy and future.Holdings.Quantity != 0:
# We expect the contract to have been liquidated immediately

View File

@@ -28,10 +28,12 @@ from QuantConnect import Market
### <summary>
### This regression algorithm tests Out of The Money (OTM) future option expiry for puts.
### We expect 1 order from the algorithm, which are:
### We expect 2 orders from the algorithm, which are:
###
### * Initial entry, buy ES Put Option (expiring OTM)
### - contract expires worthless, not exercised, so never opened a position in the underlying
###
### * Liquidation of worthless ES Put OTM contract
###
### Additionally, we test delistings for future options and assert that our
### portfolio holdings reflect the orders the algorithm has submitted.

View File

@@ -28,11 +28,13 @@ from QuantConnect import Market
### <summary>
### This regression algorithm tests Out of The Money (OTM) future option expiry for short calls.
### We expect 1 order from the algorithm, which are:
### We expect 2 orders from the algorithm, which are:
###
### * Initial entry, sell ES Call Option (expiring OTM)
### - Profit the option premium, since the option was not assigned.
###
### * Liquidation of ES call OTM contract on the last trade date
###
### Additionally, we test delistings for future options and assert that our
### portfolio holdings reflect the orders the algorithm has submitted.
### </summary>

View File

@@ -28,11 +28,13 @@ from QuantConnect import Market
### <summary>
### This regression algorithm tests Out of The Money (OTM) future option expiry for short puts.
### We expect 1 order from the algorithm, which are:
### We expect 2 orders from the algorithm, which are:
###
### * Initial entry, sell ES Put Option (expiring OTM)
### - Profit the option premium, since the option was not assigned.
###
### * Liquidation of ES put OTM contract on the last trade date
###
### Additionally, we test delistings for future options and assert that our
### portfolio holdings reflect the orders the algorithm has submitted.
### </summary>

View File

@@ -0,0 +1,100 @@
from datetime import datetime, timedelta
from QuantConnect.Algorithm import *
from QuantConnect.Data import *
from QuantConnect.Data.Market import *
from QuantConnect.Orders import *
from QuantConnect import *
### <summary>
### Tests delistings for Futures and Futures Options to ensure that they are delisted at the expected times.
### </summary>
class FuturesAndFuturesOptionsExpiryTimeAndLiquidationRegressionAlgorithm(QCAlgorithm):
def Initialize(self):
self.invested = False
self.liquidated = 0
self.delistingsReceived = 0
self.expectedExpiryWarningTime = datetime(2020, 6, 19)
self.expectedExpiryDelistingTime = datetime(2020, 6, 20)
self.expectedLiquidationTime = datetime(2020, 6, 19, 9, 32, 0)
self.SetStartDate(2020, 1, 5)
self.SetEndDate(2020, 12, 1)
self.SetCash(100000)
# To ensure that the expiry liquidations are ran for the Futures and FOPs, we
# add AAPL to pump a data point through on liquidation date so that the liquidation goes through
# at AAPL market open. See issue for more details: https://github.com/QuantConnect/Lean/issues/4872
self.AddEquity("AAPL", Resolution.Daily)
es = Symbol.CreateFuture(
"ES",
Market.CME,
datetime(2020, 6, 19)
)
esOption = Symbol.CreateOption(
es,
Market.CME,
OptionStyle.American,
OptionRight.Put,
3400.0,
datetime(2020, 6, 19)
)
self.esFuture = self.AddFutureContract(es, Resolution.Minute).Symbol
self.esFutureOption = self.AddFutureOptionContract(esOption, Resolution.Minute).Symbol
def OnData(self, data: Slice):
for delisting in data.Delistings.Values:
self.delistingsReceived += 1
if delisting.Type == DelistingType.Warning and delisting.Time != self.expectedExpiryWarningTime:
raise AssertionError(f"Expiry warning with time {delisting.Time} but is expected to be {self.expectedExpiryWarningTime}")
if delisting.Type == DelistingType.Warning and delisting.Time != datetime(self.Time.year, self.Time.month, self.Time.day):
raise AssertionError(f"Delisting warning received at an unexpected date: {self.Time} - expected {delisting.Time}")
if delisting.Type == DelistingType.Delisted and delisting.Time != self.expectedExpiryDelistingTime:
raise AssertionError(f"Delisting occurred at unexpected time: {delisting.Time} - expected: {self.expectedExpiryDelistingTime}")
if delisting.Type == DelistingType.Delisted and delisting.Time != datetime(self.Time.year, self.Time.month, self.Time.day):
raise AssertionError(f"Delisting notice received at an unexpected date: {self.Time} - expected {delisting.Time}")
if not self.invested and \
(self.esFuture in data.Bars or self.esFuture in data.QuoteBars) and \
(self.esFutureOption in data.Bars or self.esFutureOption in data.QuoteBars):
self.invested = True
self.MarketOrder(self.esFuture, 1)
self.MarketOrder(self.esFutureOption, 1)
def OnOrderEvent(self, orderEvent: OrderEvent):
if orderEvent.Direction != OrderDirection.Sell or orderEvent.Status != OrderStatus.Filled:
return
# * Future Liquidation
# * Future Option Exercise
# * Underlying Future Liquidation
self.liquidated += 1
if orderEvent.Symbol.SecurityType == SecurityType.FutureOption and self.expectedLiquidationTime != self.Time:
raise AssertionError(f"Expected to liquidate option {orderEvent.Symbol} at {self.expectedLiquidationTime}, instead liquidated at {self.Time}")
if orderEvent.Symbol.SecurityType == SecurityType.Future and \
(self.expectedLiquidationTime - timedelta(minutes=1)) != self.Time and \
self.expectedLiquidationTime != self.Time:
raise AssertionError(f"Expected to liquidate future {orderEvent.Symbol} at {self.expectedLiquidationTime} (+1 minute), instead liquidated at {self.Time}")
def OnEndOfAlgorithm(self):
if not self.invested:
raise AssertionError("Never invested in ES futures and FOPs")
if self.delistingsReceived != 4:
raise AssertionError(f"Expected 4 delisting events received, found: {self.delistingsReceived}")
if self.liquidated != 3:
raise AssertionError(f"Expected 3 liquidation events, found {self.liquidated}")

View File

@@ -109,6 +109,7 @@
<Content Include="FutureOptionShortCallOTMExpiryRegressionAlgorithm.py" />
<Content Include="FutureOptionShortPutITMExpiryRegressionAlgorithm.py" />
<Content Include="FutureOptionShortPutOTMExpiryRegressionAlgorithm.py" />
<Content Include="FuturesAndFuturesOptionsExpiryTimeAndLiquidationRegressionAlgorithm.py" />
<Content Include="KerasNeuralNetworkAlgorithm.py" />
<Content Include="CustomDataUsingMapFileRegressionAlgorithm.py" />
<Content Include="LiquidETFUniverseFrameworkAlgorithm.py" />

View File

@@ -41,12 +41,12 @@ Before we enable python support, follow the [installation instructions](https://
2. Install [pandas=0.25.3](https://pandas.pydata.org/) and its [dependencies](https://pandas.pydata.org/pandas-docs/stable/install.html#dependencies).
3. Install [wrapt=1.11.2](https://pypi.org/project/wrapt/) module.
*Note:* If you encounter the "System.DllNotFoundException: python3.6m" runtime error when running Python algorithms on macOS:
*Note:* If you encounter the "System.DllNotFoundException: python3.6m" runtime error when running Python algorithms, or generating reports, on macOS:
1. Find `libpython3.6m.dylib` in your Python installation folder. If you installed Python with Anaconda, it may be found at
```
/Users/{your_user_name}/anaconda3/lib/libpython3.6m.dylib
```
2. Open `Lean/Launcher/bin/Debug/Python.Runtime.dll.config`, add the following text under `<configuration> ... </configuration>` and save:
2. Open `Lean/Common/Python/Python.Runtime.dll.config`, add the following text under `<configuration> ... </configuration>` and save:
```
<dllmap dll="python3.6m" target="{the path in step 1 including libpython3.6m.dylib}" os="osx"/>
```
@@ -81,7 +81,7 @@ conda install -y wrapt=1.11.2
conda create -n qc_environment python=3.6.8 cython=0.29.11 pandas=0.25.3 wrapt=1.11.2
```
2. Open `Lean/Launcher/bin/Debug/Python.Runtime.dll.config`, add the following text under `<configuration> ... </configuration>` and save:
2. Open `Lean/Common/Python/Python.Runtime.dll.config`, add the following text under `<configuration> ... </configuration>` and save:
```
<dllmap dll="python3.6m" target="{the path in step 1 including libpython3.6m.so}" os="linux"/>
```

View File

@@ -14,6 +14,7 @@
*/
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Algorithm.Framework.Alphas;
using QuantConnect.Algorithm.Framework.Alphas.Analysis;
@@ -31,6 +32,7 @@ namespace QuantConnect.Algorithm
{
private readonly ISecurityValuesProvider _securityValuesProvider;
private bool _isEmitWarmupInsightWarningSent;
private bool _isEmitDelistedInsightWarningSent;
/// <summary>
/// Enables additional logging of framework models including:
@@ -147,7 +149,8 @@ namespace QuantConnect.Algorithm
// only fire insights generated event if we actually have insights
if (insights.Length != 0)
{
OnInsightsGenerated(insights.Select(InitializeInsightFields));
insights = InitializeInsights(insights);
OnInsightsGenerated(insights);
}
ProcessInsights(insights);
@@ -226,7 +229,7 @@ namespace QuantConnect.Algorithm
Log($"{Time}: RISK ADJUSTED TARGETS: {string.Join(" | ", riskAdjustedTargets.Select(t => t.ToString()).OrderBy(t => t))}");
}
}
Execution.Execute(this, riskAdjustedTargets);
}
@@ -382,7 +385,8 @@ namespace QuantConnect.Algorithm
return;
}
OnInsightsGenerated(insights.Select(InitializeInsightFields));
insights = InitializeInsights(insights);
OnInsightsGenerated(insights);
ProcessInsights(insights);
}
@@ -394,7 +398,52 @@ namespace QuantConnect.Algorithm
/// <param name="insight">The insight to be emitted</param>
public void EmitInsights(Insight insight)
{
EmitInsights(new []{insight});
EmitInsights(new[] { insight });
}
/// <summary>
/// Helper method used to validate insights and prepare them to be emitted
/// </summary>
/// <param name="insights">insights preparing to be emitted</param>
/// <returns>Validated insights</returns>
private Insight[] InitializeInsights(Insight[] insights)
{
List<Insight> validInsights = null;
for (var i = 0; i < insights.Length; i++)
{
if (Securities[insights[i].Symbol].IsDelisted)
{
if (!_isEmitDelistedInsightWarningSent)
{
Error($"QCAlgorithm.EmitInsights(): Warning: cannot emit insights for delisted securities, these will be discarded");
_isEmitDelistedInsightWarningSent = true;
}
// If this is our first invalid insight, create the list and fill it with previous values
if (validInsights == null)
{
validInsights = new List<Insight>() {};
for (var j = 0; j < i; j++)
{
validInsights.Add(insights[j]);
}
}
}
else
{
// Initialize the insight fields
insights[i] = InitializeInsightFields(insights[i]);
// If we already had an invalid insight, this will have been initialized storing the valid ones.
if (validInsights != null)
{
validInsights.Add(insights[i]);
}
}
}
return validInsights == null ? insights : validInsights.ToArray();
}
/// <summary>

View File

@@ -126,6 +126,28 @@ namespace QuantConnect.Algorithm
return averageDirectionalIndex;
}
/// <summary>
/// Creates a new Awesome Oscillator from the specified periods.
/// </summary>
/// <param name="symbol">The symbol whose Awesome Oscillator we seek</param>
/// <param name="resolution">The resolution.</param>
/// <param name="fastPeriod">The period of the fast moving average associated with the AO</param>
/// <param name="slowPeriod">The period of the slow moving average associated with the AO</param>
/// <param name="type">The type of moving average used when computing the fast and slow term. Defaults to simple moving average.</param>
public AwesomeOscillator AO(Symbol symbol, int slowPeriod, int fastPeriod, MovingAverageType type, Resolution? resolution = null, Func<IBaseData, IBaseDataBar> selector = null)
{
var name = CreateIndicatorName(symbol, $"AO({fastPeriod},{slowPeriod},{type})", resolution);
var awesomeOscillator = new AwesomeOscillator(name, fastPeriod, slowPeriod, type);
RegisterIndicator(symbol, awesomeOscillator, resolution, selector);
if (EnableAutomaticIndicatorWarmUp)
{
WarmUpIndicator(symbol, awesomeOscillator, resolution);
}
return awesomeOscillator;
}
/// <summary>
/// Creates a new AverageDirectionalMovementIndexRating indicator.
/// </summary>
@@ -354,6 +376,28 @@ namespace QuantConnect.Algorithm
return commodityChannelIndex;
}
/// <summary>
/// Creates a new ChaikinMoneyFlow indicator.
/// </summary>
/// <param name="symbol">The symbol whose CMF we want</param>
/// <param name="period">The period over which to compute the CMF</param>
/// <param name="resolution">The resolution</param>
/// <param name="selector">Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar</param>
/// <returns>The ChaikinMoneyFlow indicator for the requested symbol over the specified period</returns>
public ChaikinMoneyFlow CMF(Symbol symbol, int period, Resolution? resolution = null, Func<IBaseData, TradeBar> selector = null)
{
var name = CreateIndicatorName(symbol, $"CMF({period})", resolution);
var chaikinMoneyFlow = new ChaikinMoneyFlow(name, period);
RegisterIndicator(symbol, chaikinMoneyFlow, resolution, selector);
if (EnableAutomaticIndicatorWarmUp)
{
WarmUpIndicator(symbol, chaikinMoneyFlow, resolution);
}
return chaikinMoneyFlow;
}
/// <summary>
/// Creates a new ChandeMomentumOscillator indicator.
@@ -376,7 +420,31 @@ namespace QuantConnect.Algorithm
return chandeMomentumOscillator;
}
///<summary>
/// Creates a new DeMarker Indicator (DEM), an oscillator-type indicator measuring changes in terms of an asset's
/// High and Low tradebar values.
///</summary>
/// <param name="symbol">The symbol whose DEM we seek.</param>
/// <param name="period">The period of the moving average implemented</param>
/// <param name="movingAverageType">Specifies the type of moving average to be used</param>
/// <param name="resolution">The resolution.</param>
/// <param name="selector">Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar</param>
/// <returns>The DeMarker indicator for the requested symbol.</returns>
public DeMarkerIndicator DEM(Symbol symbol, int period, MovingAverageType type, Resolution? resolution = null, Func<IBaseData, TradeBar> selector = null)
{
var name = CreateIndicatorName(symbol, $"DEM({period},{type})", resolution);
var deMarkerIndicator = new DeMarkerIndicator(name, period, type);
RegisterIndicator(symbol, deMarkerIndicator, resolution, selector);
if (EnableAutomaticIndicatorWarmUp)
{
WarmUpIndicator(symbol, deMarkerIndicator, resolution);
}
return deMarkerIndicator;
}
/// <summary>
/// Creates a new Donchian Channel indicator which will compute the Upper Band and Lower Band.
/// The indicator will be automatically updated on the given resolution.
@@ -2543,4 +2611,4 @@ namespace QuantConnect.Algorithm
return new BaseDataConsolidator(calendar);
}
}
}
}

View File

@@ -2286,17 +2286,15 @@ namespace QuantConnect.Algorithm
/// </summary>
/// <param name="insights">The collection of insights generaed at the current time step</param>
/// <param name="clone">Will emit a clone of the generated insights</param>
private void OnInsightsGenerated(IEnumerable<Insight> insights, bool clone = true)
private void OnInsightsGenerated(Insight[] insights, bool clone = true)
{
var insightCollection = insights.ToArray();
// debug printing of generated insights
if (DebugMode)
{
Log($"{Time}: ALPHA: {string.Join(" | ", insightCollection.Select(i => i.ToString()).OrderBy(i => i))}");
Log($"{Time}: ALPHA: {string.Join(" | ", insights.Select(i => i.ToString()).OrderBy(i => i))}");
}
InsightsGenerated?.Invoke(this, new GeneratedInsightsCollection(UtcTime, insightCollection, clone: clone));
InsightsGenerated?.Invoke(this, new GeneratedInsightsCollection(UtcTime, insights, clone: clone));
}
/// <summary>

View File

@@ -101,21 +101,21 @@ while not sys.gettrace():
count = 1
while count <= 10:
try:
pydevd_pycharm.settrace('localhost', port=5678, stdoutToServer=True, stderrToServer=True, suspend=False)
pydevd_pycharm.settrace('localhost', port=6000, stdoutToServer=True, stderrToServer=True, suspend=False)
print('SUCCESS: Connected to local program')
break
except ConnectionRefusedError:
pass
try:
pydevd_pycharm.settrace('host.docker.internal', port=5678, stdoutToServer=True, stderrToServer=True, suspend=False)
pydevd_pycharm.settrace('host.docker.internal', port=6000, stdoutToServer=True, stderrToServer=True, suspend=False)
print('SUCCESS: Connected to docker container')
break
except ConnectionRefusedError:
pass
print('\n')
print('Failed: Ensure your PyCharm Debugger is actively waiting for a connection at port 5678!')
print('Failed: Ensure your PyCharm Debugger is actively waiting for a connection at port 6000!')
print('Try ' + count.__str__() + ' out of 10')
print('\n')
count += 1

View File

@@ -20,6 +20,7 @@ using System.Net;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using QuantConnect.Interfaces;
using QuantConnect.Logging;
using QuantConnect.Orders;
using RestSharp;
using RestSharp.Extensions;
@@ -383,9 +384,15 @@ namespace QuantConnect.Api
backtestName
}), ParameterType.RequestBody);
Backtest result;
BacktestResponseWrapper result;
ApiConnection.TryRequest(request, out result);
return result;
// Use API Response values for Backtest Values
result.Backtest.Success = result.Success;
result.Backtest.Errors = result.Errors;
// Return only the backtest object
return result.Backtest;
}
/// <summary>
@@ -393,9 +400,10 @@ namespace QuantConnect.Api
/// </summary>
/// <param name="projectId">Project id to read</param>
/// <param name="backtestId">Specific backtest id to read</param>
/// <param name="getCharts">True will return backtest charts</param>
/// <returns><see cref="Backtest"/></returns>
public Backtest ReadBacktest(int projectId, string backtestId)
public Backtest ReadBacktest(int projectId, string backtestId, bool getCharts = true)
{
var request = new RestRequest("backtests/read", Method.POST)
{
@@ -408,9 +416,63 @@ namespace QuantConnect.Api
backtestId
}), ParameterType.RequestBody);
Backtest result;
BacktestResponseWrapper result;
ApiConnection.TryRequest(request, out result);
return result;
if (!result.Success)
{
// place an empty place holder so we can return any errors back to the user and not just null
result.Backtest = new Backtest { BacktestId = backtestId };
}
// Go fetch the charts if the backtest is completed and success
else if (getCharts && result.Backtest.Completed)
{
// For storing our collected charts
var updatedCharts = new Dictionary<string, Chart>();
// Create backtest requests for each chart that is empty
foreach (var chart in result.Backtest.Charts)
{
if (!chart.Value.Series.IsNullOrEmpty())
{
continue;
}
var chartRequest = new RestRequest("backtests/read", Method.POST)
{
RequestFormat = DataFormat.Json
};
chartRequest.AddParameter("application/json", JsonConvert.SerializeObject(new
{
projectId,
backtestId,
chart = chart.Key.Replace(' ', '+')
}), ParameterType.RequestBody);
BacktestResponseWrapper chartResponse;
ApiConnection.TryRequest(chartRequest, out chartResponse);
// Add this chart to our updated collection
if (chartResponse.Success)
{
updatedCharts.Add(chart.Key, chartResponse.Backtest.Charts[chart.Key]);
}
}
// Update our result
foreach(var updatedChart in updatedCharts)
{
result.Backtest.Charts[updatedChart.Key] = updatedChart.Value;
}
}
// Use API Response values for Backtest Values
result.Backtest.Success = result.Success;
result.Backtest.Errors = result.Errors;
// Return only the backtest object
return result.Backtest;
}
/// <summary>
@@ -761,8 +823,29 @@ namespace QuantConnect.Api
var uri = new Uri(link.DataLink);
var client = new RestClient(uri.Scheme + "://" + uri.Host);
var request = new RestRequest(uri.PathAndQuery, Method.GET);
client.DownloadData(request).SaveAs(path);
// MAke a request for the data at the link
var response = client.Execute(request);
// If the response is JSON it doesn't contain any data, try and extract the message and write it
if (response.ContentType.ToLowerInvariant() == "application/json")
{
try
{
var contentObj = JObject.Parse(response.Content);
var message = contentObj["message"].Value<string>();
Log.Error($"Api.DownloadData(): Failed to download zip for {symbol} {resolution} data for date {date}, Api response: {message}");
}
catch
{
Log.Error($"Api.DownloadData(): Failed to download zip for {symbol} {resolution} data for date {date}. Api response could not be parsed.");
}
return false;
}
// Any other case save the content to given path
response.RawBytes.SaveAs(path);
return true;
}

View File

@@ -28,11 +28,6 @@ namespace QuantConnect.Api
/// </summary>
public class ApiConnection
{
/// <summary>
/// The current config api url
/// </summary>
public static string ApiUrl = Config.Get("cloud-api-url", "https://www.quantconnect.com/api/v2/");
/// <summary>
/// Authorized client to use for requests.
/// </summary>
@@ -51,7 +46,7 @@ namespace QuantConnect.Api
{
_token = token;
_userId = userId.ToStringInvariant();
Client = new RestClient(ApiUrl);
Client = new RestClient("https://www.quantconnect.com/api/v2/");
}
/// <summary>
@@ -121,6 +116,7 @@ namespace QuantConnect.Api
if (result == null || !result.Success)
{
Log.Debug($"ApiConnection.TryRequest(): Raw response: '{responseContent}'");
return false;
}
}

View File

@@ -45,7 +45,7 @@ namespace QuantConnect.Brokerages.Alpaca
return new Tick
{
Symbol = Symbol.Create(response.Symbol, SecurityType.Equity, Market.USA),
Symbol = _symbolMapper.GetLeanSymbol(response.Symbol, SecurityType.Equity, Market.USA),
BidPrice = response.BidPrice,
AskPrice = response.AskPrice,
Time = response.Time,
@@ -95,7 +95,7 @@ namespace QuantConnect.Brokerages.Alpaca
}
CheckRateLimiting();
var task = _alpacaTradingClient.PostOrderAsync(new NewOrderRequest(order.Symbol.Value, quantity, side, type, timeInForce)
var task = _alpacaTradingClient.PostOrderAsync(new NewOrderRequest(_symbolMapper.GetBrokerageSymbol(order.Symbol), quantity, side, type, timeInForce)
{
LimitPrice = limitPrice,
StopPrice = stopPrice
@@ -211,7 +211,7 @@ namespace QuantConnect.Brokerages.Alpaca
var task = _polygonDataClient.ListAggregatesAsync(
new AggregatesRequest(
symbol.Value,
_symbolMapper.GetBrokerageSymbol(symbol),
new AggregationPeriod(
1,
resolution == Resolution.Daily ? AggregationPeriodUnit.Day : AggregationPeriodUnit.Minute
@@ -296,7 +296,7 @@ namespace QuantConnect.Brokerages.Alpaca
var dateUtc = startTimeUtc.Date;
var date = startTimeUtc.ConvertFromUtc(requestedTimeZone).Date;
var task = _polygonDataClient.ListHistoricalTradesAsync(new HistoricalRequest(symbol.Value, date)
var task = _polygonDataClient.ListHistoricalTradesAsync(new HistoricalRequest(_symbolMapper.GetBrokerageSymbol(symbol), date)
{
Timestamp = previousTimestamp
});
@@ -396,7 +396,7 @@ namespace QuantConnect.Brokerages.Alpaca
var instrument = order.Symbol;
var id = order.OrderId.ToString();
qcOrder.Symbol = Symbol.Create(instrument, SecurityType.Equity, Market.USA);
qcOrder.Symbol = _symbolMapper.GetLeanSymbol(instrument, SecurityType.Equity, Market.USA);
if (order.SubmittedAt != null)
{
@@ -429,15 +429,12 @@ namespace QuantConnect.Brokerages.Alpaca
/// <summary>
/// Converts an Alpaca position into a LEAN holding.
/// </summary>
private static Holding ConvertHolding(IPosition position)
private Holding ConvertHolding(IPosition position)
{
const SecurityType securityType = SecurityType.Equity;
var symbol = Symbol.Create(position.Symbol, securityType, Market.USA);
return new Holding
{
Symbol = symbol,
Type = securityType,
Symbol = _symbolMapper.GetLeanSymbol(position.Symbol, SecurityType.Equity, Market.USA),
Type = SecurityType.Equity,
AveragePrice = position.AverageEntryPrice,
MarketPrice = position.AssetCurrentPrice,
MarketValue = position.MarketValue,

View File

@@ -18,6 +18,7 @@ using System.Collections.Generic;
using System.Linq;
using QuantConnect.Brokerages.Alpaca.Markets;
using QuantConnect.Data;
using QuantConnect.Interfaces;
using QuantConnect.Logging;
using QuantConnect.Orders;
using QuantConnect.Orders.Fees;
@@ -39,6 +40,7 @@ namespace QuantConnect.Brokerages.Alpaca
private readonly AlpacaTradingClient _alpacaTradingClient;
private readonly PolygonDataClient _polygonDataClient;
private readonly SockClient _sockClient;
private readonly ISymbolMapper _symbolMapper;
/// <summary>
/// This lock is used to sync 'PlaceOrder' and callback 'OnTradeUpdate'
@@ -65,10 +67,11 @@ namespace QuantConnect.Brokerages.Alpaca
/// </summary>
/// <param name="orderProvider">The order provider.</param>
/// <param name="securityProvider">The holdings provider.</param>
/// <param name="mapFileProvider">representing all the map files</param>
/// <param name="accountKeyId">The Alpaca api key id</param>
/// <param name="secretKey">The api secret key</param>
/// <param name="tradingMode">The Alpaca trading mode. paper/live</param>
public AlpacaBrokerage(IOrderProvider orderProvider, ISecurityProvider securityProvider, string accountKeyId, string secretKey, string tradingMode)
public AlpacaBrokerage(IOrderProvider orderProvider, ISecurityProvider securityProvider, IMapFileProvider mapFileProvider, string accountKeyId, string secretKey, string tradingMode)
: base("Alpaca Brokerage")
{
var httpScheme = "https://";
@@ -80,7 +83,7 @@ namespace QuantConnect.Brokerages.Alpaca
_orderProvider = orderProvider;
_securityProvider = securityProvider;
_symbolMapper = new AlpacaSymbolMapper(mapFileProvider);
_marketHours = MarketHoursDatabase.FromDataFolder();
// Alpaca trading client

View File

@@ -19,6 +19,7 @@ using QuantConnect.Configuration;
using QuantConnect.Interfaces;
using QuantConnect.Packets;
using QuantConnect.Securities;
using QuantConnect.Util;
namespace QuantConnect.Brokerages.Alpaca
{
@@ -92,7 +93,8 @@ namespace QuantConnect.Brokerages.Alpaca
return new AlpacaBrokerage(
algorithm.Transactions,
algorithm.Portfolio,
algorithm.Portfolio,
Composer.Instance.GetExportedValueByTypeName<IMapFileProvider>(Config.Get("map-file-provider", "QuantConnect.Data.Auxiliary.LocalDiskMapFileProvider")),
keyId,
secretKey,
tradingMode);

View File

@@ -0,0 +1,88 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using QuantConnect.Interfaces;
namespace QuantConnect.Brokerages.Alpaca
{
/// <summary>
/// Provides the mapping between Lean symbols and Alpaca symbols.
/// </summary>
public class AlpacaSymbolMapper : ISymbolMapper
{
private readonly IMapFileProvider _mapFileProvider;
/// <summary>
/// Constructs InteractiveBrokersSymbolMapper. Default parameters are used.
/// </summary>
public AlpacaSymbolMapper(IMapFileProvider mapFileProvider)
{
_mapFileProvider = mapFileProvider;
}
/// <summary>
/// Converts a Lean symbol instance to an InteractiveBrokers symbol
/// </summary>
/// <param name="symbol">A Lean symbol instance</param>
/// <returns>The InteractiveBrokers symbol</returns>
public string GetBrokerageSymbol(Symbol symbol)
{
if (string.IsNullOrWhiteSpace(symbol?.Value))
throw new ArgumentException("Invalid symbol: " + (symbol == null ? "null" : symbol.ToString()));
if (symbol.SecurityType != SecurityType.Equity)
throw new ArgumentException($"Invalid security type: {symbol.SecurityType}");
var mapFile = _mapFileProvider.Get(symbol.ID.Market).ResolveMapFile(symbol.ID.Symbol, symbol.ID.Date);
return mapFile.GetMappedSymbol(DateTime.UtcNow, symbol.Value);
}
/// <summary>
/// Converts an Alpaca symbol to a Lean symbol instance
/// </summary>
/// <param name="brokerageSymbol">The Alpaca symbol</param>
/// <param name="securityType">The security type</param>
/// <param name="market">The market</param>
/// <param name="expirationDate">Expiration date of the security(if applicable)</param>
/// <param name="strike">The strike of the security (if applicable)</param>
/// <param name="optionRight">The option right of the security (if applicable)</param>
/// <returns>A new Lean Symbol instance</returns>
public Symbol GetLeanSymbol(
string brokerageSymbol,
SecurityType securityType,
string market,
DateTime expirationDate = default(DateTime),
decimal strike = 0,
OptionRight optionRight = OptionRight.Call
)
{
if (string.IsNullOrWhiteSpace(brokerageSymbol))
throw new ArgumentException($"Invalid symbol: {brokerageSymbol}");
if (securityType != SecurityType.Equity)
throw new ArgumentException($"Invalid security type: {securityType}");
try
{
return Symbol.Create(brokerageSymbol, securityType, market);
}
catch (Exception)
{
throw new ArgumentException($"Invalid symbol: {brokerageSymbol}, security type: {securityType}, market: {market}.");
}
}
}
}

View File

@@ -28,6 +28,7 @@ using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using QuantConnect.Brokerages.Bitfinex.Messages;
using Order = QuantConnect.Orders.Order;
@@ -53,6 +54,9 @@ namespace QuantConnect.Brokerages.Bitfinex
private readonly object _clientOrderIdLocker = new object();
private long _nextClientOrderId;
// map Bitfinex currency to LEAN currency
private readonly Dictionary<string, string> _currencyMap;
/// <summary>
/// Locking object for the Ticks list in the data queue handler
/// </summary>
@@ -89,6 +93,15 @@ namespace QuantConnect.Brokerages.Bitfinex
_algorithm = algorithm;
_aggregator = aggregator;
// load currency map
using (var wc = new WebClient())
{
var json = wc.DownloadString("https://api-pub.bitfinex.com/v2/conf/pub:map:currency:sym");
var rows = JsonConvert.DeserializeObject<List<List<List<string>>>>(json)[0];
_currencyMap = rows
.ToDictionary(row => row[0], row => row[1].ToUpperInvariant());
}
WebSocket.Open += (sender, args) =>
{
SubscribeAuth();
@@ -384,7 +397,7 @@ namespace QuantConnect.Brokerages.Bitfinex
var fillQuantity = update.ExecAmount;
var direction = fillQuantity < 0 ? OrderDirection.Sell : OrderDirection.Buy;
var updTime = Time.UnixMillisecondTimeStampToDateTime(update.MtsCreate);
var orderFee = new OrderFee(new CashAmount(Math.Abs(update.Fee), update.FeeCurrency));
var orderFee = new OrderFee(new CashAmount(Math.Abs(update.Fee), GetLeanCurrency(update.FeeCurrency)));
var status = OrderStatus.Filled;
if (fillQuantity != order.Quantity)
@@ -440,6 +453,17 @@ namespace QuantConnect.Brokerages.Bitfinex
}
}
private string GetLeanCurrency(string brokerageCurrency)
{
string currency;
if (!_currencyMap.TryGetValue(brokerageCurrency.ToUpperInvariant(), out currency))
{
currency = brokerageCurrency.ToUpperInvariant();
}
return currency;
}
/// <summary>
/// Emit stream tick
/// </summary>

View File

@@ -280,7 +280,7 @@ namespace QuantConnect.Brokerages.Bitfinex
{
if (item.Balance > 0)
{
list.Add(new CashAmount(item.Balance, item.Currency.ToUpperInvariant()));
list.Add(new CashAmount(item.Balance, GetLeanCurrency(item.Currency)));
}
}

View File

@@ -76,6 +76,7 @@ namespace QuantConnect.Brokerages.InteractiveBrokers
// Notifies the thread reading information from Gateway/TWS whenever there are messages ready to be consumed
private readonly EReaderSignal _signal = new EReaderMonitorSignal();
private readonly ManualResetEvent _connectEvent = new ManualResetEvent(false);
private readonly ManualResetEvent _waitForNextValidId = new ManualResetEvent(false);
private readonly ManualResetEvent _accountHoldingsResetEvent = new ManualResetEvent(false);
private Exception _accountHoldingsLastException;
@@ -97,7 +98,7 @@ namespace QuantConnect.Brokerages.InteractiveBrokers
private readonly ConcurrentDictionary<string, ContractDetails> _contractDetails = new ConcurrentDictionary<string, ContractDetails>();
private readonly InteractiveBrokersSymbolMapper _symbolMapper = new InteractiveBrokersSymbolMapper();
private readonly InteractiveBrokersSymbolMapper _symbolMapper;
// Prioritized list of exchanges used to find right futures contract
private readonly Dictionary<string, string> _futuresExchanges = new Dictionary<string, string>
@@ -161,12 +162,14 @@ namespace QuantConnect.Brokerages.InteractiveBrokers
/// <param name="orderProvider">An instance of IOrderProvider used to fetch Order objects by brokerage ID</param>
/// <param name="securityProvider">The security provider used to give access to algorithm securities</param>
/// <param name="aggregator">consolidate ticks</param>
public InteractiveBrokersBrokerage(IAlgorithm algorithm, IOrderProvider orderProvider, ISecurityProvider securityProvider, IDataAggregator aggregator)
/// <param name="mapFileProvider">representing all the map files</param>
public InteractiveBrokersBrokerage(IAlgorithm algorithm, IOrderProvider orderProvider, ISecurityProvider securityProvider, IDataAggregator aggregator, IMapFileProvider mapFileProvider)
: this(
algorithm,
orderProvider,
securityProvider,
aggregator,
mapFileProvider,
Config.Get("ib-account"),
Config.Get("ib-host", "LOCALHOST"),
Config.GetInt("ib-port", 4001),
@@ -186,13 +189,16 @@ namespace QuantConnect.Brokerages.InteractiveBrokers
/// <param name="algorithm">The algorithm instance</param>
/// <param name="orderProvider">An instance of IOrderProvider used to fetch Order objects by brokerage ID</param>
/// <param name="securityProvider">The security provider used to give access to algorithm securities</param>
/// <param name="aggregator">consolidate ticks</param>
/// <param name="mapFileProvider">representing all the map files</param>
/// <param name="account">The account used to connect to IB</param>
public InteractiveBrokersBrokerage(IAlgorithm algorithm, IOrderProvider orderProvider, ISecurityProvider securityProvider, IDataAggregator aggregator, string account)
public InteractiveBrokersBrokerage(IAlgorithm algorithm, IOrderProvider orderProvider, ISecurityProvider securityProvider, IDataAggregator aggregator, IMapFileProvider mapFileProvider, string account)
: this(
algorithm,
orderProvider,
securityProvider,
aggregator,
mapFileProvider,
account,
Config.Get("ib-host", "LOCALHOST"),
Config.GetInt("ib-port", 4001),
@@ -213,6 +219,7 @@ namespace QuantConnect.Brokerages.InteractiveBrokers
/// <param name="orderProvider">An instance of IOrderProvider used to fetch Order objects by brokerage ID</param>
/// <param name="securityProvider">The security provider used to give access to algorithm securities</param>
/// <param name="aggregator">consolidate ticks</param>
/// <param name="mapFileProvider">representing all the map files</param>
/// <param name="account">The Interactive Brokers account name</param>
/// <param name="host">host name or IP address of the machine where TWS is running. Leave blank to connect to the local host.</param>
/// <param name="port">must match the port specified in TWS on the Configure&gt;API&gt;Socket Port field.</param>
@@ -227,6 +234,7 @@ namespace QuantConnect.Brokerages.InteractiveBrokers
IOrderProvider orderProvider,
ISecurityProvider securityProvider,
IDataAggregator aggregator,
IMapFileProvider mapFileProvider,
string account,
string host,
int port,
@@ -247,6 +255,8 @@ namespace QuantConnect.Brokerages.InteractiveBrokers
_port = port;
_agentDescription = agentDescription;
_symbolMapper = new InteractiveBrokersSymbolMapper(mapFileProvider);
_subscriptionManager = new EventBasedDataQueueHandlerSubscriptionManager();
_subscriptionManager.SubscribeImpl += (s, t) => Subscribe(s);
_subscriptionManager.UnsubscribeImpl += (s, t) => Unsubscribe(s);
@@ -296,11 +306,13 @@ namespace QuantConnect.Brokerages.InteractiveBrokers
_client.ConnectAck += (sender, e) =>
{
Log.Trace("InteractiveBrokersBrokerage.HandleConnectAck(): API client connected.");
_connectEvent.Set();
};
_client.ConnectionClosed += (sender, e) =>
{
Log.Trace("InteractiveBrokersBrokerage.HandleConnectionClosed(): API client disconnected.");
_connectEvent.Set();
};
}
@@ -676,9 +688,16 @@ namespace QuantConnect.Brokerages.InteractiveBrokers
Thread.Sleep(2500);
}
_connectEvent.Reset();
// we're going to try and connect several times, if successful break
_client.ClientSocket.eConnect(_host, _port, ClientId);
if (!_connectEvent.WaitOne(TimeSpan.FromSeconds(15)))
{
Log.Error("InteractiveBrokersBrokerage.Connect(): timeout waiting for connect callback");
}
// create the message processing thread
var reader = new EReader(_client.ClientSocket, _signal);
reader.Start();
@@ -990,7 +1009,7 @@ namespace QuantConnect.Brokerages.InteractiveBrokers
return $"{contract.ToString().ToUpperInvariant()} {contract.LastTradeDateOrContractMonth.ToStringInvariant()} {contract.Strike.ToStringInvariant()} {contract.Right}";
}
private static string GetContractDescription(Contract contract)
public static string GetContractDescription(Contract contract)
{
return $"{contract} {contract.PrimaryExch ?? string.Empty} {contract.LastTradeDateOrContractMonth.ToStringInvariant()} {contract.Strike.ToStringInvariant()} {contract.Right}";
}
@@ -1193,6 +1212,9 @@ namespace QuantConnect.Brokerages.InteractiveBrokers
/// </summary>
private void HandleError(object sender, IB.ErrorEventArgs e)
{
// handles the 'connection refused' connect cases
_connectEvent.Set();
// https://www.interactivebrokers.com/en/software/api/apiguide/tables/api_message_codes.htm
var requestId = e.Id;
@@ -2244,51 +2266,76 @@ namespace QuantConnect.Brokerages.InteractiveBrokers
/// </summary>
private Symbol MapSymbol(Contract contract)
{
var securityType = ConvertSecurityType(contract);
var ibSymbol = securityType == SecurityType.Forex ? contract.Symbol + contract.Currency : contract.Symbol;
var market = InteractiveBrokersBrokerageModel.DefaultMarketMap[securityType];
var isFutureOption = contract.SecType == IB.SecurityType.FutureOption;
// Handle future options as a Future, up until we actually return the future.
if (isFutureOption || securityType == SecurityType.Future)
try
{
var leanSymbol = _symbolMapper.GetLeanRootSymbol(ibSymbol);
var defaultMarket = market;
if (!_symbolPropertiesDatabase.TryGetMarket(leanSymbol, SecurityType.Future, out market))
var securityType = ConvertSecurityType(contract);
var ibSymbol = securityType == SecurityType.Forex ? contract.Symbol + contract.Currency : contract.Symbol;
var market = InteractiveBrokersBrokerageModel.DefaultMarketMap[securityType];
var isFutureOption = contract.SecType == IB.SecurityType.FutureOption;
if ((isFutureOption || securityType == SecurityType.Option) &&
contract.LastTradeDateOrContractMonth == "0")
{
market = defaultMarket;
// Try our best to recover from a malformed contract.
// You can read more about malformed contracts at the ParseMalformedContract method's documentation.
var exchange = GetSymbolExchange(securityType, market);
contract = InteractiveBrokersSymbolMapper.ParseMalformedContractOptionSymbol(contract, exchange);
ibSymbol = contract.Symbol;
}
else if (securityType == SecurityType.Future && contract.LastTradeDateOrContractMonth == "0")
{
contract = _symbolMapper.ParseMalformedContractFutureSymbol(contract, _symbolPropertiesDatabase);
ibSymbol = contract.Symbol;
}
var contractExpiryDate = DateTime.ParseExact(contract.LastTradeDateOrContractMonth, DateFormat.EightCharacter, CultureInfo.InvariantCulture);
if (!isFutureOption)
// Handle future options as a Future, up until we actually return the future.
if (isFutureOption || securityType == SecurityType.Future)
{
return _symbolMapper.GetLeanSymbol(ibSymbol, SecurityType.Future, market, contractExpiryDate);
var leanSymbol = _symbolMapper.GetLeanRootSymbol(ibSymbol);
var defaultMarket = market;
if (!_symbolPropertiesDatabase.TryGetMarket(leanSymbol, SecurityType.Future, out market))
{
market = defaultMarket;
}
var contractExpiryDate = DateTime.ParseExact(contract.LastTradeDateOrContractMonth, DateFormat.EightCharacter, CultureInfo.InvariantCulture);
if (!isFutureOption)
{
return _symbolMapper.GetLeanSymbol(ibSymbol, SecurityType.Future, market, contractExpiryDate);
}
// Create a canonical future Symbol for lookup in the FuturesExpiryFunctions helper class.
// We then get the delta between the futures option's expiry month vs. the future's expiry month.
var canonicalFutureSymbol = _symbolMapper.GetLeanSymbol(ibSymbol, SecurityType.Future, market, SecurityIdentifier.DefaultDate);
var futureExpiryFunction = FuturesExpiryFunctions.FuturesExpiryFunction(canonicalFutureSymbol);
var futureContractExpiryDate = futureExpiryFunction(FuturesOptionsExpiryFunctions.GetFutureContractMonth(canonicalFutureSymbol, contractExpiryDate));
var futureSymbol = Symbol.CreateFuture(canonicalFutureSymbol.ID.Symbol, canonicalFutureSymbol.ID.Market, futureContractExpiryDate);
var right = contract.Right == IB.RightType.Call ? OptionRight.Call : OptionRight.Put;
var strike = Convert.ToDecimal(contract.Strike);
return Symbol.CreateOption(futureSymbol, market, OptionStyle.American, right, strike, contractExpiryDate);
}
// Create a canonical future Symbol for lookup in the FuturesExpiryFunctions helper class.
// We then get the delta between the futures option's expiry month vs. the future's expiry month.
var canonicalFutureSymbol = _symbolMapper.GetLeanSymbol(ibSymbol, SecurityType.Future, market, SecurityIdentifier.DefaultDate);
var futureExpiryFunction = FuturesExpiryFunctions.FuturesExpiryFunction(canonicalFutureSymbol);
var futureContractExpiryDate = futureExpiryFunction(FuturesOptionsExpiryFunctions.GetFutureContractMonth(canonicalFutureSymbol, contractExpiryDate));
var futureSymbol = Symbol.CreateFuture(canonicalFutureSymbol.ID.Symbol, canonicalFutureSymbol.ID.Market, futureContractExpiryDate);
if (securityType == SecurityType.Option)
{
var expiryDate = DateTime.ParseExact(contract.LastTradeDateOrContractMonth, DateFormat.EightCharacter, CultureInfo.InvariantCulture);
var right = contract.Right == IB.RightType.Call ? OptionRight.Call : OptionRight.Put;
var strike = Convert.ToDecimal(contract.Strike);
var right = contract.Right == IB.RightType.Call ? OptionRight.Call : OptionRight.Put;
var strike = Convert.ToDecimal(contract.Strike);
return _symbolMapper.GetLeanSymbol(ibSymbol, securityType, market, expiryDate, strike, right);
}
return Symbol.CreateOption(futureSymbol, market, OptionStyle.American, right, strike, contractExpiryDate);
return _symbolMapper.GetLeanSymbol(ibSymbol, securityType, market);
}
if (securityType == SecurityType.Option)
catch (Exception error)
{
var expiryDate = DateTime.ParseExact(contract.LastTradeDateOrContractMonth, DateFormat.EightCharacter, CultureInfo.InvariantCulture);
var right = contract.Right == IB.RightType.Call ? OptionRight.Call : OptionRight.Put;
var strike = Convert.ToDecimal(contract.Strike);
return _symbolMapper.GetLeanSymbol(ibSymbol, securityType, market, expiryDate, strike, right);
throw new Exception($"InteractiveBrokersBrokerage.MapSymbol(): Failed to convert contract for {contract.Symbol}; Contract description: {GetContractDescription(contract)}", error);
}
return _symbolMapper.GetLeanSymbol(ibSymbol, securityType, market);
}
private static decimal RoundPrice(decimal input, decimal minTick)
@@ -2374,7 +2421,7 @@ namespace QuantConnect.Brokerages.InteractiveBrokers
// we ignore futures canonical symbol
if (symbol.ID.SecurityType == SecurityType.Future && symbol.IsCanonical())
{
return false;
continue;
}
var id = GetNextId();
@@ -2401,10 +2448,10 @@ namespace QuantConnect.Brokerages.InteractiveBrokers
_subscribedTickers[id] = new SubscriptionEntry { Symbol = subscribeSymbol };
Log.Trace($"InteractiveBrokersBrokerage.Subscribe(): Subscribe Processed: {symbol.Value} ({GetContractDescription(contract)}) # {id}");
return true;
}
}
}
return true;
}
catch (Exception err)
{
@@ -3087,10 +3134,11 @@ namespace QuantConnect.Brokerages.InteractiveBrokers
/// <summary>
/// Gets the exchange the Symbol should be routed to
/// </summary>
/// <param name="symbol">Symbol to route</param>
private string GetSymbolExchange(Symbol symbol)
/// <param name="securityType">SecurityType of the Symbol</param>
/// <param name="market">Market of the Symbol</param>
private string GetSymbolExchange(SecurityType securityType, string market)
{
switch (symbol.SecurityType)
switch (securityType)
{
case SecurityType.Option:
// Regular equity options uses default, in this case "Smart"
@@ -3099,15 +3147,24 @@ namespace QuantConnect.Brokerages.InteractiveBrokers
// Futures options share the same market as the underlying Symbol
case SecurityType.FutureOption:
case SecurityType.Future:
return _futuresExchanges.ContainsKey(symbol.ID.Market)
? _futuresExchanges[symbol.ID.Market]
: symbol.ID.Market;
return _futuresExchanges.ContainsKey(market)
? _futuresExchanges[market]
: market;
default:
return "Smart";
}
}
/// <summary>
/// Gets the exchange the Symbol should be routed to
/// </summary>
/// <param name="symbol">Symbol to route</param>
private string GetSymbolExchange(Symbol symbol)
{
return GetSymbolExchange(symbol.SecurityType, symbol.ID.Market);
}
/// <summary>
/// Returns whether the brokerage should perform the cash synchronization
/// </summary>
@@ -3220,7 +3277,7 @@ namespace QuantConnect.Brokerages.InteractiveBrokers
// these are warning messages from IB
private static readonly HashSet<int> WarningCodes = new HashSet<int>
{
102, 104, 105, 106, 107, 109, 110, 111, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 129, 131, 132, 133, 134, 135, 136, 137, 140, 141, 146, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 201, 303,313,314,315,319,325,328,329,334,335,336,337,338,339,340,341,342,343,345,347,348,349,350,352,353,355,356,358,359,360,361,362,363,364,367,368,369,370,371,372,373,374,375,376,377,378,379,380,382,383,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,402,403,404,405,406,407,408,409,410,411,412,413,417,418,419,420,421,422,423,424,425,426,427,428,429,430,433,434,435,436,437,439,440,441,442,443,444,445,446,447,448,449,450,1100,10002,10003,10006,10007,10008,10009,10010,10011,10012,10014,10018,10019,10020,10052,10147,10148,10149,1101,1102,2100,2101,2102,2103,2105,2109,2110,2148
102, 104, 105, 106, 107, 109, 110, 111, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 129, 131, 132, 133, 134, 135, 136, 137, 140, 141, 146, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 201, 303,313,314,315,319,325,328,329,334,335,336,337,338,339,340,341,342,343,345,347,348,349,350,352,353,355,356,358,359,360,361,362,363,364,367,368,369,370,371,372,373,374,375,376,377,378,379,380,382,383,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,402,403,404,405,406,407,408,409,410,411,412,413,417,418,419,420,421,422,423,424,425,426,427,428,429,430,433,434,435,436,437,439,440,441,442,443,444,445,446,447,448,449,450,10002,10003,10006,10007,10008,10009,10010,10011,10012,10014,10018,10019,10020,10052,10147,10148,10149,2100,2101,2102,2109,2148
};
// these require us to issue invalidated order events

View File

@@ -97,6 +97,7 @@ namespace QuantConnect.Brokerages.InteractiveBrokers
algorithm.Transactions,
algorithm.Portfolio,
Composer.Instance.GetExportedValueByTypeName<IDataAggregator>(Config.Get("data-aggregator", "QuantConnect.Lean.Engine.DataFeeds.AggregationManager")),
Composer.Instance.GetExportedValueByTypeName<IMapFileProvider>(Config.Get("map-file-provider", "QuantConnect.Data.Auxiliary.LocalDiskMapFileProvider")),
account,
host,
port,

View File

@@ -14,12 +14,19 @@
*/
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using QuantConnect.Interfaces;
using QuantConnect.Securities.Future;
using QuantConnect.Securities.FutureOption;
using IB = QuantConnect.Brokerages.InteractiveBrokers.Client;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using IBApi;
using QuantConnect.Logging;
using QuantConnect.Securities;
namespace QuantConnect.Brokerages.InteractiveBrokers
{
@@ -28,6 +35,8 @@ namespace QuantConnect.Brokerages.InteractiveBrokers
/// </summary>
public class InteractiveBrokersSymbolMapper : ISymbolMapper
{
private readonly IMapFileProvider _mapFileProvider;
// we have a special treatment of futures, because IB renamed several exchange tickers (like GBP instead of 6B). We fix this:
// We map those tickers back to their original names using the map below
private readonly Dictionary<string, string> _ibNameMap = new Dictionary<string, string>();
@@ -35,9 +44,10 @@ namespace QuantConnect.Brokerages.InteractiveBrokers
/// <summary>
/// Constructs InteractiveBrokersSymbolMapper. Default parameters are used.
/// </summary>
public InteractiveBrokersSymbolMapper():
public InteractiveBrokersSymbolMapper(IMapFileProvider mapFileProvider) :
this(Path.Combine("InteractiveBrokers", "IB-symbol-map.json"))
{
_mapFileProvider = mapFileProvider;
}
/// <summary>
@@ -67,9 +77,14 @@ namespace QuantConnect.Brokerages.InteractiveBrokers
/// <returns>The InteractiveBrokers symbol</returns>
public string GetBrokerageSymbol(Symbol symbol)
{
if (symbol == null || string.IsNullOrWhiteSpace(symbol.Value))
if (string.IsNullOrWhiteSpace(symbol?.Value))
throw new ArgumentException("Invalid symbol: " + (symbol == null ? "null" : symbol.ToString()));
var ticker = GetMappedTicker(symbol);
if (string.IsNullOrWhiteSpace(ticker))
throw new ArgumentException("Invalid symbol: " + symbol.ToString());
if (symbol.ID.SecurityType != SecurityType.Forex &&
symbol.ID.SecurityType != SecurityType.Equity &&
symbol.ID.SecurityType != SecurityType.Option &&
@@ -77,7 +92,7 @@ namespace QuantConnect.Brokerages.InteractiveBrokers
symbol.ID.SecurityType != SecurityType.Future)
throw new ArgumentException("Invalid security type: " + symbol.ID.SecurityType);
if (symbol.ID.SecurityType == SecurityType.Forex && symbol.Value.Length != 6)
if (symbol.ID.SecurityType == SecurityType.Forex && ticker.Length != 6)
throw new ArgumentException("Forex symbol length must be equal to 6: " + symbol.Value);
switch (symbol.ID.SecurityType)
@@ -85,7 +100,7 @@ namespace QuantConnect.Brokerages.InteractiveBrokers
case SecurityType.Option:
// Final case is for equities. We use the mapped value to select
// the equity we want to trade.
return symbol.Underlying.Value;
return GetMappedTicker(symbol.Underlying);
case SecurityType.FutureOption:
// We use the underlying Future Symbol since IB doesn't use
@@ -97,10 +112,10 @@ namespace QuantConnect.Brokerages.InteractiveBrokers
return GetBrokerageRootSymbol(symbol.ID.Symbol);
case SecurityType.Equity:
return symbol.Value.Replace(".", " ");
return ticker.Replace(".", " ");
}
return symbol.Value;
return ticker;
}
/// <summary>
@@ -173,7 +188,7 @@ namespace QuantConnect.Brokerages.InteractiveBrokers
{
var brokerageSymbol = _ibNameMap.FirstOrDefault(kv => kv.Value == rootSymbol);
return brokerageSymbol.Key??rootSymbol;
return brokerageSymbol.Key ?? rootSymbol;
}
/// <summary>
@@ -186,5 +201,117 @@ namespace QuantConnect.Brokerages.InteractiveBrokers
return _ibNameMap.ContainsKey(brokerageRootSymbol) ? _ibNameMap[brokerageRootSymbol] : brokerageRootSymbol;
}
/// <summary>
/// Parses a contract for future with malformed data.
/// Malformed data usually manifests itself by having "0" assigned to some values
/// we expect, like the contract's expiry date. The contract is returned by IB
/// like this, usually due to a high amount of data subscriptions that are active
/// in an account, surpassing IB's imposed limit. Read more about this here: https://interactivebrokers.github.io/tws-api/rtd_fqa_errors.html#rtd_common_errors_maxmktdata
///
/// We are provided a string in the Symbol in malformed contracts that can be
/// parsed to construct the clean contract, which is done by this method.
/// </summary>
/// <param name="malformedContract">Malformed contract (for futures), i.e. a contract with invalid values ("0") in some of its fields</param>
/// <param name="symbolPropertiesDatabase">The symbol properties database to use</param>
/// <returns>Clean Contract for the future</returns>
/// <remarks>
/// The malformed contract returns data similar to the following when calling <see cref="InteractiveBrokersBrokerage.GetContractDetails"/>: ES MAR2021
/// </remarks>
public Contract ParseMalformedContractFutureSymbol(Contract malformedContract, SymbolPropertiesDatabase symbolPropertiesDatabase)
{
Log.Trace($"InteractiveBrokersSymbolMapper.ParseMalformedContractFutureSymbol(): Parsing malformed contract: {InteractiveBrokersBrokerage.GetContractDescription(malformedContract)} with trading class: \"{malformedContract.TradingClass}\"");
// capture any character except spaces, match spaces, capture any char except digits, capture digits
var matches = Regex.Matches(malformedContract.Symbol, @"^(\S*)\s*(\D*)(\d*)");
var match = matches[0].Groups;
var contractSymbol = match[1].Value;
var contractMonthExpiration = DateTime.ParseExact(match[2].Value, "MMM", CultureInfo.CurrentCulture).Month;
var contractYearExpiration = match[3].Value;
var leanSymbol = GetLeanRootSymbol(contractSymbol);
string market;
if (!symbolPropertiesDatabase.TryGetMarket(leanSymbol, SecurityType.Future, out market))
{
market = InteractiveBrokersBrokerageModel.DefaultMarketMap[SecurityType.Future];
}
var canonicalSymbol = Symbol.Create(leanSymbol, SecurityType.Future, market);
var contractMonthYear = new DateTime(int.Parse(contractYearExpiration, CultureInfo.InvariantCulture), contractMonthExpiration, 1);
// we get the expiration date using the FuturesExpiryFunctions
var contractExpirationDate = FuturesExpiryFunctions.FuturesExpiryFunction(canonicalSymbol)(contractMonthYear);
return new Contract
{
Symbol = contractSymbol,
Multiplier = malformedContract.Multiplier,
LastTradeDateOrContractMonth = $"{contractExpirationDate:yyyyMMdd}",
Exchange = malformedContract.Exchange,
SecType = malformedContract.SecType,
IncludeExpired = false,
Currency = malformedContract.Currency
};
}
private string GetMappedTicker(Symbol symbol)
{
var ticker = symbol.Value;
if (symbol.ID.SecurityType == SecurityType.Equity)
{
var mapFile = _mapFileProvider.Get(symbol.ID.Market).ResolveMapFile(symbol.ID.Symbol, symbol.ID.Date);
ticker = mapFile.GetMappedSymbol(DateTime.UtcNow, symbol.Value);
}
return ticker;
}
/// <summary>
/// Parses a contract for options with malformed data.
/// Malformed data usually manifests itself by having "0" assigned to some values
/// we expect, like the contract's expiry date. The contract is returned by IB
/// like this, usually due to a high amount of data subscriptions that are active
/// in an account, surpassing IB's imposed limit. Read more about this here: https://interactivebrokers.github.io/tws-api/rtd_fqa_errors.html#rtd_common_errors_maxmktdata
///
/// We are provided a string in the Symbol in malformed contracts that can be
/// parsed to construct the clean contract, which is done by this method.
/// </summary>
/// <param name="malformedContract">Malformed contract (for options), i.e. a contract with invalid values ("0") in some of its fields</param>
/// <param name="exchange">Exchange that the contract's asset lives on/where orders will be routed through</param>
/// <returns>Clean Contract for the option</returns>
/// <remarks>
/// The malformed contract returns data similar to the following when calling <see cref="InteractiveBrokersBrokerage.GetContractDetails"/>:
/// OPT SPY JUN2021 350 P [SPY 210618P00350000 100] USD 0 0 0
///
/// ... which the contents inside [] follow the pattern:
///
/// [SYMBOL YY_MM_DD_OPTIONRIGHT_STRIKE(divide by 1000) MULTIPLIER]
/// </remarks>
public static Contract ParseMalformedContractOptionSymbol(Contract malformedContract, string exchange = "Smart")
{
Log.Trace($"InteractiveBrokersSymbolMapper.ParseMalformedContractOptionSymbol(): Parsing malformed contract: {InteractiveBrokersBrokerage.GetContractDescription(malformedContract)} with trading class: \"{malformedContract.TradingClass}\"");
// we search for the '[ ]' pattern, inside of it we: (capture any character except spaces, match spaces) -> 3 times
var matches = Regex.Matches(malformedContract.Symbol, @"^.*[\[](\S*)\s*(\S*)\s*(\S*)[\]]");
var match = matches[0].Groups;
var contractSymbol = match[1].Value;
var contractSpecification = match[2].Value;
var multiplier = match[3].Value;
var expiryDate = "20" + contractSpecification.Substring(0, 6);
var contractRight = contractSpecification[6] == 'C' ? IB.RightType.Call : IB.RightType.Put;
var contractStrike = long.Parse(contractSpecification.Substring(7), CultureInfo.InvariantCulture) / 1000.0;
return new Contract
{
Symbol = contractSymbol,
Multiplier = multiplier,
LastTradeDateOrContractMonth = expiryDate,
Right = contractRight,
Strike = contractStrike,
Exchange = exchange,
SecType = malformedContract.SecType,
IncludeExpired = false,
Currency = malformedContract.Currency
};
}
}
}

View File

@@ -195,6 +195,7 @@
<Compile Include="Alpaca\AlpacaBrokerage.cs" />
<Compile Include="Alpaca\AlpacaBrokerage.Utility.cs" />
<Compile Include="Alpaca\AlpacaBrokerageFactory.cs" />
<Compile Include="Alpaca\AlpacaSymbolMapper.cs" />
<Compile Include="Alpaca\Markets\AlpacaTradingClient.cs" />
<Compile Include="Alpaca\Markets\AlpacaTradingClient.General.cs" />
<Compile Include="Alpaca\Markets\AlpacaTradingClient.Orders.cs" />

View File

@@ -19,6 +19,7 @@ using System.Collections.Generic;
using Newtonsoft.Json;
using QuantConnect.Algorithm.Framework.Alphas;
using QuantConnect.Interfaces;
using QuantConnect.Util;
namespace QuantConnect
{
@@ -183,7 +184,7 @@ namespace QuantConnect
/// It is calculated by taking a portfolio's annualized rate of return and subtracting the risk free rate of return.
/// </summary>
/// <remarks>For performance we only truncate when the value is gotten</remarks>
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore), JsonConverter(typeof(StringDecimalJsonConverter), true)]
public decimal SortinoRatio
{
get

View File

@@ -16,7 +16,7 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using QuantConnect.Packets;
using QuantConnect.Statistics;
namespace QuantConnect.Api
{
@@ -55,12 +55,6 @@ namespace QuantConnect.Api
[JsonProperty(PropertyName = "progress")]
public decimal Progress;
/// <summary>
/// Result packet for the backtest
/// </summary>
[JsonProperty(PropertyName = "result")]
public BacktestResult Result;
/// <summary>
/// Backtest error message
/// </summary>
@@ -78,6 +72,56 @@ namespace QuantConnect.Api
/// </summary>
[JsonProperty(PropertyName = "created")]
public DateTime Created;
/// <summary>
/// Rolling window detailed statistics.
/// </summary>
[JsonProperty(PropertyName = "rollingWindow", NullValueHandling = NullValueHandling.Ignore)]
public Dictionary<string, AlgorithmPerformance> RollingWindow;
/// <summary>
/// Rolling window detailed statistics.
/// </summary>
[JsonProperty(PropertyName = "totalPerformance", NullValueHandling = NullValueHandling.Ignore)]
public AlgorithmPerformance TotalPerformance;
/// <summary>
/// Contains population averages scores over the life of the algorithm
/// </summary>
[JsonProperty(PropertyName = "alphaRuntimeStatistics", NullValueHandling = NullValueHandling.Ignore)]
public AlphaRuntimeStatistics AlphaRuntimeStatistics;
/// <summary>
/// Charts updates for the live algorithm since the last result packet
/// </summary>
[JsonProperty(PropertyName = "charts", NullValueHandling = NullValueHandling.Ignore)]
public IDictionary<string, Chart> Charts;
/// <summary>
/// Statistics information sent during the algorithm operations.
/// </summary>
/// <remarks>Intended for update mode -- send updates to the existing statistics in the result GUI. If statistic key does not exist in GUI, create it</remarks>
[JsonProperty(PropertyName = "statistics", NullValueHandling = NullValueHandling.Ignore)]
public IDictionary<string, string> Statistics;
/// <summary>
/// Runtime banner/updating statistics in the title banner of the live algorithm GUI.
/// </summary>
[JsonProperty(PropertyName = "runtimeStatistics", NullValueHandling = NullValueHandling.Ignore)]
public IDictionary<string, string> RuntimeStatistics;
}
/// <summary>
/// Wrapper class for Backtest/* endpoints JSON response
/// Currently used by Backtest/Read and Backtest/Create
/// </summary>
public class BacktestResponseWrapper : RestResponse
{
/// <summary>
/// Backtest Object
/// </summary>
[JsonProperty(PropertyName = "backtest")]
public Backtest Backtest;
}
/// <summary>

View File

@@ -16,12 +16,14 @@
using QuantConnect.Util;
using System;
using ProtoBuf;
namespace QuantConnect.Data.Market
{
/// <summary>
/// Defines a data type that represents open interest for given security
/// </summary>
[ProtoContract(SkipConstructor = true)]
public class OpenInterest : Tick
{
/// <summary>

View File

@@ -29,6 +29,7 @@ namespace QuantConnect.Data.Market
/// which implements IDictionary and passed into an OnData event handler.
/// </summary>
[ProtoContract(SkipConstructor = true)]
[ProtoInclude(1000, typeof(OpenInterest))]
public class Tick : BaseData
{
private uint? _parsedSaleCondition;

View File

@@ -139,8 +139,9 @@ namespace QuantConnect.Interfaces
/// </summary>
/// <param name="projectId">Project id for the backtest we'd like to read</param>
/// <param name="backtestId">Backtest id for the backtest we'd like to read</param>
/// <param name="getCharts">True will return backtest charts</param>
/// <returns>Backtest result object</returns>
Backtest ReadBacktest(int projectId, string backtestId);
Backtest ReadBacktest(int projectId, string backtestId, bool getCharts = true);
/// <summary>
/// Update the backtest name

View File

@@ -14,12 +14,14 @@
*/
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Data.Market;
using QuantConnect.Python;
using QuantConnect.Orders.Fees;
using QuantConnect.Securities;
using QuantConnect.Util;
namespace QuantConnect.Orders.Fills
{
@@ -116,17 +118,8 @@ namespace QuantConnect.Orders.Fills
// make sure the exchange is open/normal market hours before filling
if (!IsExchangeOpen(asset, false)) return fill;
var prices = GetPricesCheckingPythonWrapper(asset, order.Direction);
var pricesEndTimeUtc = prices.EndTime.ConvertToUtc(asset.Exchange.TimeZone);
// if the order is filled on stale (fill-forward) data, set a warning message on the order event
if (pricesEndTimeUtc.Add(Parameters.StalePriceTimeSpan) < order.Time)
{
fill.Message = $"Warning: fill at stale price ({prices.EndTime.ToStringInvariant()} {asset.Exchange.TimeZone})";
}
//Order [fill]price for a market order model is the current security price
fill.FillPrice = prices.Current;
// Define the last bid or ask time to set stale prices message
var endTime = DateTime.MinValue;
fill.Status = OrderStatus.Filled;
//Calculate the model slippage: e.g. 0.01c
@@ -136,13 +129,23 @@ namespace QuantConnect.Orders.Fills
switch (order.Direction)
{
case OrderDirection.Buy:
fill.FillPrice += slip;
//Order [fill]price for a buy market order model is the current security ask price
fill.FillPrice = GetAskPrice(asset, out endTime) + slip;
break;
case OrderDirection.Sell:
fill.FillPrice -= slip;
//Order [fill]price for a buy market order model is the current security bid price
fill.FillPrice = GetBidPrice(asset, out endTime) - slip;
break;
}
var endTimeUtc = endTime.ConvertToUtc(asset.Exchange.TimeZone);
// if the order is filled on stale (fill-forward) data, set a warning message on the order event
if (endTimeUtc.Add(Parameters.StalePriceTimeSpan) < order.Time)
{
fill.Message = $"Warning: fill at stale price ({endTime.ToStringInvariant()} {asset.Exchange.TimeZone})";
}
// assume the order completely filled
fill.FillQuantity = order.Quantity;
@@ -460,6 +463,144 @@ namespace QuantConnect.Orders.Fills
return fill;
}
/// <summary>
/// Get data types the Security is subscribed to
/// </summary>
/// <param name="asset">Security which has subscribed data types</param>
private HashSet<Type> GetSubscribedTypes(Security asset)
{
var subscribedTypes = Parameters
.ConfigProvider
.GetSubscriptionDataConfigs(asset.Symbol)
.ToHashSet(x => x.Type);
if (subscribedTypes.Count == 0)
{
throw new InvalidOperationException($"Cannot perform fill for {asset.Symbol} because no data subscription were found.");
}
return subscribedTypes;
}
/// <summary>
/// Get current ask price for subscribed data
/// This method will try to get the most recent ask price data, so it will try to get tick quote first, then quote bar.
/// If no quote, tick or bar, is available (e.g. hourly data), use trade data with preference to tick data.
/// </summary>
/// <param name="asset">Security which has subscribed data types</param>
/// <param name="endTime">Timestamp of the most recent data type</param>
private decimal GetAskPrice(Security asset, out DateTime endTime)
{
var subscribedTypes = GetSubscribedTypes(asset);
List<Tick> ticks = null;
var isTickSubscribed = subscribedTypes.Contains(typeof(Tick));
if (isTickSubscribed)
{
ticks = asset.Cache.GetAll<Tick>().ToList();
var quote = ticks.LastOrDefault(x => x.TickType == TickType.Quote && x.AskPrice > 0);
if (quote != null)
{
endTime = quote.EndTime;
return quote.AskPrice;
}
}
if (subscribedTypes.Contains(typeof(QuoteBar)))
{
var quoteBar = asset.Cache.GetData<QuoteBar>();
if (quoteBar != null)
{
endTime = quoteBar.EndTime;
return quoteBar.Ask?.Close ?? quoteBar.Close;
}
}
if (isTickSubscribed)
{
var trade = ticks.LastOrDefault(x => x.TickType == TickType.Trade && x.Price > 0);
if (trade != null)
{
endTime = trade.EndTime;
return trade.Price;
}
}
if (subscribedTypes.Contains(typeof(TradeBar)))
{
var tradeBar = asset.Cache.GetData<TradeBar>();
if (tradeBar != null)
{
endTime = tradeBar.EndTime;
return tradeBar.Close;
}
}
throw new InvalidOperationException($"Cannot get ask price to perform fill for {asset.Symbol} because no market data subscription were found.");
}
/// <summary>
/// Get current bid price for subscribed data
/// This method will try to get the most recent bid price data, so it will try to get tick quote first, then quote bar.
/// If no quote, tick or bar, is available (e.g. hourly data), use trade data with preference to tick data.
/// </summary>
/// <param name="asset">Security which has subscribed data types</param>
/// <param name="endTime">Timestamp of the most recent data type</param>
private decimal GetBidPrice(Security asset, out DateTime endTime)
{
var subscribedTypes = GetSubscribedTypes(asset);
List<Tick> ticks = null;
var isTickSubscribed = subscribedTypes.Contains(typeof(Tick));
if (isTickSubscribed)
{
ticks = asset.Cache.GetAll<Tick>().ToList();
var quote = ticks.LastOrDefault(x => x.TickType == TickType.Quote && x.BidPrice > 0);
if (quote != null)
{
endTime = quote.EndTime;
return quote.BidPrice;
}
}
if (subscribedTypes.Contains(typeof(QuoteBar)))
{
var quoteBar = asset.Cache.GetData<QuoteBar>();
if (quoteBar != null)
{
endTime = quoteBar.EndTime;
return quoteBar.Bid?.Close ?? quoteBar.Close;
}
}
if (isTickSubscribed)
{
var trade = ticks.LastOrDefault(x => x.TickType == TickType.Trade && x.Price > 0);
if (trade != null)
{
endTime = trade.EndTime;
return trade.Price;
}
}
if (subscribedTypes.Contains(typeof(TradeBar)))
{
var tradeBar = asset.Cache.GetData<TradeBar>();
if (tradeBar != null)
{
endTime = tradeBar.EndTime;
return tradeBar.Close;
}
}
throw new InvalidOperationException($"Cannot get bid price to perform fill for {asset.Symbol} because no market data subscription were found.");
}
/// <summary>
/// This is required due to a limitation in PythonNet to resolved
/// overriden methods. <see cref="GetPrices"/>

View File

@@ -33,6 +33,12 @@ namespace QuantConnect.Packets
: base(type)
{ }
/// <summary>
/// The host name to use if any
/// </summary>
[JsonProperty(PropertyName = "sHostName")]
public string HostName;
/// <summary>
/// User Id placing request
/// </summary>

View File

@@ -49,6 +49,12 @@ namespace QuantConnect.Packets
[JsonProperty(PropertyName = "sAlgorithmID")]
public string AlgorithmId;
/// <summary>
/// OptimizationId for this result packet if any
/// </summary>
[JsonProperty(PropertyName = "sOptimizationID")]
public string OptimizationId;
/// <summary>
/// Project Id associated with this status packet
/// </summary>

View File

@@ -44,6 +44,12 @@ namespace QuantConnect.Packets
[JsonProperty(PropertyName = "sBacktestID")]
public string BacktestId = DefaultId;
/// <summary>
/// Optimization Id for this task
/// </summary>
[JsonProperty(PropertyName = "sOptimizationID")]
public string OptimizationId;
/// <summary>
/// Backtest start-date as defined in the Initialize() method.
/// </summary>

View File

@@ -52,6 +52,12 @@ namespace QuantConnect.Packets
[JsonProperty(PropertyName = "sBacktestID")]
public string BacktestId = "";
/// <summary>
/// OptimizationId for this result packet if any
/// </summary>
[JsonProperty(PropertyName = "sOptimizationID")]
public string OptimizationId;
/// <summary>
/// Compile Id for the algorithm which generated this result packet.
/// </summary>
@@ -147,6 +153,7 @@ namespace QuantConnect.Packets
Results = packet.Results;
ProcessingTime = packet.ProcessingTime;
TradeableDates = packet.TradeableDates;
OptimizationId = packet.OptimizationId;
}
catch (Exception err)
{
@@ -175,6 +182,7 @@ namespace QuantConnect.Packets
CompileId = job.CompileId;
Channel = job.Channel;
BacktestId = job.BacktestId;
OptimizationId = job.OptimizationId;
Results = results;
Name = job.Name;
UserId = job.UserId;

View File

@@ -146,8 +146,8 @@ namespace QuantConnect.Packets
/// <summary>
/// The cost associated with running this job
/// </summary>
[JsonProperty(PropertyName = "iCreditCost")]
public uint CreditCost;
[JsonProperty(PropertyName = "dCreditCost")]
public decimal CreditCost;
/// <summary>
/// Initializes a new default instance of the <see cref="Controls"/> class

View File

@@ -31,9 +31,9 @@ namespace QuantConnect.Packets
// rounded up to 18 to prevent a very small decrease in refilling, IOW, if it's defaulting to 17, then
// after 7 days have passed, we'll end up being at 119 and not completely refilled, but at 18, on the 6th
// day we'll reach 108 and on the seventh day it will top off at 120 since it's not permitted to exceed the max
public static int DefaultCapacity => Config.GetInt("scheduled-event-leaky-bucket-capacity", 2 * 60);
public static int DefaultTimeInterval => Config.GetInt("scheduled-event-leaky-bucket-time-interval-minutes", 1440);
public static int DefaultRefillAmount => Config.GetInt("scheduled-event-leaky-bucket-refill-amount", (int)Math.Ceiling(DefaultCapacity/7.0));
public static int DefaultCapacity = Config.GetInt("scheduled-event-leaky-bucket-capacity", 2 * 60);
public static int DefaultTimeInterval = Config.GetInt("scheduled-event-leaky-bucket-time-interval-minutes", 1440);
public static int DefaultRefillAmount = Config.GetInt("scheduled-event-leaky-bucket-refill-amount", (int)Math.Ceiling(DefaultCapacity/7.0));
/// <summary>
/// Sets the total capacity of the bucket in a leaky bucket algorithm. This is the maximum

View File

@@ -162,6 +162,9 @@ namespace QuantConnect.Packets
OptimizationEstimate,
/// Optimization work status update
OptimizationStatus
OptimizationStatus,
/// Optimization work result
OptimizationResult
}
}

View File

@@ -84,6 +84,9 @@ def mapper(key):
if keyType is Symbol:
return str(key.ID)
if keyType is str:
reserved = ['high', 'low', 'open', 'close']
if key in reserved:
return key
kvp = SymbolCache.TryGetSymbol(key, None)
if kvp[0]:
return str(kvp[1].ID)

View File

@@ -1,30 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Microsoft.CodeAnalysis.FxCopAnalyzers.2.9.3\build\Microsoft.CodeAnalysis.FxCopAnalyzers.props" Condition="Exists('..\packages\Microsoft.CodeAnalysis.FxCopAnalyzers.2.9.3\build\Microsoft.CodeAnalysis.FxCopAnalyzers.props')" />
<Import Project="..\packages\Microsoft.NetFramework.Analyzers.2.9.3\build\Microsoft.NetFramework.Analyzers.props" Condition="Exists('..\packages\Microsoft.NetFramework.Analyzers.2.9.3\build\Microsoft.NetFramework.Analyzers.props')" />
<Import Project="..\packages\Microsoft.NetCore.Analyzers.2.9.3\build\Microsoft.NetCore.Analyzers.props" Condition="Exists('..\packages\Microsoft.NetCore.Analyzers.2.9.3\build\Microsoft.NetCore.Analyzers.props')" />
<Import Project="..\packages\Microsoft.CodeQuality.Analyzers.2.9.3\build\Microsoft.CodeQuality.Analyzers.props" Condition="Exists('..\packages\Microsoft.CodeQuality.Analyzers.2.9.3\build\Microsoft.CodeQuality.Analyzers.props')" />
<Import Project="..\packages\Microsoft.CodeAnalysis.VersionCheckAnalyzer.2.9.3\build\Microsoft.CodeAnalysis.VersionCheckAnalyzer.props" Condition="Exists('..\packages\Microsoft.CodeAnalysis.VersionCheckAnalyzer.2.9.3\build\Microsoft.CodeAnalysis.VersionCheckAnalyzer.props')" />
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<TargetFramework>net462</TargetFramework>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{2545C0B4-FABB-49C9-8DD1-9AD7EE23F86B}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>QuantConnect</RootNamespace>
<AssemblyName>QuantConnect.Common</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
<LangVersion>6</LangVersion>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<CodeAnalysisRuleSet>..\QuantConnect.ruleset</CodeAnalysisRuleSet>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -106,71 +91,42 @@
<CodeAnalysisRuleSet>..\QuantConnect.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="CloneExtensions, Version=1.3.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\CloneExtensions.1.3.0\lib\net461\CloneExtensions.dll</HintPath>
</Reference>
<Reference Include="DotNetZip, Version=1.13.3.0, Culture=neutral, PublicKeyToken=6583c7c814667745, processorArchitecture=MSIL">
<HintPath>..\packages\DotNetZip.1.13.3\lib\net40\DotNetZip.dll</HintPath>
</Reference>
<Reference Include="Fasterflect">
<HintPath>..\packages\fasterflect.2.1.3\lib\net40\Fasterflect.dll</HintPath>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=1.2.0.246, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<HintPath>..\packages\SharpZipLib.1.2.0\lib\net45\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
<Reference Include="MathNet.Numerics, Version=3.19.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\MathNet.Numerics.3.19.0\lib\net40\MathNet.Numerics.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IO.RecyclableMemoryStream, Version=1.3.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IO.RecyclableMemoryStream.1.3.5\lib\net46\Microsoft.IO.RecyclableMemoryStream.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="NodaTime, Version=1.3.0.0, Culture=neutral, PublicKeyToken=4226afe0d9b296d1, processorArchitecture=MSIL">
<HintPath>..\packages\NodaTime.1.3.4\lib\net35-Client\NodaTime.dll</HintPath>
</Reference>
<Reference Include="protobuf-net, Version=3.0.0.0, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL">
<HintPath>..\packages\protobuf-net.3.0.29\lib\net461\protobuf-net.dll</HintPath>
</Reference>
<Reference Include="protobuf-net.Core, Version=3.0.0.0, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL">
<HintPath>..\packages\protobuf-net.Core.3.0.29\lib\net461\protobuf-net.Core.dll</HintPath>
</Reference>
<Reference Include="QLNet, Version=1.11.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\QLNet.1.11.3\lib\net452\QLNet.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Collections.Immutable, Version=1.2.5.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Collections.Immutable.1.7.1\lib\net461\System.Collections.Immutable.dll</HintPath>
</Reference>
<Reference Include="System.Configuration" />
<Reference Include="System.IdentityModel" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.IdentityModel" />
<Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.ServiceModel.Primitives, Version=4.7.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.ServiceModel.Primitives.4.7.0\lib\net461\System.ServiceModel.Primitives.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.Numerics" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="CloneExtensions" Version="1.3.0" />
<PackageReference Include="DotNetZip" Version="1.13.3" />
<PackageReference Include="fasterflect" Version="2.1.3" />
<PackageReference Include="SharpZipLib" Version="1.2.0" />
<PackageReference Include="MathNet.Numerics" Version="3.19.0" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="1.3.5" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="NodaTime" Version="1.3.4" />
<PackageReference Include="protobuf-net" Version="3.0.29" />
<PackageReference Include="protobuf-net.Core" Version="3.0.29" />
<PackageReference Include="QLNet" Version="1.11.3" />
<PackageReference Include="System.Buffers" Version="4.5.1" />
<PackageReference Include="System.Collections.Immutable" Version="1.7.1" />
<PackageReference Include="System.Memory" Version="4.5.4" />
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.5.3" />
<PackageReference Include="System.ServiceModel.Primitives" Version="4.7.0" />
</ItemGroup>
<PropertyGroup>
<IsWindows>false</IsWindows>
@@ -211,730 +167,14 @@
</When>
</Choose>
<ItemGroup>
<Compile Include="AlgorithmSettings.cs" />
<Compile Include="Algorithm\Framework\Alphas\Analysis\IInsightManager.cs" />
<Compile Include="Algorithm\Framework\Alphas\Analysis\ReadOnlySecurityValuesCollection.cs" />
<Compile Include="Algorithm\Framework\Alphas\IInsightManagerExtension.cs" />
<Compile Include="Algorithm\Framework\Alphas\InsightCollection.cs" />
<Compile Include="Algorithm\Framework\Alphas\Serialization\InsightJsonConverter.cs" />
<Compile Include="Algorithm\Framework\Alphas\Serialization\SerializedInsight.cs" />
<Compile Include="Algorithm\Framework\Portfolio\IPortfolioTarget.cs" />
<Compile Include="Algorithm\Framework\Portfolio\PortfolioTarget.cs" />
<Compile Include="Algorithm\Framework\Alphas\Analysis\Providers\AlgorithmSecurityValuesProvider.cs" />
<Compile Include="Algorithm\Framework\Alphas\Analysis\Functions\BinaryInsightScoreFunction.cs" />
<Compile Include="Algorithm\Framework\Alphas\Analysis\ISecurityValuesProvider.cs" />
<Compile Include="Algorithm\Framework\Alphas\Analysis\IInsightScoreFunction.cs" />
<Compile Include="Algorithm\Framework\Alphas\Analysis\IInsightScoreFunctionProvider.cs" />
<Compile Include="Algorithm\Framework\Alphas\Analysis\Providers\DefaultInsightScoreFunctionProvider.cs" />
<Compile Include="Algorithm\Framework\Alphas\Analysis\SecurityValues.cs" />
<Compile Include="Algorithm\Framework\Alphas\Insight.cs" />
<Compile Include="Algorithm\Framework\Alphas\Analysis\InsightAnalysisContext.cs" />
<Compile Include="Algorithm\Framework\Alphas\GeneratedInsightsCollection.cs" />
<Compile Include="Algorithm\Framework\Alphas\Analysis\InsightManager.cs" />
<Compile Include="Algorithm\Framework\Alphas\InsightScore.cs" />
<Compile Include="Algorithm\Framework\Alphas\InsightScoreType.cs" />
<Compile Include="Algorithm\Framework\Portfolio\PortfolioTargetCollection.cs" />
<Compile Include="AlphaRuntimeStatistics.cs" />
<Compile Include="Api\Account.cs" />
<Compile Include="Api\AuthenticationResponse.cs" />
<Compile Include="Api\Backtest.cs" />
<Compile Include="Api\Compile.cs" />
<Compile Include="Api\CompileState.cs" />
<Compile Include="Api\BacktestReport.cs" />
<Compile Include="Api\Dividends.cs" />
<Compile Include="Api\Link.cs" />
<Compile Include="Api\LiveAlgorithm.cs" />
<Compile Include="Api\LiveAlgorithmResults.cs" />
<Compile Include="Api\LiveAlgorithmResultsJsonConverter.cs" />
<Compile Include="Api\LiveAlgorithmSettings.cs" />
<Compile Include="Api\LiveLog.cs" />
<Compile Include="Api\Nodes.cs" />
<Compile Include="Api\Prices.cs" />
<Compile Include="Api\Project.cs" />
<Compile Include="Api\ProjectFile.cs" />
<Compile Include="Api\RestResponse.cs" />
<Compile Include="Api\Split.cs" />
<Compile Include="Benchmarks\FuncBenchmark.cs" />
<Compile Include="Benchmarks\IBenchmark.cs" />
<Compile Include="Benchmarks\SecurityBenchmark.cs" />
<Compile Include="BinaryComparison.cs" />
<Compile Include="BinaryComparisonExtensions.cs" />
<Compile Include="Brokerages\AlpacaBrokerageModel.cs" />
<Compile Include="Brokerages\AlphaStreamsBrokerageModel.cs" />
<Compile Include="Brokerages\BinanceBrokerageModel.cs" />
<Compile Include="Brokerages\BrokerageFactoryAttribute.cs" />
<Compile Include="Brokerages\BrokerageName.cs" />
<Compile Include="Brokerages\DefaultBrokerageMessageHandler.cs" />
<Compile Include="Brokerages\DefaultBrokerageModel.cs" />
<Compile Include="Brokerages\DowngradeErrorCodeToWarningBrokerageMessageHandler.cs" />
<Compile Include="Brokerages\FxcmBrokerageModel.cs" />
<Compile Include="Brokerages\BitfinexBrokerageModel.cs" />
<Compile Include="Brokerages\GDAXBrokerageModel.cs" />
<Compile Include="Chart.cs" />
<Compile Include="ChartPoint.cs" />
<Compile Include="Data\Channel.cs" />
<Compile Include="Data\Custom\Quiver\Congress.cs" />
<Compile Include="Data\Custom\Quiver\QuiverCongress.cs" />
<Compile Include="Data\Custom\Quiver\QuiverEventsBeta.cs" />
<Compile Include="Data\Custom\Quiver\QuiverWallStreetBets.cs" />
<Compile Include="Data\Custom\Quiver\QuiverWikipedia.cs" />
<Compile Include="Data\Custom\Quiver\TransactionDirection.cs" />
<Compile Include="Data\Custom\Quiver\TransactionDirectionJsonConverter.cs" />
<Compile Include="Data\EventBasedDataQueueHandlerSubscriptionManager.cs" />
<Compile Include="Data\IDataAggregator.cs" />
<Compile Include="Data\Auxiliary\MappingExtensions.cs" />
<Compile Include="Data\Consolidators\Calendar.cs" />
<Compile Include="Data\Consolidators\CalendarType.cs" />
<Compile Include="Data\Consolidators\FilteredIdentityDataConsolidator.cs" />
<Compile Include="Data\Custom\Benzinga\BenzingaNewsJsonConverter.cs" />
<Compile Include="Data\Custom\CBOE\CBOE.cs" />
<Compile Include="Data\Custom\Fred\CBOE.cs" />
<Compile Include="Data\Custom\Fred\CentralBankInterventions.cs" />
<Compile Include="Data\Custom\Fred\CommercialPaper.cs" />
<Compile Include="Data\Custom\Fred\Fred.cs" />
<Compile Include="Data\Custom\Fred\FredApi.cs" />
<Compile Include="Data\Custom\Fred\ICEBofAML.cs" />
<Compile Include="Data\Custom\Fred\LIBOR.cs" />
<Compile Include="Data\Custom\Fred\OECDRecessionIndicators.cs" />
<Compile Include="Data\Custom\Fred\TradeWeightedIndexes.cs" />
<Compile Include="Data\Custom\Fred\Wilshire.cs" />
<Compile Include="Data\Custom\Benzinga\BenzingaNews.cs" />
<Compile Include="Data\Custom\FxcmVolume.cs" />
<Compile Include="Data\Custom\NullData.cs" />
<Compile Include="Data\Custom\SEC\ISECReport.cs" />
<Compile Include="Data\Custom\SEC\SECReportBusinessAddress.cs" />
<Compile Include="Data\Custom\SEC\SECReportCompanyData.cs" />
<Compile Include="Data\Custom\SEC\SECReportConverters.cs" />
<Compile Include="Data\Custom\SEC\SECReportDocument.cs" />
<Compile Include="Data\Custom\SEC\SECReportFiler.cs" />
<Compile Include="Data\Custom\SEC\SECReportFilingValues.cs" />
<Compile Include="Data\Custom\SEC\SECReportFormerCompany.cs" />
<Compile Include="Data\Custom\SEC\SECReportMailAddress.cs" />
<Compile Include="Data\Custom\SEC\SECReportFactory.cs" />
<Compile Include="Data\Custom\SEC\SECReport8K.cs" />
<Compile Include="Data\Custom\SEC\SECReport10Q.cs" />
<Compile Include="Data\Custom\SEC\SECReport10K.cs" />
<Compile Include="Data\Custom\SEC\SECReportIndexFile.cs" />
<Compile Include="Data\Custom\SEC\SECReportSubmission.cs" />
<Compile Include="Data\Custom\SmartInsider\SmartInsiderExecutionHolding.cs" />
<Compile Include="Data\Custom\SmartInsider\SmartInsiderExecutionEntity.cs" />
<Compile Include="Data\Custom\SmartInsider\SmartInsiderEventType.cs" />
<Compile Include="Data\Custom\SmartInsider\SmartInsiderExecutionType.cs" />
<Compile Include="Data\Custom\Tiingo\TiingoDailyData.cs" />
<Compile Include="Data\Custom\Tiingo\TiingoNews.cs" />
<Compile Include="Data\Custom\Tiingo\TiingoNewsJsonConverter.cs" />
<Compile Include="Data\Custom\Tiingo\TiingoSymbolMapper.cs" />
<Compile Include="Data\Custom\TradingEconomics\TradingEconomics.Indicators.cs" />
<Compile Include="Data\Custom\TradingEconomics\TradingEconomics.Event.cs" />
<Compile Include="Data\Custom\TradingEconomics\TradingEconomics.Calendar.cs" />
<Compile Include="Data\Custom\TradingEconomics\TradingEconomicsEarnings.cs" />
<Compile Include="Data\Custom\TradingEconomics\TradingEconomicsEventFilter.cs" />
<Compile Include="Data\Custom\TradingEconomics\TradingEconomicsIndicator.cs" />
<Compile Include="Data\Custom\TradingEconomics\TradingEconomicsDateTimeConverter.cs" />
<Compile Include="Data\Custom\TradingEconomics\TradingEconomicsCalendar.cs" />
<Compile Include="Data\Custom\Estimize\EstimizeConsensus.cs" />
<Compile Include="Data\Custom\Estimize\EstimizeEstimate.cs" />
<Compile Include="Data\Custom\Estimize\EstimizeRelease.cs" />
<Compile Include="Data\Custom\USEnergy\USEnergy.cs" />
<Compile Include="Data\Custom\USEnergy\USEnergyAPI.cs" />
<Compile Include="Data\Custom\USEnergy\USEnergy.Category.cs" />
<Compile Include="Data\Custom\USTreasury\USTreasuryYieldCurveRate.cs" />
<Compile Include="Data\Fundamental\AssetClassificationHelper.cs" />
<Compile Include="Data\GetSetPropertyDynamicMetaObject.cs" />
<Compile Include="Data\HistoryProviderBase.cs" />
<Compile Include="Data\HistoryProviderInitializeParameters.cs" />
<Compile Include="Data\HistoryRequestFactory.cs" />
<Compile Include="Data\Custom\SmartInsider\SmartInsiderEvent.cs" />
<Compile Include="Data\Custom\SmartInsider\SmartInsiderIntention.cs" />
<Compile Include="Data\Custom\SmartInsider\SmartInsiderTransaction.cs" />
<Compile Include="Data\IndexedBasedData.cs" />
<Compile Include="Data\DataQueueHandlerSubscriptionManager.cs" />
<Compile Include="Data\UniverseSelection\UniversePythonWrapper.cs" />
<Compile Include="ExtendedDictionary.cs" />
<Compile Include="Data\SubscriptionDataConfigExtensions.cs" />
<Compile Include="Data\UniverseSelection\ConstituentsUniverse.cs" />
<Compile Include="Data\UniverseSelection\ConstituentsUniverseData.cs" />
<Compile Include="Expiry.cs" />
<Compile Include="DataProviderEvents.cs" />
<Compile Include="IIsolatorLimitResultProvider.cs" />
<Compile Include="Indicators\IIndicatorWarmUpPeriodProvider.cs" />
<Compile Include="Interfaces\IAccountCurrencyProvider.cs" />
<Compile Include="Interfaces\IAlgorithmSubscriptionManager.cs" />
<Compile Include="Interfaces\IDataChannelProvider.cs" />
<Compile Include="Interfaces\IDataPermissionManager.cs" />
<Compile Include="Interfaces\IExtendedDictionary.cs" />
<Compile Include="Interfaces\IObjectStore.cs" />
<Compile Include="Interfaces\IBrokerageCashSynchronizer.cs" />
<Compile Include="Interfaces\IBusyCollection.cs" />
<Compile Include="Interfaces\IDataProviderEvents.cs" />
<Compile Include="Interfaces\IDownloadProvider.cs" />
<Compile Include="Interfaces\IHistoryProvider.cs" />
<Compile Include="Interfaces\IOptionPrice.cs" />
<Compile Include="Interfaces\ISecurityInitializerProvider.cs" />
<Compile Include="Interfaces\ISecurityService.cs" />
<Compile Include="Interfaces\ISecurityPrice.cs" />
<Compile Include="Interfaces\ISubscriptionDataConfigProvider.cs" />
<Compile Include="Interfaces\ISubscriptionDataConfigService.cs" />
<Compile Include="Interfaces\ITimeKeeper.cs" />
<Compile Include="Interfaces\ObjectStoreErrorRaisedEventArgs.cs" />
<Compile Include="Orders\BinanceOrderProperties.cs" />
<Compile Include="Orders\Fees\BinanceFeeModel.cs" />
<Compile Include="IsolatorLimitResult.cs" />
<Compile Include="IsolatorLimitResultProvider.cs" />
<Compile Include="ITimeProvider.cs" />
<Compile Include="Orders\Fees\AlphaStreamsFeeModel.cs" />
<Compile Include="Orders\Fees\ModifiedFillQuantityOrderFee.cs" />
<Compile Include="Orders\Fills\Fill.cs" />
<Compile Include="Orders\Fills\EquityFillModel.cs" />
<Compile Include="Orders\Fills\FillModelParameters.cs" />
<Compile Include="Orders\Fees\FeeModel.cs" />
<Compile Include="Orders\Fees\OrderFee.cs" />
<Compile Include="Orders\Fees\OrderFeeParameters.cs" />
<Compile Include="Orders\Serialization\OrderEventJsonConverter.cs" />
<Compile Include="Orders\Serialization\SerializedOrder.cs" />
<Compile Include="Orders\Serialization\SerializedOrderEvent.cs" />
<Compile Include="Orders\Serialization\SerializedOrderJsonConverter.cs" />
<Compile Include="Orders\Slippage\AlphaStreamsSlippageModel.cs" />
<Compile Include="Packets\BacktestResultParameters.cs" />
<Compile Include="Packets\BaseResultParameters.cs" />
<Compile Include="Packets\Breakpoint.cs" />
<Compile Include="Packets\LeakyBucketControlParameters.cs" />
<Compile Include="Packets\LiveResultParameters.cs" />
<Compile Include="Python\BrokerageMessageHandlerPythonWrapper.cs" />
<Compile Include="Python\PythonConsolidator.cs" />
<Compile Include="Python\MarginCallModelPythonWrapper.cs" />
<Compile Include="Python\PythonInitializer.cs" />
<Compile Include="Python\PythonWrapper.cs" />
<Compile Include="RealTimeProvider.cs" />
<Compile Include="Scheduling\ScheduledEventException.cs" />
<Compile Include="Scheduling\TimeConsumer.cs" />
<Compile Include="Scheduling\TimeMonitor.cs" />
<Compile Include="Securities\BuyingPower.cs" />
<Compile Include="Securities\BuyingPowerModel.cs" />
<Compile Include="Securities\BuyingPowerModelExtensions.cs" />
<Compile Include="Securities\BuyingPowerParameters.cs" />
<Compile Include="Securities\ContractSecurityFilterUniverse.cs" />
<Compile Include="Securities\FutureOption\Api\CMEOptionChainQuotes.cs" />
<Compile Include="Securities\FutureOption\Api\CMEOptionsCategoryList.cs" />
<Compile Include="Securities\FutureOption\Api\CMEProductSlateV2.cs" />
<Compile Include="Securities\FutureOption\Api\CMEStrikePriceScalingFactors.cs" />
<Compile Include="Securities\FutureOption\FutureOption.cs" />
<Compile Include="Securities\FutureOption\FutureOptionSymbol.cs" />
<Compile Include="Securities\FutureOption\FuturesOptionsMarginModel.cs" />
<Compile Include="Securities\FutureOption\FuturesOptionsExpiryFunctions.cs" />
<Compile Include="Securities\FutureOption\FuturesOptionsSymbolMappings.cs" />
<Compile Include="Securities\Future\FutureSymbol.cs" />
<Compile Include="Securities\GetMaximumOrderQuantityForDeltaBuyingPowerParameters.cs" />
<Compile Include="Securities\Option\StrategyMatcher\AbsoluteRiskOptionPositionCollectionEnumerator.cs" />
<Compile Include="Securities\Option\StrategyMatcher\ConstantOptionStrategyLegPredicateReferenceValue.cs" />
<Compile Include="Securities\Option\StrategyMatcher\DefaultOptionPositionCollectionEnumerator.cs" />
<Compile Include="Securities\Option\StrategyMatcher\DescendingByLegCountOptionStrategyDefinitionEnumerator.cs" />
<Compile Include="Securities\Option\StrategyMatcher\FunctionalOptionPositionCollectionEnumerator.cs" />
<Compile Include="Securities\Option\StrategyMatcher\IdentityOptionStrategyDefinitionEnumerator.cs" />
<Compile Include="Securities\Option\StrategyMatcher\IOptionPositionCollectionEnumerator.cs" />
<Compile Include="Securities\Option\StrategyMatcher\IOptionStrategyDefinitionEnumerator.cs" />
<Compile Include="Securities\Option\StrategyMatcher\IOptionStrategyLegPredicateReferenceValue.cs" />
<Compile Include="Securities\Option\StrategyMatcher\IOptionStrategyMatchObjectiveFunction.cs" />
<Compile Include="Securities\Option\StrategyMatcher\OptionStrategyDefinition.cs" />
<Compile Include="Securities\Option\StrategyMatcher\OptionStrategyDefinitionMatch.cs" />
<Compile Include="Securities\Option\StrategyMatcher\OptionStrategyDefinitions.cs" />
<Compile Include="Securities\Option\StrategyMatcher\OptionStrategyLegDefinitionMatch.cs" />
<Compile Include="Securities\Option\StrategyMatcher\OptionStrategyLegPredicateReferenceValue.cs" />
<Compile Include="Securities\Option\StrategyMatcher\OptionPosition.cs" />
<Compile Include="Securities\Option\StrategyMatcher\OptionPositionCollection.cs" />
<Compile Include="Securities\Option\StrategyMatcher\OptionStrategyLegDefinition.cs" />
<Compile Include="Securities\Option\StrategyMatcher\OptionStrategyLegPredicate.cs" />
<Compile Include="Securities\Option\StrategyMatcher\OptionStrategyMatch.cs" />
<Compile Include="Securities\Option\StrategyMatcher\OptionStrategyMatcher.cs" />
<Compile Include="Securities\Option\StrategyMatcher\OptionStrategyMatcherOptions.cs" />
<Compile Include="Securities\Option\StrategyMatcher\PredicateTargetValue.cs" />
<Compile Include="Securities\Option\StrategyMatcher\UnmatchedPositionCountOptionStrategyMatchObjectiveFunction.cs" />
<Compile Include="Securities\RegisteredSecurityDataTypesProvider.cs" />
<Compile Include="Securities\ErrorCurrencyConverter.cs" />
<Compile Include="Securities\GetMaximumOrderQuantityForTargetBuyingPowerParameters.cs" />
<Compile Include="Securities\HasSufficientBuyingPowerForOrderParameters.cs" />
<Compile Include="Securities\ICurrencyConverter.cs" />
<Compile Include="Python\BuyingPowerModelPythonWrapper.cs" />
<Compile Include="Securities\CashAmount.cs" />
<Compile Include="Securities\IdentityCurrencyConverter.cs" />
<Compile Include="Securities\AccountCurrencyImmediateSettlementModel.cs" />
<Compile Include="Securities\IRegisteredSecurityDataTypesProvider.cs" />
<Compile Include="Securities\InitialMarginRequiredForOrderParameters.cs" />
<Compile Include="Securities\IOrderEventProvider.cs" />
<Compile Include="Securities\GetMinimumPriceVariationParameters.cs" />
<Compile Include="Securities\ReservedBuyingPowerForPosition.cs" />
<Compile Include="Securities\ReservedBuyingPowerForPositionParameters.cs" />
<Compile Include="Securities\SecurityCacheDataStoredEventArgs.cs" />
<Compile Include="Securities\DynamicSecurityData.cs" />
<Compile Include="Securities\SecurityCacheProvider.cs" />
<Compile Include="Securities\SecurityService.cs" />
<Compile Include="Securities\Volatility\BaseVolatilityModel.cs" />
<Compile Include="Series.cs" />
<Compile Include="Data\Custom\Intrinio\IntrinioConfig.cs" />
<Compile Include="Data\Custom\Intrinio\IntrinioEconomicData.cs" />
<Compile Include="Data\Custom\Intrinio\EconomicDataSources.cs" />
<Compile Include="Data\Custom\Tiingo\Tiingo.cs" />
<Compile Include="Data\Custom\Tiingo\TiingoPrice.cs" />
<Compile Include="Data\Fundamental\Fundamentals.cs" />
<Compile Include="Data\Fundamental\Generated\AssetClassification.cs" />
<Compile Include="Data\Fundamental\Generated\CompanyProfile.cs" />
<Compile Include="Data\UniverseSelection\ITimeTriggeredUniverse.cs" />
<Compile Include="Data\UniverseSelection\ScheduledUniverse.cs" />
<Compile Include="Exceptions\DllNotFoundPythonExceptionInterpreter.cs" />
<Compile Include="Exceptions\InvalidTokenPythonExceptionInterpreter.cs" />
<Compile Include="Exceptions\KeyErrorPythonExceptionInterpreter.cs" />
<Compile Include="Exceptions\NoMethodMatchPythonExceptionInterpreter.cs" />
<Compile Include="Exceptions\PythonExceptionInterpreter.cs" />
<Compile Include="Exceptions\StackExceptionInterpreter.cs" />
<Compile Include="Exceptions\IExceptionInterpreter.cs" />
<Compile Include="Exceptions\ScheduledEventExceptionInterpreter.cs" />
<Compile Include="Exceptions\UnsupportedOperandPythonExceptionInterpreter.cs" />
<Compile Include="Interfaces\IAlgorithmSettings.cs" />
<Compile Include="Interfaces\IPriceProvider.cs" />
<Compile Include="Interfaces\IFutureChainProvider.cs" />
<Compile Include="Interfaces\IRegressionAlgorithmDefinition.cs" />
<Compile Include="Interfaces\ITimeInForceHandler.cs" />
<Compile Include="Orders\Fees\BitfinexFeeModel.cs" />
<Compile Include="Orders\Fills\FillModel.cs" />
<Compile Include="Orders\Fills\LatestPriceFillModel.cs" />
<Compile Include="Orders\BitfinexOrderProperties.cs" />
<Compile Include="Orders\GDAXOrderProperties.cs" />
<Compile Include="Orders\OrderSizing.cs" />
<Compile Include="Orders\TimeInForceJsonConverter.cs" />
<Compile Include="Orders\TimeInForces\DayTimeInForce.cs" />
<Compile Include="Orders\TimeInForces\GoodTilCanceledTimeInForce.cs" />
<Compile Include="Orders\TimeInForces\GoodTilDateTimeInForce.cs" />
<Compile Include="Orders\InteractiveBrokersOrderProperties.cs" />
<Compile Include="Interfaces\IOrderProperties.cs" />
<Compile Include="Orders\OrderProperties.cs" />
<Compile Include="Orders\OrderSubmissionData.cs" />
<Compile Include="Orders\TimeInForce.cs" />
<Compile Include="Packets\AlphaNodePacket.cs" />
<Compile Include="Packets\AlphaResultPacket.cs" />
<Compile Include="Python\BrokerageModelPythonWrapper.cs" />
<Compile Include="Python\PythonActivator.cs" />
<Compile Include="Python\PythonSlice.cs" />
<Compile Include="Python\VolatilityModelPythonWrapper.cs" />
<Compile Include="Python\PandasData.cs" />
<Compile Include="Python\SecurityInitializerPythonWrapper.cs" />
<Compile Include="Python\SlippageModelPythonWrapper.cs" />
<Compile Include="Python\FillModelPythonWrapper.cs" />
<Compile Include="Python\DataConsolidatorPythonWrapper.cs" />
<Compile Include="Python\PandasConverter.cs" />
<Compile Include="Python\FeeModelPythonWrapper.cs" />
<Compile Include="Securities\CashBuyingPowerModel.cs" />
<Compile Include="Securities\GetMaximumOrderQuantityResult.cs" />
<Compile Include="Securities\HasSufficientBuyingPowerForOrderResult.cs" />
<Compile Include="Securities\IBaseCurrencySymbol.cs" />
<Compile Include="Securities\Future\EmptyFutureChainProvider.cs" />
<Compile Include="Securities\IDerivativeSecurity.cs" />
<Compile Include="Securities\Option\EmptyOptionChainProvider.cs" />
<Compile Include="Interfaces\IOptionChainProvider.cs" />
<Compile Include="Brokerages\IBrokerageMessageHandler.cs" />
<Compile Include="Brokerages\IBrokerageModel.cs" />
<Compile Include="Brokerages\InteractiveBrokersBrokerageModel.cs" />
<Compile Include="Brokerages\OandaBrokerageModel.cs" />
<Compile Include="Brokerages\TradierBrokerageModel.cs" />
<Compile Include="Data\Market\IBaseDataBar.cs" />
<Compile Include="Data\Consolidators\OpenInterestConsolidator.cs" />
<Compile Include="Data\Market\OpenInterest.cs" />
<Compile Include="Data\Market\RenkoType.cs" />
<Compile Include="Data\Fundamental\FineFundamental.cs" />
<Compile Include="Data\Fundamental\Generated\BalanceSheet.cs" />
<Compile Include="Data\Fundamental\Generated\CashFlowStatement.cs" />
<Compile Include="Data\Fundamental\Generated\CompanyReference.cs" />
<Compile Include="Data\Fundamental\Generated\EarningRatios.cs" />
<Compile Include="Data\Fundamental\Generated\EarningReports.cs" />
<Compile Include="Data\Fundamental\Generated\FinancialStatements.cs" />
<Compile Include="Data\Fundamental\Generated\FineFundamental.cs" />
<Compile Include="Data\Fundamental\Generated\IncomeStatement.cs" />
<Compile Include="Data\Fundamental\MultiPeriodField.cs" />
<Compile Include="Data\Fundamental\Generated\MultiPeriodValueTypes.cs" />
<Compile Include="Data\Fundamental\Generated\OperationRatios.cs" />
<Compile Include="Data\Fundamental\Period.cs" />
<Compile Include="Data\Fundamental\Generated\SecurityReference.cs" />
<Compile Include="Data\Fundamental\Generated\ValuationRatios.cs" />
<Compile Include="Data\ISubscriptionEnumeratorFactory.cs" />
<Compile Include="Data\Market\Greeks.cs" />
<Compile Include="Data\Market\FuturesChain.cs" />
<Compile Include="Data\Market\OptionChain.cs" />
<Compile Include="Data\Market\OptionChains.cs" />
<Compile Include="Data\Market\FuturesChains.cs" />
<Compile Include="Data\Market\FuturesContract.cs" />
<Compile Include="Data\Market\OptionContract.cs" />
<Compile Include="Data\Market\FuturesContracts.cs" />
<Compile Include="Data\Market\OptionContracts.cs" />
<Compile Include="Data\Market\QuoteBars.cs" />
<Compile Include="Data\Market\BarDirection.cs" />
<Compile Include="Data\SubscriptionDataConfigList.cs" />
<Compile Include="Data\UniverseSelection\CoarseFundamentalUniverse.cs" />
<Compile Include="Data\UniverseSelection\FineFundamentalUniverse.cs" />
<Compile Include="Data\UniverseSelection\GetSubscriptionRequestsUniverseDecorator.cs" />
<Compile Include="Data\UniverseSelection\FineFundamentalFilteredUniverse.cs" />
<Compile Include="Data\UniverseSelection\FuturesChainUniverse.cs" />
<Compile Include="Data\UniverseSelection\FuturesChainUniverseDataCollection.cs" />
<Compile Include="Data\UniverseSelection\SelectSymbolsUniverseDecorator.cs" />
<Compile Include="Data\UniverseSelection\SubscriptionRequest.cs" />
<Compile Include="Data\UniverseSelection\UniverseDecorator.cs" />
<Compile Include="Data\UniverseSelection\UniverseExtensions.cs" />
<Compile Include="Globals.cs" />
<Compile Include="Currencies.cs" />
<Compile Include="Data\Auxiliary\FactorFile.cs" />
<Compile Include="Data\Auxiliary\FactorFileRow.cs" />
<Compile Include="Data\Auxiliary\LocalDiskFactorFileProvider.cs" />
<Compile Include="Data\Auxiliary\MapFile.cs" />
<Compile Include="Data\Auxiliary\LocalDiskMapFileProvider.cs" />
<Compile Include="Data\Auxiliary\MapFileResolver.cs" />
<Compile Include="Data\Auxiliary\MapFileRow.cs" />
<Compile Include="Data\Auxiliary\ZipEntryName.cs" />
<Compile Include="Data\Consolidators\BaseDataConsolidator.cs" />
<Compile Include="Data\Consolidators\DynamicDataConsolidator.cs" />
<Compile Include="Data\Consolidators\PeriodCountConsolidatorBase.cs" />
<Compile Include="Data\Consolidators\QuoteBarConsolidator.cs" />
<Compile Include="Data\Consolidators\RenkoConsolidator.cs" />
<Compile Include="Data\Consolidators\TickConsolidator.cs" />
<Compile Include="Data\Consolidators\TickQuoteBarConsolidator.cs" />
<Compile Include="Data\Consolidators\TradeBarConsolidatorBase.cs" />
<Compile Include="Data\FileFormat.cs" />
<Compile Include="Data\HistoryRequest.cs" />
<Compile Include="Data\Market\Bar.cs" />
<Compile Include="Data\Market\DataDictionary.cs" />
<Compile Include="Data\Market\Delisting.cs" />
<Compile Include="Data\Market\Delistings.cs" />
<Compile Include="Data\Market\Dividend.cs" />
<Compile Include="Data\Market\Dividends.cs" />
<Compile Include="Data\Market\IBar.cs" />
<Compile Include="Data\Market\QuoteBar.cs" />
<Compile Include="Data\Market\RenkoBar.cs" />
<Compile Include="Brokerages\BrokerageMessageEvent.cs" />
<Compile Include="Brokerages\BrokerageMessageType.cs" />
<Compile Include="Data\Market\Split.cs" />
<Compile Include="Data\Market\Splits.cs" />
<Compile Include="Data\Market\SymbolChangedEvent.cs" />
<Compile Include="Data\Market\SymbolChangedEvents.cs" />
<Compile Include="Data\Slice.cs" />
<Compile Include="Data\SliceExtensions.cs" />
<Compile Include="Data\SubscriptionDataSource.cs" />
<Compile Include="Data\UniverseSelection\CoarseFundamental.cs" />
<Compile Include="Data\UniverseSelection\BaseDataCollection.cs" />
<Compile Include="Data\UniverseSelection\OptionChainUniverse.cs" />
<Compile Include="Data\UniverseSelection\OptionChainUniverseDataCollection.cs" />
<Compile Include="Data\UniverseSelection\UserDefinedUniverse.cs" />
<Compile Include="Data\UniverseSelection\FuncUniverse.cs" />
<Compile Include="Data\UniverseSelection\Universe.cs" />
<Compile Include="Data\UniverseSelection\SecurityChanges.cs" />
<Compile Include="Data\UniverseSelection\UniverseSettings.cs" />
<Compile Include="Field.cs" />
<Compile Include="Indicators\IIndicator.cs" />
<Compile Include="Indicators\IndicatorDataPoint.cs" />
<Compile Include="Indicators\IndicatorUpdatedHandler.cs" />
<Compile Include="Indicators\IReadOnlyWindow.cs" />
<Compile Include="Indicators\RollingWindow.cs" />
<Compile Include="Interfaces\IAlgorithm.cs" />
<Compile Include="Interfaces\IApi.cs" />
<Compile Include="Interfaces\IBrokerage.cs" />
<Compile Include="Interfaces\IBrokerageFactory.cs" />
<Compile Include="Interfaces\IDataCacheProvider.cs" />
<Compile Include="Interfaces\IDataQueueUniverseProvider.cs" />
<Compile Include="Interfaces\IDataQueueHandler.cs" />
<Compile Include="Interfaces\IFactorFileProvider.cs" />
<Compile Include="Interfaces\IDataProvider.cs" />
<Compile Include="Interfaces\IJobQueueHandler.cs" />
<Compile Include="Interfaces\IMapFileProvider.cs" />
<Compile Include="Interfaces\IMessagingHandler.cs" />
<Compile Include="Interfaces\IStreamReader.cs" />
<Compile Include="Interfaces\ITradeBuilder.cs" />
<Compile Include="LocalTimeKeeper.cs" />
<Compile Include="Market.cs" />
<Compile Include="Notifications\Notification.cs" />
<Compile Include="Notifications\NotificationManager.cs" />
<Compile Include="Orders\CancelOrderRequest.cs" />
<Compile Include="Orders\Fees\ConstantFeeModel.cs" />
<Compile Include="Orders\Fees\GDAXFeeModel.cs" />
<Compile Include="Orders\Fees\InteractiveBrokersFeeModel.cs" />
<Compile Include="Orders\Fees\FxcmFeeModel.cs" />
<Compile Include="Orders\Fees\IFeeModel.cs" />
<Compile Include="Orders\Fills\ImmediateFillModel.cs" />
<Compile Include="Orders\Fills\IFillModel.cs" />
<Compile Include="Orders\MarketOnCloseOrder.cs" />
<Compile Include="Orders\MarketOnOpenOrder.cs" />
<Compile Include="Orders\OptionExerciseOrder.cs" />
<Compile Include="Orders\OptionExercise\DefaultExerciseModel.cs" />
<Compile Include="Orders\OptionExercise\IOptionExerciseModel.cs" />
<Compile Include="Orders\OrderField.cs" />
<Compile Include="Orders\OrderJsonConverter.cs" />
<Compile Include="Orders\OrderRequest.cs" />
<Compile Include="Orders\OrderRequestStatus.cs" />
<Compile Include="Orders\OrderRequestType.cs" />
<Compile Include="Orders\OrderResponse.cs" />
<Compile Include="Orders\OrderResponseErrorCode.cs" />
<Compile Include="Orders\OrderExtensions.cs" />
<Compile Include="Orders\OrderTicket.cs" />
<Compile Include="Orders\Slippage\VolumeShareSlippageModel.cs" />
<Compile Include="Orders\Slippage\ConstantSlippageModel.cs" />
<Compile Include="Orders\Slippage\ISlippageModel.cs" />
<Compile Include="Orders\StopLimitOrder.cs" />
<Compile Include="Orders\StopMarketOrder.cs" />
<Compile Include="Orders\LimitOrder.cs" />
<Compile Include="Orders\MarketOrder.cs" />
<Compile Include="Orders\OrderTypes.cs" />
<Compile Include="Orders\OrderError.cs" />
<Compile Include="Orders\SubmitOrderRequest.cs" />
<Compile Include="Orders\UpdateOrderFields.cs" />
<Compile Include="Orders\UpdateOrderRequest.cs" />
<Compile Include="Packets\Controls.cs" />
<Compile Include="Packets\HandledErrorPacket.cs" />
<Compile Include="Packets\HistoryPacket.cs" />
<Compile Include="Packets\SystemDebugPacket.cs" />
<Compile Include="Parameters\ParameterAttribute.cs" />
<Compile Include="Properties\SharedAssemblyInfo.cs" />
<Compile Include="Python\PythonData.cs" />
<Compile Include="Python\PythonQuandl.cs" />
<Compile Include="Scheduling\CompositeTimeRule.cs" />
<Compile Include="Scheduling\DateRules.cs" />
<Compile Include="Scheduling\FluentScheduledEventBuilder.cs" />
<Compile Include="Scheduling\FuncDateRule.cs" />
<Compile Include="Scheduling\IDateRule.cs" />
<Compile Include="Scheduling\IEventSchedule.cs" />
<Compile Include="Scheduling\ITimeRule.cs" />
<Compile Include="Scheduling\ScheduledEvent.cs" />
<Compile Include="Scheduling\ScheduleManager.cs" />
<Compile Include="Scheduling\FuncTimeRule.cs" />
<Compile Include="Scheduling\TimeRules.cs" />
<Compile Include="Securities\BrokerageModelSecurityInitializer.cs" />
<Compile Include="Securities\Cash.cs" />
<Compile Include="Securities\CashBook.cs" />
<Compile Include="Securities\Cfd\Cfd.cs" />
<Compile Include="Securities\Cfd\CfdCache.cs" />
<Compile Include="Securities\Cfd\CfdDataFilter.cs" />
<Compile Include="Securities\Cfd\CfdExchange.cs" />
<Compile Include="Securities\Cfd\CfdHolding.cs" />
<Compile Include="Securities\CompositeSecurityInitializer.cs" />
<Compile Include="Securities\Crypto\Crypto.cs" />
<Compile Include="Securities\Crypto\CryptoExchange.cs" />
<Compile Include="Securities\Crypto\CryptoHolding.cs" />
<Compile Include="Securities\DelayedSettlementModel.cs" />
<Compile Include="Securities\AdjustedPriceVariationModel.cs" />
<Compile Include="Securities\FuncSecuritySeeder.cs" />
<Compile Include="Securities\Future\FutureExpirationCycles.cs" />
<Compile Include="Securities\Future\FutureFilterUniverse.cs" />
<Compile Include="Securities\Future\FuturesExpiryFunctions.cs" />
<Compile Include="Securities\Future\FuturesExpiryUtilityFunctions.cs" />
<Compile Include="Securities\Option\OptionFilterUniverse.cs" />
<Compile Include="Securities\IDerivativeSecurityFilterUniverse.cs" />
<Compile Include="Securities\IMarginCallModel.cs" />
<Compile Include="Securities\ISecuritySeeder.cs" />
<Compile Include="Securities\Option\OptionSymbol.cs" />
<Compile Include="Securities\SecurityPriceVariationModel.cs" />
<Compile Include="Securities\FuncSecurityDerivativeFilter.cs" />
<Compile Include="Securities\FuncSecurityInitializer.cs" />
<Compile Include="Securities\EquityPriceVariationModel.cs" />
<Compile Include="Securities\IPriceVariationModel.cs" />
<Compile Include="Securities\Future\Future.cs" />
<Compile Include="Securities\Future\FutureCache.cs" />
<Compile Include="Securities\Future\FutureExchange.cs" />
<Compile Include="Securities\Future\FutureHolding.cs" />
<Compile Include="Securities\Future\Futures.cs" />
<Compile Include="Securities\Future\FutureMarginModel.cs" />
<Compile Include="Securities\IDerivativeSecurityFilter.cs" />
<Compile Include="Securities\Volatility\IndicatorVolatilityModel.cs" />
<Compile Include="Securities\Interfaces\IContinuousContractModel.cs" />
<Compile Include="Securities\ISecurityInitializer.cs" />
<Compile Include="Securities\ISettlementModel.cs" />
<Compile Include="Securities\Volatility\IVolatilityModel.cs" />
<Compile Include="Securities\LocalMarketHours.cs" />
<Compile Include="Securities\MarketHoursSegment.cs" />
<Compile Include="Securities\MarketHoursState.cs" />
<Compile Include="Securities\Option\CurrentPriceOptionPriceModel.cs" />
<Compile Include="Securities\Option\ConstantQLDividendYieldEstimator.cs" />
<Compile Include="Securities\Option\ConstantQLRiskFreeRateEstimator.cs" />
<Compile Include="Securities\Option\ConstantQLUnderlyingVolatilityEstimator.cs" />
<Compile Include="Securities\Option\IQLDividendYieldEstimator.cs" />
<Compile Include="Securities\Option\IOptionPriceModel.cs" />
<Compile Include="Securities\Option\IQLRiskFreeRateEstimator.cs" />
<Compile Include="Securities\Option\IQLUnderlyingVolatilityEstimator.cs" />
<Compile Include="Securities\Option\Option.cs" />
<Compile Include="Securities\Option\OptionCache.cs" />
<Compile Include="Securities\Option\OptionDataFilter.cs" />
<Compile Include="Securities\Option\OptionExchange.cs" />
<Compile Include="Securities\Option\OptionHolding.cs" />
<Compile Include="Securities\Option\OptionPortfolioModel.cs" />
<Compile Include="Securities\Option\OptionPriceModelResult.cs" />
<Compile Include="Securities\Option\OptionPriceModels.cs" />
<Compile Include="Securities\Option\OptionStrategies.cs" />
<Compile Include="Securities\Option\OptionStrategy.cs" />
<Compile Include="Securities\Option\OptionSymbolProperties.cs" />
<Compile Include="Securities\Option\OptionMarginModel.cs" />
<Compile Include="Securities\Option\QLOptionPriceModel.cs" />
<Compile Include="Securities\PatternDayTradingMarginModel.cs" />
<Compile Include="Securities\Volatility\StandardDeviationOfReturnsVolatilityModel.cs" />
<Compile Include="Securities\Volatility\RelativeStandardDeviationVolatilityModel.cs" />
<Compile Include="Securities\SecurityDatabaseKey.cs" />
<Compile Include="Securities\SecurityExchangeHours.cs" />
<Compile Include="Securities\MarketHoursDatabase.cs" />
<Compile Include="Securities\ISecurityProvider.cs" />
<Compile Include="Securities\IOrderProcessor.cs" />
<Compile Include="Securities\IBuyingPowerModel.cs" />
<Compile Include="Securities\IOrderProvider.cs" />
<Compile Include="Securities\ISecurityPortfolioModel.cs" />
<Compile Include="Securities\DefaultMarginCallModel.cs" />
<Compile Include="Securities\SecurityPortfolioModel.cs" />
<Compile Include="Securities\SecurityMarginModel.cs" />
<Compile Include="Securities\ImmediateSettlementModel.cs" />
<Compile Include="Securities\SymbolProperties.cs" />
<Compile Include="Securities\SymbolPropertiesDatabase.cs" />
<Compile Include="Securities\UniverseManager.cs" />
<Compile Include="Securities\UnsettledCashAmount.cs" />
<Compile Include="SecurityIdentifier.cs" />
<Compile Include="SeriesSampler.cs" />
<Compile Include="Data\Custom\Quandl.cs" />
<Compile Include="Data\DynamicData.cs" />
<Compile Include="Data\Consolidators\DataConsolidator.cs" />
<Compile Include="Data\Consolidators\IDataConsolidator.cs" />
<Compile Include="Data\Consolidators\IdentityDataConsolidator.cs" />
<Compile Include="Data\Consolidators\SequentialConsolidator.cs" />
<Compile Include="Data\Consolidators\TradeBarConsolidator.cs" />
<Compile Include="Orders\OrderEvent.cs" />
<Compile Include="Packets\AlgorithmNodePacket.cs" />
<Compile Include="Packets\AlgorithmStatusPacket.cs" />
<Compile Include="Packets\BacktestNodePacket.cs" />
<Compile Include="Packets\BacktestResultPacket.cs" />
<Compile Include="Packets\DebugPacket.cs" />
<Compile Include="Packets\LiveNodePacket.cs" />
<Compile Include="Packets\LiveResultPacket.cs" />
<Compile Include="Packets\LogPacket.cs" />
<Compile Include="Packets\MarketTodayPacket.cs" />
<Compile Include="Packets\OrderEventPacket.cs" />
<Compile Include="Packets\Packet.cs" />
<Compile Include="Packets\RuntimeErrorPacket.cs" />
<Compile Include="Packets\SecurityTypesPacket.cs" />
<Compile Include="Data\BaseData.cs" />
<Compile Include="Data\IBaseData.cs" />
<Compile Include="Data\SubscriptionDataConfig.cs" />
<Compile Include="Data\Market\Tick.cs" />
<Compile Include="Data\Market\TradeBar.cs" />
<Compile Include="Data\SubscriptionManager.cs" />
<Compile Include="Data\Market\Ticks.cs" />
<Compile Include="Data\Market\TradeBars.cs" />
<Compile Include="Isolator.cs" />
<Compile Include="Global.cs" />
<Compile Include="Extensions.cs" />
<Compile Include="Orders\Order.cs" />
<Compile Include="Securities\AccountEvent.cs" />
<Compile Include="Securities\Equity\EquityCache.cs" />
<Compile Include="Securities\Equity\EquityDataFilter.cs" />
<Compile Include="Securities\Forex\ForexCache.cs" />
<Compile Include="Securities\Forex\ForexDataFilter.cs" />
<Compile Include="Securities\Interfaces\ISecurityDataFilter.cs" />
<Compile Include="Securities\SecurityDataFilter.cs" />
<Compile Include="Securities\Equity\Equity.cs" />
<Compile Include="Securities\Equity\EquityExchange.cs" />
<Compile Include="Securities\Equity\EquityHolding.cs" />
<Compile Include="Securities\Forex\Forex.cs" />
<Compile Include="Securities\Forex\ForexExchange.cs" />
<Compile Include="Securities\Forex\ForexHolding.cs" />
<Compile Include="Securities\Security.cs" />
<Compile Include="Securities\SecurityCache.cs" />
<Compile Include="Securities\SecurityExchange.cs" />
<Compile Include="Securities\SecurityHolding.cs" />
<Compile Include="Securities\SecurityManager.cs" />
<Compile Include="Securities\SecurityPortfolioManager.cs" />
<Compile Include="Securities\SecurityTransactionManager.cs" />
<Compile Include="OS.cs" />
<Compile Include="Algorithm\Framework\Alphas\InsightDirection.cs" />
<Compile Include="Algorithm\Framework\Alphas\InsightType.cs" />
<Compile Include="Statistics\AlgorithmPerformance.cs" />
<Compile Include="Statistics\FitnessScoreManager.cs" />
<Compile Include="Statistics\KellyCriterionManager.cs" />
<Compile Include="Statistics\PortfolioStatistics.cs" />
<Compile Include="Statistics\StatisticsBuilder.cs" />
<Compile Include="Statistics\StatisticsResults.cs" />
<Compile Include="Statistics\TradeStatistics.cs" />
<Compile Include="Statistics\Statistics.cs" />
<Compile Include="RealTimeSynchronizedTimer.cs" />
<Compile Include="Storage\ObjectStore.cs" />
<Compile Include="StringExtensions.cs" />
<Compile Include="Parse.cs" />
<Compile Include="Symbol.cs" />
<Compile Include="Statistics\Trade.cs" />
<Compile Include="Statistics\TradeBuilder.cs" />
<Compile Include="Statistics\TradeEnums.cs" />
<Compile Include="SymbolCache.cs" />
<Compile Include="Result.cs" />
<Compile Include="SymbolJsonConverter.cs" />
<Compile Include="SymbolRepresentation.cs" />
<Compile Include="SymbolValueJsonConverter.cs" />
<Compile Include="Time.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TimeKeeper.cs" />
<Compile Include="TimeUpdatedEventArgs.cs" />
<Compile Include="TimeZoneOffsetProvider.cs" />
<Compile Include="TimeZones.cs" />
<Compile Include="TradingCalendar.cs" />
<Compile Include="TradingDay.cs" />
<Compile Include="Util\BusyBlockingCollection.cs" />
<Compile Include="Util\BusyCollection.cs" />
<Compile Include="Util\CircularQueue.cs" />
<Compile Include="Util\ComparisonOperator.cs" />
<Compile Include="Util\Composer.cs" />
<Compile Include="Util\ConcurrentSet.cs" />
<Compile Include="Util\DateTimeJsonConverter.cs" />
<Compile Include="Util\DisposableExtensions.cs" />
<Compile Include="Util\DoubleUnixSecondsDateTimeJsonConverter.cs" />
<Compile Include="Util\EnumeratorExtensions.cs" />
<Compile Include="Util\ExpressionBuilder.cs" />
<Compile Include="Util\FixedSizeQueue.cs" />
<Compile Include="Util\FixedSizeHashQueue.cs" />
<Compile Include="Util\FuncTextWriter.cs" />
<Compile Include="Util\JsonRoundingConverter.cs" />
<Compile Include="Util\ComparisonOperatorTypes.cs" />
<Compile Include="Util\RateLimit\BusyWaitSleepStrategy.cs" />
<Compile Include="Util\RateLimit\FixedIntervalRefillStrategy.cs" />
<Compile Include="Util\RateLimit\IRefillStrategy.cs" />
<Compile Include="Util\RateLimit\ISleepStrategy.cs" />
<Compile Include="Util\RateLimit\ITokenBucket.cs" />
<Compile Include="Util\RateLimit\LeakyBucket.cs" />
<Compile Include="Util\RateLimit\ThreadSleepStrategy.cs" />
<Compile Include="Util\LeanData.cs" />
<Compile Include="Util\LeanDataPathComponents.cs" />
<Compile Include="Util\ListComparer.cs" />
<Compile Include="Util\MarketHoursDatabaseJsonConverter.cs" />
<Compile Include="Util\ColorJsonConverter.cs" />
<Compile Include="Util\PythonUtil.cs" />
<Compile Include="Util\RateGate.cs" />
<Compile Include="Util\RateLimit\TokenBucket.cs" />
<Compile Include="Util\ReferenceWrapper.cs" />
<Compile Include="Util\SecurityExtensions.cs" />
<Compile Include="Util\SecurityIdentifierJsonConverter.cs" />
<Compile Include="Util\SeriesJsonConverter.cs" />
<Compile Include="Util\StreamReaderEnumerable.cs" />
<Compile Include="Util\StreamReaderExtensions.cs" />
<Compile Include="Util\StringDecimalJsonConverter.cs" />
<Compile Include="Util\TypeChangeJsonConverter.cs" />
<Compile Include="Util\LinqExtensions.cs" />
<Compile Include="Util\MemoizingEnumerable.cs" />
<Compile Include="Util\NullStringValueConverter.cs" />
<Compile Include="Util\ObjectActivator.cs" />
<Compile Include="Util\ReaderWriterLockSlimExtensions.cs" />
<Compile Include="Util\Ref.cs" />
<Compile Include="Util\SingleValueListConverter.cs" />
<Compile Include="Util\Validate.cs" />
<Compile Include="Util\VersionHelper.cs" />
<Compile Include="Util\WorkerThread.cs" />
<Compile Include="Util\XElementExtensions.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Configuration\QuantConnect.Configuration.csproj">
<Project>{0aeb4ea3-28c8-476e-89fd-926f06590b4c}</Project>
<Name>QuantConnect.Configuration</Name>
</ProjectReference>
<ProjectReference Include="..\Logging\QuantConnect.Logging.csproj">
<Project>{01911409-86BE-4E7D-9947-DF714138610D}</Project>
<Name>QuantConnect.Logging</Name>
</ProjectReference>
<ProjectReference Include="..\Configuration\QuantConnect.Configuration.csproj" />
<ProjectReference Include="..\Logging\QuantConnect.Logging.csproj" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="Python\Python.Runtime.dll.config" Link="Python.Runtime.dll.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Content Include="decimal.py">
@@ -951,9 +191,6 @@
<Analyzer Include="..\packages\Microsoft.NetFramework.Analyzers.2.9.3\analyzers\dotnet\cs\Microsoft.NetFramework.Analyzers.dll" />
<Analyzer Include="..\packages\Microsoft.NetFramework.Analyzers.2.9.3\analyzers\dotnet\cs\Microsoft.NetFramework.CSharp.Analyzers.dll" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<Import Project="..\packages\QuantConnect.pythonnet.1.0.5.30\build\QuantConnect.pythonnet.targets" Condition="Exists('..\packages\QuantConnect.pythonnet.1.0.5.30\build\QuantConnect.pythonnet.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
@@ -972,4 +209,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>

View File

@@ -240,7 +240,7 @@ namespace QuantConnect
{
if (SecurityType != SecurityType.Option && SecurityType != SecurityType.FutureOption)
{
throw new InvalidOperationException("OptionType is only defined for SecurityType.Option and SecurityType.FutureOption");
throw new InvalidOperationException("StrikePrice is only defined for SecurityType.Option and SecurityType.FutureOption");
}
// performance: lets calculate strike price once

View File

@@ -41,8 +41,9 @@ namespace QuantConnect
/// <param name="series">The series to be sampled</param>
/// <param name="start">The date to start sampling, if before start of data then start of data will be used</param>
/// <param name="stop">The date to stop sampling, if after stop of data, then stop of data will be used</param>
/// <param name="truncateValues">True will truncate values to integers</param>
/// <returns>The sampled series</returns>
public Series Sample(Series series, DateTime start, DateTime stop)
public Series Sample(Series series, DateTime start, DateTime stop, bool truncateValues = false)
{
var sampled = new Series(series.Name, series.SeriesType, series.Index, series.Unit);
@@ -59,7 +60,13 @@ namespace QuantConnect
{
if (point.x >= nextSample && point.x <= unixStopDate)
{
sampled.Values.Add(point);
var samplePoint = point;
if (truncateValues)
{
// let's not modify the original
samplePoint = new ChartPoint(samplePoint) { y = Math.Truncate(samplePoint.y) };
}
sampled.Values.Add(samplePoint);
}
}
return sampled;
@@ -106,7 +113,12 @@ namespace QuantConnect
while (nextSample <= current.x && nextSample <= unixStopDate)
{
var value = Interpolate(previous, current, (long) nextSample);
sampled.Values.Add(new ChartPoint {x = (long) nextSample, y = value});
var point = new ChartPoint {x = (long) nextSample, y = value};
if (truncateValues)
{
point.y = Math.Truncate(point.y);
}
sampled.Values.Add(point);
nextSample += _seconds;
}

View File

@@ -307,6 +307,10 @@ namespace QuantConnect
throw new ArgumentNullException(nameof(value));
}
ID = sid;
if (ID.HasUnderlying)
{
Underlying = new Symbol(ID.Underlying, ID.Underlying.Symbol);
}
Value = value.LazyToUpper();
}

View File

@@ -14,6 +14,7 @@
*/
using System;
using System.Globalization;
using Newtonsoft.Json;
namespace QuantConnect.Util
@@ -69,13 +70,14 @@ namespace QuantConnect.Util
if (value is double)
{
var rounded = Math.Round((double)value, FractionalDigits);
writer.WriteValue(rounded);
writer.WriteValue(rounded.ToString(CultureInfo.InvariantCulture));
}
else
{
// we serialize decimal as string so that json doesn't use exponential notation which actually will lose precision
var rounded = Math.Round((decimal)value, FractionalDigits);
writer.WriteValue(rounded);
writer.WriteValue(rounded.ToString(CultureInfo.InvariantCulture));
}
}
}
}
}

View File

@@ -91,7 +91,7 @@ Y | BATS Y-Exchange
Z | BATS Exchange
#### Tick Sale Conditions
Sale Condition Code | Exchange | Description |
Exchange | Sale Condition Code | Description |
---- | --- | ---
CTS | Blank or @ | Regular Sale (no condition)
CTS | B | Average Price Trade

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -23140,7 +23140,134 @@
}
],
"saturday": [],
"holidays": []
"holidays": [
"4/10/2009",
"12/25/2009",
"1/1/2010",
"4/2/2010",
"12/24/2010",
"1/1/2011",
"4/22/2011",
"12/26/2011",
"4/6/2012",
"12/25/2012",
"1/2/2013",
"3/29/2013",
"12/25/2013",
"1/1/2014",
"4/18/2014",
"12/25/2014",
"1/1/2015",
"12/25/2015",
"1/1/2016",
"3/25/2016",
"12/26/2016",
"1/2/2017",
"4/14/2017",
"12/25/2017",
"1/1/2018",
"3/30/2018",
"12/25/2018",
"1/1/2019",
"4/19/2019",
"12/25/2019",
"1/1/2020"
],
"earlyCloses": {
"1/19/2009": "10:30:00",
"2/16/2009": "10:30:00",
"5/25/2009": "10:30:00",
"7/3/2009": "10:30:00",
"9/7/2009": "10:30:00",
"11/26/2009": "10:30:00",
"11/27/2009": "12:15:00",
"12/24/2009": "12:15:00",
"1/18/2010": "10:30:00",
"2/15/2010": "10:30:00",
"5/31/2010": "10:30:00",
"7/5/2010": "10:30:00",
"9/6/2010": "10:30:00",
"11/25/2010": "10:30:00",
"11/26/2010": "12:15:00",
"1/17/2011": "10:30:00",
"2/21/2011": "10:30:00",
"5/30/2011": "10:30:00",
"7/4/2011": "10:30:00",
"9/5/2011": "10:30:00",
"11/24/2011": "10:30:00",
"11/25/2011": "12:15:00",
"1/16/2012": "10:30:00",
"2/20/2012": "10:30:00",
"5/28/2012": "10:30:00",
"7/3/2012": "12:15:00",
"7/4/2012": "10:30:00",
"9/3/2012": "10:30:00",
"11/22/2012": "10:30:00",
"11/23/2012": "12:15:00",
"12/24/2012": "12:15:00",
"1/21/2013": "10:30:00",
"2/18/2013": "10:30:00",
"5/27/2013": "10:30:00",
"7/3/2013": "12:15:00",
"7/4/2013": "10:30:00",
"7/5/2013": "15:15:00",
"9/2/2013": "10:30:00",
"11/28/2013": "10:30:00",
"11/29/2013": "12:15:00",
"12/24/2013": "12:15:00",
"12/26/2013": "15:15:00",
"1/2/2014": "15:15:00",
"1/20/2014": "10:30:00",
"2/17/2014": "10:30:00",
"5/26/2014": "12:00:00",
"7/3/2014": "12:00:00",
"9/1/2014": "12:00:00",
"11/27/2014": "12:00:00",
"11/28/2014": "12:15:00",
"12/24/2014": "12:15:00",
"1/19/2015": "12:00:00",
"2/16/2015": "12:00:00",
"4/3/2015": "08:15:00",
"5/25/2015": "12:00:00",
"7/3/2015": "12:00:00",
"9/7/2015": "12:00:00",
"11/26/2015": "12:00:00",
"11/27/2015": "12:15:00",
"12/24/2015": "12:15:00",
"1/18/2016": "12:00:00",
"2/15/2016": "12:00:00",
"5/30/2016": "12:00:00",
"7/4/2016": "12:00:00",
"9/5/2016": "12:00:00",
"11/24/2016": "12:00:00",
"11/25/2016": "12:15:00",
"1/16/2017": "12:00:00",
"2/20/2017": "12:00:00",
"5/29/2017": "12:00:00",
"7/3/2017": "12:15:00",
"7/4/2017": "12:00:00",
"9/4/2017": "12:00:00",
"11/23/2017": "12:00:00",
"11/24/2017": "12:15:00",
"1/15/2018": "12:00:00",
"2/19/2018": "12:00:00",
"5/28/2018": "12:00:00",
"7/3/2018": "12:15:00",
"7/4/2018": "12:00:00",
"9/3/2018": "12:00:00",
"11/22/2018": "12:00:00",
"11/23/2018": "12:15:00",
"12/24/2018": "12:15:00",
"1/21/2019": "12:00:00",
"2/18/2019": "12:00:00",
"5/27/2019": "12:00:00",
"7/3/2019": "12:15:00",
"7/4/2019": "12:00:00",
"9/2/2019": "12:00:00",
"11/28/2019": "12:00:00",
"11/29/2019": "12:15:00",
"12/24/2019": "12:15:00"
}
},
"Future-cme-NQ": {
"dataTimeZone": "UTC",
@@ -23233,7 +23360,134 @@
}
],
"saturday": [],
"holidays": []
"holidays": [
"4/10/2009",
"12/25/2009",
"1/1/2010",
"4/2/2010",
"12/24/2010",
"1/1/2011",
"4/22/2011",
"12/26/2011",
"4/6/2012",
"12/25/2012",
"1/2/2013",
"3/29/2013",
"12/25/2013",
"1/1/2014",
"4/18/2014",
"12/25/2014",
"1/1/2015",
"12/25/2015",
"1/1/2016",
"3/25/2016",
"12/26/2016",
"1/2/2017",
"4/14/2017",
"12/25/2017",
"1/1/2018",
"3/30/2018",
"12/25/2018",
"1/1/2019",
"4/19/2019",
"12/25/2019",
"1/1/2020"
],
"earlyCloses": {
"1/19/2009": "10:30:00",
"2/16/2009": "10:30:00",
"5/25/2009": "10:30:00",
"7/3/2009": "10:30:00",
"9/7/2009": "10:30:00",
"11/26/2009": "10:30:00",
"11/27/2009": "12:15:00",
"12/24/2009": "12:15:00",
"1/18/2010": "10:30:00",
"2/15/2010": "10:30:00",
"5/31/2010": "10:30:00",
"7/5/2010": "10:30:00",
"9/6/2010": "10:30:00",
"11/25/2010": "10:30:00",
"11/26/2010": "12:15:00",
"1/17/2011": "10:30:00",
"2/21/2011": "10:30:00",
"5/30/2011": "10:30:00",
"7/4/2011": "10:30:00",
"9/5/2011": "10:30:00",
"11/24/2011": "10:30:00",
"11/25/2011": "12:15:00",
"1/16/2012": "10:30:00",
"2/20/2012": "10:30:00",
"5/28/2012": "10:30:00",
"7/3/2012": "12:15:00",
"7/4/2012": "10:30:00",
"9/3/2012": "10:30:00",
"11/22/2012": "10:30:00",
"11/23/2012": "12:15:00",
"12/24/2012": "12:15:00",
"1/21/2013": "10:30:00",
"2/18/2013": "10:30:00",
"5/27/2013": "10:30:00",
"7/3/2013": "12:15:00",
"7/4/2013": "10:30:00",
"7/5/2013": "15:15:00",
"9/2/2013": "10:30:00",
"11/28/2013": "10:30:00",
"11/29/2013": "12:15:00",
"12/24/2013": "12:15:00",
"12/26/2013": "15:15:00",
"1/2/2014": "15:15:00",
"1/20/2014": "10:30:00",
"2/17/2014": "10:30:00",
"5/26/2014": "12:00:00",
"7/3/2014": "12:00:00",
"9/1/2014": "12:00:00",
"11/27/2014": "12:00:00",
"11/28/2014": "12:15:00",
"12/24/2014": "12:15:00",
"1/19/2015": "12:00:00",
"2/16/2015": "12:00:00",
"4/3/2015": "08:15:00",
"5/25/2015": "12:00:00",
"7/3/2015": "12:00:00",
"9/7/2015": "12:00:00",
"11/26/2015": "12:00:00",
"11/27/2015": "12:15:00",
"12/24/2015": "12:15:00",
"1/18/2016": "12:00:00",
"2/15/2016": "12:00:00",
"5/30/2016": "12:00:00",
"7/4/2016": "12:00:00",
"9/5/2016": "12:00:00",
"11/24/2016": "12:00:00",
"11/25/2016": "12:15:00",
"1/16/2017": "12:00:00",
"2/20/2017": "12:00:00",
"5/29/2017": "12:00:00",
"7/3/2017": "12:15:00",
"7/4/2017": "12:00:00",
"9/4/2017": "12:00:00",
"11/23/2017": "12:00:00",
"11/24/2017": "12:15:00",
"1/15/2018": "12:00:00",
"2/19/2018": "12:00:00",
"5/28/2018": "12:00:00",
"7/3/2018": "12:15:00",
"7/4/2018": "12:00:00",
"9/3/2018": "12:00:00",
"11/22/2018": "12:00:00",
"11/23/2018": "12:15:00",
"12/24/2018": "12:15:00",
"1/21/2019": "12:00:00",
"2/18/2019": "12:00:00",
"5/27/2019": "12:00:00",
"7/3/2019": "12:15:00",
"7/4/2019": "12:00:00",
"9/2/2019": "12:00:00",
"11/28/2019": "12:00:00",
"11/29/2019": "12:15:00",
"12/24/2019": "12:15:00"
}
},
"Future-cbot-YM": {
"dataTimeZone": "UTC",
@@ -23326,7 +23580,134 @@
}
],
"saturday": [],
"holidays": []
"holidays": [
"4/10/2009",
"12/25/2009",
"1/1/2010",
"4/2/2010",
"12/24/2010",
"1/1/2011",
"4/22/2011",
"12/26/2011",
"4/6/2012",
"12/25/2012",
"1/2/2013",
"3/29/2013",
"12/25/2013",
"1/1/2014",
"4/18/2014",
"12/25/2014",
"1/1/2015",
"12/25/2015",
"1/1/2016",
"3/25/2016",
"12/26/2016",
"1/2/2017",
"4/14/2017",
"12/25/2017",
"1/1/2018",
"3/30/2018",
"12/25/2018",
"1/1/2019",
"4/19/2019",
"12/25/2019",
"1/1/2020"
],
"earlyCloses": {
"1/19/2009": "10:30:00",
"2/16/2009": "10:30:00",
"5/25/2009": "10:30:00",
"7/3/2009": "10:30:00",
"9/7/2009": "10:30:00",
"11/26/2009": "10:30:00",
"11/27/2009": "12:15:00",
"12/24/2009": "12:15:00",
"1/18/2010": "10:30:00",
"2/15/2010": "10:30:00",
"5/31/2010": "10:30:00",
"7/5/2010": "10:30:00",
"9/6/2010": "10:30:00",
"11/25/2010": "10:30:00",
"11/26/2010": "12:15:00",
"1/17/2011": "10:30:00",
"2/21/2011": "10:30:00",
"5/30/2011": "10:30:00",
"7/4/2011": "10:30:00",
"9/5/2011": "10:30:00",
"11/24/2011": "10:30:00",
"11/25/2011": "12:15:00",
"1/16/2012": "10:30:00",
"2/20/2012": "10:30:00",
"5/28/2012": "10:30:00",
"7/3/2012": "12:15:00",
"7/4/2012": "10:30:00",
"9/3/2012": "10:30:00",
"11/22/2012": "10:30:00",
"11/23/2012": "12:15:00",
"12/24/2012": "12:15:00",
"1/21/2013": "10:30:00",
"2/18/2013": "10:30:00",
"5/27/2013": "10:30:00",
"7/3/2013": "12:15:00",
"7/4/2013": "10:30:00",
"7/5/2013": "15:15:00",
"9/2/2013": "10:30:00",
"11/28/2013": "10:30:00",
"11/29/2013": "12:15:00",
"12/24/2013": "12:15:00",
"12/26/2013": "15:15:00",
"1/2/2014": "15:15:00",
"1/20/2014": "10:30:00",
"2/17/2014": "10:30:00",
"5/26/2014": "12:00:00",
"7/3/2014": "12:00:00",
"9/1/2014": "12:00:00",
"11/27/2014": "12:00:00",
"11/28/2014": "12:15:00",
"12/24/2014": "12:15:00",
"1/19/2015": "12:00:00",
"2/16/2015": "12:00:00",
"4/3/2015": "08:15:00",
"5/25/2015": "12:00:00",
"7/3/2015": "12:00:00",
"9/7/2015": "12:00:00",
"11/26/2015": "12:00:00",
"11/27/2015": "12:15:00",
"12/24/2015": "12:15:00",
"1/18/2016": "12:00:00",
"2/15/2016": "12:00:00",
"5/30/2016": "12:00:00",
"7/4/2016": "12:00:00",
"9/5/2016": "12:00:00",
"11/24/2016": "12:00:00",
"11/25/2016": "12:15:00",
"1/16/2017": "12:00:00",
"2/20/2017": "12:00:00",
"5/29/2017": "12:00:00",
"7/3/2017": "12:15:00",
"7/4/2017": "12:00:00",
"9/4/2017": "12:00:00",
"11/23/2017": "12:00:00",
"11/24/2017": "12:15:00",
"1/15/2018": "12:00:00",
"2/19/2018": "12:00:00",
"5/28/2018": "12:00:00",
"7/3/2018": "12:15:00",
"7/4/2018": "12:00:00",
"9/3/2018": "12:00:00",
"11/22/2018": "12:00:00",
"11/23/2018": "12:15:00",
"12/24/2018": "12:15:00",
"1/21/2019": "12:00:00",
"2/18/2019": "12:00:00",
"5/27/2019": "12:00:00",
"7/3/2019": "12:15:00",
"7/4/2019": "12:00:00",
"9/2/2019": "12:00:00",
"11/28/2019": "12:00:00",
"11/29/2019": "12:15:00",
"12/24/2019": "12:15:00"
}
},
"Future-cboe-VX": {
"dataTimeZone": "UTC",

View File

@@ -1,5 +1,5 @@
#
# LEAN Foundation Docker Container 20200428
# LEAN Foundation Docker Container 20201214
# Cross platform deployment for multiple brokerages
# Intended to be used in conjunction with Dockerfile. This is just the foundation common OS+Dependencies required.
#
@@ -18,19 +18,17 @@ RUN env TZ=UTC
# Install OS Packages:
# Misc tools for running Python.NET and IB inside a headless container.
RUN add-apt-repository ppa:ubuntu-toolchain-r/test && apt-get update
RUN apt-get install -y git bzip2 clang cmake curl unzip wget python3-pip python-opengl zlib1g-dev && \
apt-get install -y xvfb libxrender1 libxtst6 libxi6 libglib2.0-dev libopenmpi-dev libstdc++6 openmpi-bin && \
# Install R
apt-get install -y r-base pandoc libcurl4-openssl-dev
# Java for running IB inside container:
RUN apt-get install -y openjdk-8-jdk openjdk-8-jre
RUN add-apt-repository ppa:apt-fast/stable && apt-get update && apt-get -y install apt-fast
RUN apt-fast install -y git bzip2 clang cmake curl unzip wget python3-pip python-opengl zlib1g-dev \
xvfb libxrender1 libxtst6 libxi6 libglib2.0-dev libopenmpi-dev libstdc++6 openmpi-bin \
r-base pandoc libcurl4-openssl-dev \
openjdk-8-jdk openjdk-8-jre
# Install IB Gateway: Installs to ~/Jts
RUN wget http://cdn.quantconnect.com/interactive/ibgateway-stable-standalone-linux-x64-v978.2c.sh && \
RUN wget https://cdn.quantconnect.com/interactive/ibgateway-stable-standalone-linux-x64-v978.2c.sh && \
chmod 777 ibgateway-stable-standalone-linux-x64-v978.2c.sh && \
./ibgateway-stable-standalone-linux-x64-v978.2c.sh -q && \
wget -O ~/Jts/jts.ini http://cdn.quantconnect.com/interactive/ibgateway-latest-standalone-linux-x64-v974.4g.jts.ini && \
wget -O ~/Jts/jts.ini https://cdn.quantconnect.com/interactive/ibgateway-latest-standalone-linux-x64-v974.4g.jts.ini && \
rm ibgateway-stable-standalone-linux-x64-v978.2c.sh
# Mono C# for LEAN:
@@ -38,8 +36,8 @@ RUN wget http://cdn.quantconnect.com/interactive/ibgateway-stable-standalone-lin
RUN apt-get update && rm -rf /var/lib/apt/lists/*
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
RUN echo "deb http://download.mono-project.com/repo/ubuntu stable-xenial/snapshots/5.12.0.226 main" > /etc/apt/sources.list.d/mono-xamarin.list && \
apt-get update && apt-get install -y binutils mono-complete ca-certificates-mono mono-vbnc nuget referenceassemblies-pcl && \
apt-get install -y fsharp && rm -rf /var/lib/apt/lists/* /tmp/*
apt-get update && apt-fast install -y binutils mono-complete ca-certificates-mono mono-vbnc nuget referenceassemblies-pcl && \
apt-fast install -y fsharp && rm -rf /var/lib/apt/lists/* /tmp/*
# Install miniconda
ENV CONDA="Miniconda3-4.5.12-Linux-x86_64.sh"
@@ -53,193 +51,189 @@ RUN wget https://cdn.quantconnect.com/miniconda/${CONDA} && \
RUN conda update -y conda pip
# Updates pip
RUN pip install --upgrade pip
RUN pip install --upgrade --no-cache-dir pip
# Sets python version to 3.6.8
RUN conda install -y python=3.6.8
RUN conda clean -y --all
# Install essential packages
# Conda install required so that the packages are not
# overwritten and have their version invalidated by
# subsequent calls to conda install
RUN conda install -y \
cython=0.29.15 \
numpy=1.18.1 \
cython=0.29.17 \
pandas=0.25.3 \
wrapt=1.12.1
numpy=1.18.1
# Install all packages
RUN pip install --no-cache-dir \
wrapt==1.12.1 \
astropy==4.0.1.post1 \
beautifulsoup4==4.9.0 \
dill==0.3.1.1 \
jsonschema==3.2.0 \
lxml==4.5.0 \
msgpack==1.0.0 \
numba==0.46 \
setuptools-git==1.2 \
xarray==0.15.1 \
plotly==4.7.1 \
jupyterlab==2.1.2 \
tensorflow==1.15.2 \
docutils==0.14 \
cvxopt==1.2.0 \
gensim==3.8.0 \
Keras==2.3.1 \
lightgbm==2.3.0 \
mpi4py==3.0.3 \
nltk==3.4.5 \
pomegranate==0.11.1 \
graphviz==0.8.4 \
cmdstanpy==0.4 \
copulae==0.3.1 \
featuretools==0.14.0 \
fbprophet==0.6 \
PuLP==1.6.8 \
pymc3==3.8 \
rauth==0.7.3 \
scikit-learn==0.21.3 \
scikit-multiflow==0.4.1 \
scikit-optimize==0.7.4 \
Theano==1.0.4 \
tsfresh==0.15.1 \
tslearn==0.3.1 \
tweepy==3.8.0 \
PyWavelets==1.1.1 \
umap-learn==0.4.3 \
nvidia-ml-py3==7.352.0 \
fastai==1.0.61 \
arch==4.14 \
copulalib==1.1.0 \
copulas==0.3.3 \
creme==0.5.1 \
cufflinks==0.17.3 \
gym==0.17.2 \
ipywidgets==7.5.1 \
deap==1.3.1 \
cvxpy==1.0.31 \
pykalman==0.9.5 \
pyportfolioopt==1.2.2 \
pyramid-arima==0.9.0 \
pyro-ppl==1.3.1 \
riskparityportfolio==0.2 \
sklearn==0.0 \
sklearn-json==0.1.0 \
stable-baselines==2.10.0 \
statistics==1.0.3.5 \
statsmodels==0.11.1 \
tensorforce==0.5.4 \
QuantLib-Python==1.18 \
xgboost==1.1.0 \
dtw-python==1.0.5 \
cntk==2.7 \
mxnet==1.6 \
gluonts==0.4.3 \
gplearn==0.4.1 \
jax==0.1.68 \
jaxlib==0.1.47 \
keras-rl==0.4.2 \
pennylane==0.9.0 \
neural-tangents==0.2.1 \
mplfinance==0.12.4a0 \
hmmlearn==0.2.3 \
catboost==0.23.2 \
fastai2==0.0.17 \
ppscore==0.0.2 \
scikit-tda==0.0.3 \
ta==0.5.25
RUN wget -O mlfinlab.zip https://cdn.quantconnect.com/mlfinlab/mlfinlab-0.9.3.zip && \
unzip -q mlfinlab.zip && \
mkdir -p /opt/miniconda3/lib/python3.6/site-packages/ && \
mv mlfinlab /opt/miniconda3/lib/python3.6/site-packages/
RUN conda install -y -c conda-forge \
openmpi=4.0.3
# Install non-math packages
RUN conda install -y \
astropy=4.0.1.post1 \
beautifulsoup4=4.9.0 \
blaze=0.11.3 \
dill=0.3.1.1 \
jsonschema=3.2.0 \
lxml=4.5.0 \
msgpack-python=1.0.0 \
numba=0.46 \
setuptools-git=1.2 \
xarray=0.15.1
RUN conda install -y -c plotly \
plotly=4.6.0
RUN conda install -y -c conda-forge \
jupyterlab=2.1.0
# Install TensorFlow 1.15.2
RUN pip install tensorflow==1.15.2
# Install math/ML packages
RUN conda install -y \
docutils=0.14 \
cvxopt=1.2.0 \
gensim=3.8.0 \
keras=2.3.1 \
lightgbm=2.3.0 \
nltk=3.4.5 \
pomegranate=0.11.1 \
tensorflow-base=1.15.0 \
python-graphviz=0.8.4
# Install requirement for fbprophet
RUN pip install cmdstanpy==0.4
# Install math/ML from conda-forge
RUN conda install -y -c conda-forge \
copulae=0.3.1 \
featuretools=0.13.4 \
fbprophet=0.6 \
pulp=1.6.8 \
pymc3=3.8 \
rauth=0.7.3 \
scikit-learn=0.21.3 \
scikit-multiflow=0.4.1 \
scikit-optimize=0.7.4 \
theano=1.0.4 \
tsfresh=0.15.1 \
tslearn=0.3.1 \
tweepy=3.8.0 \
pywavelets=1.1.1 \
umap-learn=0.4.1
tensorflow-base=1.15.0
# Install math/ML from pytorch
RUN conda install -y -c pytorch \
pytorch=1.5.0 \
torchvision=0.6.0
# Install math/ML from fastai
RUN conda install -y -c fastai \
nvidia-ml-py3=7.352.0 \
fastai=1.0.60
RUN conda clean -y --all
# Install from PIP I
RUN pip install arch==4.14 \
copulalib==1.1.0 \
copulas==0.3.0 \
creme==0.5.1 \
cufflinks==0.17.3 \
gym==0.17.1 \
ipywidgets==7.5.1
# Install from PIP II
RUN pip install deap==1.3.1 \
cvxpy==1.1.0a3 \
mlfinlab==0.9.3 \
pykalman==0.9.5 \
pyportfolioopt==1.1.0 \
pyramid-arima==0.9.0 \
pyro-ppl==1.3.1 \
riskparityportfolio==0.1.6
# Install from PIP III
RUN pip install sklearn==0.0 \
stable-baselines==2.10.0 \
statistics==1.0.3.5 \
statsmodels==0.11.1 \
tensorforce==0.5.4 \
QuantLib-Python==1.18 \
xgboost==1.0.2 \
dtw-python==1.0.5
# Install from PIP IV
RUN pip install cntk==2.7 \
mxnet==1.6 \
gluonts==0.4.3 \
gplearn==0.4.1 \
jax==0.1.64 \
jaxlib==0.1.45 \
keras-rl==0.4.2 \
pennylane==0.8.1
# Install Google Neural Tangents after JAX
RUN pip install neural-tangents==0.2.1
RUN pip install --upgrade mplfinance==0.12.3a3
RUN pip install --upgrade hmmlearn==0.2.3
RUN python -m nltk.downloader -d /usr/share/nltk_data punkt
RUN python -m nltk.downloader -d /usr/share/nltk_data vader_lexicon
# Install TA-lib for python
RUN wget http://cdn.quantconnect.com/ta-lib/ta-lib-0.4.0-src.tar.gz && \
tar -zxvf ta-lib-0.4.0-src.tar.gz && cd ta-lib && \
./configure --prefix=/usr && make && make install && \
pip install TA-lib && cd .. && rm -irf ta-lib
# Install DX Analytics
RUN wget https://cdn.quantconnect.com/dx/dx-master-9fab393.zip && \
unzip -q dx-master-9fab393 && cd dx-master && \
python setup.py install && cd .. && rm -irf dx-master
# Install py-earth
RUN wget https://cdn.quantconnect.com/py-earth/py-earth-master-b209d19.zip && \
unzip -q py-earth-master-b209d19.zip && cd py-earth-master && \
python setup.py install && cd .. && rm -irf py-earth-master
# Install fastText
RUN wget https://cdn.quantconnect.com/fastText/fastText-master-6d7c77c.zip && \
unzip -q fastText-master-6d7c77c.zip && cd fastText-master && \
python setup.py install && cd .. && rm -irf fastText-master
# Update ODO
RUN conda remove --force-remove -y odo
RUN wget https://cdn.quantconnect.com/odo/odo-master-9fce669.zip && \
unzip -q odo-master-9fce669.zip && cd odo-master && \
python setup.py install && cd .. && rm -irf odo-master
pip install . && cd .. && rm -rf odo-master
# Install DX Analytics
RUN wget https://cdn.quantconnect.com/dx/dx-master-4c47c25.zip && \
unzip -q dx-master-4c47c25.zip && cd dx-master && \
pip install . && cd .. && rm -rf dx-master
# Install Auto-KS
RUN wget https://cdn.quantconnect.com/auto_ks/auto_ks-master-b39e8f3.zip && \
unzip -q auto_ks-master-b39e8f3.zip && cd auto_ks-master && \
python setup.py install && cd .. && rm -irf auto_ks-master
pip install . && cd .. && rm -rf auto_ks-master
# Install Pyrb
RUN wget https://cdn.quantconnect.com/pyrb/pyrb-master-d02b56a.zip && \
unzip -q pyrb-master-d02b56a.zip && cd pyrb-master && \
python setup.py install && cd .. && rm -irf pyrb-master
pip install . && cd .. && rm -rf pyrb-master
# Install SSM
RUN wget https://cdn.quantconnect.com/ssm/ssm-master-34b50d4.zip && \
unzip -q ssm-master-34b50d4.zip && cd ssm-master && \
python setup.py install && cd .. && rm -irf ssm-master
RUN wget https://cdn.quantconnect.com/ssm/ssm-9fd66aed.zip && \
unzip -q ssm-9fd66aed.zip && cd ssm && \
pip install . && cd .. && rm -rf ssm
# Install TA-lib for python
RUN wget https://cdn.quantconnect.com/ta-lib/ta-lib-0.4.0-src.tar.gz && \
tar -zxvf ta-lib-0.4.0-src.tar.gz && cd ta-lib && \
./configure --prefix=/usr && make && make install && \
wget https://cdn.quantconnect.com/ta-lib/TA_Lib-0.4.18.zip && \
unzip -q TA_Lib-0.4.18.zip && cd ta-lib-TA_Lib-0.4.18 && \
python setup.py install && cd ../.. && rm -rf ta-lib
# Install py-earth
RUN wget https://cdn.quantconnect.com/py-earth/py-earth-0.1.0.zip && \
unzip -q py-earth-0.1.0.zip && cd py-earth-0.1.0 && \
python setup.py install && cd .. && rm -rf py-earth-0.1.0
# Install fastText
RUN wget https://cdn.quantconnect.com/fastText/fastText-0.9.2.zip && \
unzip -q fastText-0.9.2.zip && cd fastText-0.9.2 && \
pip install . && cd .. && rm -rf fastText-0.9.2
# Install Tigramite
RUN wget https://cdn.quantconnect.com/tigramite/tigramite-master-eee4809.zip && \
unzip -q tigramite-master-eee4809.zip && cd tigramite-master && \
python setup.py install && cd .. && rm -irf tigramite-master
RUN wget https://cdn.quantconnect.com/tigramite/tigramite-4.1.zip && \
unzip -q tigramite-4.1.zip && cd tigramite-4.1 && \
python setup.py install && cd .. && rm -rf tigramite-4.1
# Install H2O
RUN wget https://cdn.quantconnect.com/h2o/h2o-3.30.0.1.zip && \
unzip -q h2o-3.30.0.1.zip && \
pip install h2o-3.30.0.1/python/h2o-3.30.0.1-py2.py3-none-any.whl && \
rm -irf h2o-3.30.0.1
# Install H2O: https://www.h2o.ai/download/
RUN wget https://cdn.quantconnect.com/h2o/h2o-3.30.0.3.zip && \
unzip -q h2o-3.30.0.3.zip && \
pip install h2o-3.30.0.3/python/h2o-3.30.0.3-py2.py3-none-any.whl && \
rm -rf h2o-3.30.0.3
# Delete temporary zip files
RUN rm -irf *.zip *.gz
RUN rm -rf *.zip *.gz
# Remove black-listed packages
RUN pip uninstall -y s3transfer
RUN conda remove --force-remove -y s3transfer
RUN conda clean -y --all
# Clean up any unused packages installed by apt-get
RUN apt-get autoremove --purge -y
# List all packages
RUN conda list
RUN conda list

View File

@@ -1030,19 +1030,26 @@ namespace QuantConnect.Lean.Engine
{
for (var i = delistings.Count - 1; i >= 0; i--)
{
// check if we are holding position
var security = algorithm.Securities[delistings[i].Symbol];
var delisting = delistings[i];
var security = algorithm.Securities[delisting.Symbol];
if (security.Holdings.Quantity == 0)
{
continue;
}
// check if the time has come for delisting
var delistingTime = delistings[i].Time;
var nextMarketOpen = security.Exchange.Hours.GetNextMarketOpen(delistingTime, false);
var nextMarketClose = security.Exchange.Hours.GetNextMarketClose(nextMarketOpen, false);
var delistingTime = delisting.Time;
if (!security.Exchange.Hours.IsOpen(delistingTime, false))
{
// This exists as a defensive measure to ensure that the delisting time
// does not get moved if the market is open. If the market is closed,
// we get the next market open, which will be on the same day if the delisting
// date is a trading day. If the delisting date is after market close, then
// the delisting will be adjusted to the next market open.
delistingTime = security.Exchange.Hours.GetNextMarketOpen(delistingTime, false);
delistingTime = security.Exchange.Hours.GetNextMarketClose(delistingTime, false);
}
if (security.LocalTime < nextMarketClose)
if (security.LocalTime < delistingTime)
{
continue;
}

View File

@@ -31,6 +31,7 @@ namespace QuantConnect.Lean.Engine.DataFeeds
private readonly int _uid = Config.GetInt("job-user-id", 0);
private readonly string _token = Config.Get("api-access-token", "1");
private readonly string _dataPath = Config.Get("data-folder", "../../../Data/");
private static readonly int DownloadPeriod = Config.GetInt("api-data-update-period", 5);
private readonly Api.Api _api;
/// <summary>
@@ -51,40 +52,70 @@ namespace QuantConnect.Lean.Engine.DataFeeds
/// <returns>A <see cref="Stream"/> of the data requested</returns>
public Stream Fetch(string key)
{
if (File.Exists(key))
{
return new FileStream(key, FileMode.Open, FileAccess.Read, FileShare.Read);
}
// If the file cannot be found on disc, attempt to retrieve it from the API
Symbol symbol;
DateTime date;
Resolution resolution;
// Fetch the details of this data request
if (LeanData.TryParsePath(key, out symbol, out date, out resolution))
{
Log.Trace("ApiDataProvider.Fetch(): Attempting to get data from QuantConnect.com's data library for symbol({0}), resolution({1}) and date({2}).",
if (!File.Exists(key) || IsOutOfDate(resolution, key))
{
return DownloadData(key, symbol, date, resolution);
}
// Use the file already on the disk
return new FileStream(key, FileMode.Open, FileAccess.Read, FileShare.Read);
}
Log.Error("ApiDataProvider.Fetch(): failed to parse key {0}", key);
return null;
}
/// <summary>
/// Determine if the file is out of date based on configuration and needs to be updated
/// </summary>
/// <param name="resolution">Data resolution</param>
/// <param name="filepath">Path to the file</param>
/// <returns>True if the file is out of date</returns>
/// <remarks>Files are only "out of date" for Hourly/Daily data because this data is stored all in one file</remarks>
public static bool IsOutOfDate(Resolution resolution, string filepath)
{
return resolution >= Resolution.Hour &&
(DateTime.Now - TimeSpan.FromDays(DownloadPeriod)) > File.GetLastWriteTime(filepath);
}
/// <summary>
/// Attempt to download data using the Api for and return a FileStream of that data.
/// </summary>
/// <param name="key"></param>
/// <param name="symbol"></param>
/// <param name="date"></param>
/// <param name="resolution"></param>
/// <returns>A FileStream of the data</returns>
private FileStream DownloadData(string filepath, Symbol symbol, DateTime date, Resolution resolution)
{
Log.Trace("ApiDataProvider.Fetch(): Attempting to get data from QuantConnect.com's data library for symbol({0}), resolution({1}) and date({2}).",
symbol.Value,
resolution,
date.Date.ToShortDateString());
var downloadSuccessful = _api.DownloadData(symbol, resolution, date);
if (downloadSuccessful)
{
Log.Trace("ApiDataProvider.Fetch(): Successfully retrieved data for symbol({0}), resolution({1}) and date({2}).",
symbol.Value,
resolution,
date.Date.ToShortDateString());
var downloadSuccessful = _api.DownloadData(symbol, resolution, date);
if (downloadSuccessful)
{
Log.Trace("ApiDataProvider.Fetch(): Successfully retrieved data for symbol({0}), resolution({1}) and date({2}).",
symbol.Value,
resolution,
date.Date.ToShortDateString());
return new FileStream(key, FileMode.Open, FileAccess.Read, FileShare.Read);
}
return new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.Read);
}
// Failed to download
Log.Error("ApiDataProvider.Fetch(): Unable to remotely retrieve data for path {0}. " +
"Please make sure you have the necessary data in your online QuantConnect data library.",
key);
"Please make sure you have the necessary data in your online QuantConnect data library.",
filepath);
return null;
}
}

View File

@@ -45,7 +45,6 @@ namespace QuantConnect.Lean.Engine.DataFeeds.Enumerators
private readonly DateTime _subscriptionEndTimeRoundDownByDataResolution;
private readonly IEnumerator<BaseData> _enumerator;
private readonly IReadOnlyRef<TimeSpan> _fillForwardResolution;
private readonly TimeZoneOffsetProvider _offsetProvider;
/// <summary>
/// The exchange used to determine when to insert fill forward data
@@ -65,15 +64,13 @@ namespace QuantConnect.Lean.Engine.DataFeeds.Enumerators
/// <param name="dataResolution">The source enumerator's data resolution</param>
/// <param name="dataTimeZone">The time zone of the underlying source data. This is used for rounding calculations and
/// is NOT the time zone on the BaseData instances (unless of course data time zone equals the exchange time zone)</param>
/// <param name="subscriptionStartTime">The subscriptions start time</param>
public FillForwardEnumerator(IEnumerator<BaseData> enumerator,
SecurityExchange exchange,
IReadOnlyRef<TimeSpan> fillForwardResolution,
bool isExtendedMarketHours,
DateTime subscriptionEndTime,
TimeSpan dataResolution,
DateTimeZone dataTimeZone,
DateTime subscriptionStartTime
DateTimeZone dataTimeZone
)
{
_subscriptionEndTime = subscriptionEndTime;
@@ -83,9 +80,6 @@ namespace QuantConnect.Lean.Engine.DataFeeds.Enumerators
_dataTimeZone = dataTimeZone;
_fillForwardResolution = fillForwardResolution;
_isExtendedMarketHours = isExtendedMarketHours;
_offsetProvider = new TimeZoneOffsetProvider(Exchange.TimeZone,
subscriptionStartTime.ConvertToUtc(Exchange.TimeZone),
subscriptionEndTime.ConvertToUtc(Exchange.TimeZone));
// '_dataResolution' and '_subscriptionEndTime' are readonly they won't change, so lets calculate this once here since it's expensive
_subscriptionEndTimeRoundDownByDataResolution = RoundDown(_subscriptionEndTime, _dataResolution);
}
@@ -271,16 +265,6 @@ namespace QuantConnect.Lean.Engine.DataFeeds.Enumerators
return false;
}
// define real delta, can be bigger than data resolution, for example during weekend
var nextPreviousTimeDelta = next.Time - previous.Time;
// 1. Utc => allows us to define did we swallow hour when calculated EndTime (Time+Period) or not,
// for example, with data resolution 1 day and dataTimeZone = UTC we have next.Time 20111105 20:00, next.EndTime = 20111106 20:00
// but converting these values to UTC we have next.Time 20111106 00:00 (recognized as EDT), next.EndTime = 20111107 01:00 (recognized as EST)
// 2. previous.Time - next.Time => gives us real delta time in local time zone - not necessary equals data resolution(for weekend)
// 3. dataResolution => we use EndTime
var daylightMovement = nextEndTimeUtc - (previousTimeUtc + nextPreviousTimeDelta + _dataResolution);
// every bar emitted MUST be of the data resolution.
// compute end times of the four potential fill forward scenarios
@@ -294,20 +278,58 @@ namespace QuantConnect.Lean.Engine.DataFeeds.Enumerators
foreach (var item in GetSortedReferenceDateIntervals(previous, fillForwardResolution, _dataResolution))
{
// add interval in utc to avoid daylight savings from swallowing it, see GH 3707
var potentialUtc = _offsetProvider.ConvertToUtc(item.ReferenceDateTime) + item.Interval;
var potentialInTimeZone = _offsetProvider.ConvertFromUtc(potentialUtc);
var potentialBarEndTime = RoundDown(potentialInTimeZone, item.Interval);
// apply the same timezone to next and potential bars because incoming next.EndTime can swallow one hour
var nextEndTime = next.EndTime - daylightMovement;
if (potentialBarEndTime < nextEndTime)
// issue GH 4925 , more description https://github.com/QuantConnect/Lean/pull/4941
// To build Time/EndTime we always use '+'/'-' dataResolution
// DataTime TZ = UTC -5; Exchange TZ = America/New York (-5/-4)
// Standard TimeZone 00:00:00 + 1 day = 1.00:00:00
// Daylight Time 01:00:00 + 1 day = 1.01:00:00
// daylight saving time starts/end at 2 a.m. on Sunday
// Having this information we find that the specific bar of Sunday
// Starts in one TZ (Standard TZ), but finishes in another (Daylight TZ) (consider winter => summer)
// During simple arithmetic operations like +/- we shift the time, but not the time zone
// which is sensitive for specific dates (daylight movement) if we are in Exchange TimeZone, for example
// We have 00:00:00 + 1 day = 1.00:00:00, so both are in Standard TZ, but we expect endTime in Daylight, i.e. 1.01:00:00
// futher down double Convert (Exchange TZ => data TZ => Exchange TZ)
// allows us to calculate Time using it's own TZ (aka reapply)
// and don't rely on TZ of bar start/end time
// i.e. 00:00:00 + 1 day = 1.01:00:00, both start and end are in their own TZ
// it's interesting that NodaTime consider next
// if time great or equal than 01:00 AM it's considered as "moved" (Standard, not Daylight)
// when time less than 01:00 AM it's considered as previous TZ (Standard, not Daylight)
// it's easy to fix this behavior by substract 1 tick before first convert, and then return it back.
// so we work with 0:59:59.. AM instead.
// but now follow native behavior
// all above means, that all Time values, calculated using simple +/- operations
// sticks to original Time Zone, swallowing its own TZ and movement i.e.
// EndTime = Time + resolution, both Time and EndTime in the TZ of Time (Standard/Daylight)
// Time = EndTime - resolution, both Time and EndTime in the TZ of EndTime (Standard/Daylight)
// next.EndTime sticks to Time TZ,
// potentialBarEndTime should be calculated in the same way as bar.EndTime, i.e. Time + resolution
var potentialBarEndTime = RoundDown(item.ReferenceDateTime, item.Interval).ConvertToUtc(Exchange.TimeZone) + item.Interval;
// to avoid duality it's necessary to compare potentialBarEndTime with
// next.EndTime calculated as Time + resolution,
// and both should be based on the same TZ (for example UTC)
if (potentialBarEndTime < (next.Time.ConvertToUtc(Exchange.TimeZone) + _dataResolution))
{
var nextFillForwardBarStartTime = potentialBarEndTime - item.Interval;
if (Exchange.IsOpenDuringBar(nextFillForwardBarStartTime, potentialBarEndTime, _isExtendedMarketHours))
// to check open hours we need to convert potential
// bar EndTime into exchange time zone
var potentialBarEndTimeInExchangeTZ =
potentialBarEndTime.ConvertFromUtc(Exchange.TimeZone);
var nextFillForwardBarStartTime = potentialBarEndTimeInExchangeTZ - item.Interval;
if (Exchange.IsOpenDuringBar(nextFillForwardBarStartTime, potentialBarEndTimeInExchangeTZ, _isExtendedMarketHours))
{
fillForward = previous.Clone(true);
fillForward.Time = potentialBarEndTime - _dataResolution; // bar are ALWAYS of the data resolution
fillForward.EndTime = potentialBarEndTime;
// bar are ALWAYS of the data resolution
fillForward.Time = (potentialBarEndTime - _dataResolution).ConvertFromUtc(Exchange.TimeZone);
fillForward.EndTime = potentialBarEndTimeInExchangeTZ;
return true;
}
}
@@ -380,7 +402,7 @@ namespace QuantConnect.Lean.Engine.DataFeeds.Enumerators
result.Add(new ReferenceDateInterval(marketOpen, largerResolution));
// we need to order them because they might not be in an incremental order and consumer expects them to be
foreach(var referenceDateInterval in result.OrderBy(interval => interval.ReferenceDateTime + interval.Interval))
foreach (var referenceDateInterval in result.OrderBy(interval => interval.ReferenceDateTime + interval.Interval))
{
yield return referenceDateInterval;
}

View File

@@ -45,9 +45,8 @@ namespace QuantConnect.Lean.Engine.DataFeeds.Enumerators
/// <param name="subscriptionEndTime">The end time of the subscription, once passing this date the enumerator will stop</param>
/// <param name="dataResolution">The source enumerator's data resolution</param>
/// <param name="dataTimeZone">Time zone of the underlying source data</param>
/// <param name="subscriptionStartTime">The start time of the subscription</param>
public LiveFillForwardEnumerator(ITimeProvider timeProvider, IEnumerator<BaseData> enumerator, SecurityExchange exchange, IReadOnlyRef<TimeSpan> fillForwardResolution, bool isExtendedMarketHours, DateTime subscriptionEndTime, TimeSpan dataResolution, DateTimeZone dataTimeZone, DateTime subscriptionStartTime)
: base(enumerator, exchange, fillForwardResolution, isExtendedMarketHours, subscriptionEndTime, dataResolution, dataTimeZone, subscriptionStartTime)
public LiveFillForwardEnumerator(ITimeProvider timeProvider, IEnumerator<BaseData> enumerator, SecurityExchange exchange, IReadOnlyRef<TimeSpan> fillForwardResolution, bool isExtendedMarketHours, DateTime subscriptionEndTime, TimeSpan dataResolution, DateTimeZone dataTimeZone)
: base(enumerator, exchange, fillForwardResolution, isExtendedMarketHours, subscriptionEndTime, dataResolution, dataTimeZone)
{
_timeProvider = timeProvider;
}

View File

@@ -205,7 +205,7 @@ namespace QuantConnect.Lean.Engine.DataFeeds
var fillForwardResolution = _subscriptions.UpdateAndGetFillForwardResolution(request.Configuration);
enumerator = new FillForwardEnumerator(enumerator, request.Security.Exchange, fillForwardResolution,
request.Configuration.ExtendedMarketHours, request.EndTimeLocal, request.Configuration.Resolution.ToTimeSpan(), request.Configuration.DataTimeZone, request.StartTimeLocal);
request.Configuration.ExtendedMarketHours, request.EndTimeLocal, request.Configuration.Resolution.ToTimeSpan(), request.Configuration.DataTimeZone);
}
// optionally apply exchange/user filters

View File

@@ -252,7 +252,7 @@ namespace QuantConnect.Lean.Engine.DataFeeds
{
var fillForwardResolution = _subscriptions.UpdateAndGetFillForwardResolution(request.Configuration);
enumerator = new LiveFillForwardEnumerator(_frontierTimeProvider, enumerator, request.Security.Exchange, fillForwardResolution, request.Configuration.ExtendedMarketHours, localEndTime, request.Configuration.Increment, request.Configuration.DataTimeZone, request.StartTimeLocal);
enumerator = new LiveFillForwardEnumerator(_frontierTimeProvider, enumerator, request.Security.Exchange, fillForwardResolution, request.Configuration.ExtendedMarketHours, localEndTime, request.Configuration.Increment, request.Configuration.DataTimeZone);
}
// define market hours and user filters to incoming data
@@ -346,7 +346,7 @@ namespace QuantConnect.Lean.Engine.DataFeeds
{
var fillForwardResolution = _subscriptions.UpdateAndGetFillForwardResolution(subRequest.Configuration);
var input = _dataQueueHandler.Subscribe(subRequest.Configuration, (sender, args) => subscription.OnNewDataAvailable());
return new LiveFillForwardEnumerator(_frontierTimeProvider, input, subRequest.Security.Exchange, fillForwardResolution, subRequest.Configuration.ExtendedMarketHours, localEndTime, subRequest.Configuration.Increment, subRequest.Configuration.DataTimeZone, subRequest.StartTimeLocal);
return new LiveFillForwardEnumerator(_frontierTimeProvider, input, subRequest.Security.Exchange, fillForwardResolution, subRequest.Configuration.ExtendedMarketHours, localEndTime, subRequest.Configuration.Increment, subRequest.Configuration.DataTimeZone);
};
var symbolUniverse = _dataQueueHandler as IDataQueueUniverseProvider;

View File

@@ -14,16 +14,15 @@
*/
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Interfaces;
using System.Runtime.Caching;
using QuantConnect.Data.Fundamental;
using QuantConnect.Data.Market;
using System.Collections.Generic;
using QuantConnect.Data.Fundamental;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Logging;
namespace QuantConnect.Lean.Engine.DataFeeds
{
@@ -39,14 +38,10 @@ namespace QuantConnect.Lean.Engine.DataFeeds
private readonly SubscriptionDataConfig _config;
private BaseData _factory;
private bool _shouldCacheDataPoints;
private static readonly MemoryCache BaseDataSourceCache = new MemoryCache("BaseDataSourceCache",
// Cache can use up to 70% of the installed physical memory
new NameValueCollection { { "physicalMemoryLimitPercentage", "70" } });
private static readonly CacheItemPolicy CachePolicy = new CacheItemPolicy
{
// Cache entry should be evicted if it has not been accessed in given span of time:
SlidingExpiration = TimeSpan.FromMinutes(5)
};
private static int CacheSize = 100;
private static volatile Dictionary<string, List<BaseData>> BaseDataSourceCache = new Dictionary<string, List<BaseData>>(100);
private static Queue<string> CacheKeys = new Queue<string>(100);
/// <summary>
/// Event fired when the specified source is considered invalid, this may
@@ -105,15 +100,20 @@ namespace QuantConnect.Lean.Engine.DataFeeds
/// <returns>An <see cref="IEnumerable{BaseData}"/> that contains the data in the source</returns>
public override IEnumerable<BaseData> Read(SubscriptionDataSource source)
{
List<BaseData> cache;
List<BaseData> cache = null;
_shouldCacheDataPoints = _shouldCacheDataPoints &&
// only cache local files
source.TransportMedium == SubscriptionTransportMedium.LocalFile;
var cacheItem = _shouldCacheDataPoints
? BaseDataSourceCache.GetCacheItem(source.Source + _config.Type) : null;
if (cacheItem == null)
string cacheKey = null;
if (_shouldCacheDataPoints)
{
cache = new List<BaseData>();
cacheKey = source.Source + _config.Type;
BaseDataSourceCache.TryGetValue(cacheKey, out cache);
}
if (cache == null)
{
cache = _shouldCacheDataPoints ? new List<BaseData>(30000) : null;
using (var reader = CreateStreamReader(source))
{
// if the reader doesn't have data then we're done with this subscription
@@ -174,14 +174,34 @@ namespace QuantConnect.Lean.Engine.DataFeeds
yield break;
}
cacheItem = new CacheItem(source.Source + _config.Type, cache);
BaseDataSourceCache.Add(cacheItem, CachePolicy);
lock (CacheKeys)
{
CacheKeys.Enqueue(cacheKey);
// we create a new dictionary, so we don't have to take locks when reading, and add our new item
var newCache = new Dictionary<string, List<BaseData>>(BaseDataSourceCache) { [cacheKey] = cache };
if (BaseDataSourceCache.Count > CacheSize)
{
var removeCount = 0;
// we remove a portion of the first in entries
while (++removeCount < (CacheSize / 4))
{
newCache.Remove(CacheKeys.Dequeue());
}
// update the cache instance
BaseDataSourceCache = newCache;
}
else
{
// update the cache instance
BaseDataSourceCache = newCache;
}
}
}
cache = cacheItem.Value as List<BaseData>;
if (cache == null)
{
throw new InvalidOperationException("CacheItem can not be cast into expected type. " +
$"Type is: {cacheItem.Value.GetType()}");
throw new InvalidOperationException($"Cache should not be null. Key: {cacheKey}");
}
// Find the first data point 10 days (just in case) before the desired date
// and subtract one item (just in case there was a time gap and data.Time is after _date)
@@ -228,5 +248,19 @@ namespace QuantConnect.Lean.Engine.DataFeeds
var handler = CreateStreamReaderError;
if (handler != null) handler(this, new CreateStreamReaderErrorEventArgs(date, source));
}
/// <summary>
/// Set the cache size to use
/// </summary>
/// <remarks>How to size this cache: Take worst case scenario, BTCUSD hour, 60k QuoteBar entries, which are roughly 200 bytes in size -> 11 MB * CacheSize</remarks>
public static void SetCacheSize(int megaBytesToUse)
{
if (megaBytesToUse != 0)
{
// we take worst case scenario, each entry is 12 MB
CacheSize = megaBytesToUse / 12;
Log.Trace($"TextSubscriptionDataSourceReader.SetCacheSize(): Setting cache size to {CacheSize} items");
}
}
}
}

View File

@@ -91,6 +91,7 @@ namespace QuantConnect.Lean.Engine
try
{
TextSubscriptionDataSourceReader.SetCacheSize((int) (job.RamAllocation * 0.4));
//Reset thread holders.
var initializeComplete = false;

View File

@@ -172,7 +172,7 @@ namespace QuantConnect.Lean.Engine.HistoricalData
}
var readOnlyRef = Ref.CreateReadOnly(() => request.FillForwardResolution.Value.ToTimeSpan());
reader = new FillForwardEnumerator(reader, security.Exchange, readOnlyRef, request.IncludeExtendedMarketHours, endTimeLocal, config.Increment, config.DataTimeZone, startTimeLocal);
reader = new FillForwardEnumerator(reader, security.Exchange, readOnlyRef, request.IncludeExtendedMarketHours, endTimeLocal, config.Increment, config.DataTimeZone);
}
// since the SubscriptionDataReader performs an any overlap condition on the trade bar's entire

View File

@@ -148,7 +148,7 @@ namespace QuantConnect.Lean.Engine.HistoricalData
}
var readOnlyRef = Ref.CreateReadOnly(() => request.FillForwardResolution.Value.ToTimeSpan());
reader = new FillForwardEnumerator(reader, security.Exchange, readOnlyRef, request.IncludeExtendedMarketHours, end, config.Increment, config.DataTimeZone, start);
reader = new FillForwardEnumerator(reader, security.Exchange, readOnlyRef, request.IncludeExtendedMarketHours, end, config.Increment, config.DataTimeZone);
}
var subscriptionRequest = new SubscriptionRequest(false, null, security, config, request.StartTimeUtc, request.EndTimeUtc);

View File

@@ -361,13 +361,16 @@ namespace QuantConnect.Lean.Engine.Results
{
result = BacktestResultPacket.CreateEmpty(_job);
}
result.ProcessingTime = (DateTime.UtcNow - StartTime).TotalSeconds;
var utcNow = DateTime.UtcNow;
result.ProcessingTime = (utcNow - StartTime).TotalSeconds;
result.DateFinished = DateTime.Now;
result.Progress = 1;
//Place result into storage.
StoreResult(result);
result.Results.ServerStatistics = GetServerStatistics(utcNow);
//Second, send the truncated packet:
MessagingHandler.Send(result);
@@ -653,7 +656,7 @@ namespace QuantConnect.Lean.Engine.Results
/// <param name="message">Additional optional status message.</param>
public virtual void SendStatusUpdate(AlgorithmStatus status, string message = "")
{
var statusPacket = new AlgorithmStatusPacket(_algorithmId, _projectId, status, message);
var statusPacket = new AlgorithmStatusPacket(_algorithmId, _projectId, status, message) { OptimizationId = _job.OptimizationId };
MessagingHandler.Send(statusPacket);
}

View File

@@ -42,6 +42,8 @@ namespace QuantConnect.Lean.Engine.Results
private static readonly TextWriter StandardOut = Console.Out;
private static readonly TextWriter StandardError = Console.Error;
private string _hostName;
/// <summary>
/// The main loop update interval
/// </summary>
@@ -232,6 +234,7 @@ namespace QuantConnect.Lean.Engine.Results
protected virtual Dictionary<string, string> GetServerStatistics(DateTime utcNow)
{
var serverStatistics = OS.GetServerStatistics();
serverStatistics["Hostname"] = _hostName;
var upTime = utcNow - StartTime;
serverStatistics["Up Time"] = $"{upTime.Days}d {upTime:hh\\:mm\\:ss}";
serverStatistics["Total RAM (MB)"] = RamAllocation;
@@ -305,6 +308,7 @@ namespace QuantConnect.Lean.Engine.Results
/// <param name="transactionHandler">The transaction handler used to get the algorithms <see cref="Order"/> information</param>
public virtual void Initialize(AlgorithmNodePacket job, IMessagingHandler messagingHandler, IApi api, ITransactionHandler transactionHandler)
{
_hostName = job.HostName ?? Environment.MachineName;
MessagingHandler = messagingHandler;
TransactionHandler = transactionHandler;
CompileId = job.CompileId;

View File

@@ -236,11 +236,21 @@ namespace QuantConnect.Lean.Engine.Setup
//Set the source impl for the event scheduling
algorithm.Schedule.SetEventSchedule(parameters.RealTimeHandler);
var optionChainProvider = Composer.Instance.GetPart<IOptionChainProvider>();
if (optionChainProvider == null)
{
optionChainProvider = new CachingOptionChainProvider(new LiveOptionChainProvider());
}
// set the option chain provider
algorithm.SetOptionChainProvider(new CachingOptionChainProvider(new LiveOptionChainProvider()));
algorithm.SetOptionChainProvider(optionChainProvider);
var futureChainProvider = Composer.Instance.GetPart<IFutureChainProvider>();
if (futureChainProvider == null)
{
futureChainProvider = new CachingFutureChainProvider(new LiveFutureChainProvider());
}
// set the future chain provider
algorithm.SetFutureChainProvider(new CachingFutureChainProvider(new LiveFutureChainProvider()));
algorithm.SetFutureChainProvider(futureChainProvider);
// set the object store
algorithm.SetObjectStore(parameters.ObjectStore);

View File

@@ -0,0 +1,101 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using QuantConnect.Data.Market;
using System;
namespace QuantConnect.Indicators
{
/// <summary>
/// The Awesome Oscillator Indicator tracks the price midpoint-movement of a security. Specifically,
/// <para>
/// AO = MAfast[(H+L)/2] - MAslow[(H+L)/2]
/// </para>
/// where MAfast and MAslow denote simple moving averages wherein fast has a shorter period.
/// https://www.barchart.com/education/technical-indicators/awesome_oscillator
/// </summary>
public class AwesomeOscillator : BarIndicator, IIndicatorWarmUpPeriodProvider
{
/// <summary>
/// Gets the indicators slow period moving average.
/// </summary>
public IndicatorBase<IndicatorDataPoint> SlowAo { get; }
/// <summary>
/// Gets the indicators fast period moving average.
/// </summary>
public IndicatorBase<IndicatorDataPoint> FastAo { get; }
/// <summary>
/// Gets a flag indicating when this indicator is ready and fully initialized
/// </summary>
public override bool IsReady => SlowAo.IsReady && FastAo.IsReady;
/// <summary>
/// Required period, in data points, for the indicator to be ready and fully initialized.
/// </summary>
public int WarmUpPeriod { get; }
/// <summary>
/// Creates a new Awesome Oscillator from the specified periods.
/// </summary>
/// <param name="fastPeriod">The period of the fast moving average associated with the AO</param>
/// <param name="slowPeriod">The period of the slow moving average associated with the AO</param>
/// <param name="type">The type of moving average used when computing the fast and slow term. Defaults to simple moving average.</param>
public AwesomeOscillator(int fastPeriod, int slowPeriod, MovingAverageType type=MovingAverageType.Simple)
: this($"AO({fastPeriod},{slowPeriod},{type})", fastPeriod, slowPeriod, type)
{
}
/// <summary>
/// Creates a new Awesome Oscillator from the specified periods.
/// </summary>
/// <param name="name">The name of this indicator</param>
/// <param name="fastPeriod">The period of the fast moving average associated with the AO</param>
/// <param name="slowPeriod">The period of the slow moving average associated with the AO</param>
/// <param name="type">The type of moving average used when computing the fast and slow term. Defaults to simple moving average.</param>
public AwesomeOscillator(string name, int fastPeriod, int slowPeriod, MovingAverageType type=MovingAverageType.Simple)
: base(name)
{
SlowAo = type.AsIndicator(slowPeriod);
FastAo = type.AsIndicator(fastPeriod);
WarmUpPeriod = Math.Max(slowPeriod, fastPeriod);
}
/// <summary>
/// Computes the next value of this indicator from the given state.
/// </summary>
/// <param name="input">The input given to the indicator</param>
/// <returns>A new value for this indicator</returns>
protected override decimal ComputeNextValue(IBaseDataBar input)
{
var presentValue = (input.High + input.Low) / 2;
SlowAo.Update(input.Time, presentValue);
FastAo.Update(input.Time, presentValue);
return IsReady ? FastAo - SlowAo : 0m;
}
/// <summary>
/// Resets this indicator
/// </summary>
public override void Reset()
{
FastAo.Reset();
SlowAo.Reset();
base.Reset();
}
}
}

View File

@@ -0,0 +1,95 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using QuantConnect.Data.Market;
namespace QuantConnect.Indicators
{
/// <summary>
/// The Chaikin Money Flow Index (CMF) is a volume-weighted average of accumulation and distribution over
/// a specified period.
///
/// CMF = n-day Sum of [(((C - L) - (H - C)) / (H - L)) x Vol] / n-day Sum of Vol
///
/// Where:
/// n = number of periods, typically 21
/// H = high
/// L = low
/// C = close
/// Vol = volume
///
/// https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/cmf
/// </summary>
public class ChaikinMoneyFlow : TradeBarIndicator, IIndicatorWarmUpPeriodProvider
{
/// <summary>
/// Holds the point-wise flow-sum and volume terms.
/// </summary>
private readonly Sum _flowRatioSum;
private readonly Sum _volumeSum;
/// <summary>
/// Gets a flag indicating when this indicator is ready and fully initialized
/// </summary>
public override bool IsReady => _flowRatioSum.IsReady;
/// <summary>
/// Required period, in data points, for the indicator to be ready and fully initialized.
/// </summary>
public int WarmUpPeriod { get; }
/// <summary>
/// Resets this indicator to its initial state
/// </summary>
public override void Reset()
{
_volumeSum.Reset();
_flowRatioSum.Reset();
base.Reset();
}
/// <summary>
/// Initializes a new instance of the ChaikinMoneyFlow class
/// </summary>
/// <param name="name">A name for the indicator</param>
/// <param name="period">The period over which to perform computation</param>
public ChaikinMoneyFlow(string name, int period)
: base($"CMF({name})")
{
WarmUpPeriod = period;
_flowRatioSum = new Sum(period);
_volumeSum = new Sum(period);
}
/// <summary>
/// Computes the next value for this indicator from the given state.
/// </summary>
/// <param name="input">The input value to this indicator on this time step</param>
/// <returns>A new value for this indicator</returns>
protected override decimal ComputeNextValue(TradeBar input)
{
var denominator = (input.High - input.Low);
var flowRatio = denominator > 0
? input.Volume * (input.Close - input.Low - (input.High - input.Close)) / denominator
: 0m;
_flowRatioSum.Update(input.EndTime, flowRatio);
_volumeSum.Update(input.EndTime, input.Volume);
return !IsReady || _volumeSum == 0m ? 0m : _flowRatioSum / _volumeSum;
}
}
}

View File

@@ -0,0 +1,120 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using QuantConnect.Data.Market;
namespace QuantConnect.Indicators
{
/// <summary>
/// In the DeMarker strategy, for some period of size N, set:
/// <para>
/// DeMax = High - Previous High, and
/// DeMin = Previous Low - Low
/// </para>
/// where, in the prior, if either term is less than zero (DeMax or DeMin), set it to zero.
/// We can now define the indicator itself, DEM, as:
///<para>
/// DEM = MA(DeMax)/(MA(DeMax)+MA(DeMin))
///</para>
/// where MA denotes a Moving Average of period N.
///
/// https://www.investopedia.com/terms/d/demarkerindicator.asp
/// </summary>
public class DeMarkerIndicator : BarIndicator, IIndicatorWarmUpPeriodProvider
{
private readonly IndicatorBase<IndicatorDataPoint> _maxMA;
private readonly IndicatorBase<IndicatorDataPoint> _minMA;
private decimal _lastHigh;
private decimal _lastLow;
/// <summary>
/// Initializes a new instance of the DeMarkerIndicator class with the specified period
/// </summary>
/// <param name="period">The period of the DeMarker Indicator</param>
/// <param name="type">The type of moving average to use in calculations</param>
public DeMarkerIndicator(int period, MovingAverageType type = MovingAverageType.Simple)
: this($"DEM({period},{type})", period, type)
{
}
/// <summary>
/// Initializes a new instance of the DeMarkerIndicator class with the specified name and period
/// </summary>
/// <param name="name">The name of this indicator</param>
/// <param name="period">The period of the DeMarker Indicator</param>
/// <param name="type">The type of moving average to use in calculations</param>
public DeMarkerIndicator(string name, int period, MovingAverageType type = MovingAverageType.Simple)
: base(name)
{
var _lastHigh = 0m;
var _lastLow = 0m;
WarmUpPeriod = period;
_maxMA = type.AsIndicator(period);
_minMA = type.AsIndicator(period);
}
/// <summary>
/// Gets a flag indicating when this indicator is ready and fully initialized
/// </summary>
public override bool IsReady => _maxMA.IsReady && _minMA.IsReady;
/// <summary>
/// Required period, in data points, for the indicator to be ready and fully initialized.
/// </summary>
public int WarmUpPeriod { get; }
/// <summary>
/// Resets this indicator to its initial state
/// </summary>
public override void Reset()
{
_maxMA.Reset();
_minMA.Reset();
base.Reset();
}
/// <summary>
/// Computes the next value of this indicator from the given state
/// </summary>
/// <param name="input">The input given to the indicator</param>
/// <returns>A new value for this indicator</returns>
protected override decimal ComputeNextValue(IBaseDataBar input)
{
var deMax = 0m;
var deMin = 0m;
if (Samples > 1)
{
// By default, DeMin and DeMax must be 0m initially
deMax = Math.Max(input.High - _lastHigh, 0);
deMin = Math.Max(_lastLow - input.Low, 0);
}
_maxMA.Update(input.Time, deMax);
_minMA.Update(input.Time, deMin);
_lastHigh = input.High;
_lastLow = input.Low;
if (!IsReady)
{
return 0m;
}
var currentValue = _maxMA + _minMA;
return currentValue > 0m ? _maxMA / currentValue : 0m;
}
}
}

View File

@@ -120,7 +120,18 @@ namespace QuantConnect.Indicators
return Update((T)(object)new IndicatorDataPoint(time, value));
}
throw new NotSupportedException($"{GetType().Name} does not support Update(DateTime, decimal) method overload. Use Update({typeof(T).Name}) instead.");
var suggestions = new List<string>
{
"Update(TradeBar)",
"Update(QuoteBar)"
};
if (typeof(T) == typeof(IBaseData))
{
suggestions.Add("Update(Tick)");
}
throw new NotSupportedException($"{GetType().Name} does not support the `Update(DateTime, decimal)` method. Use one of the following methods instead: {string.Join(", ", suggestions)}");
}
/// <summary>
@@ -257,4 +268,4 @@ namespace QuantConnect.Indicators
Updated?.Invoke(this, consolidated);
}
}
}
}

View File

@@ -108,6 +108,7 @@
<Compile Include="ArnaudLegouxMovingAverage.cs" />
<Compile Include="AverageDirectionalIndex.cs" />
<Compile Include="AverageDirectionalMovementIndexRating.cs" />
<Compile Include="AwesomeOscillator.cs" />
<Compile Include="BalanceOfPower.cs" />
<Compile Include="CandlestickPatterns\UpDownGapThreeMethods.cs" />
<Compile Include="CandlestickPatterns\UpsideGapTwoCrows.cs" />
@@ -173,8 +174,10 @@
<Compile Include="CandlestickPatterns\ThreeWhiteSoldiers.cs" />
<Compile Include="CandlestickPatterns\Doji.cs" />
<Compile Include="CandlestickPatterns\TwoCrows.cs" />
<Compile Include="ChaikinMoneyFlow.cs" />
<Compile Include="ChandeMomentumOscillator.cs" />
<Compile Include="CoppockCurve.cs" />
<Compile Include="DeMarkerIndicator.cs" />
<Compile Include="DetrendedPriceOscillator.cs" />
<Compile Include="DonchianChannel.cs" />
<Compile Include="DoubleExponentialMovingAverage.cs" />
@@ -183,7 +186,7 @@
<Compile Include="SchaffTrendCycle.cs" />
<Compile Include="WilderMovingAverage.cs" />
<Compile Include="FractalAdaptiveMovingAverage.cs" />
<Compile Include="EaseOfMovementValue.cs"/>
<Compile Include="EaseOfMovementValue.cs" />
<Compile Include="FilteredIdentity.cs" />
<Compile Include="HullMovingAverage.cs" />
<Compile Include="MassIndex.cs" />

View File

@@ -122,7 +122,7 @@ namespace QuantConnect.Lean.Launcher
leanEngineSystemHandlers.Notify.SetAuthentication(job);
leanEngineSystemHandlers.Notify.Send(new RuntimeErrorPacket(job.UserId, job.AlgorithmId, _collapseMessage));
leanEngineSystemHandlers.JobQueue.AcknowledgeJob(job);
Exit();
Exit(1);
}
try
@@ -140,7 +140,9 @@ namespace QuantConnect.Lean.Launcher
}
finally
{
Exit();
var algorithmStatus = algorithmManager?.State ?? AlgorithmStatus.DeployError;
Exit(algorithmStatus != AlgorithmStatus.Completed ? 1 : 0);
}
}
@@ -154,7 +156,7 @@ namespace QuantConnect.Lean.Launcher
Log.Trace("Program.ExitKeyPress(): Lean instance has been cancelled, shutting down safely now");
}
public static void Exit()
public static void Exit(int exitCode)
{
//Delete the message from the job queue:
leanEngineSystemHandlers.JobQueue.AcknowledgeJob(job);
@@ -166,7 +168,7 @@ namespace QuantConnect.Lean.Launcher
Log.LogHandler.DisposeSafely();
Log.Trace("Program.Main(): Exiting Lean...");
Environment.Exit(0);
Environment.Exit(exitCode);
}
}
}

View File

@@ -236,9 +236,6 @@
<None Include="packages.config">
<SubType>Designer</SubType>
</None>
<None Include="Python.Runtime.dll.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.VersionCheckAnalyzer.2.9.3\analyzers\dotnet\Microsoft.CodeAnalysis.VersionCheckAnalyzer.dll" />

View File

@@ -16,7 +16,7 @@
//Physical DLL location
"algorithm-location": "QuantConnect.Algorithm.CSharp.dll",
//"algorithm-location": "../../../Algorithm.Python/BasicTemplateFrameworkAlgorithm.py"
//"algorithm-location": "../../../Algorithm.Python/BasicTemplateFrameworkAlgorithm.py",
//Research notebook
//"composer-dll-directory": ".",
@@ -321,4 +321,4 @@
}
}
}
}

View File

@@ -0,0 +1,39 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace QuantConnect.Logging
{
/// <summary>
/// Subclass of ConsoleLogHandler that only logs error messages
/// </summary>
public class ConsoleErrorLogHandler : ConsoleLogHandler
{
/// <summary>
/// Hide debug messages from log
/// </summary>
/// <param name="text">The debug text to log</param>
public override void Debug(string text)
{
}
/// <summary>
/// Hide trace messages from log
/// </summary>
/// <param name="text">The trace text to log</param>
public override void Trace(string text)
{
}
}
}

View File

@@ -54,7 +54,7 @@ namespace QuantConnect.Logging
/// Write error message to log
/// </summary>
/// <param name="text">The error text to log</param>
public void Error(string text)
public virtual void Error(string text)
{
#if DEBUG
Console.ForegroundColor = ConsoleColor.Red;
@@ -69,7 +69,7 @@ namespace QuantConnect.Logging
/// Write debug message to log
/// </summary>
/// <param name="text">The debug text to log</param>
public void Debug(string text)
public virtual void Debug(string text)
{
_trace.WriteLine(DateTime.Now.ToString(_dateFormat, CultureInfo.InvariantCulture) + " DEBUG:: " + text);
}
@@ -78,7 +78,7 @@ namespace QuantConnect.Logging
/// Write debug message to log
/// </summary>
/// <param name="text">The trace text to log</param>
public void Trace(string text)
public virtual void Trace(string text)
{
_trace.WriteLine(DateTime.Now.ToString(_dateFormat, CultureInfo.InvariantCulture) + " Trace:: " + text);
}

View File

@@ -109,6 +109,7 @@
</Compile>
<Compile Include="CompositeLogHandler.cs" />
<Compile Include="CompositeNLogHandler.cs" />
<Compile Include="ConsoleErrorLogHandler.cs" />
<Compile Include="NLogHandler.cs" />
<Compile Include="QueueLogHandler.cs" />
<Compile Include="FunctionalLogHandler.cs" />

Some files were not shown because too many files have changed in this diff Show More