Compare commits

...

10 Commits

Author SHA1 Message Date
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
26 changed files with 982 additions and 37 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

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

@@ -354,6 +354,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 +2565,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,56 @@ 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 == null)
{
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 +815,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

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

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

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

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

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

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

@@ -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,7 @@ 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");
// 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,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

@@ -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,7 @@
<Compile Include="Indicators\AdvanceDeclineRatioVolumeTests.cs" />
<Compile Include="Indicators\AdvanceDeclineRatioTests.cs" />
<Compile Include="Indicators\ArmsIndexTests.cs" />
<Compile Include="Indicators\ChaikinMoneyFlowTests.cs" />
<Compile Include="Indicators\PythonIndicatorNoinheritanceTestsLegacy.cs" />
<Compile Include="Indicators\PythonIndicatorNoinheritanceTests.cs" />
<Compile Include="Indicators\PythonIndicatorTests.cs" />
@@ -991,6 +992,9 @@
<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

@@ -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");

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

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