Compare commits

...

19 Commits

Author SHA1 Message Date
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
72 changed files with 2260 additions and 265 deletions

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

@@ -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

@@ -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

@@ -148,6 +148,7 @@
<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

@@ -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.
@@ -2543,4 +2587,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

@@ -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>
@@ -408,9 +415,58 @@ namespace QuantConnect.Api
backtestId
}), ParameterType.RequestBody);
Backtest result;
BacktestResponseWrapper result;
ApiConnection.TryRequest(request, out result);
return result;
// Go fetch the charts if the backtest is completed
if (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 +817,17 @@ 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);
// If the response is not a zip then it is not data, don't write it.
var response = client.Execute(request);
if (response.ContentType != "application/zip")
{
var message = JObject.Parse(response.Content)["message"].Value<string>();
Log.Error($"Api.DownloadData(): Failed to download zip for {symbol} {resolution} data for date {date}, Api response: {message}");
return false;
}
response.RawBytes.SaveAs(path);
return true;
}

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

@@ -3220,7 +3220,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

@@ -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

@@ -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

@@ -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

@@ -935,6 +935,9 @@
</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">

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

@@ -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

@@ -653,7 +653,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

@@ -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

@@ -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,6 +174,7 @@
<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="DetrendedPriceOscillator.cs" />
@@ -183,7 +185,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

@@ -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

@@ -18,6 +18,7 @@ using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.IO;
using System.Linq;
using QuantConnect.Optimizer.Parameters;
using Log = QuantConnect.Logging.Log;
@@ -142,7 +143,8 @@ namespace QuantConnect.Optimizer.Launcher
if (Status != OptimizationStatus.Ended && Status != OptimizationStatus.Aborted)
{
var currentEstimate = GetCurrentEstimate();
var message = $"ConsoleLeanOptimizer.SendUpdate(): {currentEstimate}";
var stats = GetRuntimeStatistics();
var message = $"ConsoleLeanOptimizer.SendUpdate(): {currentEstimate} {string.Join(", ", stats.Select(pair => $"{pair.Key}:{pair.Value}"))}";
var currentBestBacktest = Strategy.Solution;
if (currentBestBacktest != null)
{

View File

@@ -19,6 +19,8 @@ using QuantConnect.Util;
using QuantConnect.Logging;
using QuantConnect.Configuration;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using QuantConnect.Optimizer.Objectives;
using QuantConnect.Optimizer.Parameters;
using QuantConnect.Optimizer.Strategies;
@@ -276,19 +278,27 @@ namespace QuantConnect.Optimizer
/// <summary>
/// Returns the current optimization status and strategy estimates
/// </summary>
public OptimizationEstimate GetCurrentEstimate()
public int GetCurrentEstimate()
{
return Strategy.GetTotalBacktestEstimate();
}
/// <summary>
/// Get the current runtime statistics
/// </summary>
public Dictionary<string, string> GetRuntimeStatistics()
{
var completedCount = _completedBacktest;
var totalCount = completedCount + _failedBacktest;
var runtime = DateTime.UtcNow - _startedAt;
return new OptimizationEstimate
return new Dictionary<string, string>
{
TotalBacktest = Strategy.GetTotalBacktestEstimate(),
CompletedBacktest = completedCount,
FailedBacktest = _failedBacktest,
RunningBacktest = RunningParameterSetForBacktest.Count,
InQueueBacktest = PendingParameterSet.Count,
AverageBacktest = completedCount > 0 ? new TimeSpan(runtime.Ticks / completedCount) : TimeSpan.Zero,
TotalRuntime = runtime
{ "Completed", $"{completedCount}"},
{ "Failed", $"{_failedBacktest}"},
{ "Running", $"{RunningParameterSetForBacktest.Count}"},
{ "In Queue", $"{PendingParameterSet.Count}"},
{ "Average Length", $"{(totalCount > 0 ? new TimeSpan(runtime.Ticks / totalCount) : TimeSpan.Zero).ToString(@"hh\:mm\:ss", CultureInfo.InvariantCulture)}"},
{ "Total Runtime", $"{runtime.ToString(@"hh\:mm\:ss", CultureInfo.InvariantCulture)}" }
};
}
@@ -301,7 +311,7 @@ namespace QuantConnect.Optimizer
{
return $"OID {NodePacket.OptimizationId}";
}
return $"UI {NodePacket.UserId} PID {NodePacket.ProjectId} OID {NodePacket.OptimizationId}";
return $"UI {NodePacket.UserId} PID {NodePacket.ProjectId} OID {NodePacket.OptimizationId} S {Status}";
}
/// <summary>

View File

@@ -1,74 +0,0 @@
/*
* 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 Newtonsoft.Json;
namespace QuantConnect.Optimizer
{
public class OptimizationEstimate
{
/// <summary>
/// Total number of backtests, approximately
/// </summary>
[JsonProperty("totalBacktest")]
public int TotalBacktest { get; set; }
/// <summary>
/// Number of completed backtests
/// </summary>
[JsonProperty("completedBacktest")]
public int CompletedBacktest { get; set; }
/// <summary>
/// Number of failed backtests
/// </summary>
[JsonProperty("failedBacktest")]
public int FailedBacktest { get; set; }
/// <summary>
/// Number of running backtests
/// </summary>
[JsonProperty("runningBacktest")]
public int RunningBacktest { get; set; }
/// <summary>
/// Number of backtests in queue
/// </summary>
[JsonProperty("inQueueBacktest")]
public int InQueueBacktest { get; set; }
/// <summary>
/// Indicates backtest average duration; (start - now) / CompletedBacktest
/// </summary>
[JsonProperty("averageBacktest")]
public TimeSpan AverageBacktest { get; set; }
/// <summary>
/// The run time of this optimization
/// </summary>
[JsonProperty(PropertyName = "totalRuntime")]
public TimeSpan TotalRuntime { get; set; }
/// <summary>
/// Pretty representation of an optimization estimate
/// </summary>
public override string ToString()
{
return $"TotalBacktest: {TotalBacktest}. CompletedBacktest: {CompletedBacktest}. FailedBacktest: {FailedBacktest}." +
$" RunningBacktest: {RunningBacktest}. InQueueBacktest: {InQueueBacktest}. TotalRuntime {TotalRuntime}. AverageBacktest: {AverageBacktest}";
}
}
}

View File

@@ -63,7 +63,6 @@
<Compile Include="Strategies\OptimizationStrategySettings.cs" />
<Compile Include="Strategies\StepBaseOptimizationStrategy.cs" />
<Compile Include="Objectives\Objective.cs" />
<Compile Include="OptimizationEstimate.cs" />
<Compile Include="Objectives\Target.cs" />
<Compile Include="Objectives\Constraint.cs" />
<Compile Include="LeanOptimizer.cs" />

View File

@@ -128,6 +128,9 @@ namespace QuantConnect.Report
// More initialization, this time with Algorithm and other misc. classes
_resultHandler.Initialize(job, new Messaging.Messaging(), new Api.Api(), transactions);
_resultHandler.SetAlgorithm(Algorithm, Algorithm.Portfolio.TotalPortfolioValue);
Algorithm.Transactions.SetOrderProcessor(transactions);
transactions.Initialize(Algorithm, new BacktestingBrokerage(Algorithm), _resultHandler);
feed.Initialize(Algorithm, job, _resultHandler, null, null, null, _dataManager, null, null);

View File

@@ -324,7 +324,22 @@ namespace QuantConnect.Research
// Load a canonical option Symbol if the user provides us with an underlying Symbol
if (symbol.SecurityType != SecurityType.Option && symbol.SecurityType != SecurityType.FutureOption)
{
symbol = AddOption(symbol, resolution, symbol.ID.Market).Symbol;
var option = AddOption(symbol, resolution, symbol.ID.Market);
// Allow 20 strikes from the money for futures. No expiry filter is applied
// so that any future contract provided will have data returned.
if (symbol.SecurityType == SecurityType.Future && symbol.IsCanonical())
{
throw new ArgumentException("The Future Symbol provided is a canonical Symbol (i.e. a Symbol representing all Futures), which is not supported at this time. " +
"If you are using the Symbol accessible from `AddFuture(...)`, use the Symbol from `AddFutureContract(...)` instead. " +
"You can use `qb.FutureOptionChainProvider(canonicalFuture, datetime)` to get a list of futures contracts for a given date, and add them to your algorithm with `AddFutureContract(symbol, Resolution)`.");
}
if (symbol.SecurityType == SecurityType.Future && !symbol.IsCanonical())
{
option.SetFilter(universe => universe.Strikes(-10, +10));
}
symbol = option.Symbol;
}
IEnumerable<Symbol> symbols;
@@ -337,8 +352,19 @@ namespace QuantConnect.Research
.GetHighestResolution();
if (!Securities.ContainsKey(symbol.Underlying))
{
// only add underlying if not present
AddEquity(symbol.Underlying.Value, resolutionToUseForUnderlying);
if (symbol.Underlying.SecurityType == SecurityType.Equity)
{
// only add underlying if not present
AddEquity(symbol.Underlying.Value, resolutionToUseForUnderlying);
}
if (symbol.Underlying.SecurityType == SecurityType.Future && symbol.Underlying.IsCanonical())
{
AddFuture(symbol.Underlying.ID.Symbol, resolutionToUseForUnderlying);
}
else if (symbol.Underlying.SecurityType == SecurityType.Future)
{
AddFutureContract(symbol.Underlying, resolutionToUseForUnderlying);
}
}
var allSymbols = new List<Symbol>();
for (var date = start; date < end; date = date.AddDays(1))

View File

@@ -71,6 +71,47 @@ namespace QuantConnect.Tests.Algorithm.Framework
Assert.IsTrue(construction.Insights.All(insight => insight.CloseTimeUtc != default(DateTime)));
}
[TestCase(true, 0)]
[TestCase(false, 2)]
public void DelistedSecuritiesInsightsTest(bool isDelisted, int expectedCount)
{
var algorithm = new QCAlgorithm();
algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm));
algorithm.Transactions.SetOrderProcessor(new FakeOrderProcessor());
algorithm.SetStartDate(2007, 5, 16);
algorithm.SetUniverseSelection(new ManualUniverseSelectionModel());
algorithm.SetFinishedWarmingUp();
var alpha = new FakeAlpha();
algorithm.SetAlpha(alpha);
var construction = new FakePortfolioConstruction();
algorithm.SetPortfolioConstruction(construction);
var actualInsights = new List<Insight>();
algorithm.InsightsGenerated += (s, e) => actualInsights.AddRange(e.Insights);
var security = algorithm.AddEquity("SPY", Resolution.Daily);
var tick = new Tick
{
Symbol = security.Symbol,
Value = 1,
Quantity = 2
};
security.SetMarketPrice(tick);
security.IsDelisted = isDelisted;
// Trigger Alpha to emit insight
algorithm.OnFrameworkData(new Slice(new DateTime(2000, 01, 01), new List<BaseData>() { tick }));
// Manually emit insight
algorithm.EmitInsights(Insight.Price(Symbols.SPY, TimeSpan.FromDays(1), InsightDirection.Up, .5, .75));
// Should be zero because security is delisted
Assert.AreEqual(expectedCount, actualInsights.Count);
}
class FakeAlpha : AlphaModel
{
public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice data)

View File

@@ -353,7 +353,8 @@ namespace QuantConnect.Tests.API
Assert.IsTrue(backtestRead.Success);
Assert.IsTrue(backtestRead.Progress == 1);
Assert.IsTrue(backtestRead.Name == backtestName);
Assert.IsTrue(backtestRead.Result.Statistics["Total Trades"] == "1");
Assert.IsTrue(backtestRead.Statistics["Total Trades"] == "1");
Assert.IsTrue(backtestRead.Charts["Benchmark"].Series.Count > 0);
// Verify we have the backtest in our project
var listBacktests = _api.ListBacktests(project.Projects.First().ProjectId);

View File

@@ -587,6 +587,23 @@ namespace QuantConnect.Tests.Common
Assert.IsTrue(nonCanonicalFutureOption.Value.StartsWith(expectedFutureOptionTicker));
}
[Test]
public void SymbolWithSidContainingUnderlyingCreatedWithoutNullUnderlying()
{
var future = Symbol.CreateFuture("ES", Market.CME, new DateTime(2020, 6, 19));
var optionSid = SecurityIdentifier.GenerateOption(
future.ID.Date,
future.ID,
future.ID.Market,
3500m,
OptionRight.Call,
OptionStyle.American);
var option = new Symbol(optionSid, "ES");
Assert.IsNotNull(option.Underlying);
Assert.AreEqual(future, option.Underlying);
}
class OldSymbol
{
public string Value { get; set; }

View File

@@ -0,0 +1,34 @@
/*
* 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 NUnit.Framework;
using QuantConnect.Data.Market;
using QuantConnect.Indicators;
namespace QuantConnect.Tests.Indicators
{
[TestFixture]
public class AwesomeOscillatorTests : CommonIndicatorTests<IBaseDataBar>
{
protected override IndicatorBase<IBaseDataBar> CreateIndicator()
{
return new AwesomeOscillator(5, 34);
}
protected override string TestFileName => "spy_ao.txt";
protected override string TestColumnName => "AO";
}
}

View File

@@ -0,0 +1,74 @@
/*
* 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 NUnit.Framework;
using QuantConnect.Data.Market;
using QuantConnect.Indicators;
namespace QuantConnect.Tests.Indicators
{
[TestFixture]
public class ChaikinMoneyFlowTests : CommonIndicatorTests<TradeBar>
{
protected override IndicatorBase<TradeBar> CreateIndicator()
{
return new ChaikinMoneyFlow("CMF", 20);
}
protected override string TestFileName => "spy_cmf.txt";
protected override string TestColumnName => "CMF_20";
[Test]
public void TestTradeBarsWithNoVolume()
{
// As volume is a multiplier in numerator, should return default value 0m.
var cmf = new ChaikinMoneyFlow("CMF", 3);
foreach (var data in TestHelper.GetDataStream(4))
{
var tradeBar = new TradeBar
{
Open = data.Value,
Close = data.Value,
High = data.Value,
Low = data.Value,
Volume = 0
};
cmf.Update(tradeBar);
}
Assert.AreEqual(cmf.Current.Value, 0m);
}
[Test]
public void TestDivByZero()
{
var cmf = new ChaikinMoneyFlow("CMF", 3);
foreach (var data in TestHelper.GetDataStream(4))
{
// Should handle High = Low case by returning 0m.
var tradeBar = new TradeBar
{
Open = data.Value,
Close = data.Value,
High = 1,
Low = 1,
Volume = 1
};
cmf.Update(tradeBar);
}
Assert.AreEqual(cmf.Current.Value, 0m);
}
}
}

View File

@@ -17,6 +17,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using QuantConnect.Optimizer;
using QuantConnect.Optimizer.Parameters;
@@ -38,8 +39,7 @@ namespace QuantConnect.Tests.Optimizer
var id = Guid.NewGuid().ToString();
_backtests.Add(id);
Timer timer = null;
timer = new Timer(y =>
Task.Delay(100).ContinueWith(task =>
{
try
{
@@ -53,14 +53,11 @@ namespace QuantConnect.Tests.Optimizer
// fail some backtests by passing empty json
NewResult(string.Empty, id);
}
timer.Dispose();
}
catch
{
}
});
timer.Change(100, Timeout.Infinite);
return id;
}

View File

@@ -20,6 +20,7 @@ using NUnit.Framework;
using QuantConnect.Optimizer;
using QuantConnect.Util;
using System.Collections.Generic;
using System.Globalization;
using System.Threading;
using QuantConnect.Configuration;
using QuantConnect.Optimizer.Objectives;
@@ -237,7 +238,6 @@ namespace QuantConnect.Tests.Optimizer
public void TrackEstimation()
{
Config.Set("optimization-update-interval", 1);
OptimizationEstimate estimate = null;
OptimizationResult result = null;
var resetEvent = new ManualResetEvent(false);
var packet = new OptimizationNodePacket
@@ -246,7 +246,7 @@ namespace QuantConnect.Tests.Optimizer
OptimizationParameters = new HashSet<OptimizationParameter>
{
new OptimizationStepParameter("ema-slow", 1, 10, 1),
new OptimizationStepParameter("ema-fast", 10, 100, 3)
new OptimizationStepParameter("ema-fast", 10, 100, 10)
},
Constraints = new List<Constraint>
{
@@ -256,25 +256,26 @@ namespace QuantConnect.Tests.Optimizer
};
var optimizer = new FakeLeanOptimizer(packet);
// keep stats up-to-date
int totalBacktest = optimizer.GetCurrentEstimate().TotalBacktest;
int totalBacktest = optimizer.GetCurrentEstimate();
int totalUpdates = 0;
int completedTests = 0;
int failed = 0;
optimizer.Update += (s, e) =>
{
estimate = optimizer.GetCurrentEstimate();
Assert.LessOrEqual(estimate.RunningBacktest, packet.MaximumConcurrentBacktests);
Assert.LessOrEqual(completedTests, estimate.CompletedBacktest);
Assert.LessOrEqual(failed, estimate.FailedBacktest);
var runtimeStats = optimizer.GetRuntimeStatistics();
Assert.LessOrEqual(int.Parse(runtimeStats["Running"], CultureInfo.InvariantCulture), packet.MaximumConcurrentBacktests);
Assert.LessOrEqual(completedTests, int.Parse(runtimeStats["Completed"], CultureInfo.InvariantCulture));
Assert.LessOrEqual(failed, int.Parse(runtimeStats["Failed"], CultureInfo.InvariantCulture));
Assert.AreEqual(totalBacktest, estimate.TotalBacktest);
Assert.AreEqual(totalBacktest, optimizer.GetCurrentEstimate());
completedTests = estimate.CompletedBacktest;
failed = estimate.FailedBacktest;
completedTests = int.Parse(runtimeStats["Completed"], CultureInfo.InvariantCulture);
failed = int.Parse(runtimeStats["Failed"], CultureInfo.InvariantCulture);
if (completedTests > 0)
{
Assert.Greater(estimate.AverageBacktest, TimeSpan.Zero);
// 'ms' aren't stored so might be 0
Assert.GreaterOrEqual(TimeSpan.Parse(runtimeStats["Average Length"], CultureInfo.InvariantCulture), TimeSpan.Zero);
}
totalUpdates++;
@@ -282,7 +283,6 @@ namespace QuantConnect.Tests.Optimizer
optimizer.Ended += (s, solution) =>
{
result = solution;
estimate = optimizer.GetCurrentEstimate();
optimizer.DisposeSafely();
resetEvent.Set();
};
@@ -291,11 +291,14 @@ namespace QuantConnect.Tests.Optimizer
resetEvent.WaitOne();
Assert.NotZero(estimate.CompletedBacktest);
Assert.NotZero(estimate.FailedBacktest);
var runtimeStatistics = optimizer.GetRuntimeStatistics();
Assert.NotZero(int.Parse(runtimeStatistics["Completed"], CultureInfo.InvariantCulture));
Assert.NotZero(int.Parse(runtimeStatistics["Failed"], CultureInfo.InvariantCulture));
// we have 2 force updates at least, expect a few more over it.
Assert.Greater(totalUpdates, 2);
Assert.AreEqual(estimate.CompletedBacktest + estimate.FailedBacktest + estimate.RunningBacktest, totalBacktest);
Assert.AreEqual(int.Parse(runtimeStatistics["Completed"], CultureInfo.InvariantCulture)
+ int.Parse(runtimeStatistics["Failed"], CultureInfo.InvariantCulture)
+ int.Parse(runtimeStatistics["Running"], CultureInfo.InvariantCulture), totalBacktest);
}
}
}

View File

@@ -223,6 +223,97 @@ namespace QuantConnect.Tests.Python
}
}
/// <summary>
/// Specific issues for symbol LOW, reference GH issue #4886
/// </summary>
[Test]
public void HandlesOddTickers()
{
var converter = new PandasConverter();
var symbol = Symbols.LOW;
var rawBars = Enumerable
.Range(0, 10)
.Select(i => new TradeBar(DateTime.UtcNow.AddMinutes(i), symbol, i + 101m, i + 102m, i + 100m, i + 101m, 0m))
.ToArray();
// GetDataFrame with argument of type IEnumerable<TradeBar>
var history = GetHistory(symbol, Resolution.Minute, rawBars);
dynamic dataFrame = converter.GetDataFrame(history);
// Add LOW to our symbol cache
SymbolCache.Set("LOW", Symbols.LOW);
using (Py.GIL())
{
dynamic test = PythonEngine.ModuleFromString("testModule",
$@"
def Test(dataFrame):
data = dataFrame.loc['LOW']
if data.empty:
raise Exception('LOW history data is empty')
if data.__len__() != 10:
raise Exception('Expected 10 data points')
lowData = data.low
if lowData.empty:
raise Exception('LOW history low data is empty')").GetAttr("Test");
Assert.DoesNotThrow(() => test(dataFrame));
}
}
[Test]
public void BreakingOddTickers()
{
var converter = new PandasConverter();
var symbol = Symbols.LOW;
var rawBars = Enumerable
.Range(0, 10)
.Select(i => new TradeBar(DateTime.UtcNow.AddMinutes(i), symbol, i + 101m, i + 102m, i + 100m, i + 101m, 0m))
.ToArray();
// GetDataFrame with argument of type IEnumerable<TradeBar>
var history = GetHistory(symbol, Resolution.Minute, rawBars);
dynamic dataFrame = converter.GetDataFrame(history);
// Add LOW to our symbol cache
SymbolCache.Set("LOW", Symbols.LOW);
using (Py.GIL())
{
var Test = PythonEngine.ModuleFromString("testModule",
$@"
def Test1(dataFrame):
# Should not throw, access all LOW ticker data
data = dataFrame.loc['LOW']
def Test2(dataFrame):
# Bad accessor, expected to throw
data = dataFrame.LOW
def Test3(dataFrame):
# Bad key, expected to throw
data = dataFrame.loc['low']
def Test4(dataFrame):
# Should not throw, access data column low for all tickers
data = dataFrame.low
");
dynamic test1 = Test.GetAttr("Test1");
dynamic test2 = Test.GetAttr("Test2");
dynamic test3 = Test.GetAttr("Test3");
dynamic test4 = Test.GetAttr("Test4");
Assert.DoesNotThrow(() => test1(dataFrame));
Assert.Throws<PythonException>(() => test2(dataFrame));
Assert.Throws<PythonException>(() => test3(dataFrame));
Assert.DoesNotThrow(() => test4(dataFrame));
}
}
[TestCase("'SPY'", true)]
[TestCase("symbol")]
[TestCase("str(symbol.ID)")]

View File

@@ -533,6 +533,8 @@
<Compile Include="Indicators\AdvanceDeclineRatioVolumeTests.cs" />
<Compile Include="Indicators\AdvanceDeclineRatioTests.cs" />
<Compile Include="Indicators\ArmsIndexTests.cs" />
<Compile Include="Indicators\AwesomeOscillatorTests.cs" />
<Compile Include="Indicators\ChaikinMoneyFlowTests.cs" />
<Compile Include="Indicators\PythonIndicatorNoinheritanceTestsLegacy.cs" />
<Compile Include="Indicators\PythonIndicatorNoinheritanceTests.cs" />
<Compile Include="Indicators\PythonIndicatorTests.cs" />
@@ -988,9 +990,15 @@
<Content Include="TestData\spy_alma.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="TestData\spy_ao.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="TestData\spy_atr_wilder.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="TestData\spy_cmf.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="TestData\spy_hma.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

View File

@@ -113,5 +113,70 @@ namespace QuantConnect.Tests.Report
Assert.AreEqual(80000, pointInTimePortfolio[1].TotalPortfolioValue);
Assert.AreEqual(80000, pointInTimePortfolio[2].TotalPortfolioValue);
}
[Test]
public void OptionOrderDoesNotThrow()
{
var equityPoints = new SortedList<DateTime, double>
{
{ new DateTime(2019, 1, 3, 5, 0, 5), 100000 },
{ new DateTime(2019, 1, 4, 5, 0, 5), 90000 },
};
var series = new Series<DateTime, double>(equityPoints);
var equity = Symbol.Create("SPY", SecurityType.Equity, Market.USA);
var optionSid = SecurityIdentifier.GenerateOption(
equity.ID.Date,
equity.ID,
equity.ID.Market,
200m,
OptionRight.Call,
OptionStyle.American);
var option = new Symbol(optionSid, optionSid.Symbol);
var entryOrder = Order.CreateOrder(new SubmitOrderRequest(
OrderType.Market,
SecurityType.Option,
option,
1,
0m,
0m,
new DateTime(2019, 1, 3, 5, 0, 5),
string.Empty
));
var exitOrder = Order.CreateOrder(new SubmitOrderRequest(
OrderType.Market,
SecurityType.Option,
option,
-1,
0m,
0m,
new DateTime(2019, 1, 4, 5, 0, 5),
string.Empty
));
entryOrder.LastFillTime = new DateTime(2019, 1, 3, 5, 0, 5);
exitOrder.LastFillTime = new DateTime(2019, 1, 4, 5, 0, 5);
entryOrder.GetType().GetProperty("Id").SetValue(entryOrder, 1);
entryOrder.GetType().GetProperty("Price").SetValue(entryOrder, 100000m);
Order marketOnFillOrder = null;
exitOrder.GetType().GetProperty("Id").SetValue(exitOrder, 2);
exitOrder.GetType().GetProperty("Price").SetValue(exitOrder, 80000m);
exitOrder.GetType().GetProperty("Status").SetValue(exitOrder, OrderStatus.Filled);
var orders = new[] { entryOrder, marketOnFillOrder, exitOrder }.Where(x => x != null);
var looper = PortfolioLooper.FromOrders(series, orders);
Assert.DoesNotThrow(() =>
{
foreach (var pointInTimePortfolio in looper)
{
Assert.AreEqual(option, pointInTimePortfolio.Order.Symbol);
Assert.AreEqual(option.Underlying, pointInTimePortfolio.Order.Symbol.Underlying);
}
});
}
}
}

View File

@@ -270,5 +270,67 @@ namespace QuantConnect.Tests.Research
Assert.GreaterOrEqual(startDate.AddDays(-1).Date, firstIndex.Date);
}
}
[Test]
public void FuturesOptionsWithFutureContract()
{
using (Py.GIL())
{
var qb = new QuantBook();
var expiry = new DateTime(2020, 3, 20);
var future = Symbol.CreateFuture(Futures.Indices.SP500EMini, Market.CME, expiry);
var start = new DateTime(2020, 1, 5);
var end = new DateTime(2020, 1, 6);
var history = qb.GetOptionHistory(future, start, end, Resolution.Minute);
dynamic df = history.GetAllData();
Assert.IsNotNull(df);
Assert.IsFalse((bool)df.empty.AsManagedObject(typeof(bool)));
Assert.Greater((int)df.__len__().AsManagedObject(typeof(int)), 360);
Assert.AreEqual(5, (int)df.index.levels.__len__().AsManagedObject(typeof(int)));
Assert.IsTrue((bool)df.index.levels[0].__contains__(expiry.ToStringInvariant("yyyy-MM-dd")).AsManagedObject(typeof(bool)));
}
}
[Test]
public void FuturesOptionsWithFutureOptionContract()
{
using (Py.GIL())
{
var qb = new QuantBook();
var expiry = new DateTime(2020, 3, 20);
var future = Symbol.CreateFuture(Futures.Indices.SP500EMini, Market.CME, expiry);
var futureOption = Symbol.CreateOption(
future,
future.ID.Market,
OptionStyle.American,
OptionRight.Call,
3300m,
expiry);
var start = new DateTime(2020, 1, 5);
var end = new DateTime(2020, 1, 6);
var history = qb.GetOptionHistory(futureOption, start, end, Resolution.Minute);
dynamic df = history.GetAllData();
Assert.IsNotNull(df);
Assert.IsFalse((bool)df.empty.AsManagedObject(typeof(bool)));
Assert.AreEqual(360, (int)df.__len__().AsManagedObject(typeof(int)));
Assert.AreEqual(5, (int)df.index.levels.__len__().AsManagedObject(typeof(int)));
Assert.IsTrue((bool)df.index.levels[0].__contains__(expiry.ToStringInvariant("yyyy-MM-dd")).AsManagedObject(typeof(bool)));
}
}
[Test]
public void CanoicalFutureCrashesGetOptionHistory()
{
var qb = new QuantBook();
var future = Symbol.Create(Futures.Indices.SP500EMini, SecurityType.Future, Market.CME);
Assert.Throws<ArgumentException>(() =>
{
qb.GetOptionHistory(future, default(DateTime), DateTime.MaxValue, Resolution.Minute);
});
}
}
}

View File

@@ -34,6 +34,7 @@ namespace QuantConnect.Tests
public static readonly Symbol LODE = CreateEquitySymbol("LODE");
public static readonly Symbol IBM = CreateEquitySymbol("IBM");
public static readonly Symbol GOOG = CreateEquitySymbol("GOOG");
public static readonly Symbol LOW = CreateEquitySymbol("LOW");
public static readonly Symbol USDJPY = CreateForexSymbol("USDJPY");
public static readonly Symbol EURUSD = CreateForexSymbol("EURUSD");

501
Tests/TestData/spy_ao.txt Normal file
View File

@@ -0,0 +1,501 @@
,Date,Open,High,Low,Close,Volume,AO
0,2013/02/22,151.16,151.89,150.49,151.89,106292600,
1,2013/02/25,152.63,152.86,149.0,149.0,245483200,
2,2013/02/26,149.72,150.2,148.73,150.02,186331600,
3,2013/02/27,149.89,152.33,149.76,151.91,143932600,
4,2013/02/28,151.9,152.87,151.41,151.61,123724200,
5,2013/03/01,151.09,152.34,150.41,152.11,170612700,
6,2013/03/04,151.76,152.92,151.52,152.92,97328800,
7,2013/03/05,153.66,154.7,153.64,154.29,121238200,
8,2013/03/06,154.84,154.92,154.16,154.5,94284300,
9,2013/03/07,154.71,154.98,154.52,154.78,86002000,
10,2013/03/08,155.46,155.65,154.66,155.44,122805700,
11,2013/03/11,155.33,156.04,155.13,156.03,83235500,
12,2013/03/12,155.92,156.1,155.21,155.68,104108300,
13,2013/03/13,155.76,156.12,155.23,155.9,91051500,
14,2013/03/14,156.31,156.8,156.22,156.73,123614200,
15,2013/03/15,155.85,156.04,155.31,155.83,133153200,
16,2013/03/18,154.34,155.64,154.2,154.97,126518300,
17,2013/03/19,155.3,155.51,153.59,154.61,167049900,
18,2013/03/20,155.52,155.95,155.26,155.69,113607800,
19,2013/03/21,154.75,155.64,154.1,154.36,128492900,
20,2013/03/22,154.84,155.6,154.73,155.6,111103200,
21,2013/03/25,155.99,156.27,154.35,154.95,151231800,
22,2013/03/26,155.59,156.23,155.42,156.19,86114000,
23,2013/03/27,155.26,156.24,155.0,156.19,99783700,
24,2013/03/28,156.09,156.85,155.75,156.67,102687700,
25,2013/04/01,156.59,156.91,155.67,156.05,99128500,
26,2013/04/02,156.61,157.21,156.37,156.82,101291000,
27,2013/04/03,156.91,157.03,154.82,155.23,153781800,
28,2013/04/04,155.43,156.17,155.09,155.86,129370000,
29,2013/04/05,153.95,155.35,153.77,155.16,155171000,
30,2013/04/08,155.27,156.22,154.75,156.21,86039700,
31,2013/04/09,156.5,157.32,155.98,156.75,100591500,
32,2013/04/10,157.17,158.87,157.13,158.67,134837300,
33,2013/04/11,158.7,159.71,158.54,159.19,109635100,1.978705882352898
34,2013/04/12,158.68,159.04,157.92,158.8,116024900,2.5482941176470035
35,2013/04/15,158.0,158.13,155.1,155.12,215505700,2.6070882352940714
36,2013/04/16,156.29,157.49,155.91,157.41,147152400,2.4042941176470265
37,2013/04/17,156.29,156.32,154.28,155.11,226231500,1.7391470588235336
38,2013/04/18,155.37,155.41,153.55,154.14,166888900,0.7413235294117726
39,2013/04/19,154.5,155.55,154.12,155.48,149219300,-0.08944117647058647
40,2013/04/22,155.78,156.54,154.75,156.17,106216500,-0.3841764705882156
41,2013/04/23,156.95,157.93,156.17,157.78,165592000,-0.3988823529412002
42,2013/04/24,157.83,158.3,157.54,157.88,94996400,0.025705882352951903
43,2013/04/25,158.25,159.27,158.1,158.52,130774400,0.7509705882352478
44,2013/04/26,158.32,158.6,157.73,158.24,95639000,1.328441176470534
45,2013/04/29,158.67,159.65,158.42,159.3,88223400,1.9049705882352441
46,2013/04/30,159.27,159.72,158.61,159.68,115647600,2.224735294117636
47,2013/05/01,159.33,159.41,158.1,158.28,138538400,2.301147058823517
48,2013/05/02,158.68,159.89,158.53,159.75,96232300,2.326735294117668
49,2013/05/03,161.14,161.88,161.04,161.37,143795900,2.8155882352941433
50,2013/05/06,161.49,162.01,161.42,161.78,66618900,3.151735294117657
51,2013/05/07,162.11,162.65,161.67,162.6,89907000,3.5269117647059147
52,2013/05/08,162.42,163.39,162.33,163.34,96840500,4.134529411764731
53,2013/05/09,163.27,163.7,162.47,162.88,106479000,4.667911764705906
54,2013/05/10,163.0,163.55,162.51,163.41,102968200,4.7505882352941455
55,2013/05/13,163.0,163.81,162.82,163.54,79718500,4.835147058823594
56,2013/05/14,163.67,165.35,163.67,165.23,118429300,5.04970588235301
57,2013/05/15,164.98,166.45,164.91,166.12,120520600,5.317823529411811
58,2013/05/16,165.76,166.36,165.09,165.34,109631200,5.568617647058858
59,2013/05/17,165.98,167.04,165.73,166.94,129521200,5.9427058823529535
60,2013/05/20,166.78,167.58,166.61,166.93,84703300,6.3956176470588275
61,2013/05/21,167.07,167.8,166.5,167.17,95130500,6.593470588235306
62,2013/05/22,167.34,169.07,165.17,165.93,243215800,6.543529411764723
63,2013/05/23,164.2,165.91,163.94,165.45,210629800,6.078676470588249
64,2013/05/24,164.44,165.38,163.98,165.31,151265100,5.467235294117643
65,2013/05/28,167.04,167.78,165.81,166.3,142755000,5.108852941176451
66,2013/05/29,165.41,165.8,164.34,165.22,160155000,4.484911764705856
67,2013/05/30,165.35,166.59,165.22,165.83,106389200,4.04249999999999
68,2013/05/31,165.36,166.31,163.13,163.45,175401500,3.8179705882352835
69,2013/06/03,163.86,164.46,162.66,164.35,167947700,3.389705882352871
70,2013/06/04,164.44,165.1,162.73,163.56,157405600,2.601499999999902
71,2013/06/05,163.11,163.42,161.13,161.27,210885500,1.8373529411763627
72,2013/06/06,161.2,162.74,160.25,162.73,200017000,0.7490294117646386
73,2013/06/07,163.89,164.95,163.14,164.8,188303400,0.34314705882346175
74,2013/06/10,165.31,165.4,164.37,164.8,102463000,0.33638235294108654
75,2013/06/11,163.27,164.54,162.74,163.1,159335000,0.08755882352932076
76,2013/06/12,164.25,164.39,161.6,161.75,176792400,0.08229411764696692
77,2013/06/13,161.64,164.5,161.3,164.21,163114300,0.2393235294117062
78,2013/06/14,164.03,164.67,162.91,163.18,140994200,0.022882352941110184
79,2013/06/17,164.3,165.22,163.55,164.44,135807000,-0.23447058823535372
80,2013/06/18,164.54,165.99,164.52,165.74,114574200,-0.09058823529417737
81,2013/06/19,165.61,165.89,163.38,163.45,205760600,0.06447058823522411
82,2013/06/20,161.83,162.1,158.98,159.4,320271500,-0.4466470588236007
83,2013/06/21,159.6,159.76,157.47,159.07,270449000,-1.3979705882353528
84,2013/06/24,157.39,158.43,155.73,157.06,221705700,-2.722647058823611
85,2013/06/25,158.52,159.17,157.42,158.57,161967200,-4.0009705882353614
86,2013/06/26,159.89,160.5,159.25,160.14,134499400,-4.865176470588324
87,2013/06/27,161.12,161.82,160.95,161.08,129281700,-4.64617647058833
88,2013/06/28,160.62,161.4,159.86,160.42,160138800,-4.172588235294199
89,2013/07/01,161.27,162.48,161.08,161.36,131682500,-3.1874411764707133
90,2013/07/02,161.1,162.3,160.5,161.21,154807500,-2.474970588235408
91,2013/07/03,160.51,161.77,160.22,161.28,75214000,-2.1131764705883427
92,2013/07/05,162.53,163.08,161.3,163.02,121865400,-1.848205882353028
93,2013/07/08,163.89,164.39,163.08,163.95,107930700,-1.1492647058824161
94,2013/07/09,164.97,165.33,164.27,165.13,119159000,-0.47776470588240727
95,2013/07/10,165.01,165.75,164.63,165.19,119410100,0.3378823529411079
96,2013/07/11,167.13,167.61,166.53,167.44,135448000,1.554352941176461
97,2013/07/12,167.4,167.93,167.13,167.51,102636900,2.545735294117634
98,2013/07/15,167.97,168.39,167.68,168.15,69376600,3.3070588235294167
99,2013/07/16,168.25,168.36,167.07,167.52,88577000,3.862999999999971
100,2013/07/17,168.18,168.48,167.73,167.95,91526200,4.3567352941176125
101,2013/07/18,168.28,169.27,168.2,168.87,104445800,4.606499999999983
102,2013/07/19,168.51,169.23,168.31,169.17,103363100,4.735382352941173
103,2013/07/22,169.39,169.74,169.01,169.5,79268700,4.832352941176509
104,2013/07/23,169.79,169.83,169.05,169.14,80761400,5.0148529411764855
105,2013/07/24,169.8,169.86,168.18,168.52,112662100,4.999470588235283
106,2013/07/25,168.2,169.08,167.94,168.93,111033200,4.748147058823491
107,2013/07/26,168.24,169.16,167.52,169.11,107418600,4.5358235294117435
108,2013/07/29,168.71,169.06,168.11,168.59,79614200,4.268999999999977
109,2013/07/30,169.12,169.28,168.19,168.59,85026800,3.9781470588235095
110,2013/07/31,168.94,169.85,168.49,168.71,142264100,3.82652941176471
111,2013/08/01,169.98,170.81,169.9,170.66,109966700,3.976264705882329
112,2013/08/02,170.3,170.97,170.05,170.95,89402700,4.212617647058806
113,2013/08/05,170.61,170.96,170.35,170.7,53408200,4.4422058823529085
114,2013/08/06,170.37,170.52,169.35,169.73,87231100,4.5445588235294
115,2013/08/07,169.2,169.43,168.55,169.18,84558600,4.3804705882352835
116,2013/08/08,170.0,170.18,168.93,169.8,101924300,3.9553235294117712
117,2013/08/09,169.56,170.1,168.72,169.31,91473000,3.4178235294117485
118,2013/08/12,168.44,169.31,168.38,169.11,68436400,2.70979411764705
119,2013/08/13,169.4,169.9,168.41,169.61,80630100,2.234382352941168
120,2013/08/14,169.52,169.8,168.7,168.74,78905600,2.0106470588235084
121,2013/08/15,167.35,167.43,166.09,166.38,152546100,1.2935588235293949
122,2013/08/16,166.04,166.63,165.5,165.83,130207000,0.46470588235294485
123,2013/08/19,165.64,166.21,164.76,164.77,96296100,-0.31626470588233246
124,2013/08/20,165.03,166.2,164.86,165.58,88917400,-1.1627352941176525
125,2013/08/21,165.15,166.03,164.19,164.56,157723100,-2.1117647058823366
126,2013/08/22,164.92,166.3,164.89,166.06,101273000,-2.4449117647058927
127,2013/08/23,166.54,166.83,165.77,166.62,90796000,-2.4733529411765005
128,2013/08/26,166.77,167.3,165.89,166.0,89398400,-2.3041470588235597
129,2013/08/27,164.33,164.98,163.21,163.33,154275400,-2.558941176470597
130,2013/08/28,163.3,164.49,163.05,163.91,105120800,-2.729882352941246
131,2013/08/29,163.55,165.04,163.4,164.17,118828000,-2.907529411764756
132,2013/08/30,164.52,164.53,163.17,163.65,134186300,-3.274441176470674
133,2013/09/03,165.24,165.58,163.7,164.39,142802600,-3.5750000000001023
134,2013/09/04,164.44,166.03,164.14,165.75,97290400,-3.2881764705883825
135,2013/09/05,165.85,166.4,165.73,165.96,62845000,-2.7506470588236596
136,2013/09/06,166.49,166.98,164.48,166.04,159383800,-2.359235294117724
137,2013/09/09,166.45,167.73,166.45,167.63,87407200,-1.6440294117648193
138,2013/09/10,168.63,168.9,168.26,168.87,104783000,-0.8307352941177726
139,2013/09/11,168.64,169.4,168.35,169.4,94325700,-0.06847058823538532
140,2013/09/12,169.37,169.56,168.72,168.95,82557800,0.5279999999999063
141,2013/09/13,169.15,169.46,168.74,169.33,72257500,1.1796470588234342
142,2013/09/16,171.18,171.24,170.04,170.31,126050700,1.829205882352852
143,2013/09/17,170.47,171.11,170.46,171.07,82232500,2.209911764705822
144,2013/09/18,170.97,173.52,170.58,173.05,201318000,2.7602058823528637
145,2013/09/19,173.51,173.6,172.59,172.76,146440600,3.4706176470587593
146,2013/09/20,172.3,172.33,170.58,170.72,132317600,3.9138235294117294
147,2013/09/23,170.5,170.65,169.39,169.93,104533900,3.808499999999924
148,2013/09/24,169.89,170.53,169.21,169.53,100422400,3.6274117647057835
149,2013/09/25,169.65,169.98,168.89,169.04,114559100,3.0913235294116532
150,2013/09/26,169.34,170.17,169.05,169.69,76579600,2.392705882352857
151,2013/09/27,168.81,169.14,168.47,168.91,97695900,1.88049999999987
152,2013/09/30,167.45,168.54,167.15,168.01,143609700,1.4749117647057517
153,2013/10/01,168.14,169.5,168.0,169.34,126981900,1.2628235294116337
154,2013/10/02,168.35,169.34,167.83,169.18,112803800,1.1123823529410686
155,2013/10/03,168.77,168.94,166.84,167.62,176384300,0.7351470588234008
156,2013/10/04,167.74,169.06,167.53,168.89,96600700,0.5675588235292821
157,2013/10/07,167.43,168.45,167.25,167.43,95653200,0.4989999999998531
158,2013/10/08,167.45,167.62,165.36,165.48,176560600,0.018764705882205135
159,2013/10/09,165.8,166.2,164.53,165.6,168100500,-0.6327352941177935
160,2013/10/10,167.29,169.26,167.23,169.17,193988300,-0.6396764705883697
161,2013/10/11,168.9,170.32,168.77,170.26,104956400,-0.48511764705898486
162,2013/10/14,169.24,171.08,169.08,170.94,111248400,-0.14161764705897895
163,2013/10/15,170.52,171.15,169.47,169.7,154901700,0.43958823529396795
164,2013/10/16,170.75,172.16,170.63,172.07,160895600,1.4213235294115805
165,2013/10/17,171.37,173.32,171.34,173.22,128890400,1.9997941176468714
166,2013/10/18,173.86,174.51,173.51,174.39,138055900,2.593970588235095
167,2013/10/21,174.45,174.75,174.01,174.4,104058600,3.1674999999998192
168,2013/10/22,174.91,175.93,174.66,175.41,126638900,3.864205882352735
169,2013/10/23,174.83,174.89,173.96,174.57,105043800,4.224323529411549
170,2013/10/24,174.9,175.37,174.51,175.15,70037700,4.475441176470383
171,2013/10/25,175.51,176.0,175.17,175.95,93453900,4.540588235293939
172,2013/10/28,175.9,176.47,175.7,176.23,84497900,4.660852941176302
173,2013/10/29,176.6,177.24,176.38,177.17,87200600,4.730470588235107
174,2013/10/30,177.4,177.51,175.66,176.29,135506600,4.94349999999983
175,2013/10/31,176.18,176.89,175.53,175.79,133352300,4.9883823529410165
176,2013/11/01,176.05,176.61,175.22,176.21,142771700,4.89923529411746
177,2013/11/04,176.71,176.9,175.9825,176.83,85257800,4.804124999999857
178,2013/11/05,176.16,176.75,175.57,176.27,85466500,4.55324264705871
179,2013/11/06,177.03,177.5,176.54,177.17,87123100,4.524801470588102
180,2013/11/07,177.56,177.64,174.76,174.93,148632200,4.383242647058694
181,2013/11/08,174.85,177.31,174.85,177.29,136500100,4.238007352941054
182,2013/11/11,177.14,177.53,176.91,177.32,66226700,4.1775808823528
183,2013/11/12,176.95,177.36,176.37,176.96,83193500,4.10005147058817
184,2013/11/13,176.1,178.41,176.09,178.38,99795600,3.9213455882352264
185,2013/11/14,178.53,179.42,178.25,179.27,102965800,4.153345588235226
186,2013/11/15,179.57,180.12,179.33,180.05,102759600,4.53293382352939
187,2013/11/18,180.39,180.5,179.02,179.42,98459500,4.717110294117617
188,2013/11/19,179.31,179.87,178.72,179.03,93045800,4.888110294117638
189,2013/11/20,179.41,179.93,177.98,178.47,124692900,4.903669117647041
190,2013/11/21,179.0,180.05,178.86,179.91,91804700,4.699433823529375
191,2013/11/22,180.01,180.83,179.77,180.81,81234700,4.448257352941113
192,2013/11/25,181.11,181.17,180.37,180.63,79187800,4.230257352941152
193,2013/11/26,180.74,181.22,180.4,180.68,86697800,4.0789926470587545
194,2013/11/27,180.89,181.24,180.65,181.12,58227900,4.103463235294072
195,2013/11/29,181.34,181.75,180.8,181.0,54981700,4.122463235294106
196,2013/12/02,181.12,181.43,180.25,180.53,99262300,3.913992647058791
197,2013/12/03,179.95,180.39,179.17,179.75,115939400,3.4374632352941035
198,2013/12/04,179.18,180.48,178.35,179.73,122956300,2.922580882352918
199,2013/12/05,179.42,179.74,178.77,178.94,106333600,2.380904411764675
200,2013/12/06,180.72,181.11,180.15,180.94,127424400,2.057198529411721
201,2013/12/09,181.47,181.67,181.16,181.4,69987400,1.9652867647058656
202,2013/12/10,180.96,181.36,180.63,180.75,77428000,2.0406397058823416
203,2013/12/11,180.81,180.85,178.5,178.72,130188800,1.93822794117645
204,2013/12/12,178.61,178.86,177.76,178.13,115321400,1.65011029411761
205,2013/12/13,178.48,178.66,177.77,178.11,107741000,1.0897573529411204
206,2013/12/16,178.95,179.81,178.9,179.22,96100500,0.5815808823529096
207,2013/12/17,179.37,179.41,178.25,178.65,89432200,0.0891691176470033
208,2013/12/18,178.91,181.73,177.32,181.7,234455700,-0.02730147058827015
209,2013/12/19,181.18,181.7,180.71,181.49,136717700,0.40478676470584674
210,2013/12/20,180.67,181.99,180.57,181.56,196678700,0.8599926470587889
211,2013/12/23,182.41,182.64,182.07,182.53,85407800,1.2860588235293733
212,2013/12/24,182.57,183.01,182.53,182.93,45363300,1.8796470588234797
213,2013/12/26,183.37,183.96,183.32,183.85,63215200,2.5079411764705526
214,2013/12/27,184.14,184.18,183.66,183.85,61794800,2.8238823529411263
215,2013/12/30,183.92,184.02,183.58,183.82,56807200,3.100823529411713
216,2013/12/31,184.11,184.69,183.93,184.69,86123600,3.2832941176469888
217,2014/01/02,183.91,184.07,182.48,182.92,119511100,3.195764705882283
218,2014/01/03,183.24,183.6,182.63,182.88,81352000,2.918264705882308
219,2014/01/06,183.52,183.56,182.08,182.36,106889400,2.581058823529361
220,2014/01/07,183.12,183.79,182.95,183.48,86041200,2.387852941176419
221,2014/01/08,183.46,183.83,182.89,183.52,96481400,2.091970588235256
222,2014/01/09,184.1,184.13,182.79,183.64,90529400,2.0064705882352882
223,2014/01/10,183.96,184.22,183.01,184.14,101986500,1.9694117647058818
224,2014/01/13,183.64,184.18,181.34,181.68,149507600,1.8602058823529433
225,2014/01/14,182.27,183.77,181.95,183.67,104596300,1.6829117647058922
226,2014/01/15,184.1,184.94,183.71,184.66,98370100,1.7713529411764455
227,2014/01/16,184.3,184.66,183.83,184.42,72112100,1.827323529411757
228,2014/01/17,184.1,184.45,183.32,183.63,107832500,1.7948529411764298
229,2014/01/21,184.72,184.77,183.05,184.18,88504600,1.9473529411764616
230,2014/01/22,184.51,184.57,183.91,184.3,60761400,2.1233529411764493
231,2014/01/23,183.38,183.4,181.82,182.79,132343700,1.6971176470588034
232,2014/01/24,181.59,181.66,178.83,178.89,208595800,0.8727058823529603
233,2014/01/27,179.05,179.52,177.12,178.01,179949700,-0.21279411764703582
234,2014/01/28,178.23,179.3,178.12,179.07,108851800,-1.1963235294117283
235,2014/01/29,177.59,178.55,176.88,177.35,215244500,-2.3925000000000125
236,2014/01/30,178.88,179.81,178.26,179.23,116150500,-3.0498529411764537
237,2014/01/31,177.0,179.29,176.92,178.18,194573800,-3.431676470588229
238,2014/02/03,177.95,178.37,173.83,174.17,254370100,-3.81067647058822
239,2014/02/04,174.98,175.84,174.11,175.38,164781000,-4.46238235294112
240,2014/02/05,174.77,175.56,173.71,175.17,163629100,-4.939558823529353
241,2014/02/06,175.61,177.48,175.22,177.48,132379000,-5.4036176470587804
242,2014/02/07,178.29,179.87,177.73,179.68,170701300,-5.243294117647025
243,2014/02/10,179.7,180.07,179.21,180.01,91977200,-4.489264705882306
244,2014/02/11,180.23,182.44,180.04,181.98,121636400,-3.2350882352940857
245,2014/02/12,182.26,182.83,181.71,182.07,94414700,-1.7055882352941012
246,2014/02/13,180.85,183.2,180.83,183.01,100515600,-0.550382352941142
247,2014/02/14,182.9,184.36,182.67,184.02,96413500,0.396294117647102
248,2014/02/18,184.2,184.49,183.65,184.24,80018500,1.2778823529412193
249,2014/02/19,183.78,184.95,182.87,183.02,125995500,1.808647058823567
250,2014/02/20,183.27,184.52,182.6,184.1,104841400,2.0887058823529685
251,2014/02/21,184.45,184.89,183.8,183.89,118069200,2.5232352941176543
252,2014/02/24,184.3,186.15,184.2,184.91,113918000,2.794647058823557
253,2014/02/25,185.03,185.59,184.23,184.84,116815100,2.9011764705882683
254,2014/02/26,185.1,185.6,184.33,184.85,98329400,3.065264705882356
255,2014/02/27,184.58,185.87,184.37,185.82,93720800,3.3255000000000052
256,2014/02/28,185.78,187.15,185.05,186.29,150681900,3.5988529411764887
257,2014/03/03,184.65,185.45,183.75,184.98,167434300,3.4548823529411834
258,2014/03/04,186.79,187.98,186.75,187.58,169638300,3.8104411764706185
259,2014/03/05,187.75,188.07,187.45,187.75,88273700,4.2253235294117815
260,2014/03/06,188.24,188.61,187.78,188.18,82328000,4.726500000000016
261,2014/03/07,188.93,188.96,187.43,188.26,117468700,5.029323529411812
262,2014/03/10,187.94,188.23,187.08,188.16,74834300,5.5294411764706695
263,2014/03/11,188.48,188.71,186.8,187.23,98827400,5.494352941176544
264,2014/03/12,186.32,187.35,185.9,187.28,104701600,5.197205882352989
265,2014/03/13,187.88,187.99,184.66,185.18,154146000,4.713941176470655
266,2014/03/14,184.8,185.8,184.44,184.66,153743000,3.9555588235295147
267,2014/03/17,185.62,186.77,185.51,186.33,98250600,3.4225588235295277
268,2014/03/18,186.74,187.91,186.51,187.66,101626300,3.063558823529519
269,2014/03/19,187.71,187.94,185.47,186.66,176115300,2.815147058823669
270,2014/03/20,186.25,187.89,185.92,187.75,116944200,2.699676470588372
271,2014/03/21,187.71,189.02,186.03,186.2,163058100,2.9036176470589794
272,2014/03/24,186.84,187.07,184.62,185.43,120889800,2.558000000000135
273,2014/03/25,186.4,186.94,185.27,186.31,103492000,2.009647058823674
274,2014/03/26,187.0,187.34,184.92,184.97,119656900,1.556558823529599
275,2014/03/27,184.77,185.34,183.9,184.58,142204500,0.8563235294119522
276,2014/03/28,185.14,186.42,185.0,185.49,101527200,0.29008823529431993
277,2014/03/31,186.66,187.3,186.47,187.01,99626700,0.2850000000001671
278,2014/04/01,187.65,188.36,187.45,188.25,88958900,0.4489705882354542
279,2014/04/02,188.5,189.13,188.14,188.88,78714300,0.7627647058825175
280,2014/04/03,189.13,189.22,188.05,188.63,77253000,1.3710588235295518
281,2014/04/04,189.64,189.7,186.1,186.4,169003600,1.6800882352942494
282,2014/04/07,185.9,186.26,183.96,184.34,140661000,1.2945000000001414
283,2014/04/08,184.18,185.4,183.59,185.1,112585800,0.595294117647228
284,2014/04/09,185.61,187.15,185.06,187.09,100013900,0.014441176470768369
285,2014/04/10,187.07,187.17,182.93,183.15,172873800,-0.7232941176468728
286,2014/04/11,182.16,183.42,181.31,181.51,167016600,-1.7476470588233042
287,2014/04/14,182.92,183.37,181.44,182.94,132183000,-2.214970588235076
288,2014/04/15,183.35,184.33,181.51,184.2,157026300,-2.469823529411542
289,2014/04/16,185.47,186.14,184.65,186.12,104151700,-2.619911764705705
290,2014/04/17,185.87,186.91,185.56,186.39,105192300,-2.3868823529409156
291,2014/04/21,186.45,187.1,186.21,187.04,68212800,-1.5893235294115016
292,2014/04/22,187.24,188.4,187.13,187.89,85686400,-0.5290882352938411
293,2014/04/23,187.8,187.92,187.3,187.45,73611400,0.41332352941202544
294,2014/04/24,188.39,188.39,186.93,187.83,88109600,0.8820588235296896
295,2014/04/25,187.23,187.33,185.87,186.29,100307700,1.0019705882355936
296,2014/04/28,187.08,187.69,184.96,186.88,134950500,0.975088235294379
297,2014/04/29,187.48,188.04,187.08,187.75,83971400,0.9398235294120241
298,2014/04/30,187.46,188.5,187.18,188.31,101461700,0.9500882352943449
299,2014/05/01,188.25,188.84,187.73,188.32,92856500,1.0174411764708395
300,2014/05/02,188.33,189.14,187.78,188.06,97969300,1.2912058823531538
301,2014/05/05,187.16,188.55,186.62,188.42,75827800,1.5007058823531452
302,2014/05/06,188.03,188.13,186.74,186.78,85356200,1.469088235294322
303,2014/05/07,187.41,187.97,186.01,187.88,106377000,1.2907058823531656
304,2014/05/08,187.71,189.05,187.08,187.68,93495400,1.2125882352943336
305,2014/05/09,187.71,188.04,186.83,187.96,83648000,1.0102352941178196
306,2014/05/12,188.77,189.88,188.0,189.79,86871400,1.1902058823531547
307,2014/05/13,190.03,190.42,189.77,189.96,66416800,1.6048529411766594
308,2014/05/14,189.82,189.88,188.79,189.06,72243900,1.9795882352943295
309,2014/05/15,188.68,188.72,186.48,187.4,154897300,1.7989411764707484
310,2014/05/16,187.5,188.13,186.72,188.05,97384100,1.746500000000168
311,2014/05/19,187.71,188.89,187.52,188.74,63676300,1.560676470588362
312,2014/05/20,188.67,188.67,187.07,187.55,111512600,1.1167058823531022
313,2014/05/21,188.07,189.22,188.06,189.13,88998000,0.9775588235295913
314,2014/05/22,189.2,189.98,188.86,189.59,61519500,1.3184705882354706
315,2014/05/23,189.76,190.48,189.59,190.35,61108000,1.7776764705884034
316,2014/05/27,191.06,191.58,190.95,191.52,71961100,2.2086470588237432
317,2014/05/28,191.55,191.82,191.06,191.38,66048500,2.7183823529413758
318,2014/05/29,191.85,192.4,191.33,192.37,64139000,3.193970588235487
319,2014/05/30,192.21,192.8,192.03,192.68,76256200,3.5763529411766513
320,2014/06/02,192.98,192.99,191.97,192.9,64568200,3.7678529411766988
321,2014/06/03,192.41,192.9,192.25,192.8,64985200,3.730735294117835
322,2014/06/04,192.46,193.3,192.26,193.19,55495200,3.7087352941178438
323,2014/06/05,193.43,194.65,192.7,194.45,92035600,3.827205882353155
324,2014/06/06,194.88,195.43,194.78,195.38,78650300,4.104323529411971
325,2014/06/09,195.36,196.05,195.17,195.58,65025700,4.466941176470783
326,2014/06/10,195.36,195.64,194.92,195.6,56992500,4.786911764706105
327,2014/06/11,194.87,195.12,194.48,194.92,68703000,4.979441176470772
328,2014/06/12,194.68,194.8,193.11,193.54,106125500,4.850294117647223
329,2014/06/13,193.89,194.32,193.3,194.13,81991000,4.379235294117819
330,2014/06/16,193.88,194.7,193.66,194.29,87349400,3.8622058823531233
331,2014/06/17,194.0,194.97,193.81,194.83,84776800,3.4833235294119334
332,2014/06/18,194.83,196.37,194.4,196.26,105144800,3.378411764706044
333,2014/06/19,196.46,196.6,195.8,196.48,85833100,3.5946176470590103
334,2014/06/20,196.01,196.1,195.7,195.94,99965100,3.793794117647252
335,2014/06/23,196.0,196.05,195.52,195.88,70447200,3.873617647059035
336,2014/06/24,195.54,196.5,194.48,194.7,96018200,3.856705882353168
337,2014/06/25,194.28,195.78,194.25,195.58,82694100,3.5466764705884657
338,2014/06/26,195.6,195.63,194.13,195.44,84216600,3.082235294117851
339,2014/06/27,194.98,195.88,194.88,195.82,71326100,2.7445588235295872
340,2014/06/30,195.71,196.16,195.53,195.72,70396800,2.5534705882354274
341,2014/07/01,196.21,197.63,196.13,197.03,90321700,2.6319117647060466
342,2014/07/02,197.03,197.48,196.96,197.23,52316200,2.8410000000001503
343,2014/07/03,197.81,198.29,197.64,198.2,52894800,3.15314705882372
344,2014/07/07,197.84,197.98,197.22,197.51,61676700,3.2978823529413432
345,2014/07/08,197.12,197.22,195.76,196.24,108055300,3.1832058823531213
346,2014/07/09,196.75,197.29,196.31,197.12,72953600,2.9045588235296123
347,2014/07/10,195.24,196.86,195.06,196.34,98922400,2.4372647058825123
348,2014/07/11,196.24,196.75,195.78,196.61,64226200,1.8959411764707852
349,2014/07/14,197.63,197.86,197.44,197.6,58563600,1.6819705882355152
350,2014/07/15,197.71,198.1,196.36,197.23,111297400,1.6545294117649405
351,2014/07/16,198.12,198.26,197.42,197.96,79978600,1.674294117647264
352,2014/07/17,197.33,198.1,195.43,195.71,144412600,1.691176470588431
353,2014/07/18,196.38,197.91,196.24,197.71,124256300,1.7161176470590362
354,2014/07/21,197.08,197.5,196.43,197.34,67480300,1.4472058823531881
355,2014/07/22,198.04,198.56,197.87,198.2,67612500,1.4783235294119947
356,2014/07/23,198.51,198.85,198.1,198.64,65545600,1.4378235294119577
357,2014/07/24,198.82,199.06,198.45,198.65,56417500,1.6864117647060652
358,2014/07/25,198.11,198.26,197.33,197.72,76782500,1.7512941176472054
359,2014/07/28,197.78,198.09,196.62,197.8,69106500,1.777970588235462
360,2014/07/29,198.21,198.45,196.92,196.95,80408600,1.6012352941177994
361,2014/07/30,197.66,197.91,196.16,196.98,104105100,1.2475000000001444
362,2014/07/31,195.63,195.78,192.97,193.09,183073500,0.3591470588237087
363,2014/08/01,192.58,193.76,191.57,192.5,189075200,-0.6331764705880687
364,2014/08/04,192.87,194.3,192.05,193.89,91108400,-1.4396176470586681
365,2014/08/05,193.11,193.6,191.31,192.01,152557200,-2.428705882352773
366,2014/08/06,191.08,192.89,191.08,192.07,94628200,-3.3387058823527127
367,2014/08/07,192.96,193.13,190.55,191.03,135507800,-3.7174705882350736
368,2014/08/08,191.43,193.37,190.95,193.24,116999400,-3.708470588235059
369,2014/08/11,193.99,194.66,193.71,193.79,74451200,-3.4594117647056635
370,2014/08/12,193.63,194.15,192.94,193.53,73605400,-3.1842058823526997
371,2014/08/13,194.3,195.06,193.96,194.84,68961600,-2.664352941176247
372,2014/08/14,195.19,195.76,194.98,195.76,57228200,-1.9727647058821276
373,2014/08/15,196.49,196.65,194.31,195.72,139872000,-1.3117058823526406
374,2014/08/18,196.81,197.45,196.69,197.36,75188600,-0.7707352941173156
375,2014/08/19,197.85,198.54,197.44,198.39,58964600,0.08561764705913788
376,2014/08/20,198.15,199.16,198.08,198.92,72725600,0.8664411764708859
377,2014/08/21,199.06,199.76,198.93,199.5,67745800,1.6208529411767927
378,2014/08/22,199.32,199.69,198.74,199.19,76067700,2.320352941176793
379,2014/08/25,200.16,200.59,199.15,200.2,63806000,2.7809411764709466
380,2014/08/26,200.35,200.82,200.28,200.33,47256100,3.182647058823875
381,2014/08/27,200.45,200.57,199.94,200.25,47820600,3.383323529412081
382,2014/08/28,199.59,200.27,199.39,200.14,58267500,3.375470588235629
383,2014/08/29,200.44,200.73,199.82,200.71,65886200,3.5102647058826335
384,2014/09/02,200.97,200.99,199.86,200.61,72322600,3.5272941176473864
385,2014/09/03,201.35,201.41,200.22,200.5,57371400,3.492794117647378
386,2014/09/04,200.86,201.58,199.66,200.21,85000300,3.4524117647061985
387,2014/09/05,200.19,201.19,199.41,201.11,102015100,3.4515588235297514
388,2014/09/08,200.94,201.21,200.0,200.59,64102500,3.4105000000003542
389,2014/09/09,200.42,200.55,198.91,199.32,88482500,3.2269411764709446
390,2014/09/10,199.46,200.2,198.77,200.07,67154300,2.9312352941179824
391,2014/09/11,199.28,200.33,199.12,200.3,66737400,2.723705882353272
392,2014/09/12,200.12,200.12,198.56,199.13,117408300,2.486264705882661
393,2014/09/15,199.17,199.32,198.38,198.98,76357300,2.091294117647351
394,2014/09/16,198.64,200.84,198.5,200.48,116043200,2.0209117647061703
395,2014/09/17,200.8,201.68,199.75,200.75,151153900,2.1586764705885173
396,2014/09/18,201.36,201.85,201.1,201.82,94940000,2.299852941176738
397,2014/09/19,201.53,201.9,200.29,200.7,121449500,2.40291176470609
398,2014/09/22,200.33,200.38,198.73,199.15,125433400,2.356264705882552
399,2014/09/23,198.41,199.26,197.95,198.01,111088300,1.9623823529413755
400,2014/09/24,198.06,199.69,197.52,199.56,107137500,1.3456764705884439
401,2014/09/25,199.05,199.05,196.27,196.34,150009700,0.4115000000001885
402,2014/09/26,196.7,198.39,196.42,197.9,103505800,-0.4807647058821374
403,2014/09/29,196.18,197.89,196.05,197.54,95085900,-1.0796764705880548
404,2014/09/30,197.7,198.3,196.61,197.02,130138700,-1.4246764705880537
405,2014/10/01,196.68,196.77,193.91,194.35,177612400,-2.1020882352939623
406,2014/10/02,194.18,195.05,192.35,194.38,157170400,-2.844970588235128
407,2014/10/03,195.71,196.94,195.08,196.52,121466200,-3.1395588235292564
408,2014/10/06,197.36,197.6,195.58,196.29,104737900,-3.2014411764704676
409,2014/10/07,195.29,195.72,193.22,193.26,147603600,-3.6949117647058074
410,2014/10/08,193.36,196.92,192.36,196.64,186054900,-3.7178529411763748
411,2014/10/09,196.36,196.6,192.58,192.74,209978700,-3.3999999999999204
412,2014/10/10,192.7,193.65,190.49,190.54,221648200,-3.977852941176394
413,2014/10/13,190.47,191.15,187.3,187.41,230050200,-5.137764705882319
414,2014/10/14,188.46,189.82,187.04,187.7,215307000,-5.9892941176470345
415,2014/10/15,185.19,187.69,181.92,186.43,380336300,-7.501882352941124
416,2014/10/16,183.05,187.58,182.89,186.27,270175000,-8.943617647058772
417,2014/10/17,188.42,189.75,187.62,188.47,214253300,-9.279735294117614
418,2014/10/20,188.12,190.45,188.07,190.3,129599500,-8.944352941176447
419,2014/10/21,191.7,194.2,191.48,194.07,154476400,-7.827794117647045
420,2014/10/22,194.44,194.91,192.61,192.69,151477500,-5.8350294117647366
421,2014/10/23,194.64,196.2,194.26,194.93,154681700,-3.686911764705883
422,2014/10/24,195.23,196.49,194.49,196.43,116840100,-2.1754705882352994
423,2014/10/27,195.75,196.45,195.03,196.16,82755000,-0.7621176470588011
424,2014/10/28,196.84,198.42,196.73,198.41,106688000,0.24105882352944263
425,2014/10/29,198.59,199.12,196.8,198.11,142365300,1.132970588235338
426,2014/10/30,197.59,199.61,197.4,199.38,113026700,1.8125294117647286
427,2014/10/31,201.78,201.82,200.77,201.66,146857100,2.901617647058856
428,2014/11/03,201.92,202.45,201.3,201.77,93539900,4.063764705882392
429,2014/11/04,201.22,201.6,200.06,201.07,93177300,4.7113823529412
430,2014/11/05,202.56,202.59,201.45,202.34,91468900,5.507352941176492
431,2014/11/06,202.41,203.26,201.64,203.15,106742100,6.256500000000045
432,2014/11/07,203.17,203.6,202.61,203.34,89472200,6.514088235294139
433,2014/11/10,203.4,204.04,203.13,203.98,65917600,6.709617647058849
434,2014/11/11,204.07,204.31,203.65,204.18,54299100,7.1815294117647
435,2014/11/12,203.35,204.24,203.31,203.96,89967500,7.352676470588278
436,2014/11/13,204.14,204.83,203.21,204.19,84991500,7.4721176470588375
437,2014/11/14,204.13,204.49,203.72,204.24,80335200,7.4622647058823475
438,2014/11/17,203.85,204.58,203.65,204.37,80377300,7.372382352941173
439,2014/11/18,204.46,205.92,204.44,205.55,75891900,7.322970588235279
440,2014/11/19,205.3,205.55,204.3,205.22,82229900,7.222823529411755
441,2014/11/20,204.25,205.71,204.18,205.58,72589800,7.14502941176471
442,2014/11/21,207.6,207.84,205.98,206.68,142173900,7.402500000000032
443,2014/11/24,207.19,207.39,206.91,207.26,65675200,7.636558823529441
444,2014/11/25,207.54,207.79,206.8,207.11,79019800,7.687352941176499
445,2014/11/26,207.27,207.76,207.03,207.64,56385900,7.804735294117705
446,2014/11/28,207.52,207.87,206.91,207.2,57890100,7.843147058823604
447,2014/12/01,206.4,206.54,205.38,205.76,103806900,7.160941176470658
448,2014/12/02,205.8,207.34,205.78,207.09,74456200,6.509705882352989
449,2014/12/03,207.28,208.15,207.1,207.89,68873500,5.9045294117647416
450,2014/12/04,207.55,208.26,206.7,207.66,91225300,5.267264705882411
451,2014/12/05,207.88,208.47,207.55,208.0,90989800,4.822882352941207
452,2014/12/08,207.55,208.12,205.93,206.61,108465100,4.51338235294125
453,2014/12/09,204.37,206.6,203.91,206.47,125039000,3.887235294117744
454,2014/12/10,205.94,205.98,202.93,203.16,159237100,2.9386764705883195
455,2014/12/11,203.89,206.19,203.71,204.19,158628800,2.146794117647147
456,2014/12/12,202.65,203.82,200.85,200.89,202123800,0.8104705882353755
457,2014/12/15,202.0,202.53,198.78,199.51,189556900,-0.6080882352940193
458,2014/12/16,198.55,202.4,197.86,197.91,258910900,-1.7082352941175714
459,2014/12/17,198.48,202.34,198.29,201.79,252523700,-2.605499999999921
460,2014/12/18,204.78,212.97,203.92,206.78,256995300,-2.1988529411763977
461,2014/12/19,206.46,207.33,205.61,206.52,243364900,-1.5240588235293444
462,2014/12/22,206.71,207.47,206.46,207.47,148194100,-0.4117647058822911
463,2014/12/23,208.2,208.23,207.4,207.75,120621800,0.9197941176471147
464,2014/12/24,208.03,208.34,207.72,207.77,42963400,2.28602941176473
465,2014/12/26,208.29,208.85,208.25,208.44,57211900,2.1276176470588553
466,2014/12/29,208.25,208.97,208.14,208.72,79532000,2.3843235294117733
467,2014/12/30,208.21,208.37,207.51,207.6,73448300,2.4512352941177085
468,2014/12/31,207.96,208.19,205.39,205.54,130281700,2.1635882352941564
469,2015/01/02,206.39,206.88,204.18,205.43,121408500,1.6119705882353514
470,2015/01/05,204.2,204.37,201.35,201.72,169440600,0.508088235294224
471,2015/01/06,202.13,202.72,198.85,199.82,208923900,-0.9482647058822522
472,2015/01/07,201.46,202.72,200.88,202.31,125069600,-2.1081764705881767
473,2015/01/08,204.0,206.16,203.99,205.9,146056100,-2.4480882352940228
474,2015/01/09,206.39,206.42,203.51,204.25,157609800,-2.5622647058822565
475,2015/01/12,204.42,204.6,201.92,202.65,144060200,-2.4327058823528773
476,2015/01/13,204.15,205.48,200.51,202.08,214372200,-1.87555882352936
477,2015/01/14,199.67,201.1,198.57,200.86,192575000,-2.053411764705828
478,2015/01/15,201.64,202.01,198.88,199.02,175449000,-2.7779411764705344
479,2015/01/16,198.75,201.82,198.55,201.63,211716100,-3.5218823529411054
480,2015/01/20,202.42,202.72,200.17,202.05,130876700,-3.7100294117646513
481,2015/01/21,201.51,203.66,200.94,203.08,122704300,-3.7413823529411445
482,2015/01/22,204.02,206.26,202.33,206.1,173707900,-2.7827647058823004
483,2015/01/23,205.8,206.1,204.81,204.97,117357700,-1.7169411764705274
484,2015/01/26,204.73,205.56,203.85,205.45,91710100,-0.7313235294117248
485,2015/01/27,203.0,204.12,201.74,202.74,133646200,-0.2849117647058108
486,2015/01/28,204.16,204.29,199.91,200.14,167686500,-0.18005882352940716
487,2015/01/29,200.34,202.3,198.68,201.99,173312500,-0.8009117647058872
488,2015/01/30,200.56,202.17,199.13,199.45,197508500,-1.6500000000000057
489,2015/02/02,200.07,202.03,197.86,201.92,162707100,-2.4547941176470545
490,2015/02/03,203.02,204.85,202.55,204.84,123867400,-2.3409411764705794
491,2015/02/04,203.94,205.38,203.51,204.06,133968500,-1.9834117647058918
492,2015/02/05,204.83,206.3,204.77,206.12,97731200,-1.1333823529411688
493,2015/02/06,206.57,207.24,204.92,205.55,125590100,-0.21694117647061262
494,2015/02/09,204.77,205.64,204.13,204.63,87084200,0.8757647058823181
495,2015/02/10,205.89,207.12,204.68,206.81,96142600,1.332529411764682
496,2015/02/11,206.6,207.45,205.83,206.93,90227200,1.781088235294078
497,2015/02/12,207.91,208.99,206.97,208.92,97226900,2.2652352941175877
498,2015/02/13,209.08,209.84,208.76,209.78,93617500,2.8718823529410997
499,2015/02/17,209.38,210.32,209.1,210.11,76896000,3.802764705882282

301
Tests/TestData/spy_cmf.txt Normal file
View File

@@ -0,0 +1,301 @@
Date,Open,High,Low,Close,Volume,CMF_20
2019-09-27 12:00:00 AM,297.83,297.9465,293.69,295.4,84781110,0.101462918915507
2019-09-30 12:00:00 AM,295.97,297.55,295.92,296.77,52562761,0.116739252647704
2019-10-01 12:00:00 AM,297.74,298.455,293,293.24,89900420,0.040124568303099
2019-10-02 12:00:00 AM,291.5,291.51,286.64,288.06,124523974,-0.030868971310452
2019-10-03 12:00:00 AM,287.81,290.45,284.82,290.42,85906799,0.024164528056182
2019-10-04 12:00:00 AM,291.14,294.63,290.82,294.35,66700681,0.065292656253434
2019-10-07 12:00:00 AM,293.47,295.26,292.77,293.08,60656561,0.033556819553751
2019-10-08 12:00:00 AM,291.04,291.85,288.49,288.53,101575470,-0.06984367837376
2019-10-09 12:00:00 AM,290.75,292.3,288.6559,291.27,65707329,-0.093714449761624
2019-10-10 12:00:00 AM,291.18,294.21,291,293.24,57255974,-0.072424883582483
2019-10-11 12:00:00 AM,296.27,298.74,296.1448,296.28,101228577,-0.111880440209373
2019-10-14 12:00:00 AM,295.93,296.67,295.57,295.95,40546668,-0.115393682421806
2019-10-15 12:00:00 AM,297.1,299.7,296.97,298.88,47832356,-0.12633748545401
2019-10-16 12:00:00 AM,298.37,299.16,297.92,298.4,50563596,-0.182072586229871
2019-10-17 12:00:00 AM,299.68,300.24,298.515,299.28,46784885,-0.156554503690822
2019-10-18 12:00:00 AM,298.69,299.395,296.99,297.97,64338028,-0.136560370476833
2019-10-21 12:00:00 AM,299.42,300.21,298.935,299.99,39460901,-0.121936492028043
2019-10-22 12:00:00 AM,300.58,300.9,298.91,299.01,49126038,-0.117339874192467
2019-10-23 12:00:00 AM,298.73,299.94,298.495,299.88,34991829,-0.137609806338593
2019-10-24 12:00:00 AM,300.91,301.07,299.4601,300.37,35857459,-0.149363954993933
2019-10-25 12:00:00 AM,299.74,302.2,299.6806,301.6,45205412,-0.122058926930384
2019-10-28 12:00:00 AM,302.94,303.85,302.91,303.3,42146965,-0.130618875682761
2019-10-29 12:00:00 AM,303,304.23,302.86,303.21,44284921,-0.085483771774729
2019-10-30 12:00:00 AM,303.43,304.55,301.99,304.14,49643928,-0.015341607421492
2019-10-31 12:00:00 AM,304.13,304.13,301.73,303.33,69053791,-0.071257200939535
2019-11-01 12:00:00 AM,304.92,306.19,304.74,306.14,71141515,-0.062616857623033
2019-11-04 12:00:00 AM,307.85,308,306.96,307.37,60606916,-0.033324833101153
2019-11-05 12:00:00 AM,307.59,307.9195,306.71,307.03,43033885,0.039344763926092
2019-11-06 12:00:00 AM,307.03,307.4,306.06,307.1,46487108,0.037291118025009
2019-11-07 12:00:00 AM,308.57,309.65,307.66,308.18,54272274,-0.009448178212592
2019-11-08 12:00:00 AM,307.8,309.0036,307.03,308.94,49068797,0.128796701292715
2019-11-11 12:00:00 AM,307.42,308.54,307.27,308.35,35934909,0.167894403728229
2019-11-12 12:00:00 AM,308.75,309.99,308.15,309,46484624,0.144993251847985
2019-11-13 12:00:00 AM,307.91,309.54,307.66,309.1,54459018,0.185527677655354
2019-11-14 12:00:00 AM,308.79,309.64,308.09,309.55,52001874,0.236442792274619
2019-11-15 12:00:00 AM,311.02,311.84,310.26,311.79,62706192,0.308481435971894
2019-11-18 12:00:00 AM,311.53,312.28,311.03,312.02,49327980,0.308401812557023
2019-11-19 12:00:00 AM,312.68,312.69,311.22,311.93,67927818,0.343961098362882
2019-11-20 12:00:00 AM,311.28,311.85,309.06,310.77,79696276,0.316145152266736
2019-11-21 12:00:00 AM,310.89,311.01,309.39,310.27,54664690,0.310675750950586
2019-11-22 12:00:00 AM,311.09,311.24,309.85,310.96,44850228,0.313661034351455
2019-11-25 12:00:00 AM,311.98,313.37,311.98,313.37,48762676,0.363330039194785
2019-11-26 12:00:00 AM,313.41,314.28,313.06,314.08,37727953,0.409160119921728
2019-11-27 12:00:00 AM,314.61,315.48,314.37,315.48,44793179,0.421308800295305
2019-11-29 12:00:00 AM,314.86,315.13,314.06,314.31,36592740,0.393597117325667
2019-12-02 12:00:00 AM,314.59,314.66,311.17,311.64,76110027,0.275184693920258
2019-12-03 12:00:00 AM,308.65,309.64,307.13,309.55,75172709,0.349324968058501
2019-12-04 12:00:00 AM,310.7,312.12,310.32,311.46,49190402,0.378614636703184
2019-12-05 12:00:00 AM,312.23,312.25,310.58,312.02,40781669,0.384306691781756
2019-12-06 12:00:00 AM,314.12,315.31,314.11,314.87,48956767,0.423167939098266
2019-12-09 12:00:00 AM,314.44,315.18,313.8,313.88,34904315,0.355188468112463
2019-12-10 12:00:00 AM,313.82,314.55,312.81,313.53,53109165,0.316973758289444
2019-12-11 12:00:00 AM,314.03,314.7,313.4393,314.42,53521450,0.346125153092983
2019-12-12 12:00:00 AM,314.43,317.99,314.17,317.13,96585802,0.354747460522139
2019-12-13 12:00:00 AM,316.87,318.67,316.02,317.32,81546487,0.30374826856071
2019-12-16 12:00:00 AM,319.22,320.15,317.2542,319.5,82836128,0.287151834003134
2019-12-17 12:00:00 AM,319.92,320.25,319.48,319.57,61131769,0.219532022021917
2019-12-18 12:00:00 AM,320,320.25,319.53,319.59,48199955,0.190357660962522
2019-12-19 12:00:00 AM,319.8,320.98,319.5246,320.9,85388424,0.239647951194195
2019-12-20 12:00:00 AM,320.46,321.9742,319.3873,320.73,149338215,0.222260073344695
2019-12-23 12:00:00 AM,321.59,321.65,321.06,321.22,53015641,0.180231956284472
2019-12-24 12:00:00 AM,321.47,321.52,320.9,321.23,20270007,0.145802587198574
2019-12-26 12:00:00 AM,321.65,322.95,321.64,322.94,31024188,0.150849610897894
2019-12-27 12:00:00 AM,323.74,323.8,322.28,322.86,42554820,0.106157818216781
2019-12-30 12:00:00 AM,322.95,323.1,320.55,321.08,49782730,0.097243078522149
2019-12-31 12:00:00 AM,320.53,322.13,320.15,321.86,57106998,0.178756019426095
2020-01-02 12:00:00 AM,323.54,324.89,322.53,324.87,59253833,0.171508025486788
2020-01-03 12:00:00 AM,321.16,323.64,321.1,322.41,77783566,0.158818249626562
2020-01-06 12:00:00 AM,320.49,323.73,320.36,323.64,55761948,0.175609566824186
2020-01-07 12:00:00 AM,323.02,323.54,322.24,322.73,42854811,0.15737898843113
2020-01-08 12:00:00 AM,322.94,325.78,322.67,324.45,68434153,0.185329040623397
2020-01-09 12:00:00 AM,326.16,326.73,325.52,326.65,48569601,0.226551860606209
2020-01-10 12:00:00 AM,327.2899,327.46,325.2,325.71,53057389,0.180088032311782
2020-01-13 12:00:00 AM,326.39,327.96,325.92,327.95,47262010,0.182214787469304
2020-01-14 12:00:00 AM,327.47,328.62,326.844,327.45,63036384,0.1695906074645
2020-01-15 12:00:00 AM,327.35,329.02,327.26,328.19,72056598,0.136091012156513
2020-01-16 12:00:00 AM,329.7,330.92,329.45,330.92,54050328,0.222496794229619
2020-01-17 12:00:00 AM,331.7,332.18,330.8539,331.95,95846017,0.297644157538353
2020-01-21 12:00:00 AM,330.9,332.18,330.82,331.3,77742415,0.218393494842357
2020-01-22 12:00:00 AM,332.24,332.95,331.17,331.34,48914899,0.197536442372413
2020-01-23 12:00:00 AM,330.63,332.1682,329.41,331.72,52004140,0.250844164413877
2020-01-24 12:00:00 AM,332.44,332.53,327.36,328.77,87578442,0.201885555486425
2020-01-27 12:00:00 AM,323.03,325.12,322.66,323.5,84062463,0.147016519074486
2020-01-28 12:00:00 AM,325.06,327.85,323.6038,326.89,63833953,0.180313462139402
2020-01-29 12:00:00 AM,328.38,328.63,326.4,326.62,54040889,0.168394068766126
2020-01-30 12:00:00 AM,324.36,327.91,323.54,327.68,75491844,0.186275182101096
2020-01-31 12:00:00 AM,327,327.17,320.73,321.73,113845576,0.076332501826993
2020-02-03 12:00:00 AM,323.35,326.16,323.22,324.12,69242293,0.05475590280874
2020-02-04 12:00:00 AM,328.07,330.01,327.72,329.06,62573190,0.022908743414512
2020-02-05 12:00:00 AM,332.27,333.09,330.67,332.86,65951146,0.069634612053861
2020-02-06 12:00:00 AM,333.91,334.19,332.8,333.98,50359688,0.089417569130272
2020-02-07 12:00:00 AM,332.82,333.9941,331.6,332.2,64139443,0.033679477368277
2020-02-10 12:00:00 AM,331.23,334.75,331.19,334.68,42070006,0.085682052335954
2020-02-11 12:00:00 AM,336.16,337.02,334.684,335.26,54864533,0.0300055921384
2020-02-12 12:00:00 AM,336.83,337.65,336.43,337.42,43992662,0.066020010846215
2020-02-13 12:00:00 AM,335.8621,338.12,335.56,337.06,54501922,0.07091114022732
2020-02-14 12:00:00 AM,337.51,337.73,336.2,337.6,64582210,0.070013685082478
2020-02-18 12:00:00 AM,336.51,337.6677,335.21,336.73,57342526,0.034029166777754
2020-02-19 12:00:00 AM,337.79,339.08,337.48,338.34,48814692,0.055894340749775
2020-02-20 12:00:00 AM,337.7423,338.64,333.6817,336.95,74163362,0.104020414601186
2020-02-21 12:00:00 AM,335.47,335.81,332.58,333.48,113788208,0.035700434923054
2020-02-24 12:00:00 AM,323.14,325.85,321.24,322.42,161088409,0.006492816054931
2020-02-25 12:00:00 AM,323.94,324.61,311.69,312.65,218913168,-0.096881809505168
2020-02-26 12:00:00 AM,314.18,318.11,310.7,311.5,194773819,-0.200768902790467
2020-02-27 12:00:00 AM,305.46,311.5637,297.51,297.51,284353460,-0.302466438244851
2020-02-28 12:00:00 AM,288.7,297.892,285.54,296.26,385764020,-0.163090872274955
2020-03-02 12:00:00 AM,298.21,309.16,294.46,309.09,238703625,-0.020416069736493
2020-03-03 12:00:00 AM,309.5,313.84,297.57,300.24,300139150,-0.086311051749614
2020-03-04 12:00:00 AM,306.12,313.1,303.33,312.86,176613448,-0.024297030021949
2020-03-05 12:00:00 AM,304.98,308.47,300.01,302.46,186366809,-0.070086637868782
2020-03-06 12:00:00 AM,293.15,298.78,290.23,297.46,228667168,-0.024852432692149
2020-03-09 12:00:00 AM,275.3,284.19,273.45,274.23,309417350,-0.094748437444004
2020-03-10 12:00:00 AM,284.64,288.52,273.5,288.42,276444060,-0.021459504516785
2020-03-11 12:00:00 AM,280.7,281.94,270.88,274.36,256416563,-0.038581771983007
2020-03-12 12:00:00 AM,256,266.66,247.68,248.11,392220670,-0.135129527809987
2020-03-13 12:00:00 AM,263.09,271.4754,248.5237,269.32,329566100,-0.066386145095498
2020-03-16 12:00:00 AM,241.18,256.9,237.36,239.85,297240030,-0.123693306457466
2020-03-17 12:00:00 AM,245.04,256.17,237.07,252.8,262070471,-0.085402188265652
2020-03-18 12:00:00 AM,236.25,248.37,228.02,240,327597130,-0.06979448613003
2020-03-19 12:00:00 AM,239.25,247.38,232.22,240.51,289322040,-0.066254988155308
2020-03-20 12:00:00 AM,242.53,244.47,228.5,228.8,347158790,-0.115364476026607
2020-03-23 12:00:00 AM,228.19,229.6833,218.26,222.95,326025170,-0.108375274961681
2020-03-24 12:00:00 AM,234.42,244.1,233.8,243.15,235494475,-0.041010274990023
2020-03-25 12:00:00 AM,244.87,256.35,239.75,246.79,299430255,-0.0216062922892
2020-03-26 12:00:00 AM,249.52,262.8,249.05,261.2,257632816,0.062529734990754
2020-03-27 12:00:00 AM,253.27,260.81,251.05,253.42,224341217,-0.007445189152364
2020-03-30 12:00:00 AM,255.7,262.43,253.53,261.65,170961866,-0.024910490015397
2020-03-31 12:00:00 AM,260.56,263.33,256.22,257.75,194881060,-0.008577530710815
2020-04-01 12:00:00 AM,247.98,257.6591,243.9,246.15,189554623,-0.063270270301113
2020-04-02 12:00:00 AM,245.19,252.68,244.59,251.83,177660430,-0.022803570140845
2020-04-03 12:00:00 AM,250.76,253.32,245.22,248.19,135561171,-0.059854730275437
2020-04-06 12:00:00 AM,257.84,267,248.1698,264.86,188061238,0.017888461347821
2020-04-07 12:00:00 AM,274.21,275.03,264.89,265.13,201427189,-0.072910576196774
2020-04-08 12:00:00 AM,267.96,276,265.2542,274.03,153774487,-0.03591771876302
2020-04-09 12:00:00 AM,277.58,281.2,275.47,278.2,190282705,0.038743855808232
2020-04-13 12:00:00 AM,277.14,277.51,271.41,275.66,115139268,-0.007956912540422
2020-04-14 12:00:00 AM,280.98,284.9,275.5106,283.79,134143350,0.065024114062795
2020-04-15 12:00:00 AM,277.57,279.26,275.46,277.76,121775006,0.033523026207376
2020-04-16 12:00:00 AM,279.15,280.03,275.76,279.1,131798325,0.039114224179174
2020-04-17 12:00:00 AM,285.38,287.3,282.4,286.64,146684784,0.060842626241464
2020-04-20 12:00:00 AM,282.61,286.7912,281.35,281.59,100224647,0.130603637059174
2020-04-21 12:00:00 AM,276.73,278.04,272.02,273.04,126385698,0.130841920087818
2020-04-22 12:00:00 AM,278.35,281,276.91,279.1,93524584,0.081085096480051
2020-04-23 12:00:00 AM,280.49,283.94,278.75,279.08,104709693,0.071539690088647
2020-04-24 12:00:00 AM,280.73,283.7,278.5,282.97,85165953,0.029985754134856
2020-04-27 12:00:00 AM,285.12,288.27,284.62,287.05,77896608,0.08126145439484
2020-04-28 12:00:00 AM,291.02,291.4,285.4,285.73,105283871,-0.001422926414607
2020-04-29 12:00:00 AM,291.53,294.88,290.41,293.21,118745579,0.05081162106697
2020-04-30 12:00:00 AM,291.71,293.3239,288.59,290.48,122901701,0.091167091842859
2020-05-01 12:00:00 AM,285.31,290.6572,281.52,282.79,125180028,0.003553950885294
2020-05-04 12:00:00 AM,280.74,283.9,279.13,283.57,80873213,0.045561930221432
2020-05-05 12:00:00 AM,286.64,289.25,283.7134,286.19,79569938,-0.016022883822339
2020-05-06 12:00:00 AM,288.04,288.46,283.78,284.25,73632628,0.041240665826284
2020-05-07 12:00:00 AM,287.75,289.78,287.13,287.68,75250412,-0.021302485445589
2020-05-08 12:00:00 AM,291.09,292.95,289.86,292.44,76622128,0.006315806097393
2020-05-11 12:00:00 AM,290.34,294,289.88,292.5,79514231,-0.005073278995915
2020-05-12 12:00:00 AM,293.79,294.24,286.52,286.67,95870786,-0.101415473527502
2020-05-13 12:00:00 AM,286.06,287.19,278.965,281.6,144721099,-0.13824683542759
2020-05-14 12:00:00 AM,278.95,285.11,276.37,284.97,121977890,-0.117445535686743
2020-05-15 12:00:00 AM,282.37,286.33,281.34,286.28,111146276,-0.118658344012093
2020-05-18 12:00:00 AM,293.05,296.75,292.7,295,120320229,-0.064130564447391
2020-05-19 12:00:00 AM,294.35,296.205,291.95,291.97,95189316,-0.070537593043885
2020-05-20 12:00:00 AM,295.82,297.87,295.57,296.93,85861691,-0.066241946212954
2020-05-21 12:00:00 AM,296.79,297.67,293.6886,294.88,78293925,-0.036453148815428
2020-05-22 12:00:00 AM,294.57,295.63,293.22,295.44,63958200,-0.040671649215954
2020-05-26 12:00:00 AM,301.93,302.19,298.69,299.08,88951442,-0.089286979403634
2020-05-27 12:00:00 AM,302.12,303.57,296.87,303.53,104817449,0.012198604511478
2020-05-28 12:00:00 AM,304.65,306.84,302.24,302.97,90767807,-0.035642622628572
2020-05-29 12:00:00 AM,302.46,304.96,299.47,304.32,119265702,0.02508303051682
2020-06-01 12:00:00 AM,303.62,306.205,303.06,305.55,56779836,0.093016073385456
2020-06-02 12:00:00 AM,306.55,308.13,305.1,308.08,74267162,0.094511823316611
2020-06-03 12:00:00 AM,310.24,313.22,309.94,312.18,92567574,0.116688652331164
2020-06-04 12:00:00 AM,311.11,313,309.08,311.36,75794363,0.155008254247463
2020-06-05 12:00:00 AM,317.23,321.275,317.16,319.34,150524674,0.176442452495045
2020-06-08 12:00:00 AM,320.22,323.41,319.63,323.2,73641217,0.184058707031193
2020-06-09 12:00:00 AM,320.3,323.2849,319.36,320.79,77479228,0.16207210950577
2020-06-10 12:00:00 AM,321.42,322.39,318.2209,319,95000766,0.179139484112472
2020-06-11 12:00:00 AM,311.46,312.15,300.01,300.61,209243560,0.10454919333815
2020-06-12 12:00:00 AM,308.24,309.08,298.6,304.21,194678879,0.050178597459014
2020-06-15 12:00:00 AM,298.02,308.28,296.74,307.05,135782724,0.048586127100983
2020-06-16 12:00:00 AM,315.48,315.64,307.67,312.96,137627502,0.061863632522086
2020-06-17 12:00:00 AM,314.07,314.39,310.86,311.66,83398944,0.085527193130681
2020-06-18 12:00:00 AM,310.005,312.3,309.51,311.78,80828658,0.102540614362876
2020-06-19 12:00:00 AM,314.17,314.38,306.53,308.64,135549624,0.085204373272522
2020-06-22 12:00:00 AM,307.99,311.05,306.75,310.62,74649389,0.087498030426295
2020-06-23 12:00:00 AM,313.49,314.5,311.6101,312.05,68471246,0.098428381194885
2020-06-24 12:00:00 AM,309.84,310.51,302.1,304.09,132813492,0.016783769196391
2020-06-25 12:00:00 AM,303.47,307.64,301.28,307.35,89467968,0.083188204889017
2020-06-26 12:00:00 AM,306.16,306.39,299.42,300.05,127961017,-0.007745779067094
2020-06-29 12:00:00 AM,301.41,304.61,298.93,304.46,79773260,0.011714590240321
2020-06-30 12:00:00 AM,303.99,310.2,303.82,308.36,113394772,0.000817368250859
2020-07-01 12:00:00 AM,309.57,311.89,309.07,310.52,72396542,-0.013579831249518
2020-07-02 12:00:00 AM,314.24,315.7,311.51,312.23,69344217,-0.039907609317338
2020-07-06 12:00:00 AM,316.37,317.68,315.56,317.05,61713828,-0.033978900706699
2020-07-07 12:00:00 AM,315.38,317.52,313.37,313.78,82909963,-0.096015445266383
2020-07-08 12:00:00 AM,314.61,316.3,312.7,316.18,54638596,-0.062760033504306
2020-07-09 12:00:00 AM,316.84,317.1,310.68,314.38,83354158,-0.028522861983517
2020-07-10 12:00:00 AM,314.31,317.88,312.76,317.59,57550365,0.092979046262854
2020-07-13 12:00:00 AM,320.13,322.71,314.13,314.84,102997484,0.04355257588827
2020-07-14 12:00:00 AM,313.3,319.76,312,318.92,93656951,0.026008968517732
2020-07-15 12:00:00 AM,322.41,323.04,319.265,321.85,87196524,0.01942472509847
2020-07-16 12:00:00 AM,319.79,321.28,319.09,320.79,54622520,0.063721527997236
2020-07-17 12:00:00 AM,321.88,322.57,319.735,321.72,62774911,0.049403012776951
2020-07-20 12:00:00 AM,321.43,325.13,320.62,324.32,56308749,0.112550890385741
2020-07-21 12:00:00 AM,326.45,326.93,323.94,325.01,57498967,0.066471217269233
2020-07-22 12:00:00 AM,324.62,327.2,324.5,326.86,57792915,0.123770197818835
2020-07-23 12:00:00 AM,326.47,327.23,321.48,322.96,75737989,0.149904189143265
2020-07-24 12:00:00 AM,320.95,321.99,319.246,320.88,73766597,0.107378277635958
2020-07-27 12:00:00 AM,321.63,323.41,320.775,323.22,48292970,0.214391938020084
2020-07-28 12:00:00 AM,322.43,323.64,320.85,321.17,57494979,0.133538903683879
2020-07-29 12:00:00 AM,322.12,325.73,322.075,325.12,48454159,0.128359963972607
2020-07-30 12:00:00 AM,321.9,324.41,319.64,323.96,61861714,0.165073090404892
2020-07-31 12:00:00 AM,325.9,326.63,321.33,326.52,85210755,0.256408825303431
2020-08-03 12:00:00 AM,328.32,329.62,327.73,328.79,53077948,0.244335827065056
2020-08-04 12:00:00 AM,327.86,330.06,327.86,330.06,41917893,0.334474948824337
2020-08-05 12:00:00 AM,331.47,332.39,331.18,332.11,42866354,0.316024028468933
2020-08-06 12:00:00 AM,331.4799,334.46,331.13,334.33,43679447,0.347766681252851
2020-08-07 12:00:00 AM,333.28,334.88,332.3,334.57,57308270,0.341897236711957
2020-08-10 12:00:00 AM,335.06,335.77,332.955,335.57,44282089,0.461531207124607
2020-08-11 12:00:00 AM,336.85,337.54,332.01,332.8,69600882,0.366601507824282
2020-08-12 12:00:00 AM,335.44,338.28,332.8377,337.44,53826128,0.381624258224091
2020-08-13 12:00:00 AM,336.61,338.2514,335.83,336.83,41816146,0.352892309056163
2020-08-14 12:00:00 AM,336.41,337.42,335.62,336.84,47260390,0.350340147495549
2020-08-17 12:00:00 AM,337.94,338.34,336.8517,337.91,35480974,0.337756513515973
2020-08-18 12:00:00 AM,338.34,339.1,336.61,338.64,38733908,0.381435793365019
2020-08-19 12:00:00 AM,339.05,339.61,336.62,337.23,68054244,0.301123422854845
2020-08-20 12:00:00 AM,335.36,338.8,335.22,338.28,42207826,0.373899107081965
2020-08-21 12:00:00 AM,337.92,339.72,337.55,339.48,55106628,0.408444500894128
2020-08-24 12:00:00 AM,342.12,343,339.4504,342.92,48588662,0.413217910120533
2020-08-25 12:00:00 AM,343.53,344.21,342.27,344.12,38463381,0.498760419277583
2020-08-26 12:00:00 AM,344.76,347.86,344.17,347.57,50790237,0.50793679009127
2020-08-27 12:00:00 AM,348.51,349.9,346.53,348.33,58034142,0.464362583632765
2020-08-28 12:00:00 AM,349.44,350.72,348.15,350.58,48588940,0.442546681620021
2020-08-31 12:00:00 AM,350.35,351.3,349.06,349.31,66099183,0.37851297548881
2020-09-01 12:00:00 AM,350.21,352.71,349.24,352.6,54999325,0.383129211953384
2020-09-02 12:00:00 AM,354.67,358.75,353.43,357.7,69540035,0.391694354802331
2020-09-03 12:00:00 AM,355.87,356.38,342.59,345.39,148011129,0.242995049929745
2020-09-04 12:00:00 AM,346.13,347.83,334.87,342.57,139156281,0.212447895591884
2020-09-08 12:00:00 AM,336.71,342.64,332.88,333.21,114465322,0.088594728885988
2020-09-09 12:00:00 AM,337.55,342.46,336.61,339.79,91462290,0.13113106558337
2020-09-10 12:00:00 AM,341.82,342.53,332.85,333.89,90569548,0.047166018677641
2020-09-11 12:00:00 AM,335.82,336.97,331,334.06,84680194,0.052476587946632
2020-09-14 12:00:00 AM,337.49,340.38,334.2208,338.46,65605686,0.057401153768896
2020-09-15 12:00:00 AM,341.12,342.02,338.4683,340.17,52920862,0.04464631511894
2020-09-16 12:00:00 AM,341.51,343.06,338.52,338.82,82211256,-0.021843206451497
2020-09-17 12:00:00 AM,333.56,337.6996,332.991,335.84,91523339,0.018364029498213
2020-09-18 12:00:00 AM,335.37,335.49,327.97,330.65,105877942,-0.021160314230225
2020-09-21 12:00:00 AM,325.7,327.13,321.73,326.97,99450829,0.011055424260041
2020-09-22 12:00:00 AM,328.57,330.9,325.86,330.3,63612107,0.012232218808755
2020-09-23 12:00:00 AM,330.9,331.2,322.1,322.64,93112240,-0.058171731975513
2020-09-24 12:00:00 AM,321.22,326.797,319.8,323.5,76681332,-0.07991181694192
2020-09-25 12:00:00 AM,322.58,329.58,321.64,328.73,71069426,-0.048949730832656
2020-09-28 12:00:00 AM,333.22,334.96,332.15,334.19,64584614,-0.056670220882713
2020-09-29 12:00:00 AM,333.97,334.77,331.6209,332.37,51531594,-0.042933649728329
2020-09-30 12:00:00 AM,333.09,338.29,332.88,334.89,104081136,-0.086195264499149
2020-10-01 12:00:00 AM,337.69,338.74,335.01,337.04,88698745,-0.104512120285571
2020-10-02 12:00:00 AM,331.7,337.0126,331.19,333.84,89431112,-0.061648819348872
2020-10-05 12:00:00 AM,336.06,339.96,336.01,339.76,45713108,-0.056041867984809
2020-10-06 12:00:00 AM,339.91,342.17,334.38,334.93,90128883,-0.038599675715159
2020-10-07 12:00:00 AM,338.12,341.63,338.09,340.76,56999597,-0.026053186706925
2020-10-08 12:00:00 AM,342.85,343.85,341.86,343.78,45242476,0.047469788771256
2020-10-09 12:00:00 AM,345.56,347.35,344.89,346.85,59528606,0.070431184564225
2020-10-12 12:00:00 AM,349.59,354.02,349.06,352.43,80388533,0.072483431644151
2020-10-13 12:00:00 AM,352.28,352.4651,349.09,350.13,73255513,0.054628378066156
2020-10-14 12:00:00 AM,350.75,351.93,347.14,347.93,57958749,0.077049380734238
2020-10-15 12:00:00 AM,343.71,348.02,343.13,347.5,60357659,0.097818561423823
2020-10-16 12:00:00 AM,348.96,350.75,347.1,347.29,89501868,0.064855237776124
2020-10-19 12:00:00 AM,348.65,349.33,341.04,342.01,68425614,-0.03579348663173
2020-10-20 12:00:00 AM,343.46,346.88,342.64,343.38,60051880,-0.097251082184503
2020-10-21 12:00:00 AM,343.33,348.6847,342.4,342.73,63574979,-0.08129745308831
2020-10-22 12:00:00 AM,342.96,345.24,340.65,344.61,55399292,-0.056554127021353
2020-10-23 12:00:00 AM,345.93,345.99,343.13,345.78,49143511,-0.067755343953542
2020-10-26 12:00:00 AM,342.13,342.98,335.62,339.39,91473002,-0.085954200795727
2020-10-27 12:00:00 AM,339.76,340.12,337.99,338.22,65994108,-0.102784093838538
2020-10-28 12:00:00 AM,332.1,332.84,326.13,326.66,127094307,-0.157713455637955
2020-10-29 12:00:00 AM,326.91,333.395,325.09,329.98,90596689,-0.151698843248695
2020-10-30 12:00:00 AM,328.28,329.69,322.6,326.54,120448685,-0.133678132367382
2020-11-02 12:00:00 AM,330.2,332.36,327.24,330.2,86068299,-0.148588747382156
2020-11-03 12:00:00 AM,333.69,338.25,330.2935,336.03,93294192,-0.068908898116946
2020-11-04 12:00:00 AM,340.86,347.94,339.59,343.54,126959700,-0.088722900371873
2020-11-05 12:00:00 AM,349.24,352.19,348.86,350.24,82039749,-0.121714380226285
2020-11-06 12:00:00 AM,349.93,351.51,347.65,350.16,74972973,-0.12846728735735
2020-11-09 12:00:00 AM,363.97,364.38,354.06,354.56,172304203,-0.229495727022154
2020-11-10 12:00:00 AM,353.49,355.18,350.51,354.04,85552022,-0.186087157303557
2020-11-11 12:00:00 AM,356.4,357.56,355.06,356.67,58649048,-0.153646158609706
2020-11-12 12:00:00 AM,355.58,356.7182,351.26,353.21,68118563,-0.191673702704326
2020-11-13 12:00:00 AM,355.27,358.9,354.71,358.1,62959429,-0.124729504050949
2020-11-16 12:00:00 AM,360.98,362.78,359.59,362.57,74541138,-0.055749789572226
2020-11-17 12:00:00 AM,359.97,361.92,358.34,360.62,66111009,-0.022212934192146
2020-11-18 12:00:00 AM,360.91,361.5,356.24,356.28,70591299,-0.029449306470647
2020-11-19 12:00:00 AM,355.6,358.18,354.15,357.78,59940947,-0.024825805995395
2020-11-20 12:00:00 AM,357.5,357.72,355.25,355.33,70411890,-0.086177055457969
2020-11-23 12:00:00 AM,357.28,358.82,354.865,357.46,63230608,-0.077412706258669
2020-11-24 12:00:00 AM,360.21,363.81,359.29,363.22,62415877,-0.020554179333853
2020-11-25 12:00:00 AM,363.13,363.16,361.48,362.66,45330890,0.055115222725381
2020-11-27 12:00:00 AM,363.84,364.18,362.58,363.67,28514072,0.053632017619425
2020-11-30 12:00:00 AM,362.83,363.12,359.17,362.06,83872709,0.071470788519949
2020-12-01 12:00:00 AM,365.57,367.68,364.93,366.02,74504969,0.053059519037133
2020-12-02 12:00:00 AM,364.82,366.96,364.2,366.79,45927000,0.05410882789503
2020-12-03 12:00:00 AM,366.68,368.19,365.5,366.69,62869773,0.056276531727402

View File

@@ -1,6 +1,6 @@
![alt tag](https://cdn.quantconnect.com/web/i/20180601-1615-lean-logo-small.png) Lean Data ToolBox
=========
[![Join the chat at https://gitter.im/QuantConnect/Lean](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/QuantConnect/Lean?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Slack Chat](https://img.shields.io/badge/chat-Slack-53c82b.svg)](https://www.quantconnect.com/slack)
[Lean Home][1] | [Documentation][2] | [Download Lean][3]
----------
@@ -35,6 +35,7 @@ Example: --app=YahooDownloader --tickers=SPY,AAPL --resolution=Daily --from-date
- IEXDownloader or IEXDL
- BitfinexDownloader or BFXDL
- BinanceDownloader or MBXDL
- PolygonDownloader or PDL
- **'--from-date=yyyyMMdd-HH:mm:ss'** required
- **'--tickers=SPY,AAPL,etc'** required, except for QuandlBitfinexDownloader (QBDL)
- **'--resolution=Tick/Second/Minute/Hour/Daily/All'** required, except for QuandlBitfinexDownloader (QBDL), CryptoiqDownloader (CDL). **Case sensitive. Not all downloaders support all resolutions**, send empty for more information.

View File

@@ -23,11 +23,7 @@ Want your company logo here? [Sponsor LEAN](https://github.com/sponsors/QuantCon
## QuantConnect is Hiring! ##
Join the team and solve some of the most difficult challenges in quantitative finance. If you are passionate about algorithmic trading we'd like to hear from you. The below roles are open in our Seattle, WA office. When applying, make sure to mention you came through GitHub:
- [**Senior UX Developer**](mailto:jared@quantconnect.com): Collaborate with QuantConnect to develop a world-leading online experience for a community of developers from all over the world.
- [**Technical Writers**](mailto:jared@quantconnect.com): Help us improve the QuantConnect and LEAN documentation with hands-on tutorials with how to use all the adaptors LEAN offers, and how to set up trading locally.
- [**Quantitative Development Intern**](mailto:jared@quantconnect.com): If you are a recent or current graduate with a knack for quantitative finance, consider applying for an internship!
- [**Senior UX Developer**](mailto:jared@quantconnect.com): Collaborate with QuantConnect to develop a world-leading online experience for a community of developers from all over the world.
## System Overview ##