Compare commits

...

37 Commits
16632 ... 16655

Author SHA1 Message Date
Jhonathan Abreu
c8787d7ca6 PandasData handling children class members
Address peer review
2024-09-27 17:55:48 -04:00
Jhonathan Abreu
5b357b0fe7 Cleanup 2024-09-27 15:43:12 -04:00
Jhonathan Abreu
801b0f5add Update Pythonnet to 2.0.39 2024-09-27 15:40:42 -04:00
Jhonathan Abreu
3dbcc4b41d Unit test fix 2024-09-27 12:41:13 -04:00
Jhonathan Abreu
d58d78f7fb Add data and other minor changes 2024-09-27 12:06:30 -04:00
Jhonathan Abreu
77b74f25a5 PandasData cleanup 2024-09-27 10:42:45 -04:00
Jhonathan Abreu
5d0e18d3e4 Handle Greeks unwrapping by PandasData 2024-09-26 19:17:39 -04:00
Jhonathan Abreu
5ef230256e Peer review: Non-thread-safe Lazy for Python 2024-09-26 18:30:12 -04:00
Jhonathan Abreu
52a9b8965f Minor fix and add PandasConverter unit tests 2024-09-26 18:30:11 -04:00
Jhonathan Abreu
8839ea0b14 Address peer review
Add NullGreeks class: keep ModeledGreeks as internal as possible
2024-09-26 18:30:11 -04:00
Jhonathan Abreu
80ef6a55f3 Add multiple option chains api regression algorithms and other minor changes 2024-09-26 18:30:11 -04:00
Jhonathan Abreu
6eb1df3108 Minor fix 2024-09-26 18:30:11 -04:00
Jhonathan Abreu
1d632a9a54 Format OptionContract for dataframe 2024-09-26 18:30:11 -04:00
Jhonathan Abreu
7b0db104b9 Pass symbol properties to OptionUniverse option chain from algorithm 2024-09-26 18:30:11 -04:00
Jhonathan Abreu
b96a9792ca Unify QCAlgorithmOptionChain API
Also refactor OptionContract to handle: (1) Actual market data and option price model data, and (2) OptionUniverse data
2024-09-26 18:30:11 -04:00
Jhonathan Abreu
407688deb4 Add new QCAlgorithm.OptionChains() method
- Use OptionChains as output
- Add DataFrame to OptionChain and OptionChains
- Rename Greeks classes
- Add ISymbolProvider for classes that have a symbol (IBaseData, OptionContract)
2024-09-26 18:30:11 -04:00
Jhonathan Abreu
3b649c3092 Minor fix 2024-09-26 18:30:11 -04:00
Jhonathan Abreu
aa35111566 Some cleanup 2024-09-26 18:30:10 -04:00
Jhonathan Abreu
b122ff4cd4 Add greeks columns directly in option chain dataframe.
Also add pass-through properties for greek values in OptionUniverse
2024-09-26 18:30:10 -04:00
Jhonathan Abreu
5138b1c71c Minor fix 2024-09-26 18:30:10 -04:00
Jhonathan Abreu
8123c61229 Exclude "ID" from option chain dataframe 2024-09-26 18:30:10 -04:00
Jhonathan Abreu
c2e3f7e8b1 Add symbol equality operator to compare against object 2024-09-26 18:30:10 -04:00
Jhonathan Abreu
862dc8d099 Index dataframes by symbol object instead of SID string 2024-09-26 18:30:10 -04:00
Jhonathan Abreu
be9d68c8f5 Cleanup 2024-09-26 18:30:10 -04:00
Jhonathan Abreu
11e3b9fe4a Properly convert list of data into dataframe
Take into consideration data for multiple symbols in the same list
2024-09-26 18:30:10 -04:00
Jhonathan Abreu
79369a5e40 Fix pandas converter to handle list of data with different symbols 2024-09-26 18:30:10 -04:00
Louis Szeto
809faa24de Add Backspread Option Strategies (#8312)
* Call and put backspread definitions

* Margin model

* regression tests

* strategy unit test

* refactor

* Use option strategies to order
2024-09-26 16:57:20 -03:00
Jhonathan Abreu
ad5aa263c0 Infer data type from configs in bar count history requests (#8344)
* Infer data type from configs in bar count history requests

* Infer data type from configs in bar count history requests

* Minor changes

* Minor fix

* Cleanup
2024-09-26 16:51:19 -03:00
Roman Yavnikov
a1bb907e03 Feature:Alpaca: support MarketOnOpen and MarketOnClose (#8341)
* feat: missed Alpaca config in Launcher

* feature: support of new OrderTypes for Equtity in AlpacaBrokerage model
2024-09-25 14:30:27 -03:00
Roman Yavnikov
71540f5015 Feature: support MarketOnOpen and MarketOnClose (#8340)
* remove: not used proxy config TradeStation

* feat: missed config of TradeStation in Launcher

* feat: support new OrderTypes in TradeStationBrokerageModel
2024-09-24 15:11:36 -03:00
Kevin Wheeler
a0055a3695 Improve data not found error messages. (#8295)
* Improve data not found error messages.

* Minor tweaks

---------

Co-authored-by: Kevin Wheeler <spreadlove5683@gmail.com>
Co-authored-by: Martin Molinero <martin.molinero1@gmail.com>
2024-09-20 16:56:58 -03:00
Martin-Molinero
0b285df496 Minor fix for option contract universe (#8337) 2024-09-20 13:16:20 -03:00
Martin Molinero
4d37096b3f Reduce realtime shutdown timeout 2024-09-20 10:04:58 -03:00
Martin Molinero
7c42ea795f Minor improvement for live trading shutdown 2024-09-19 20:09:21 -03:00
Martin-Molinero
f2f1d06237 Improve shutdown (#8335) 2024-09-19 19:32:29 -03:00
Martin-Molinero
86fd80a31a Generic live command support (#8330)
* Generic command support

- Adding generic algorithm command support. Adding regression algorithms
- Allow PythonWrapper to validate classes too

* Minor improvements
2024-09-19 16:02:42 -03:00
Roman Yavnikov
c556d16775 Feature: new Tick constructor for TickType.OpenInterest (#8323)
* feat: create OpenInterest constrcutor of Tick

* feat: GetSubscribedSymbols by TickType

* test:feat: GetSubscribeSymbolsBySpecificTickType

* refactor: equal channel name with InvariantCultureIgnoreCase
2024-09-17 12:52:24 -03:00
99 changed files with 4191 additions and 792 deletions

View File

@@ -117,7 +117,7 @@ namespace QuantConnect.Algorithm.CSharp
&& optionContract.ID.OptionStyle == OptionStyle.American);
AddOptionContract(option);
foreach (var symbol in new[] { option.Symbol, option.Underlying.Symbol })
foreach (var symbol in new[] { option.Symbol, option.UnderlyingSymbol })
{
var config = SubscriptionManager.SubscriptionDataConfigService.GetSubscriptionDataConfigs(symbol).ToList();

View File

@@ -0,0 +1,147 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using QuantConnect.Commands;
using QuantConnect.Interfaces;
using System.Collections.Generic;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression algorithm asserting the behavior of different callback commands call
/// </summary>
public class CallbackCommandRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
/// <summary>
/// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.
/// </summary>
public override void Initialize()
{
SetStartDate(2013, 10, 07);
SetEndDate(2013, 10, 11);
AddEquity("SPY");
AddEquity("BAC");
AddEquity("IBM");
AddCommand<BoolCommand>();
AddCommand<VoidCommand>();
}
/// <summary>
/// Handle generic command callback
/// </summary>
public override bool? OnCommand(dynamic data)
{
Buy(data.Symbol, data.parameters["quantity"]);
return true;
}
private class VoidCommand : Command
{
public DateTime TargetTime { get; set; }
public string[] Target { get; set; }
public decimal Quantity { get; set; }
public Dictionary<string, string> Parameters { get; set; }
public override bool? Run(IAlgorithm algorithm)
{
if (TargetTime != algorithm.Time)
{
return null;
}
((QCAlgorithm)algorithm).Order(Target[0], Quantity, tag: Parameters["tag"]);
return null;
}
}
private class BoolCommand : Command
{
public bool? Result { get; set; }
public override bool? Run(IAlgorithm algorithm)
{
var shouldTrade = MyCustomMethod();
if (shouldTrade.HasValue && shouldTrade.Value)
{
((QCAlgorithm)algorithm).Buy("IBM", 1);
}
return shouldTrade;
}
private bool? MyCustomMethod()
{
return Result;
}
}
/// <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; }
/// <summary>
/// This is used by the regression test system to indicate which languages this algorithm is written in.
/// </summary>
public List<Language> Languages { get; } = new() { Language.CSharp, Language.Python };
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 3943;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 0;
/// <summary>
/// Final status of the algorithm
/// </summary>
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
/// <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 Orders", "1"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "271.453%"},
{"Drawdown", "2.200%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "101691.92"},
{"Net Profit", "1.692%"},
{"Sharpe Ratio", "8.854"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "67.609%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "-0.005"},
{"Beta", "0.996"},
{"Annual Standard Deviation", "0.222"},
{"Annual Variance", "0.049"},
{"Information Ratio", "-14.565"},
{"Tracking Error", "0.001"},
{"Treynor Ratio", "1.97"},
{"Total Fees", "$3.44"},
{"Estimated Strategy Capacity", "$56000000.00"},
{"Lowest Capacity Asset", "SPY R735QTJ8XC9X"},
{"Portfolio Turnover", "19.93%"},
{"OrderListHash", "3da9fa60bf95b9ed148b95e02e0cfc9e"}
};
}
}

View File

@@ -0,0 +1,142 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Data.Market;
using QuantConnect.Interfaces;
using QuantConnect.Securities;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression algorithm illustrating the usage of the <see cref="QCAlgorithm.OptionChains(IEnumerable{Symbol})"/> method
/// to get multiple option chains, which contains additional data besides the symbols, including prices, implied volatility and greeks.
/// It also shows how this data can be used to filter the contracts based on certain criteria.
/// </summary>
public class OptionChainsMultipleFullDataRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private Symbol _googOptionContract;
private Symbol _spxOptionContract;
public override void Initialize()
{
SetStartDate(2015, 12, 24);
SetEndDate(2015, 12, 24);
SetCash(100000);
var goog = AddEquity("GOOG").Symbol;
var spx = AddIndex("SPX").Symbol;
var chains = OptionChains(new[] { goog, spx });
_googOptionContract = GetContract(chains, goog, TimeSpan.FromDays(10));
_spxOptionContract = GetContract(chains, spx, TimeSpan.FromDays(60));
AddOptionContract(_googOptionContract);
AddIndexOptionContract(_spxOptionContract);
}
private Symbol GetContract(OptionChains chains, Symbol underlying, TimeSpan expirySpan)
{
return chains
.Where(kvp => kvp.Key.Underlying == underlying)
.Select(kvp => kvp.Value)
.Single()
// Get contracts expiring within a given span, with an implied volatility greater than 0.5 and a delta less than 0.5
.Where(contractData => contractData.ID.Date - Time <= expirySpan &&
contractData.ImpliedVolatility > 0.5m &&
contractData.Greeks.Delta < 0.5m)
// Get the contract with the latest expiration date
.OrderByDescending(x => x.ID.Date)
.First();
}
public override void OnData(Slice slice)
{
// Do some trading with the selected contract for sample purposes
if (!Portfolio.Invested)
{
MarketOrder(_googOptionContract, 1);
}
else
{
Liquidate();
}
}
/// <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 virtual List<Language> Languages { get; } = new() { Language.CSharp, Language.Python };
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 1059;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 2;
/// <summary>
/// Final status of the algorithm
/// </summary>
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
/// <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 Orders", "210"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "0%"},
{"Drawdown", "0%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "96041"},
{"Net Profit", "0%"},
{"Sharpe Ratio", "0"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "0%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "0"},
{"Beta", "0"},
{"Annual Standard Deviation", "0"},
{"Annual Variance", "0"},
{"Information Ratio", "0"},
{"Tracking Error", "0"},
{"Treynor Ratio", "0"},
{"Total Fees", "$209.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "GOOCV W6U7PD1F2WYU|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "85.46%"},
{"OrderListHash", "a7ab1a9e64fe9ba76ea33a40a78a4e3b"}
};
}
}

View File

@@ -0,0 +1,128 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Data.Market;
using QuantConnect.Securities.Option;
using QuantConnect.Securities.Option.StrategyMatcher;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression algorithm exercising an equity Long Call Backspread option strategy and asserting it's being detected by Lean and works as expected
/// </summary>
public class OptionEquityCallBackspreadRegressionAlgorithm : OptionEquityBaseStrategyRegressionAlgorithm
{
/// <summary>
/// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
/// </summary>
/// <param name="slice">Slice object keyed by symbol containing the stock data</param>
public override void OnData(Slice slice)
{
if (!Portfolio.Invested)
{
OptionChain chain;
if (IsMarketOpen(_optionSymbol) && slice.OptionChains.TryGetValue(_optionSymbol, out chain))
{
var callContracts = chain
.Where(contract => contract.Right == OptionRight.Call);
var expiry = callContracts.Min(x => x.Expiry);
callContracts = callContracts.Where(x => x.Expiry == expiry)
.OrderBy(x => x.Strike)
.ToList();
var strike = callContracts.Select(x => x.Strike).Distinct();
if (strike.Count() < 2) return;
var lowStrikeCall = callContracts.First();
var highStrikeCall = callContracts.First(contract => contract.Strike > lowStrikeCall.Strike && contract.Expiry == expiry);
var initialMargin = Portfolio.MarginRemaining;
var optionStrategy = OptionStrategies.CallBackspread(_optionSymbol, lowStrikeCall.Strike, highStrikeCall.Strike, expiry);
Buy(optionStrategy, 5);
var freeMarginPostTrade = Portfolio.MarginRemaining;
// It is a combination of bear call spread and long call
AssertOptionStrategyIsPresent(OptionStrategyDefinitions.BearCallSpread.Name, 5);
AssertOptionStrategyIsPresent(OptionStrategyDefinitions.NakedCall.Name, 5);
// Should only involve the bear call spread part
var expectedMarginUsage = (highStrikeCall.Strike - lowStrikeCall.Strike) * Securities[highStrikeCall.Symbol].SymbolProperties.ContractMultiplier * 5;
if (expectedMarginUsage != Portfolio.TotalMarginUsed)
{
throw new Exception($"Unexpect margin used!:{Portfolio.TotalMarginUsed}");
}
// we payed the ask and value using the assets price
var priceLadderDifference = GetPriceSpreadDifference(lowStrikeCall.Symbol, highStrikeCall.Symbol);
if (initialMargin != (freeMarginPostTrade + expectedMarginUsage + _paidFees - priceLadderDifference))
{
throw new Exception("Unexpect margin remaining!");
}
}
}
}
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 15023;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public override int AlgorithmHistoryDataPoints => 0;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
/// </summary>
public override Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "2"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "0%"},
{"Drawdown", "0%"},
{"Expectancy", "0"},
{"Start Equity", "200000"},
{"End Equity", "198565.25"},
{"Net Profit", "0%"},
{"Sharpe Ratio", "0"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "0%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "0"},
{"Beta", "0"},
{"Annual Standard Deviation", "0"},
{"Annual Variance", "0"},
{"Information Ratio", "0"},
{"Tracking Error", "0"},
{"Treynor Ratio", "0"},
{"Total Fees", "$9.75"},
{"Estimated Strategy Capacity", "$47000.00"},
{"Lowest Capacity Asset", "GOOCV W78ZERHAOVVQ|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "11.81%"},
{"OrderListHash", "6ece6c59826ea66fa7b0a1094a0021c7"}
};
}
}

View File

@@ -0,0 +1,128 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Data.Market;
using QuantConnect.Securities.Option;
using QuantConnect.Securities.Option.StrategyMatcher;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression algorithm exercising an equity Long Put Backspread option strategy and asserting it's being detected by Lean and works as expected
/// </summary>
public class OptionEquityPutBackspreadRegressionAlgorithm : OptionEquityBaseStrategyRegressionAlgorithm
{
/// <summary>
/// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
/// </summary>
/// <param name="slice">Slice object keyed by symbol containing the stock data</param>
public override void OnData(Slice slice)
{
if (!Portfolio.Invested)
{
OptionChain chain;
if (IsMarketOpen(_optionSymbol) && slice.OptionChains.TryGetValue(_optionSymbol, out chain))
{
var putContracts = chain
.Where(contract => contract.Right == OptionRight.Put);
var expiry = putContracts.Min(x => x.Expiry);
putContracts = putContracts.Where(x => x.Expiry == expiry)
.OrderBy(x => x.Strike)
.ToList();
var strike = putContracts.Select(x => x.Strike).Distinct();
if (strike.Count() < 2) return;
var lowStrikePut = putContracts.First();
var highStrikePut = putContracts.First(contract => contract.Strike > lowStrikePut.Strike && contract.Expiry == lowStrikePut.Expiry);
var initialMargin = Portfolio.MarginRemaining;
var optionStrategy = OptionStrategies.PutBackspread(_optionSymbol, highStrikePut.Strike, lowStrikePut.Strike, expiry);
Buy(optionStrategy, 5);
var freeMarginPostTrade = Portfolio.MarginRemaining;
// It is a combination of bull put spread and long put
AssertOptionStrategyIsPresent(OptionStrategyDefinitions.BullPutSpread.Name, 5);
AssertOptionStrategyIsPresent(OptionStrategyDefinitions.NakedPut.Name, 5);
// Should only involve the bull put spread part
var expectedMarginUsage = (highStrikePut.Strike - lowStrikePut.Strike) * Securities[highStrikePut.Symbol].SymbolProperties.ContractMultiplier * 5;
if (expectedMarginUsage != Portfolio.TotalMarginUsed)
{
throw new Exception("Unexpect margin used!");
}
// we payed the ask and value using the assets price
var priceLadderDifference = GetPriceSpreadDifference(lowStrikePut.Symbol, highStrikePut.Symbol);
if (initialMargin != (freeMarginPostTrade + expectedMarginUsage + _paidFees - priceLadderDifference))
{
throw new Exception("Unexpect margin remaining!");
}
}
}
}
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 15023;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public override int AlgorithmHistoryDataPoints => 0;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
/// </summary>
public override Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "2"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "0%"},
{"Drawdown", "0%"},
{"Expectancy", "0"},
{"Start Equity", "200000"},
{"End Equity", "199015.25"},
{"Net Profit", "0%"},
{"Sharpe Ratio", "0"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "0%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "0"},
{"Beta", "0"},
{"Annual Standard Deviation", "0"},
{"Annual Variance", "0"},
{"Information Ratio", "0"},
{"Tracking Error", "0"},
{"Treynor Ratio", "0"},
{"Total Fees", "$9.75"},
{"Estimated Strategy Capacity", "$1100000.00"},
{"Lowest Capacity Asset", "GOOCV 306CZL2DIL4G6|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "9.15%"},
{"OrderListHash", "1a51f04db9201f960dc04668b7f5d41d"}
};
}
}

View File

@@ -0,0 +1,130 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Data.Market;
using QuantConnect.Securities;
using QuantConnect.Securities.Option;
using QuantConnect.Securities.Option.StrategyMatcher;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression algorithm exercising an equity Short Call Backspread option strategy and asserting it's being detected by Lean and works as expected
/// </summary>
public class OptionEquityShortCallBackspreadRegressionAlgorithm : OptionEquityBaseStrategyRegressionAlgorithm
{
/// <summary>
/// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
/// </summary>
/// <param name="slice">Slice object keyed by symbol containing the stock data</param>
public override void OnData(Slice slice)
{
if (!Portfolio.Invested)
{
OptionChain chain;
if (IsMarketOpen(_optionSymbol) && slice.OptionChains.TryGetValue(_optionSymbol, out chain))
{
var callContracts = chain
.Where(contract => contract.Right == OptionRight.Call);
var expiry = callContracts.Min(x => x.Expiry);
callContracts = callContracts.Where(x => x.Expiry == expiry)
.OrderBy(x => x.Strike)
.ToList();
var strike = callContracts.Select(x => x.Strike).Distinct();
if (strike.Count() < 2) return;
var lowStrikeCall = callContracts.First();
var highStrikeCall = callContracts.First(contract => contract.Strike > lowStrikeCall.Strike && contract.Expiry == lowStrikeCall.Expiry);
var initialMargin = Portfolio.MarginRemaining;
var optionStrategy = OptionStrategies.ShortCallBackspread(_optionSymbol, lowStrikeCall.Strike, highStrikeCall.Strike, expiry);
Buy(optionStrategy, 5);
var freeMarginPostTrade = Portfolio.MarginRemaining;
// It is a combination of bull call spread and naked call
AssertOptionStrategyIsPresent(OptionStrategyDefinitions.BullCallSpread.Name, 5);
AssertOptionStrategyIsPresent(OptionStrategyDefinitions.NakedCall.Name, 5);
// Should only involve the naked call part
var security = Securities[highStrikeCall.Symbol];
var expectedMarginUsage = security.BuyingPowerModel.GetMaintenanceMargin(MaintenanceMarginParameters.ForQuantityAtCurrentPrice(security, -5)).Value;
if (expectedMarginUsage != Portfolio.TotalMarginUsed)
{
throw new Exception("Unexpect margin used!");
}
// we payed the ask and value using the assets price
var priceLadderDifference = GetPriceSpreadDifference(lowStrikeCall.Symbol, highStrikeCall.Symbol);
if (initialMargin != (freeMarginPostTrade + expectedMarginUsage + _paidFees - priceLadderDifference))
{
throw new Exception("Unexpect margin remaining!");
}
}
}
}
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 15023;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public override int AlgorithmHistoryDataPoints => 0;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
/// </summary>
public override Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "2"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "0%"},
{"Drawdown", "0%"},
{"Expectancy", "0"},
{"Start Equity", "200000"},
{"End Equity", "199915.25"},
{"Net Profit", "0%"},
{"Sharpe Ratio", "0"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "0%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "0"},
{"Beta", "0"},
{"Annual Standard Deviation", "0"},
{"Annual Variance", "0"},
{"Information Ratio", "0"},
{"Tracking Error", "0"},
{"Treynor Ratio", "0"},
{"Total Fees", "$9.75"},
{"Estimated Strategy Capacity", "$53000.00"},
{"Lowest Capacity Asset", "GOOCV W78ZERHAOVVQ|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "11.48%"},
{"OrderListHash", "357f13ed9e71c4dd8bb8e51e339ba7c5"}
};
}
}

View File

@@ -0,0 +1,130 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Data.Market;
using QuantConnect.Securities;
using QuantConnect.Securities.Option;
using QuantConnect.Securities.Option.StrategyMatcher;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression algorithm exercising an equity Short Put Backspread option strategy and asserting it's being detected by Lean and works as expected
/// </summary>
public class OptionEquityShortPutBackspreadRegressionAlgorithm : OptionEquityBaseStrategyRegressionAlgorithm
{
/// <summary>
/// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
/// </summary>
/// <param name="slice">Slice object keyed by symbol containing the stock data</param>
public override void OnData(Slice slice)
{
if (!Portfolio.Invested)
{
OptionChain chain;
if (IsMarketOpen(_optionSymbol) && slice.OptionChains.TryGetValue(_optionSymbol, out chain))
{
var putContracts = chain
.Where(contract => contract.Right == OptionRight.Put);
var expiry = putContracts.Min(x => x.Expiry);
putContracts = putContracts.Where(x => x.Expiry == expiry)
.OrderBy(x => x.Strike)
.ToList();
var strike = putContracts.Select(x => x.Strike).Distinct();
if (strike.Count() < 2) return;
var lowStrikePut = putContracts.First();
var highStrikePut = putContracts.First(contract => contract.Strike > lowStrikePut.Strike && contract.Expiry == lowStrikePut.Expiry);
var initialMargin = Portfolio.MarginRemaining;
var optionStrategy = OptionStrategies.ShortPutBackspread(_optionSymbol, highStrikePut.Strike, lowStrikePut.Strike, expiry);
Buy(optionStrategy, 5);
var freeMarginPostTrade = Portfolio.MarginRemaining;
// It is a combination of bear put spread and naked put
AssertOptionStrategyIsPresent(OptionStrategyDefinitions.BearPutSpread.Name, 5);
AssertOptionStrategyIsPresent(OptionStrategyDefinitions.NakedPut.Name, 5);
// Should only involve the naked put part
var security = Securities[lowStrikePut.Symbol];
var expectedMarginUsage = security.BuyingPowerModel.GetMaintenanceMargin(MaintenanceMarginParameters.ForQuantityAtCurrentPrice(security, -5)).Value;
if (expectedMarginUsage != Portfolio.TotalMarginUsed)
{
throw new Exception("Unexpect margin used!");
}
// we payed the ask and value using the assets price
var priceLadderDifference = GetPriceSpreadDifference(lowStrikePut.Symbol, highStrikePut.Symbol);
if (initialMargin != (freeMarginPostTrade + expectedMarginUsage + _paidFees - priceLadderDifference))
{
throw new Exception("Unexpect margin remaining!");
}
}
}
}
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 15023;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public override int AlgorithmHistoryDataPoints => 0;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
/// </summary>
public override Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "2"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "0%"},
{"Drawdown", "0%"},
{"Expectancy", "0"},
{"Start Equity", "200000"},
{"End Equity", "199165.25"},
{"Net Profit", "0%"},
{"Sharpe Ratio", "0"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "0%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "0"},
{"Beta", "0"},
{"Annual Standard Deviation", "0"},
{"Annual Variance", "0"},
{"Information Ratio", "0"},
{"Tracking Error", "0"},
{"Treynor Ratio", "0"},
{"Total Fees", "$9.75"},
{"Estimated Strategy Capacity", "$1200000.00"},
{"Lowest Capacity Asset", "GOOCV 306CZL2DIL4G6|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "8.84%"},
{"OrderListHash", "7294da06231632975e97c57721d26442"}
};
}
}

View File

@@ -86,7 +86,7 @@ namespace QuantConnect.Algorithm.CSharp
foreach (var contract in contracts)
{
Greeks greeks = new Greeks();
Greeks greeks = null;
try
{
greeks = contract.Greeks;
@@ -110,7 +110,8 @@ namespace QuantConnect.Algorithm.CSharp
// Greeks should be valid if they were successfuly accessed for supported option style
if (_optionStyleIsSupported)
{
if (greeks.Delta == 0m && greeks.Gamma == 0m && greeks.Theta == 0m && greeks.Vega == 0m && greeks.Rho == 0m)
if (greeks == null ||
(greeks.Delta == 0m && greeks.Gamma == 0m && greeks.Theta == 0m && greeks.Vega == 0m && greeks.Rho == 0m))
{
throw new RegressionTestException($"Expected greeks to not be zero simultaneously for {contract.Symbol.Value}, an {_option.Style} style option, using {_option?.PriceModel.GetType().Name}, but they were");
}

View File

@@ -34,7 +34,7 @@
<DebugType>portable</DebugType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="QuantConnect.pythonnet" Version="2.0.38" />
<PackageReference Include="QuantConnect.pythonnet" Version="2.0.39" />
<PackageReference Include="Accord" Version="3.6.0" />
<PackageReference Include="Accord.Fuzzy" Version="3.6.0" />
<PackageReference Include="Accord.MachineLearning" Version="3.6.0" />

View File

@@ -30,7 +30,7 @@
<PackageLicenseFile>LICENSE</PackageLicenseFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="QuantConnect.pythonnet" Version="2.0.38" />
<PackageReference Include="QuantConnect.pythonnet" Version="2.0.39" />
<PackageReference Include="Accord" Version="3.6.0" />
<PackageReference Include="Accord.Math" Version="3.6.0" />
<PackageReference Include="Accord.Statistics" Version="3.6.0" />

View File

@@ -0,0 +1,73 @@
# 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.
from AlgorithmImports import *
class InvalidCommand():
variable = 10
class VoidCommand():
quantity = 0
target = []
parameters = {}
targettime = None
def run(self, algo: QCAlgorithm) -> bool | None:
if not self.targettime or self.targettime != algo.time:
return
tag = self.parameters["tag"]
algo.order(self.target[0], self.get_quantity(), tag=tag)
def get_quantity(self):
return self.quantity
class BoolCommand(Command):
result = False
def run(self, algo: QCAlgorithm) -> bool | None:
trade_ibm = self.my_custom_method()
if trade_ibm:
algo.buy("IBM", 1)
return trade_ibm
def my_custom_method(self):
return self.result
### <summary>
### Regression algorithm asserting the behavior of different callback commands call
### </summary>
class CallbackCommandRegressionAlgorithm(QCAlgorithm):
def initialize(self):
'''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''
self.set_start_date(2013, 10, 7)
self.set_end_date(2013, 10, 11)
self.add_equity("SPY")
self.add_equity("IBM")
self.add_equity("BAC")
self.add_command(VoidCommand)
self.add_command(BoolCommand)
threw_exception = False
try:
self.add_command(InvalidCommand)
except:
threw_exception = True
if not threw_exception:
raise ValueError('InvalidCommand did not throw!')
def on_command(self, data):
self.buy(data.symbol, data.parameters["quantity"])
return True # False, None

View File

@@ -12,6 +12,7 @@
# limitations under the License.
from AlgorithmImports import *
from datetime import timedelta
### <summary>
### Regression algorithm illustrating the usage of the <see cref="QCAlgorithm.OptionChain(Symbol)"/> method
@@ -27,14 +28,16 @@ class OptionChainFullDataRegressionAlgorithm(QCAlgorithm):
goog = self.add_equity("GOOG").symbol
option_chain = self.option_chain(goog)
# Demonstration using data frame:
df = option_chain.data_frame
# Get contracts expiring within 10 days, with an implied volatility greater than 0.5 and a delta less than 0.5
contracts = [
contract_data
for contract_data in self.option_chain(goog)
if contract_data.id.date - self.time <= timedelta(days=10) and contract_data.implied_volatility > 0.5 and contract_data.greeks.delta < 0.5
]
# Get the contract with the latest expiration date
self._option_contract = sorted(contracts, key=lambda x: x.id.date, reverse=True)[0]
contracts = df.loc[(df.expiry <= self.time + timedelta(days=10)) & (df.impliedvolatility > 0.5) & (df.delta < 0.5)]
# Get the contract with the latest expiration date.
# Note: the result of df.loc[] is a series, and its name is a tuple with a single element (contract symbol)
self._option_contract = contracts.loc[contracts.expiry.idxmax()].name[0]
self.add_option_contract(self._option_contract)

View File

@@ -0,0 +1,62 @@
# 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.
from AlgorithmImports import *
from datetime import timedelta
### <summary>
### Regression algorithm illustrating the usage of the <see cref="QCAlgorithm.OptionChains(IEnumerable{Symbol})"/> method
### to get multiple option chains, which contains additional data besides the symbols, including prices, implied volatility and greeks.
### It also shows how this data can be used to filter the contracts based on certain criteria.
### </summary>
class OptionChainsMultipleFullDataRegressionAlgorithm(QCAlgorithm):
def initialize(self):
self.set_start_date(2015, 12, 24)
self.set_end_date(2015, 12, 24)
self.set_cash(100000)
goog = self.add_equity("GOOG").symbol
spx = self.add_index("SPX").symbol
chains = self.option_chains([goog, spx])
self._goog_option_contract = self.get_contract(chains, goog, timedelta(days=10))
self._spx_option_contract = self.get_contract(chains, spx, timedelta(days=60))
self.add_option_contract(self._goog_option_contract)
self.add_index_option_contract(self._spx_option_contract)
def get_contract(self, chains: OptionChains, underlying: Symbol, expiry_span: timedelta) -> Symbol:
df = chains.data_frame
# Index by the requested underlying, by getting all data with canonicals which underlying is the requested underlying symbol:
canonicals = df.index.get_level_values('canonical')
condition = [canonical for canonical in canonicals if canonical.underlying == underlying]
df = df.loc[condition]
# Get contracts expiring in the next 10 days with an implied volatility greater than 0.5 and a delta less than 0.5
contracts = df.loc[(df.expiry <= self.time + expiry_span) & (df.impliedvolatility > 0.5) & (df.delta < 0.5)]
# Select the contract with the latest expiry date
contracts.sort_values(by='expiry', ascending=False, inplace=True)
# Get the symbol: the resulting series name is a tuple (canonical symbol, contract symbol)
return contracts.iloc[0].name[1]
def on_data(self, data):
# Do some trading with the selected contract for sample purposes
if not self.portfolio.invested:
self.market_order(self._goog_option_contract, 1)
else:
self.liquidate()

View File

@@ -53,7 +53,7 @@ class OptionPriceModelForOptionStylesBaseRegressionAlgorithm(QCAlgorithm):
self._tried_greeks_calculation = True
for contract in contracts:
greeks = Greeks()
greeks = None
try:
greeks = contract.greeks
@@ -70,9 +70,10 @@ class OptionPriceModelForOptionStylesBaseRegressionAlgorithm(QCAlgorithm):
# Delta can be {-1, 0, 1} if the price is too wild, rho can be 0 if risk free rate is 0
# Vega can be 0 if the price is very off from theoretical price, Gamma = 0 if Delta belongs to {-1, 1}
if (self._option_style_is_supported
and ((contract.right == OptionRight.CALL and (greeks.delta < 0.0 or greeks.delta > 1.0 or greeks.rho < 0.0))
or (contract.right == OptionRight.PUT and (greeks.delta < -1.0 or greeks.delta > 0.0 or greeks.rho > 0.0))
or greeks.theta == 0.0 or greeks.vega < 0.0 or greeks.gamma < 0.0)):
and (greeks is None
or ((contract.right == OptionRight.CALL and (greeks.delta < 0.0 or greeks.delta > 1.0 or greeks.rho < 0.0))
or (contract.right == OptionRight.PUT and (greeks.delta < -1.0 or greeks.delta > 0.0 or greeks.rho > 0.0))
or greeks.theta == 0.0 or greeks.vega < 0.0 or greeks.gamma < 0.0))):
raise Exception(f'Expected greeks to have valid values. Greeks were: Delta: {greeks.delta}, Rho: {greeks.rho}, Theta: {greeks.theta}, Vega: {greeks.vega}, Gamma: {greeks.gamma}')

View File

@@ -39,7 +39,7 @@
<Compile Include="..\Common\Properties\SharedAssemblyInfo.cs" Link="Properties\SharedAssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="QuantConnect.pythonnet" Version="2.0.38" />
<PackageReference Include="QuantConnect.pythonnet" Version="2.0.39" />
</ItemGroup>
<ItemGroup>
<Content Include="OptionUniverseFilterGreeksShortcutsRegressionAlgorithm.py" />

View File

@@ -177,7 +177,7 @@ namespace QuantConnect.Algorithm
var startTimeUtc = CreateBarCountHistoryRequests(symbols, _warmupBarCount.Value, Settings.WarmupResolution)
.DefaultIfEmpty()
.Min(request => request == null ? default : request.StartTimeUtc);
if(startTimeUtc != default)
if (startTimeUtc != default)
{
result = startTimeUtc.ConvertFromUtc(TimeZone);
return true;
@@ -353,7 +353,7 @@ namespace QuantConnect.Algorithm
/// <returns>An enumerable of slice containing the requested historical data</returns>
[DocumentationAttribute(HistoricalData)]
public IEnumerable<DataDictionary<T>> History<T>(TimeSpan span, Resolution? resolution = null, bool? fillForward = null,
bool? extendedMarketHours = null, DataMappingMode? dataMappingMode = null, DataNormalizationMode ? dataNormalizationMode = null,
bool? extendedMarketHours = null, DataMappingMode? dataMappingMode = null, DataNormalizationMode? dataNormalizationMode = null,
int? contractDepthOffset = null)
where T : IBaseData
{
@@ -518,7 +518,7 @@ namespace QuantConnect.Algorithm
{
resolution = GetResolution(symbol, resolution, typeof(T));
CheckPeriodBasedHistoryRequestResolution(new[] { symbol }, resolution, typeof(T));
var requests = CreateBarCountHistoryRequests(new [] { symbol }, typeof(T), periods, resolution, fillForward, extendedMarketHours,
var requests = CreateBarCountHistoryRequests(new[] { symbol }, typeof(T), periods, resolution, fillForward, extendedMarketHours,
dataMappingMode, dataNormalizationMode, contractDepthOffset);
return GetDataTypedHistory<T>(requests, symbol);
}
@@ -948,9 +948,19 @@ namespace QuantConnect.Algorithm
Resolution? resolution = null, bool? fillForward = null, bool? extendedMarketHours = null, DataMappingMode? dataMappingMode = null,
DataNormalizationMode? dataNormalizationMode = null, int? contractDepthOffset = null)
{
var arrayOfSymbols = symbols.ToArray();
return CreateDateRangeHistoryRequests(symbols, Extensions.GetCustomDataTypeFromSymbols(arrayOfSymbols) ?? typeof(BaseData), startAlgoTz, endAlgoTz, resolution, fillForward, extendedMarketHours,
dataMappingMode, dataNormalizationMode, contractDepthOffset);
// Materialize the symbols to avoid multiple enumeration
var symbolsArray = symbols.ToArray();
return CreateDateRangeHistoryRequests(
symbolsArray,
Extensions.GetCustomDataTypeFromSymbols(symbolsArray),
startAlgoTz,
endAlgoTz,
resolution,
fillForward,
extendedMarketHours,
dataMappingMode,
dataNormalizationMode,
contractDepthOffset);
}
/// <summary>
@@ -982,8 +992,18 @@ namespace QuantConnect.Algorithm
bool? fillForward = null, bool? extendedMarketHours = null, DataMappingMode? dataMappingMode = null,
DataNormalizationMode? dataNormalizationMode = null, int? contractDepthOffset = null)
{
return CreateBarCountHistoryRequests(symbols, typeof(BaseData), periods, resolution, fillForward, extendedMarketHours, dataMappingMode,
dataNormalizationMode, contractDepthOffset);
// Materialize the symbols to avoid multiple enumeration
var symbolsArray = symbols.ToArray();
return CreateBarCountHistoryRequests(
symbolsArray,
Extensions.GetCustomDataTypeFromSymbols(symbolsArray),
periods,
resolution,
fillForward,
extendedMarketHours,
dataMappingMode,
dataNormalizationMode,
contractDepthOffset);
}
/// <summary>
@@ -995,20 +1015,26 @@ namespace QuantConnect.Algorithm
{
return symbols.Where(HistoryRequestValid).SelectMany(symbol =>
{
var res = GetResolution(symbol, resolution, requestedType);
var exchange = GetExchangeHours(symbol, requestedType);
// Match or create configs for the symbol
var configs = GetMatchingSubscriptions(symbol, requestedType, resolution).ToList();
if (configs.Count == 0)
{
return Enumerable.Empty<HistoryRequest>();
}
var config = configs.First();
var start = _historyRequestFactory.GetStartTimeAlgoTz(symbol, periods, res, exchange, config.DataTimeZone, config.Type, extendedMarketHours);
var end = Time;
return configs.Select(config =>
{
// If no requested type was passed, use the config type to get the resolution (if not provided) and the exchange hours
var type = requestedType ?? config.Type;
var res = GetResolution(symbol, resolution, type);
var exchange = GetExchangeHours(symbol, type);
var start = _historyRequestFactory.GetStartTimeAlgoTz(symbol, periods, res, exchange, config.DataTimeZone,
config.Type, extendedMarketHours);
var end = Time;
return configs.Select(config => _historyRequestFactory.CreateHistoryRequest(config, start, end, exchange, res, fillForward,
extendedMarketHours, dataMappingMode, dataNormalizationMode, contractDepthOffset));
return _historyRequestFactory.CreateHistoryRequest(config, start, end, exchange, res, fillForward,
extendedMarketHours, dataMappingMode, dataNormalizationMode, contractDepthOffset);
});
});
}
@@ -1045,7 +1071,7 @@ namespace QuantConnect.Algorithm
// if we have any user defined subscription configuration we use it, else we use internal ones if any
List<SubscriptionDataConfig> configs = null;
if(userConfig.Count != 0)
if (userConfig.Count != 0)
{
configs = userConfig;
}
@@ -1078,13 +1104,14 @@ namespace QuantConnect.Algorithm
}
else
{
var entry = MarketHoursDatabase.GetEntry(symbol, new []{ type });
resolution = GetResolution(symbol, resolution, type);
if (!LeanData.IsCommonLeanDataType(type) && !type.IsAbstract)
// If type was specified and not a lean data type and also not abstract, we create a new subscription
if (type != null && !LeanData.IsCommonLeanDataType(type) && !type.IsAbstract)
{
// we already know it's not a common lean data type
var isCustom = Extensions.IsCustomDataType(symbol, type);
var entry = MarketHoursDatabase.GetEntry(symbol, new[] { type });
// we were giving a specific type let's fetch it
return new[] { new SubscriptionDataConfig(
@@ -1105,19 +1132,26 @@ namespace QuantConnect.Algorithm
return SubscriptionManager
.LookupSubscriptionConfigDataTypes(symbol.SecurityType, resolution.Value, symbol.IsCanonical())
.Where(tuple => SubscriptionDataConfigTypeFilter(type, tuple.Item1))
.Select(x => new SubscriptionDataConfig(
x.Item1,
symbol,
resolution.Value,
entry.DataTimeZone,
entry.ExchangeHours.TimeZone,
UniverseSettings.FillForward,
UniverseSettings.ExtendedMarketHours,
true,
false,
x.Item2,
true,
UniverseSettings.GetUniverseNormalizationModeOrDefault(symbol.SecurityType)))
.Select(x =>
{
var configType = x.Item1;
// Use the config type to get an accurate mhdb entry
var entry = MarketHoursDatabase.GetEntry(symbol, new[] { configType });
return new SubscriptionDataConfig(
configType,
symbol,
resolution.Value,
entry.DataTimeZone,
entry.ExchangeHours.TimeZone,
UniverseSettings.FillForward,
UniverseSettings.ExtendedMarketHours,
true,
false,
x.Item2,
true,
UniverseSettings.GetUniverseNormalizationModeOrDefault(symbol.SecurityType));
})
// lets make sure to respect the order of the data types, if used on a history request will affect outcome when using pushthrough for example
.OrderByDescending(config => GetTickTypeOrder(config.SecurityType, config.TickType));
}
@@ -1130,6 +1164,11 @@ namespace QuantConnect.Algorithm
/// This is useful to filter OpenInterest by default from history requests unless it's explicitly requested</remarks>
private bool SubscriptionDataConfigTypeFilter(Type targetType, Type configType)
{
if (targetType == null)
{
return configType != typeof(OpenInterest);
}
var targetIsGenericType = targetType == typeof(BaseData);
return targetType.IsAssignableFrom(configType) && (!targetIsGenericType || configType != typeof(OpenInterest));
@@ -1188,7 +1227,7 @@ namespace QuantConnect.Algorithm
}
else
{
if(resolution != null)
if (resolution != null)
{
return resolution.Value;
}

View File

@@ -498,7 +498,7 @@ namespace QuantConnect.Algorithm
InitializeIndicator(indicator, resolution, selector, symbol);
return indicator;
}
/// <summary>
/// Creates a new ChaikinMoneyFlow indicator.
/// </summary>
@@ -4004,7 +4004,9 @@ namespace QuantConnect.Algorithm
indicator.Updated -= callback;
return new IndicatorHistory(indicatorsDataPointsByTime, indicatorsDataPointPerProperty,
new Lazy<PyObject>(() => PandasConverter.GetIndicatorDataFrame(indicatorsDataPointPerProperty.Select(x => new KeyValuePair<string, List<IndicatorDataPoint>>(x.Name, x.Values)))));
new Lazy<PyObject>(
() => PandasConverter.GetIndicatorDataFrame(indicatorsDataPointPerProperty.Select(x => new KeyValuePair<string, List<IndicatorDataPoint>>(x.Name, x.Values))),
isThreadSafe: false));
}
private Type GetDataTypeFromSelector(Func<IBaseData, decimal> selector)

View File

@@ -31,6 +31,7 @@ using QuantConnect.Scheduling;
using QuantConnect.Util;
using QuantConnect.Interfaces;
using QuantConnect.Orders;
using QuantConnect.Commands;
namespace QuantConnect.Algorithm
{
@@ -1620,6 +1621,38 @@ namespace QuantConnect.Algorithm
return Liquidate(symbols.ConvertToSymbolEnumerable(), asynchronous, tag, orderProperties);
}
/// <summary>
/// Register a command type to be used
/// </summary>
/// <param name="type">The command type</param>
public void AddCommand(PyObject type)
{
// create a test instance to validate interface is implemented accurate
var testInstance = new CommandPythonWrapper(type);
var wrappedType = Extensions.CreateType(type);
_registeredCommands[wrappedType.Name] = (CallbackCommand command) =>
{
var commandWrapper = new CommandPythonWrapper(type, command.Payload);
return commandWrapper.Run(this);
};
}
/// <summary>
/// Get the option chains for the specified symbols at the current time (<see cref="Time"/>)
/// </summary>
/// <param name="symbols">
/// The symbols for which the option chain is asked for.
/// It can be either the canonical options or the underlying symbols.
/// </param>
/// <returns>The option chains</returns>
[DocumentationAttribute(AddingData)]
public OptionChains OptionChains(PyObject symbols)
{
return OptionChains(symbols.ConvertToSymbolEnumerable());
}
/// <summary>
/// Gets indicator base type
/// </summary>

View File

@@ -54,6 +54,8 @@ using QuantConnect.Securities.CryptoFuture;
using QuantConnect.Algorithm.Framework.Alphas.Analysis;
using QuantConnect.Algorithm.Framework.Portfolio.SignalExports;
using Python.Runtime;
using QuantConnect.Commands;
using Newtonsoft.Json;
namespace QuantConnect.Algorithm
{
@@ -115,6 +117,9 @@ namespace QuantConnect.Algorithm
private IStatisticsService _statisticsService;
private IBrokerageModel _brokerageModel;
private readonly HashSet<string> _oneTimeCommandErrors = new();
private readonly Dictionary<string, Func<CallbackCommand, bool?>> _registeredCommands = new(StringComparer.InvariantCultureIgnoreCase);
//Error tracking to avoid message flooding:
private string _previousDebugMessage = "";
private string _previousErrorMessage = "";
@@ -3351,38 +3356,113 @@ namespace QuantConnect.Algorithm
/// The symbol for which the option chain is asked for.
/// It can be either the canonical option or the underlying symbol.
/// </param>
/// <returns>
/// The option chain as an enumerable of <see cref="OptionUniverse"/>,
/// each containing the contract symbol along with additional data, including daily price data,
/// implied volatility and greeks.
/// </returns>
/// <returns>The option chain</returns>
/// <remarks>
/// As of 2024/09/11, future options chain will not contain any additional data (e.g. daily price data, implied volatility and greeks),
/// it will be populated with the contract symbol only. This is expected to change in the future.
/// </remarks>
[DocumentationAttribute(AddingData)]
public DataHistory<OptionUniverse> OptionChain(Symbol symbol)
public OptionChain OptionChain(Symbol symbol)
{
var canonicalSymbol = GetCanonicalOptionSymbol(symbol);
IEnumerable<OptionUniverse> optionChain;
return OptionChains(new[] { symbol }).Values.SingleOrDefault() ?? new OptionChain(GetCanonicalOptionSymbol(symbol), Time.Date);
}
// TODO: Until future options are supported by OptionUniverse, we need to fall back to the OptionChainProvider for them
if (canonicalSymbol.SecurityType != SecurityType.FutureOption)
/// <summary>
/// Get the option chains for the specified symbols at the current time (<see cref="Time"/>)
/// </summary>
/// <param name="symbols">
/// The symbols for which the option chain is asked for.
/// It can be either the canonical options or the underlying symbols.
/// </param>
/// <returns>The option chains</returns>
[DocumentationAttribute(AddingData)]
public OptionChains OptionChains(IEnumerable<Symbol> symbols)
{
var canonicalSymbols = symbols.Select(GetCanonicalOptionSymbol).ToList();
var optionCanonicalSymbols = canonicalSymbols.Where(x => x.SecurityType != SecurityType.FutureOption);
var futureOptionCanonicalSymbols = canonicalSymbols.Where(x => x.SecurityType == SecurityType.FutureOption);
var optionChainsData = History(optionCanonicalSymbols, 1).GetUniverseData()
.Select(x => (x.Keys.Single(), x.Values.Single().Cast<OptionUniverse>()));
// TODO: For FOPs, we fall back to the option chain provider until OptionUniverse supports them
var futureOptionChainsData = futureOptionCanonicalSymbols.Select(symbol =>
{
var history = History<OptionUniverse>(canonicalSymbol, 1);
optionChain = history?.SingleOrDefault()?.Data?.Cast<OptionUniverse>() ?? Enumerable.Empty<OptionUniverse>();
}
else
{
optionChain = OptionChainProvider.GetOptionContractList(canonicalSymbol, Time)
var optionChainData = OptionChainProvider.GetOptionContractList(symbol, Time)
.Select(contractSymbol => new OptionUniverse()
{
Symbol = contractSymbol,
EndTime = Time.Date
EndTime = Time.Date,
});
return (symbol, optionChainData);
});
var time = Time.Date;
var chains = new OptionChains(time);
foreach (var (symbol, contracts) in optionChainsData.Concat(futureOptionChainsData))
{
var symbolProperties = SymbolPropertiesDatabase.GetSymbolProperties(symbol.ID.Market, symbol, symbol.SecurityType, AccountCurrency);
var optionChain = new OptionChain(symbol, time, contracts, symbolProperties);
chains.Add(symbol, optionChain);
}
return new DataHistory<OptionUniverse>(optionChain, new Lazy<PyObject>(() => PandasConverter.GetDataFrame(optionChain)));
return chains;
}
/// <summary>
/// Register a command type to be used
/// </summary>
/// <typeparam name="T">The command type</typeparam>
public void AddCommand<T>() where T : Command
{
_registeredCommands[typeof(T).Name] = (CallbackCommand command) =>
{
var commandInstance = JsonConvert.DeserializeObject<T>(command.Payload);
return commandInstance.Run(this);
};
}
/// <summary>
/// Run a callback command instance
/// </summary>
/// <param name="command">The callback command instance</param>
/// <returns>The command result</returns>
public CommandResultPacket RunCommand(CallbackCommand command)
{
bool? result = null;
if (_registeredCommands.TryGetValue(command.Type, out var target))
{
try
{
result = target.Invoke(command);
}
catch (Exception ex)
{
QuantConnect.Logging.Log.Error(ex);
if (_oneTimeCommandErrors.Add(command.Type))
{
Log($"Unexpected error running command '{command.Type}' error: '{ex.Message}'");
}
}
}
else
{
if (_oneTimeCommandErrors.Add(command.Type))
{
Log($"Detected unregistered command type '{command.Type}', will be ignored");
}
}
return new CommandResultPacket(command, result) { CommandName = command.Type };
}
/// <summary>
/// Generic untyped command call handler
/// </summary>
/// <param name="data">The associated data</param>
/// <returns>True if success, false otherwise. Returning null will disable command feedback</returns>
public virtual bool? OnCommand(dynamic data)
{
return true;
}
private static Symbol GetCanonicalOptionSymbol(Symbol symbol)

View File

@@ -30,7 +30,7 @@
<PackageLicenseFile>LICENSE</PackageLicenseFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="QuantConnect.pythonnet" Version="2.0.38" />
<PackageReference Include="QuantConnect.pythonnet" Version="2.0.39" />
<PackageReference Include="MathNet.Numerics" Version="5.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="NodaTime" Version="3.0.5" />

View File

@@ -35,7 +35,7 @@ namespace QuantConnect.Algorithm.Selection
/// <param name="configuration">The universe configuration to use</param>
/// <param name="universeSettings">The universe settings to use</param>
public OptionContractUniverse(SubscriptionDataConfig configuration, UniverseSettings universeSettings)
: base(configuration, universeSettings, Time.EndOfTimeTimeSpan,
: base(AdjustUniverseConfiguration(configuration), universeSettings, Time.EndOfTimeTimeSpan,
// Argument isn't used since we override 'SelectSymbols'
Enumerable.Empty<Symbol>())
{
@@ -95,5 +95,13 @@ namespace QuantConnect.Algorithm.Selection
return new Symbol(sid, ticker);
}
/// <summary>
/// Make sure the configuration of the universe is what we want
/// </summary>
private static SubscriptionDataConfig AdjustUniverseConfiguration(SubscriptionDataConfig input)
{
return new SubscriptionDataConfig(input, fillForward: false);
}
}
}

View File

@@ -37,6 +37,7 @@ using QuantConnect.Storage;
using QuantConnect.Statistics;
using QuantConnect.Data.Market;
using QuantConnect.Algorithm.Framework.Alphas.Analysis;
using QuantConnect.Commands;
namespace QuantConnect.AlgorithmFactory.Python.Wrappers
{
@@ -62,6 +63,7 @@ namespace QuantConnect.AlgorithmFactory.Python.Wrappers
private dynamic _onEndOfDay;
private dynamic _onMarginCallWarning;
private dynamic _onOrderEvent;
private dynamic _onCommand;
private dynamic _onAssignmentOrderEvent;
private dynamic _onSecuritiesChanged;
private dynamic _onFrameworkSecuritiesChanged;
@@ -153,6 +155,7 @@ namespace QuantConnect.AlgorithmFactory.Python.Wrappers
_onDelistings = _algorithm.GetMethod("OnDelistings");
_onSymbolChangedEvents = _algorithm.GetMethod("OnSymbolChangedEvents");
_onEndOfDay = _algorithm.GetMethod("OnEndOfDay");
_onCommand = _algorithm.GetMethod("OnCommand");
_onMarginCallWarning = _algorithm.GetMethod("OnMarginCallWarning");
_onOrderEvent = _algorithm.GetMethod("OnOrderEvent");
_onAssignmentOrderEvent = _algorithm.GetMethod("OnAssignmentOrderEvent");
@@ -921,6 +924,16 @@ namespace QuantConnect.AlgorithmFactory.Python.Wrappers
_onOrderEvent(newEvent);
}
/// <summary>
/// Generic untyped command call handler
/// </summary>
/// <param name="data">The associated data</param>
/// <returns>True if success, false otherwise. Returning null will disable command feedback</returns>
public bool? OnCommand(dynamic data)
{
return _onCommand(data);
}
/// <summary>
/// Will submit an order request to the algorithm
/// </summary>
@@ -1242,5 +1255,13 @@ namespace QuantConnect.AlgorithmFactory.Python.Wrappers
{
_baseAlgorithm.SetTags(tags);
}
/// <summary>
/// Run a callback command instance
/// </summary>
/// <param name="command">The callback command instance</param>
/// <returns>The command result</returns>
public CommandResultPacket RunCommand(CallbackCommand command) => _baseAlgorithm.RunCommand(command);
}
}

View File

@@ -29,7 +29,7 @@
<PackageLicenseFile>LICENSE</PackageLicenseFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="QuantConnect.pythonnet" Version="2.0.38" />
<PackageReference Include="QuantConnect.pythonnet" Version="2.0.39" />
<PackageReference Include="NodaTime" Version="3.0.5" />
</ItemGroup>
<ItemGroup>

View File

@@ -1023,7 +1023,6 @@ namespace QuantConnect.Api
/// </summary>
/// <param name="projectId">Project for the live instance we want to stop</param>
/// <returns><see cref="RestResponse"/></returns>
public RestResponse StopLiveAlgorithm(int projectId)
{
var request = new RestRequest("live/update/stop", Method.POST)
@@ -1040,6 +1039,29 @@ namespace QuantConnect.Api
return result;
}
/// <summary>
/// Create a live command
/// </summary>
/// <param name="projectId">Project for the live instance we want to run the command against</param>
/// <param name="command">The command to run</param>
/// <returns><see cref="RestResponse"/></returns>
public RestResponse CreateLiveCommand(int projectId, object command)
{
var request = new RestRequest("live/commands/create", Method.POST)
{
RequestFormat = DataFormat.Json
};
request.AddParameter("application/json", JsonConvert.SerializeObject(new
{
projectId,
command
}), ParameterType.RequestBody);
ApiConnection.TryRequest(request, out RestResponse result);
return result;
}
/// <summary>
/// Gets the logs of a specific live algorithm
/// </summary>

View File

@@ -39,6 +39,7 @@ from QuantConnect.Orders import *
from QuantConnect.Python import *
from QuantConnect.Storage import *
from QuantConnect.Research import *
from QuantConnect.Commands import *
from QuantConnect.Algorithm import *
from QuantConnect.Statistics import *
from QuantConnect.Parameters import *

View File

@@ -30,7 +30,8 @@ namespace QuantConnect.Brokerages
/// </summary>
private readonly Dictionary<SecurityType, HashSet<OrderType>> _supportOrderTypeBySecurityType = new()
{
{ SecurityType.Equity, new HashSet<OrderType> { OrderType.Market, OrderType.Limit, OrderType.StopMarket, OrderType.StopLimit, OrderType.TrailingStop } },
{ SecurityType.Equity, new HashSet<OrderType> { OrderType.Market, OrderType.Limit, OrderType.StopMarket, OrderType.StopLimit,
OrderType.TrailingStop, OrderType.MarketOnOpen, OrderType.MarketOnClose } },
// Market and limit order types see https://docs.alpaca.markets/docs/options-trading-overview
{ SecurityType.Option, new HashSet<OrderType> { OrderType.Market, OrderType.Limit } },
{ SecurityType.Crypto, new HashSet<OrderType> { OrderType.Market, OrderType.Limit, OrderType.StopLimit }}

View File

@@ -50,6 +50,8 @@ namespace QuantConnect.Brokerages
OrderType.StopLimit,
OrderType.ComboMarket,
OrderType.ComboLimit,
OrderType.MarketOnOpen,
OrderType.MarketOnClose
});
/// <summary>

View File

@@ -15,8 +15,10 @@
using System;
using System.Linq;
using Newtonsoft.Json;
using QuantConnect.Logging;
using QuantConnect.Packets;
using Newtonsoft.Json.Linq;
using QuantConnect.Interfaces;
using System.Collections.Generic;
@@ -27,6 +29,8 @@ namespace QuantConnect.Commands
/// </summary>
public abstract class BaseCommandHandler : ICommandHandler
{
protected static readonly JsonSerializerSettings Settings = new() { TypeNameHandling = TypeNameHandling.All };
/// <summary>
/// The algorithm instance
/// </summary>
@@ -104,5 +108,41 @@ namespace QuantConnect.Commands
{
// nop
}
/// <summary>
/// Helper method to create a callback command
/// </summary>
protected ICommand TryGetCallbackCommand(string payload)
{
Dictionary<string, JToken> deserialized = new(StringComparer.InvariantCultureIgnoreCase);
try
{
if (!string.IsNullOrEmpty(payload))
{
var jobject = JObject.Parse(payload);
foreach (var kv in jobject)
{
deserialized[kv.Key] = kv.Value;
}
}
}
catch (Exception err)
{
Log.Error(err, $"Payload: '{payload}'");
return null;
}
if (!deserialized.TryGetValue("id", out var id) || id == null)
{
id = string.Empty;
}
if (!deserialized.TryGetValue("$type", out var type) || type == null)
{
type = string.Empty;
}
return new CallbackCommand { Id = id.ToString(), Type = type.ToString(), Payload = payload };
}
}
}

View File

@@ -0,0 +1,63 @@
/*
* 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 Newtonsoft.Json;
using QuantConnect.Interfaces;
namespace QuantConnect.Commands
{
/// <summary>
/// Algorithm callback command type
/// </summary>
public class CallbackCommand : BaseCommand
{
/// <summary>
/// The target command type to run, if empty or null will be the generic untyped command handler
/// </summary>
public string Type { get; set; }
/// <summary>
/// The command payload
/// </summary>
public string Payload { get; set; }
/// <summary>
/// Runs this command against the specified algorithm instance
/// </summary>
/// <param name="algorithm">The algorithm to run this command against</param>
public override CommandResultPacket Run(IAlgorithm algorithm)
{
if (string.IsNullOrEmpty(Type))
{
// target is the untyped algorithm handler
var result = algorithm.OnCommand(string.IsNullOrEmpty(Payload) ? null : JsonConvert.DeserializeObject<Command>(Payload));
return new CommandResultPacket(this, result);
}
return algorithm.RunCommand(this);
}
/// <summary>
/// The command string representation
/// </summary>
public override string ToString()
{
if (!string.IsNullOrEmpty(Type))
{
return Type;
}
return "OnCommand";
}
}
}

View File

@@ -0,0 +1,91 @@
/*
* 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.Dynamic;
using QuantConnect.Data;
using System.Reflection;
using System.Linq.Expressions;
using QuantConnect.Interfaces;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
namespace QuantConnect.Commands
{
/// <summary>
/// Base generic dynamic command class
/// </summary>
public class Command : DynamicObject
{
private static readonly MethodInfo SetPropertyMethodInfo = typeof(Command).GetMethod("SetProperty");
private static readonly MethodInfo GetPropertyMethodInfo = typeof(Command).GetMethod("GetProperty");
private readonly Dictionary<string, object> _storage = new(StringComparer.InvariantCultureIgnoreCase);
/// <summary>
/// Get the metaObject required for Dynamism.
/// </summary>
public sealed override DynamicMetaObject GetMetaObject(Expression parameter)
{
return new GetSetPropertyDynamicMetaObject(parameter, this, SetPropertyMethodInfo, GetPropertyMethodInfo);
}
/// <summary>
/// Sets the property with the specified name to the value. This is a case-insensitve search.
/// </summary>
/// <param name="name">The property name to set</param>
/// <param name="value">The new property value</param>
/// <returns>Returns the input value back to the caller</returns>
public object SetProperty(string name, object value)
{
if (value is JArray jArray)
{
return _storage[name] = jArray.ToObject<List<object>>();
}
else if (value is JObject jobject)
{
return _storage[name] = jobject.ToObject<Dictionary<string, object>>();
}
else
{
return _storage[name] = value;
}
}
/// <summary>
/// Gets the property's value with the specified name. This is a case-insensitve search.
/// </summary>
/// <param name="name">The property name to access</param>
/// <returns>object value of BaseData</returns>
public object GetProperty(string name)
{
if (!_storage.TryGetValue(name, out var value))
{
throw new KeyNotFoundException($"Property with name \'{name}\' does not exist. Properties: {string.Join(", ", _storage.Keys)}");
}
return value;
}
/// <summary>
/// Run this command using the target algorithm
/// </summary>
/// <param name="algorithm">The algorithm instance</param>
/// <returns>True if success, false otherwise. Returning null will disable command feedback</returns>
public virtual bool? Run(IAlgorithm algorithm)
{
throw new NotImplementedException($"Please implement the 'def run(algorithm) -> bool | None:' method");
}
}
}

View File

@@ -31,12 +31,12 @@ namespace QuantConnect.Commands
/// <summary>
/// Gets or sets whether or not the
/// </summary>
public bool Success { get; set; }
public bool? Success { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="CommandResultPacket"/> class
/// </summary>
public CommandResultPacket(ICommand command, bool success)
public CommandResultPacket(ICommand command, bool? success)
: base(PacketType.CommandResult)
{
Success = success;

View File

@@ -19,6 +19,7 @@ using Newtonsoft.Json;
using QuantConnect.Logging;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
namespace QuantConnect.Commands
{
@@ -90,7 +91,9 @@ namespace QuantConnect.Commands
private void ReadCommandFile(string commandFilePath)
{
Log.Trace($"FileCommandHandler.ReadCommandFile(): {Messages.FileCommandHandler.ReadingCommandFile(commandFilePath)}");
object deserialized;
string contents = null;
Exception exception = null;
object deserialized = null;
try
{
if (!File.Exists(commandFilePath))
@@ -98,13 +101,12 @@ namespace QuantConnect.Commands
Log.Error($"FileCommandHandler.ReadCommandFile(): {Messages.FileCommandHandler.CommandFileDoesNotExist(commandFilePath)}");
return;
}
var contents = File.ReadAllText(commandFilePath);
deserialized = JsonConvert.DeserializeObject(contents, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All });
contents = File.ReadAllText(commandFilePath);
deserialized = JsonConvert.DeserializeObject(contents, Settings);
}
catch (Exception err)
{
Log.Error(err);
deserialized = null;
exception = err;
}
// remove the file when we're done reading it
@@ -126,6 +128,20 @@ namespace QuantConnect.Commands
if (item != null)
{
_commands.Enqueue(item);
return;
}
var callbackCommand = TryGetCallbackCommand(contents);
if (callbackCommand != null)
{
_commands.Enqueue(callbackCommand);
return;
}
if (exception != null)
{
// if we are here we failed
Log.Error(exception);
}
}
}

View File

@@ -85,7 +85,7 @@ namespace QuantConnect.Data
var isUniverseData = path.Contains("coarse", StringComparison.OrdinalIgnoreCase) ||
path.Contains("universe", StringComparison.OrdinalIgnoreCase);
if (e.Succeded)
if (e.Succeeded)
{
WriteLineToFile(_succeededDataRequestsWriter, path, _succeededDataRequestsFileName);
Interlocked.Increment(ref _succeededDataRequestsCount);
@@ -105,7 +105,7 @@ namespace QuantConnect.Data
if (Logging.Log.DebuggingEnabled)
{
Logging.Log.Debug($"DataMonitor.OnNewDataRequest(): Data from {path} could not be fetched");
Logging.Log.Debug($"DataMonitor.OnNewDataRequest(): Data from {path} could not be fetched, error: {e.ErrorMessage}");
}
}
}

View File

@@ -102,6 +102,21 @@ namespace QuantConnect.Data
.Distinct();
}
/// <summary>
/// Retrieves the list of unique <see cref="Symbol"/> instances that are currently subscribed for a specific <see cref="TickType"/>.
/// </summary>
/// <param name="tickType">The type of tick data to filter subscriptions by.</param>
/// <returns>A collection of unique <see cref="Symbol"/> objects that match the specified <paramref name="tickType"/>.</returns>
public IEnumerable<Symbol> GetSubscribedSymbols(TickType tickType)
{
var channelName = ChannelNameFromTickType(tickType);
#pragma warning disable CA1309
return SubscribersByChannel.Keys.Where(x => x.Name.Equals(channelName, StringComparison.InvariantCultureIgnoreCase))
#pragma warning restore CA1309
.Select(c => c.Symbol)
.Distinct();
}
/// <summary>
/// Checks if there is existing subscriber for current channel
/// </summary>

View File

@@ -1,11 +1,11 @@
/*
/*
* 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");
*
* 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.
@@ -21,7 +21,7 @@ namespace QuantConnect.Data
/// <summary>
/// Base Data Class: Type, Timestamp, Key -- Base Features.
/// </summary>
public interface IBaseData
public interface IBaseData : ISymbolProvider
{
/// <summary>
/// Market Data Type of this data - does it come in individual price packets or is it grouped into OHLC.
@@ -31,7 +31,7 @@ namespace QuantConnect.Data
get;
set;
}
/// <summary>
/// Time keeper of data -- all data is timeseries based.
/// </summary>
@@ -49,16 +49,6 @@ namespace QuantConnect.Data
get;
set;
}
/// <summary>
/// Symbol for underlying Security
/// </summary>
Symbol Symbol
{
get;
set;
}
/// <summary>
@@ -112,7 +102,7 @@ namespace QuantConnect.Data
BaseData Reader(SubscriptionDataConfig config, StreamReader stream, DateTime date, bool isLiveMode);
/// <summary>
/// Return the URL string source of the file. This will be converted to a stream
/// Return the URL string source of the file. This will be converted to a stream
/// </summary>
/// <param name="datafeed">Type of datafeed we're reqesting - backtest or live</param>
/// <param name="config">Configuration object</param>

View File

@@ -0,0 +1,32 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace QuantConnect.Data
{
/// <summary>
/// Base data with a symbol
/// </summary>
public interface ISymbolProvider
{
/// <summary>
/// Gets the Symbol
/// </summary>
Symbol Symbol
{
get;
set;
}
}
}

View File

@@ -1,101 +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.
*/
namespace QuantConnect.Data.Market
{
/// <summary>
/// Defines the greeks
/// </summary>
public abstract class BaseGreeks
{
/// <summary>
/// Gets the delta.
/// <para>
/// Delta measures the rate of change of the option value with respect to changes in
/// the underlying asset'sprice. (∂V/∂S)
/// </para>
/// </summary>
public abstract decimal Delta { get; protected set; }
/// <summary>
/// Gets the gamma.
/// <para>
/// Gamma measures the rate of change of Delta with respect to changes in
/// the underlying asset'sprice. (∂²V/∂S²)
/// </para>
/// </summary>
public abstract decimal Gamma { get; protected set; }
/// <summary>
/// Gets the vega.
/// <para>
/// Vega measures the rate of change of the option value with respect to changes in
/// the underlying's volatility. (∂V/∂σ)
/// </para>
/// </summary>
public abstract decimal Vega { get; protected set; }
/// <summary>
/// Gets the theta.
/// <para>
/// Theta measures the rate of change of the option value with respect to changes in
/// time. This is commonly known as the 'time decay.' (∂V/∂τ)
/// </para>
/// </summary>
public abstract decimal Theta { get; protected set; }
/// <summary>
/// Gets the rho.
/// <para>
/// Rho measures the rate of change of the option value with respect to changes in
/// the risk free interest rate. (∂V/∂r)
/// </para>
/// </summary>
public abstract decimal Rho { get; protected set; }
/// <summary>
/// Gets the lambda.
/// <para>
/// Lambda is the percentage change in option value per percentage change in the
/// underlying's price, a measure of leverage. Sometimes referred to as gearing.
/// (∂V/∂S ✕ S/V)
/// </para>
/// </summary>
public abstract decimal Lambda { get; protected set; }
/// <summary>
/// Gets the lambda.
/// <para>
/// Lambda is the percentage change in option value per percentage change in the
/// underlying's price, a measure of leverage. Sometimes referred to as gearing.
/// (∂V/∂S ✕ S/V)
/// </para>
/// </summary>
/// <remarks>
/// Alias for <see cref="Lambda"/> required for compatibility with Python when
/// PEP8 API is used (lambda is a reserved keyword in Python).
/// </remarks>
public virtual decimal Lambda_ => Lambda;
/// <summary>
/// Gets the theta per day.
/// <para>
/// Theta measures the rate of change of the option value with respect to changes in
/// time. This is commonly known as the 'time decay.' (∂V/∂τ)
/// </para>
/// </summary>
public virtual decimal ThetaPerDay => Theta / 365m;
}
}

View File

@@ -13,146 +13,89 @@
* limitations under the License.
*/
using System;
namespace QuantConnect.Data.Market
{
/// <summary>
/// Defines the greeks
/// </summary>
public class Greeks : BaseGreeks
public abstract class Greeks
{
private Lazy<decimal> _delta;
private Lazy<decimal> _gamma;
private Lazy<decimal> _vega;
private Lazy<decimal> _theta;
private Lazy<decimal> _rho;
private Lazy<decimal> _lambda;
// _deltagamma stores gamma and delta combined and is done
// for optimization purposes (approximation of delta and gamma is very similar)
private Lazy<Tuple<decimal, decimal>> _deltaGamma;
/// <inheritdoc />
public override decimal Delta
{
get
{
return _delta != null ? _delta.Value : _deltaGamma.Value.Item1;
}
protected set
{
_delta = new Lazy<decimal>(() => value);
}
}
/// <inheritdoc />
public override decimal Gamma
{
get
{
return _gamma != null ? _gamma.Value : _deltaGamma.Value.Item2;
}
protected set
{
_gamma = new Lazy<decimal>(() => value);
}
}
/// <inheritdoc />
public override decimal Vega
{
get
{
return _vega.Value;
}
protected set
{
_vega = new Lazy<decimal>(() => value);
}
}
/// <inheritdoc />
public override decimal Theta
{
get
{
return _theta.Value;
}
protected set
{
_theta = new Lazy<decimal>(() => value);
}
}
/// <inheritdoc />
public override decimal Rho
{
get
{
return _rho.Value;
}
protected set
{
_rho = new Lazy<decimal>(() => value);
}
}
/// <inheritdoc />
public override decimal Lambda
{
get
{
return _lambda.Value;
}
protected set
{
_lambda = new Lazy<decimal>(() => value);
}
}
/// <summary>
/// Gets the delta.
/// <para>
/// Delta measures the rate of change of the option value with respect to changes in
/// the underlying asset'sprice. (∂V/∂S)
/// </para>
/// </summary>
public abstract decimal Delta { get; }
/// <summary>
/// Initializes a new default instance of the <see cref="Greeks"/> class
/// Gets the gamma.
/// <para>
/// Gamma measures the rate of change of Delta with respect to changes in
/// the underlying asset'sprice. (∂²V/∂S²)
/// </para>
/// </summary>
public Greeks()
: this(0m, 0m, 0m, 0m, 0m, 0m)
{
}
public abstract decimal Gamma { get; }
/// <summary>
/// Initializes a new instance of the <see cref="Greeks"/> class
/// Gets the vega.
/// <para>
/// Vega measures the rate of change of the option value with respect to changes in
/// the underlying's volatility. (∂V/∂σ)
/// </para>
/// </summary>
public Greeks(decimal delta, decimal gamma, decimal vega, decimal theta, decimal rho, decimal lambda)
{
Delta = delta;
Gamma = gamma;
Vega = vega;
Theta = theta;
Rho = rho;
Lambda = lambda;
}
public abstract decimal Vega { get; }
/// <summary>
/// Initializes a new instance of the <see cref="Greeks"/> class
/// Gets the theta.
/// <para>
/// Theta measures the rate of change of the option value with respect to changes in
/// time. This is commonly known as the 'time decay.' (∂V/∂τ)
/// </para>
/// </summary>
public Greeks(Func<decimal> delta, Func<decimal> gamma, Func<decimal> vega, Func<decimal> theta, Func<decimal> rho, Func<decimal> lambda)
{
_delta = new Lazy<decimal>(delta);
_gamma = new Lazy<decimal>(gamma);
_vega = new Lazy<decimal>(vega);
_theta = new Lazy<decimal>(theta);
_rho = new Lazy<decimal>(rho);
_lambda = new Lazy<decimal>(lambda);
}
public abstract decimal Theta { get; }
/// <summary>
/// Initializes a new instance of the <see cref="Greeks"/> class
/// Gets the rho.
/// <para>
/// Rho measures the rate of change of the option value with respect to changes in
/// the risk free interest rate. (∂V/∂r)
/// </para>
/// </summary>
public Greeks(Func<Tuple<decimal, decimal>> deltaGamma, Func<decimal> vega, Func<decimal> theta, Func<decimal> rho, Func<decimal> lambda)
{
_deltaGamma = new Lazy<Tuple<decimal, decimal>>(deltaGamma);
_vega = new Lazy<decimal>(vega);
_theta = new Lazy<decimal>(theta);
_rho = new Lazy<decimal>(rho);
_lambda = new Lazy<decimal>(lambda);
}
public abstract decimal Rho { get; }
/// <summary>
/// Gets the lambda.
/// <para>
/// Lambda is the percentage change in option value per percentage change in the
/// underlying's price, a measure of leverage. Sometimes referred to as gearing.
/// (∂V/∂S ✕ S/V)
/// </para>
/// </summary>
public abstract decimal Lambda { get; }
/// <summary>
/// Gets the lambda.
/// <para>
/// Lambda is the percentage change in option value per percentage change in the
/// underlying's price, a measure of leverage. Sometimes referred to as gearing.
/// (∂V/∂S ✕ S/V)
/// </para>
/// </summary>
/// <remarks>
/// Alias for <see cref="Lambda"/> required for compatibility with Python when
/// PEP8 API is used (lambda is a reserved keyword in Python).
/// </remarks>
public virtual decimal Lambda_ => Lambda;
/// <summary>
/// Gets the theta per day.
/// <para>
/// Theta measures the rate of change of the option value with respect to changes in
/// time. This is commonly known as the 'time decay.' (∂V/∂τ)
/// </para>
/// </summary>
public virtual decimal ThetaPerDay => Theta / 365m;
}
}

View File

@@ -0,0 +1,75 @@
/*
* 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;
namespace QuantConnect.Data.Market
{
/// <summary>
/// Defines the greeks
/// </summary>
public class ModeledGreeks : Greeks
{
private Lazy<decimal> _delta;
private Lazy<decimal> _gamma;
private Lazy<decimal> _vega;
private Lazy<decimal> _theta;
private Lazy<decimal> _rho;
private Lazy<decimal> _lambda;
/// <summary>
/// Gets the delta
/// </summary>
public override decimal Delta => _delta.Value;
/// <summary>
/// Gets the gamma
/// </summary>
public override decimal Gamma => _gamma.Value;
/// <summary>
/// Gets the vega
/// </summary>
public override decimal Vega => _vega.Value;
/// <summary>
/// Gets the theta
/// </summary>
public override decimal Theta => _theta.Value;
/// <summary>
/// Gets the rho
/// </summary>
public override decimal Rho => _rho.Value;
/// <summary>
/// Gets the lambda
/// </summary>
public override decimal Lambda => _lambda.Value;
/// <summary>
/// Initializes a new instance of the <see cref="ModeledGreeks"/> class
/// </summary>
public ModeledGreeks(Func<decimal> delta, Func<decimal> gamma, Func<decimal> vega, Func<decimal> theta, Func<decimal> rho, Func<decimal> lambda)
{
_delta = new Lazy<decimal>(delta, isThreadSafe: false);
_gamma = new Lazy<decimal>(gamma, isThreadSafe: false);
_vega = new Lazy<decimal>(vega, isThreadSafe: false);
_theta = new Lazy<decimal>(theta, isThreadSafe: false);
_rho = new Lazy<decimal>(rho, isThreadSafe: false);
_lambda = new Lazy<decimal>(lambda, isThreadSafe: false);
}
}
}

View File

@@ -0,0 +1,62 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace QuantConnect.Data.Market
{
/// <summary>
/// Defines greeks that are all zero
/// </summary>
internal class NullGreeks : Greeks
{
/// <summary>
/// Singleton instance of <see cref="NullGreeks"/>
/// </summary>
public static readonly NullGreeks Instance = new NullGreeks();
/// <summary>
/// Gets the delta
/// </summary>
public override decimal Delta => decimal.Zero;
/// <summary>
/// Gets the gamma
/// </summary>
public override decimal Gamma => decimal.Zero;
/// <summary>
/// Gets the vega
/// </summary>
public override decimal Vega => decimal.Zero;
/// <summary>
/// Gets the theta
/// </summary>
public override decimal Theta => decimal.Zero;
/// <summary>
/// Gets the rho
/// </summary>
public override decimal Rho => decimal.Zero;
/// <summary>
/// Gets the lambda
/// </summary>
public override decimal Lambda => decimal.Zero;
private NullGreeks()
{
}
}
}

View File

@@ -17,6 +17,10 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Python.Runtime;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Python;
using QuantConnect.Securities;
using QuantConnect.Securities.Option;
using QuantConnect.Util;
@@ -29,6 +33,7 @@ namespace QuantConnect.Data.Market
public class OptionChain : BaseData, IEnumerable<OptionContract>
{
private readonly Dictionary<Type, Dictionary<Symbol, List<BaseData>>> _auxiliaryData = new Dictionary<Type, Dictionary<Symbol, List<BaseData>>>();
private readonly Lazy<PyObject> _dataframe;
/// <summary>
/// Gets the most recent trade information for the underlying. This may
@@ -79,12 +84,18 @@ namespace QuantConnect.Data.Market
get; private set;
}
/// <summary>
/// The data frame representation of the option chain
/// </summary>
public PyObject DataFrame => _dataframe.Value;
/// <summary>
/// Initializes a new default instance of the <see cref="OptionChain"/> class
/// </summary>
private OptionChain()
{
DataType = MarketDataType.OptionChain;
_dataframe = new Lazy<PyObject>(() => new PandasConverter().GetDataFrame(this, symbolOnlyIndex: true), isThreadSafe: false);
}
/// <summary>
@@ -93,6 +104,7 @@ namespace QuantConnect.Data.Market
/// <param name="canonicalOptionSymbol">The symbol for this chain.</param>
/// <param name="time">The time of this chain</param>
public OptionChain(Symbol canonicalOptionSymbol, DateTime time)
: this()
{
Time = time;
Symbol = canonicalOptionSymbol;
@@ -116,6 +128,7 @@ namespace QuantConnect.Data.Market
/// <param name="contracts">All contracts for this option chain</param>
/// <param name="filteredContracts">The filtered list of contracts for this option chain</param>
public OptionChain(Symbol canonicalOptionSymbol, DateTime time, BaseData underlying, IEnumerable<BaseData> trades, IEnumerable<BaseData> quotes, IEnumerable<OptionContract> contracts, IEnumerable<Symbol> filteredContracts)
: this()
{
Time = time;
Underlying = underlying;
@@ -176,6 +189,32 @@ namespace QuantConnect.Data.Market
}
}
/// <summary>
/// Initializes a new option chain for a list of contracts as <see cref="OptionUniverse"/> instances
/// </summary>
/// <param name="canonicalOptionSymbol">The canonical option symbol</param>
/// <param name="time">The time of this chain</param>
/// <param name="contracts">The list of contracts data</param>
/// <param name="symbolProperties">The option symbol properties</param>
public OptionChain(Symbol canonicalOptionSymbol, DateTime time, IEnumerable<OptionUniverse> contracts, SymbolProperties symbolProperties)
: this(canonicalOptionSymbol, time)
{
Time = time;
Symbol = canonicalOptionSymbol;
DataType = MarketDataType.OptionChain;
Ticks = new Ticks(time);
TradeBars = new TradeBars(time);
QuoteBars = new QuoteBars(time);
Contracts = new OptionContracts(time);
foreach (var contractData in contracts)
{
Contracts[contractData.Symbol] = OptionContract.Create(contractData, symbolProperties);
Underlying ??= contractData.Underlying;
}
}
/// <summary>
/// Gets the auxiliary data with the specified type and symbol
/// </summary>
@@ -315,4 +354,4 @@ namespace QuantConnect.Data.Market
list.Add(baseData);
}
}
}
}

View File

@@ -1,4 +1,4 @@
/*
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
@@ -13,7 +13,11 @@
* limitations under the License.
*/
using Python.Runtime;
using QuantConnect.Python;
using System;
using System.Collections.Generic;
using System.Linq;
namespace QuantConnect.Data.Market
{
@@ -22,10 +26,15 @@ namespace QuantConnect.Data.Market
/// </summary>
public class OptionChains : DataDictionary<OptionChain>
{
private static readonly IEnumerable<string> _indexNames = new[] { "canonical", "symbol" };
private readonly Lazy<PyObject> _dataframe;
/// <summary>
/// Creates a new instance of the <see cref="OptionChains"/> dictionary
/// </summary>
public OptionChains()
: this(default)
{
}
@@ -35,8 +44,14 @@ namespace QuantConnect.Data.Market
public OptionChains(DateTime time)
: base(time)
{
_dataframe = new Lazy<PyObject>(InitializeDataFrame, isThreadSafe: false);
}
/// <summary>
/// The data frame representation of the option chains
/// </summary>
public PyObject DataFrame => _dataframe.Value;
/// <summary>
/// Gets or sets the OptionChain with the specified ticker.
/// </summary>
@@ -56,5 +71,13 @@ namespace QuantConnect.Data.Market
/// <param name="symbol">The Symbol of the element to get or set.</param>
/// <remarks>Wraps the base implementation to enable indexing in python algorithms due to pythonnet limitations</remarks>
public new OptionChain this[Symbol symbol] { get { return base[symbol]; } set { base[symbol] = value; } }
private PyObject InitializeDataFrame()
{
var dataFrames = this.Select(kvp => kvp.Value.DataFrame).ToList();
var canonicalSymbols = this.Select(kvp => kvp.Key);
return PandasConverter.ConcatDataFrames(dataFrames, keys: canonicalSymbols, names: _indexNames);
}
}
}
}

View File

@@ -13,6 +13,7 @@
* limitations under the License.
*/
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Interfaces;
using QuantConnect.Securities;
using QuantConnect.Securities.Option;
@@ -23,25 +24,28 @@ namespace QuantConnect.Data.Market
/// <summary>
/// Defines a single option contract at a specific expiration and strike price
/// </summary>
public class OptionContract
public class OptionContract : ISymbolProvider, ISymbol
{
private Lazy<OptionPriceModelResult> _optionPriceModelResult = new(() => OptionPriceModelResult.None);
private IOptionData _optionData = OptionPriceModelResultData.Null;
private readonly SymbolProperties _symbolProperties;
/// <summary>
/// Gets the option contract's symbol
/// </summary>
public Symbol Symbol
{
get; private set;
get; set;
}
/// <summary>
/// The security identifier of the option symbol
/// </summary>
public SecurityIdentifier ID => Symbol.ID;
/// <summary>
/// Gets the underlying security's symbol
/// </summary>
public Symbol UnderlyingSymbol
{
get; private set;
}
public Symbol UnderlyingSymbol => Symbol.Underlying;
/// <summary>
/// Gets the strike price
@@ -51,11 +55,7 @@ namespace QuantConnect.Data.Market
/// <summary>
/// Gets the strike price multiplied by the strike multiplier
/// </summary>
public decimal ScaledStrike
{
get;
private set;
}
public decimal ScaledStrike => Strike * _symbolProperties.StrikeMultiplier;
/// <summary>
/// Gets the expiration date
@@ -75,17 +75,17 @@ namespace QuantConnect.Data.Market
/// <summary>
/// Gets the theoretical price of this option contract as computed by the <see cref="IOptionPriceModel"/>
/// </summary>
public decimal TheoreticalPrice => _optionPriceModelResult.Value.TheoreticalPrice;
public decimal TheoreticalPrice => _optionData.TheoreticalPrice;
/// <summary>
/// Gets the implied volatility of the option contract as computed by the <see cref="IOptionPriceModel"/>
/// </summary>
public decimal ImpliedVolatility => _optionPriceModelResult.Value.ImpliedVolatility;
public decimal ImpliedVolatility => _optionData.ImpliedVolatility;
/// <summary>
/// Gets the greeks for this contract
/// </summary>
public Greeks Greeks => _optionPriceModelResult.Value.Greeks;
public Greeks Greeks => _optionData.Greeks;
/// <summary>
/// Gets the local date time this contract's data was last updated
@@ -98,77 +98,63 @@ namespace QuantConnect.Data.Market
/// <summary>
/// Gets the open interest
/// </summary>
public decimal OpenInterest
{
get; set;
}
public decimal OpenInterest => _optionData.OpenInterest;
/// <summary>
/// Gets the last price this contract traded at
/// </summary>
public decimal LastPrice
{
get; set;
}
public decimal LastPrice => _optionData.LastPrice;
/// <summary>
/// Gets the last volume this contract traded at
/// </summary>
public long Volume
{
get; set;
}
public long Volume => _optionData.Volume;
/// <summary>
/// Gets the current bid price
/// </summary>
public decimal BidPrice
{
get; set;
}
public decimal BidPrice => _optionData.BidPrice;
/// <summary>
/// Get the current bid size
/// </summary>
public long BidSize
{
get; set;
}
public long BidSize => _optionData.BidSize;
/// <summary>
/// Gets the ask price
/// </summary>
public decimal AskPrice
{
get; set;
}
public decimal AskPrice => _optionData.AskPrice;
/// <summary>
/// Gets the current ask size
/// </summary>
public long AskSize
{
get; set;
}
public long AskSize => _optionData.AskSize;
/// <summary>
/// Gets the last price the underlying security traded at
/// </summary>
public decimal UnderlyingLastPrice
{
get; set;
}
public decimal UnderlyingLastPrice => _optionData.UnderlyingLastPrice;
/// <summary>
/// Initializes a new instance of the <see cref="OptionContract"/> class
/// </summary>
/// <param name="security">The option contract security</param>
/// <param name="underlyingSymbol">The symbol of the underlying security</param>
public OptionContract(ISecurityPrice security, Symbol underlyingSymbol)
public OptionContract(ISecurityPrice security)
{
Symbol = security.Symbol;
UnderlyingSymbol = underlyingSymbol;
ScaledStrike = Strike * security.SymbolProperties.StrikeMultiplier;
_symbolProperties = security.SymbolProperties;
}
/// <summary>
/// Initializes a new option contract from a given <see cref="OptionUniverse"/> instance
/// </summary>
/// <param name="contractData">The option universe contract data to use as source for this contract</param>
/// <param name="symbolProperties">The contract symbol properties</param>
public OptionContract(OptionUniverse contractData, SymbolProperties symbolProperties)
{
Symbol = contractData.Symbol;
_symbolProperties = symbolProperties;
_optionData = new OptionUniverseData(contractData);
}
/// <summary>
@@ -177,7 +163,7 @@ namespace QuantConnect.Data.Market
/// <param name="optionPriceModelEvaluator">Function delegate used to evaluate the option price model</param>
internal void SetOptionPriceModel(Func<OptionPriceModelResult> optionPriceModelEvaluator)
{
_optionPriceModelResult = new Lazy<OptionPriceModelResult>(optionPriceModelEvaluator);
_optionData = new OptionPriceModelResultData(optionPriceModelEvaluator, _optionData as OptionPriceModelResultData);
}
/// <summary>
@@ -189,37 +175,209 @@ namespace QuantConnect.Data.Market
public override string ToString() => Symbol.Value;
/// <summary>
/// Creates a <see cref="OptionContract"/>
/// Creates a <see cref="OptionContract"/>
/// </summary>
/// <param name="baseData"></param>
/// <param name="security">provides price properties for a <see cref="Security"/></param>
/// <param name="underlyingLastPrice">last price the underlying security traded at</param>
/// <param name="security">Provides price properties for a <see cref="Security"/></param>
/// <param name="underlying">Last underlying security trade data</param>
/// <returns>Option contract</returns>
public static OptionContract Create(BaseData baseData, ISecurityPrice security, decimal underlyingLastPrice)
=> Create(baseData.Symbol.Underlying, baseData.EndTime, security, underlyingLastPrice);
public static OptionContract Create(BaseData baseData, ISecurityPrice security, BaseData underlying)
=> Create(baseData.EndTime, security, underlying);
/// <summary>
/// Creates a <see cref="OptionContract"/>
/// </summary>
/// <param name="underlyingSymbol">The symbol of the underlying security</param>
/// <param name="endTime">local date time this contract's data was last updated</param>
/// <param name="security">provides price properties for a <see cref="Security"/></param>
/// <param name="underlyingLastPrice">last price the underlying security traded at</param>
/// <param name="underlying">last underlying security trade data</param>
/// <returns>Option contract</returns>
public static OptionContract Create(Symbol underlyingSymbol, DateTime endTime, ISecurityPrice security, decimal underlyingLastPrice)
public static OptionContract Create(DateTime endTime, ISecurityPrice security, BaseData underlying)
{
return new OptionContract(security, underlyingSymbol)
var contract = new OptionContract(security)
{
Time = endTime,
LastPrice = security.Close,
Volume = (long)security.Volume,
BidPrice = security.BidPrice,
BidSize = (long)security.BidSize,
AskPrice = security.AskPrice,
AskSize = (long)security.AskSize,
OpenInterest = security.OpenInterest,
UnderlyingLastPrice = underlyingLastPrice
};
contract._optionData.SetUnderlying(underlying);
return contract;
}
/// <summary>
/// Creates a new option contract from a given <see cref="OptionUniverse"/> instance,
/// using its data to form a quote bar to source pricing data
/// </summary>
/// <param name="contractData">The option universe contract data to use as source for this contract</param>
/// <param name="symbolProperties">The contract symbol properties</param>
public static OptionContract Create(OptionUniverse contractData, SymbolProperties symbolProperties)
{
var contract = new OptionContract(contractData, symbolProperties)
{
Time = contractData.EndTime,
};
return contract;
}
/// <summary>
/// Implicit conversion into <see cref="Symbol"/>
/// </summary>
/// <param name="contract">The option contract to be converted</param>
public static implicit operator Symbol(OptionContract contract)
{
return contract.Symbol;
}
/// <summary>
/// Updates the option contract with the new data, which can be a <see cref="Tick"/> or <see cref="TradeBar"/> or <see cref="QuoteBar"/>
/// </summary>
internal void Update(BaseData data)
{
if (data.Symbol == Symbol)
{
_optionData.Update(data);
}
else if (data.Symbol == UnderlyingSymbol)
{
_optionData.SetUnderlying(data);
}
}
#region Option Contract Data Handlers
private interface IOptionData
{
decimal LastPrice { get; }
decimal UnderlyingLastPrice { get; }
long Volume { get; }
decimal BidPrice { get; }
long BidSize { get; }
decimal AskPrice { get; }
long AskSize { get; }
decimal OpenInterest { get; }
decimal TheoreticalPrice { get; }
decimal ImpliedVolatility { get; }
Greeks Greeks { get; }
void Update(BaseData data);
void SetUnderlying(BaseData data);
}
/// <summary>
/// Handles option data for a contract from actual price data (trade, quote, open interest) and theoretical price model results
/// </summary>
private class OptionPriceModelResultData : IOptionData
{
public static readonly OptionPriceModelResultData Null = new(() => OptionPriceModelResult.None);
private readonly Lazy<OptionPriceModelResult> _optionPriceModelResult;
private TradeBar _tradeBar;
private QuoteBar _quoteBar;
private OpenInterest _openInterest;
private BaseData _underlying;
public decimal LastPrice => _tradeBar?.Close ?? decimal.Zero;
public decimal UnderlyingLastPrice => _underlying?.Price ?? decimal.Zero;
public long Volume => (long)(_tradeBar?.Volume ?? 0L);
public decimal BidPrice => _quoteBar?.Bid?.Close ?? decimal.Zero;
public long BidSize => (long)(_quoteBar?.LastBidSize ?? 0L);
public decimal AskPrice => _quoteBar?.Ask?.Close ?? decimal.Zero;
public long AskSize => (long)(_quoteBar?.LastAskSize ?? 0L);
public decimal OpenInterest => _openInterest?.Value ?? decimal.Zero;
public decimal TheoreticalPrice => _optionPriceModelResult.Value.TheoreticalPrice;
public decimal ImpliedVolatility => _optionPriceModelResult.Value.ImpliedVolatility;
public Greeks Greeks => _optionPriceModelResult.Value.Greeks;
public OptionPriceModelResultData(Func<OptionPriceModelResult> optionPriceModelEvaluator,
OptionPriceModelResultData previousOptionData = null)
{
_optionPriceModelResult = new(optionPriceModelEvaluator, isThreadSafe: false);
if (previousOptionData != null)
{
_tradeBar = previousOptionData._tradeBar;
_quoteBar = previousOptionData._quoteBar;
_openInterest = previousOptionData._openInterest;
_underlying = previousOptionData._underlying;
}
}
public void Update(BaseData data)
{
switch (data)
{
case TradeBar tradeBar:
_tradeBar = tradeBar;
break;
case QuoteBar quoteBar:
_quoteBar = quoteBar;
break;
case OpenInterest openInterest:
_openInterest = openInterest;
break;
}
}
public void SetUnderlying(BaseData data)
{
_underlying = data;
}
}
/// <summary>
/// Handles option data for a contract from a <see cref="OptionUniverse"/> instance
/// </summary>
private class OptionUniverseData : IOptionData
{
private readonly OptionUniverse _contractData;
public decimal LastPrice => _contractData.Close;
// TODO: Null check required for FOPs: since OptionUniverse does not support FOPs,
// these instances will by "synthetic" and will not have underlying data.
// Can be removed after FOPs are supported by OptionUniverse
public decimal UnderlyingLastPrice => _contractData?.Underlying?.Price ?? decimal.Zero;
public long Volume => (long)_contractData.Volume;
public decimal BidPrice => _contractData.Close;
public long BidSize => 0;
public decimal AskPrice => _contractData.Close;
public long AskSize => 0;
public decimal OpenInterest => _contractData.OpenInterest;
public decimal TheoreticalPrice => decimal.Zero;
public decimal ImpliedVolatility => _contractData.ImpliedVolatility;
public Greeks Greeks => _contractData.Greeks;
public OptionUniverseData(OptionUniverse contractData)
{
_contractData = contractData;
}
public void Update(BaseData data)
{
}
public void SetUnderlying(BaseData data)
{
}
}
#endregion
}
}

View File

@@ -231,6 +231,21 @@ namespace QuantConnect.Data.Market
AskPrice = ask;
}
/// <summary>
/// Initializes a new instance of the <see cref="Tick"/> class to <see cref="TickType.OpenInterest"/>.
/// </summary>
/// <param name="time">The time at which the open interest tick occurred.</param>
/// <param name="symbol">The symbol associated with the open interest tick.</param>
/// <param name="openInterest">The value of the open interest for the specified symbol.</param>
public Tick(DateTime time, Symbol symbol, decimal openInterest)
{
Time = time;
Symbol = symbol;
Value = openInterest;
DataType = MarketDataType.Tick;
TickType = TickType.OpenInterest;
}
/// <summary>
/// Initializer for a last-trade equity tick with bid or ask prices.
/// </summary>

View File

@@ -125,7 +125,7 @@ namespace QuantConnect.Data.UniverseSelection
/// <summary>
/// Greeks values of the option
/// </summary>
public BaseGreeks Greeks
public Greeks Greeks
{
get
{
@@ -290,7 +290,7 @@ namespace QuantConnect.Data.UniverseSelection
/// Gets the CSV string representation of this universe entry
/// </summary>
public static string ToCsv(Symbol symbol, decimal open, decimal high, decimal low, decimal close, decimal volume, decimal? openInterest,
decimal? impliedVolatility, BaseGreeks greeks)
decimal? impliedVolatility, Greeks greeks)
{
return $"{symbol.ID},{symbol.Value},{open},{high},{low},{close},{volume},"
+ $"{openInterest},{impliedVolatility},{greeks?.Delta},{greeks?.Gamma},{greeks?.Vega},{greeks?.Theta},{greeks?.Rho}";
@@ -331,51 +331,21 @@ namespace QuantConnect.Data.UniverseSelection
/// Pre-calculated greeks lazily parsed from csv line.
/// It parses the greeks values from the csv line only when they are requested to avoid holding decimals in memory.
/// </summary>
private class PreCalculatedGreeks : BaseGreeks
private class PreCalculatedGreeks : Greeks
{
private readonly string _csvLine;
/// <inheritdoc />
public override decimal Delta
{
get => _csvLine.GetDecimalFromCsv(StartingGreeksCsvIndex);
protected set => throw new InvalidOperationException("Delta is read-only.");
}
public override decimal Delta => _csvLine.GetDecimalFromCsv(StartingGreeksCsvIndex);
/// <inheritdoc />
public override decimal Gamma
{
get => _csvLine.GetDecimalFromCsv(StartingGreeksCsvIndex + 1);
protected set => throw new InvalidOperationException("Gamma is read-only.");
}
public override decimal Gamma => _csvLine.GetDecimalFromCsv(StartingGreeksCsvIndex + 1);
/// <inheritdoc />
public override decimal Vega
{
get => _csvLine.GetDecimalFromCsv(StartingGreeksCsvIndex + 2);
protected set => throw new InvalidOperationException("Vega is read-only.");
}
public override decimal Vega => _csvLine.GetDecimalFromCsv(StartingGreeksCsvIndex + 2);
/// <inheritdoc />
public override decimal Theta
{
get => _csvLine.GetDecimalFromCsv(StartingGreeksCsvIndex + 3);
protected set => throw new InvalidOperationException("Theta is read-only.");
}
public override decimal Theta => _csvLine.GetDecimalFromCsv(StartingGreeksCsvIndex + 3);
/// <inheritdoc />
public override decimal Rho
{
get => _csvLine.GetDecimalFromCsv(StartingGreeksCsvIndex + 4);
protected set => throw new InvalidOperationException("Rho is read-only.");
}
public override decimal Rho => _csvLine.GetDecimalFromCsv(StartingGreeksCsvIndex + 4);
/// <inheritdoc />
public override decimal Lambda
{
get => decimal.Zero;
protected set => throw new InvalidOperationException("Lambda is read-only.");
}
public override decimal Lambda => decimal.Zero;
/// <summary>
/// Initializes a new default instance of the <see cref="PreCalculatedGreeks"/> class
@@ -384,6 +354,14 @@ namespace QuantConnect.Data.UniverseSelection
{
_csvLine = csvLine;
}
/// <summary>
/// Gets a string representation of the greeks values
/// </summary>
public override string ToString()
{
return $"D: {Delta}, G: {Gamma}, V: {Vega}, T: {Theta}, R: {Rho}";
}
}
}
}

View File

@@ -30,17 +30,24 @@ namespace QuantConnect.Interfaces
/// <summary>
/// Whether the data was fetched successfully
/// </summary>
public bool Succeded { get; }
public bool Succeeded { get; }
/// <summary>
/// Any error message that occurred during the fetch
/// </summary>
public string ErrorMessage { get; }
/// <summary>
/// Initializes a new instance of the <see cref="DataProviderNewDataRequestEventArgs"/> class
/// </summary>
/// <param name="path">The path to the fetched data</param>
/// <param name="succeded">Whether the data was fetched successfully</param>
public DataProviderNewDataRequestEventArgs(string path, bool succeded)
/// <param name="succeeded">Whether the data was fetched successfully</param>
/// <param name="errorMessage">Any error message that occured during the fetch</param>
public DataProviderNewDataRequestEventArgs(string path, bool succeeded, string errorMessage)
{
Path = path;
Succeded = succeded;
Succeeded = succeeded;
ErrorMessage = errorMessage;
}
}
}

View File

@@ -32,6 +32,7 @@ using QuantConnect.Securities.Option;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Algorithm.Framework.Alphas;
using QuantConnect.Algorithm.Framework.Alphas.Analysis;
using QuantConnect.Commands;
namespace QuantConnect.Interfaces
{
@@ -608,6 +609,13 @@ namespace QuantConnect.Interfaces
/// <param name="newEvent">Event information</param>
void OnOrderEvent(OrderEvent newEvent);
/// <summary>
/// Generic untyped command call handler
/// </summary>
/// <param name="data">The associated data</param>
/// <returns>True if success, false otherwise. Returning null will disable command feedback</returns>
bool? OnCommand(dynamic data);
/// <summary>
/// Will submit an order request to the algorithm
/// </summary>
@@ -919,5 +927,12 @@ namespace QuantConnect.Interfaces
/// </summary>
/// <param name="tags">The tags</param>
void SetTags(HashSet<string> tags);
/// <summary>
/// Run a callback command instance
/// </summary>
/// <param name="command">The callback command instance</param>
/// <returns>The command result</returns>
CommandResultPacket RunCommand(CallbackCommand command);
}
}

View File

@@ -18,7 +18,6 @@ using System.Threading;
using System.Threading.Tasks;
using QuantConnect.Logging;
using QuantConnect.Util;
using static QuantConnect.StringExtensions;
namespace QuantConnect
{
@@ -36,22 +35,6 @@ namespace QuantConnect
get; private set;
}
/// <summary>
/// Algo cancellation controls - cancellation token for algorithm thread.
/// </summary>
public CancellationToken CancellationToken
{
get { return CancellationTokenSource.Token; }
}
/// <summary>
/// Check if this task isolator is cancelled, and exit the analysis
/// </summary>
public bool IsCancellationRequested
{
get { return CancellationTokenSource.IsCancellationRequested; }
}
/// <summary>
/// Initializes a new instance of the <see cref="Isolator"/> class
/// </summary>
@@ -117,7 +100,7 @@ namespace QuantConnect
memoryCap *= 1024 * 1024;
var spikeLimit = memoryCap*2;
while (!task.IsCompleted && utcNow < end)
while (!task.IsCompleted && !CancellationTokenSource.IsCancellationRequested && utcNow < end)
{
// if over 80% allocation force GC then sample
var sample = Convert.ToDouble(GC.GetTotalMemory(memoryUsed > memoryCap * 0.8));
@@ -166,15 +149,26 @@ namespace QuantConnect
utcNow = DateTime.UtcNow;
}
if (task.IsCompleted == false && string.IsNullOrEmpty(message))
if (task.IsCompleted == false)
{
message = Messages.Isolator.MemoryUsageMonitorTaskTimedOut(timeSpan);
Log.Trace($"Isolator.ExecuteWithTimeLimit(): {message}");
if (CancellationTokenSource.IsCancellationRequested)
{
Log.Trace($"Isolator.ExecuteWithTimeLimit(): Operation was canceled");
throw new OperationCanceledException("Operation was canceled");
}
else if (string.IsNullOrEmpty(message))
{
message = Messages.Isolator.MemoryUsageMonitorTaskTimedOut(timeSpan);
Log.Trace($"Isolator.ExecuteWithTimeLimit(): {message}");
}
}
if (!string.IsNullOrEmpty(message))
{
CancellationTokenSource.Cancel();
if (!CancellationTokenSource.IsCancellationRequested)
{
CancellationTokenSource.Cancel();
}
Log.Error($"Security.ExecuteWithTimeLimit(): {message}");
throw new TimeoutException(message);
}

View File

@@ -30,15 +30,13 @@ def mapper(key):
Symbol SecurityIdentifier.If cannot map, returns the object
'''
keyType = type(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)
return kvp[1]
if keyType is list:
return [mapper(x) for x in key]
if keyType is tuple:
@@ -49,7 +47,7 @@ def mapper(key):
def wrap_keyerror_function(f):
'''Wraps function f with wrapped_function, used for functions that throw KeyError when not found.
wrapped_function converts the args / kwargs to use alternative index keys and then calls the function.
wrapped_function converts the args / kwargs to use alternative index keys and then calls the function.
If this fails we fall back to the original key and try it as well, if they both fail we throw our error.
'''
def wrapped_function(*args, **kwargs):
@@ -65,14 +63,14 @@ def wrap_keyerror_function(f):
return f(*newargs, **newkwargs)
except KeyError as e:
mKey = [arg for arg in newargs if isinstance(arg, str)]
mKey = [str(arg) for arg in newargs if isinstance(arg, str) or isinstance(arg, Symbol)]
# Execute original
# Allows for df, Series, etc indexing for keys like 'SPY' if they exist
try:
return f(*args, **kwargs)
except KeyError as e:
oKey = [arg for arg in args if isinstance(arg, str)]
oKey = [str(arg) for arg in args if isinstance(arg, str) or isinstance(arg, Symbol)]
raise KeyError(f"No key found for either mapped or original key. Mapped Key: {mKey}; Original Key: {oKey}")
wrapped_function.__name__ = f.__name__
@@ -111,7 +109,7 @@ pd.core.indexing._ScalarAccessIndexer.__getitem__ = wrap_keyerror_function(pd.co
pd.core.indexes.base.Index.get_loc = wrap_keyerror_function(pd.core.indexes.base.Index.get_loc)
# Wrap our DF _getitem__ as well, even though most pathways go through the above functions
# There are cases like indexing with an array that need to be mapped earlier to stop KeyError from arising
# There are cases like indexing with an array that need to be mapped earlier to stop KeyError from arising
pd.core.frame.DataFrame.__getitem__ = wrap_keyerror_function(pd.core.frame.DataFrame.__getitem__)
# For older version of pandas we may need to wrap extra functions
@@ -119,7 +117,7 @@ if (int(pd.__version__.split('.')[0]) < 1):
pd.core.indexes.base.Index.get_value = wrap_keyerror_function(pd.core.indexes.base.Index.get_value)
# Special cases where we need to wrap a function that won't throw a keyerror when not found but instead returns true or false
# Wrap __contains__ to support Python syntax like 'SPY' in DataFrame
# Wrap __contains__ to support Python syntax like 'SPY' in DataFrame
pd.core.indexes.base.Index.__contains__ = wrap_bool_function(pd.core.indexes.base.Index.__contains__)
# For compatibility with PandasData.cs usage of this module (Previously wrapped classes)

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 Python.Runtime;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using QuantConnect.Commands;
using QuantConnect.Interfaces;
using System.Collections.Generic;
namespace QuantConnect.Python
{
/// <summary>
/// Python wrapper for a python defined command type
/// </summary>
public class CommandPythonWrapper : BasePythonWrapper<Command>
{
/// <summary>
/// Constructor for initialising the <see cref="CommandPythonWrapper"/> class with wrapped <see cref="PyObject"/> object
/// </summary>
/// <param name="type">Python command type</param>
/// <param name="data">Command data</param>
public CommandPythonWrapper(PyObject type, string data = null)
: base()
{
using var _ = Py.GIL();
var instance = type.Invoke();
SetPythonInstance(instance);
if (data != null)
{
foreach (var kvp in JsonConvert.DeserializeObject<Dictionary<string, object>>(data))
{
if (kvp.Value is JArray jArray)
{
SetProperty(kvp.Key, jArray.ToObject<List<object>>());
}
else if (kvp.Value is JObject jobject)
{
SetProperty(kvp.Key, jobject.ToObject<Dictionary<string, object>>());
}
else
{
SetProperty(kvp.Key, kvp.Value);
}
}
}
}
/// <summary>
/// Run this command using the target algorithm
/// </summary>
/// <param name="algorithm">The algorithm instance</param>
/// <returns>True if success, false otherwise. Returning null will disable command feedback</returns>
public bool? Run(IAlgorithm algorithm)
{
var result = InvokeMethod(nameof(Run), algorithm);
return result.GetAndDispose<bool?>();
}
}
}

View File

@@ -70,54 +70,34 @@ namespace QuantConnect.Python
AddSliceDataTypeDataToDict(slice, requestedTick, requestedTradeBar, requestedQuoteBar, sliceDataDict, ref maxLevels, dataType);
}
using (Py.GIL())
{
if (sliceDataDict.Count == 0)
{
return _pandas.DataFrame();
}
using var dataFrames = sliceDataDict.Select(x => x.Value.ToPandasDataFrame(maxLevels)).ToPyListUnSafe();
using var sortDic = Py.kw("sort", true);
var result = _concat.Invoke(new[] { dataFrames }, sortDic);
foreach (var df in dataFrames)
{
df.Dispose();
}
return result;
}
return CreateDataFrame(sliceDataDict, maxLevels);
}
/// <summary>
/// Converts an enumerable of <see cref="IBaseData"/> in a pandas.DataFrame
/// </summary>
/// <param name="data">Enumerable of <see cref="Slice"/></param>
/// <param name="symbolOnlyIndex">Whether to make the index only the symbol, without time or any other index levels</param>
/// <returns><see cref="PyObject"/> containing a pandas.DataFrame</returns>
/// <remarks>Helper method for testing</remarks>
public PyObject GetDataFrame<T>(IEnumerable<T> data)
where T : IBaseData
public PyObject GetDataFrame<T>(IEnumerable<T> data, bool symbolOnlyIndex = false)
where T : ISymbolProvider
{
PandasData sliceData = null;
var pandasDataBySymbol = new Dictionary<SecurityIdentifier, PandasData>();
var maxLevels = 0;
foreach (var datum in data)
{
if (sliceData == null)
{
sliceData = new PandasData(datum);
}
sliceData.Add(datum);
var pandasData = GetPandasDataValue(pandasDataBySymbol, datum.Symbol, datum, ref maxLevels);
pandasData.Add(datum);
}
using (Py.GIL())
{
// If sliceData is still null, data is an empty enumerable
// returns an empty pandas.DataFrame
if (sliceData == null)
{
return _pandas.DataFrame();
}
return sliceData.ToPandasDataFrame();
}
return CreateDataFrame(pandasDataBySymbol,
// Use 2 instead of maxLevels for backwards compatibility
maxLevels: symbolOnlyIndex ? 1 : 2,
sort: false,
// Multiple data frames (one for each symbol) will be concatenated,
// so make sure rows with missing values only are not filtered out before concatenation
filterMissingValueColumns: pandasDataBySymbol.Count <= 1);
}
/// <summary>
@@ -187,9 +167,92 @@ namespace QuantConnect.Python
/// <returns></returns>
public override string ToString()
{
return _pandas == null
? Messages.PandasConverter.PandasModuleNotImported
: _pandas.Repr();
if (_pandas == null)
{
return Messages.PandasConverter.PandasModuleNotImported;
}
using (Py.GIL())
{
return _pandas.Repr();
}
}
/// <summary>
/// Create a data frame by concatenated the resulting data frames from the given data
/// </summary>
private static PyObject CreateDataFrame(Dictionary<SecurityIdentifier, PandasData> dataBySymbol, int maxLevels = 2, bool sort = true,
bool filterMissingValueColumns = true)
{
using (Py.GIL())
{
if (dataBySymbol.Count == 0)
{
return _pandas.DataFrame();
}
var dataFrames = dataBySymbol.Select(x => x.Value.ToPandasDataFrame(maxLevels, filterMissingValueColumns));
var result = ConcatDataFrames(dataFrames, sort: sort, dropna: true);
foreach (var df in dataFrames)
{
df.Dispose();
}
return result;
}
}
/// <summary>
/// Concatenates multiple data frames
/// </summary>
/// <param name="dataFrames">The data frames to concatenate</param>
/// <param name="keys">
/// Optional new keys for a new multi-index level that would be added
/// to index each individual data frame in the resulting one
/// </param>
/// <param name="names">The optional names of the new index level (and the existing ones if they need to be changed)</param>
/// <param name="sort">Whether to sort the resulting data frame</param>
/// <param name="dropna">Whether to drop columns containing NA values only (Nan, None, etc)</param>
/// <returns>A new data frame result from concatenating the input</returns>
public static PyObject ConcatDataFrames(IEnumerable<PyObject> dataFrames, IEnumerable<object> keys = null, IEnumerable<string> names = null,
bool sort = true, bool dropna = true)
{
var dataFramesList = dataFrames.ToList();
if (dataFramesList.Count == 0)
{
return _pandas.DataFrame();
}
using (Py.GIL())
{
using var pyDataFrames = dataFramesList.ToPyListUnSafe();
using var kwargs = Py.kw("sort", sort);
PyList pyKeys = null;
PyList pyNames = null;
if (keys != null && names != null)
{
pyKeys = keys.ToPyListUnSafe();
pyNames = names.ToPyListUnSafe();
kwargs.SetItem("keys", pyKeys);
kwargs.SetItem("names", pyNames);
}
var result = _concat.Invoke(new[] { pyDataFrames }, kwargs);
// Drop columns with only NaN or None values
if (dropna)
{
using var dropnaKwargs = Py.kw("axis", 1, "inplace", true, "how", "all");
result.GetAttr("dropna").Invoke(Array.Empty<PyObject>(), dropnaKwargs);
}
pyKeys?.Dispose();
pyNames?.Dispose();
return result;
}
}
/// <summary>

View File

@@ -25,7 +25,6 @@ using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using QuantConnect.Util;
namespace QuantConnect.Python
{
@@ -60,6 +59,34 @@ namespace QuantConnect.Python
private const string Suspicious = "suspicious";
private const string OpenInterest = "openinterest";
#region OptionContract Members Handling
// TODO: In the future, excluding, adding, renaming and unwrapping members (like the Greeks case)
// should be handled generically: we could define attributes so that class members can be marked as
// excluded, or to be renamed and/ or unwrapped (much like how Json attributes work)
private static readonly string[] _optionContractExcludedMembers = new[]
{
nameof(OptionContract.ID),
};
private static readonly string[] _greeksMemberNames = new[]
{
nameof(Greeks.Delta).ToLowerInvariant(),
nameof(Greeks.Gamma).ToLowerInvariant(),
nameof(Greeks.Vega).ToLowerInvariant(),
nameof(Greeks.Theta).ToLowerInvariant(),
nameof(Greeks.Rho).ToLowerInvariant(),
};
private static readonly MemberInfo[] _greeksMembers = typeof(Greeks)
.GetMembers(BindingFlags.Instance | BindingFlags.Public)
.Where(x => (x.MemberType == MemberTypes.Field || x.MemberType == MemberTypes.Property) &&
_greeksMemberNames.Contains(x.Name.ToLowerInvariant()))
.ToArray();
#endregion
// we keep these so we don't need to ask for them each time
private static PyString _empty;
private static PyObject _pandas;
@@ -68,12 +95,13 @@ namespace QuantConnect.Python
private static PyObject _multiIndexFactory;
private static PyList _defaultNames;
private static PyList _level1Names;
private static PyList _level2Names;
private static PyList _level3Names;
private readonly static HashSet<string> _baseDataProperties = typeof(BaseData).GetProperties().ToHashSet(x => x.Name.ToLowerInvariant());
private readonly static ConcurrentDictionary<Type, IEnumerable<MemberInfo>> _membersByType = new ();
private readonly static IReadOnlyList<string> _standardColumns = new string []
private readonly static ConcurrentDictionary<Type, IEnumerable<DataTypeMember>> _membersByType = new();
private readonly static IReadOnlyList<string> _standardColumns = new string[]
{
Open, High, Low, Close, LastPrice, Volume,
AskOpen, AskHigh, AskLow, AskClose, AskPrice, AskSize, Quantity, Suspicious,
@@ -82,9 +110,10 @@ namespace QuantConnect.Python
private readonly Symbol _symbol;
private readonly bool _isFundamentalType;
private readonly bool _isBaseData;
private readonly Dictionary<string, Serie> _series;
private readonly IEnumerable<MemberInfo> _members = Enumerable.Empty<MemberInfo>();
private readonly IEnumerable<DataTypeMember> _members = Enumerable.Empty<DataTypeMember>();
/// <summary>
/// Gets true if this is a custom data request, false for normal QC data
@@ -117,33 +146,48 @@ namespace QuantConnect.Python
var symbol = new PyString("symbol");
var expiry = new PyString("expiry");
_defaultNames = new PyList(new PyObject[] { expiry, new PyString("strike"), new PyString("type"), symbol, time });
_level1Names = new PyList(new PyObject[] { symbol });
_level2Names = new PyList(new PyObject[] { symbol, time });
_level3Names = new PyList(new PyObject[] { expiry, symbol, time });
}
}
var baseData = data as IBaseData;
// in the case we get a list/collection of data we take the first data point to determine the type
// but it's also possible to get a data which supports enumerating we don't care about those cases
if (data is not IBaseData && data is IEnumerable enumerable)
if (baseData == null && data is IEnumerable enumerable)
{
foreach (var item in enumerable)
{
data = item;
baseData = data as IBaseData;
break;
}
}
var type = data.GetType();
_isFundamentalType = type == typeof(Fundamental);
_symbol = ((IBaseData)data).Symbol;
_isBaseData = baseData != null;
_symbol = _isBaseData ? baseData.Symbol : ((ISymbolProvider)data).Symbol;
IsCustomData = Extensions.IsCustomDataType(_symbol, type);
if (_symbol.SecurityType == SecurityType.Future) Levels = 3;
if (_symbol.SecurityType.IsOption()) Levels = 5;
if (baseData == null)
{
Levels = 1;
}
else if (_symbol.SecurityType == SecurityType.Future)
{
Levels = 3;
}
else if (_symbol.SecurityType.IsOption())
{
Levels = 5;
}
IEnumerable<string> columns = _standardColumns;
if (IsCustomData || ((IBaseData)data).DataType == MarketDataType.Auxiliary)
if (IsCustomData || !_isBaseData || baseData.DataType == MarketDataType.Auxiliary)
{
var keys = (data as DynamicData)?.GetStorageDictionary()
// if this is a PythonData instance we add in '__typename' which we don't want into the data frame
@@ -154,33 +198,51 @@ namespace QuantConnect.Python
{
if (_membersByType.TryGetValue(type, out _members))
{
keys = _members.ToHashSet(x => x.Name.ToLowerInvariant());
keys = _members.SelectMany(x => x.GetMemberNames()).ToHashSet();
}
else
{
var members = type.GetMembers().Where(x => x.MemberType == MemberTypes.Field || x.MemberType == MemberTypes.Property).ToList();
var members = type
.GetMembers(BindingFlags.Instance | BindingFlags.Public)
.Where(x => x.MemberType == MemberTypes.Field || x.MemberType == MemberTypes.Property);
var duplicateKeys = members.GroupBy(x => x.Name.ToLowerInvariant()).Where(x => x.Count() > 1).Select(x => x.Key);
// TODO: Avoid hard-coded especial cases by using something like attributes to change
// pandas conversion behavior
if (type.IsAssignableTo(typeof(OptionContract)))
{
members = members.Where(x => !_optionContractExcludedMembers.Contains(x.Name));
}
var dataTypeMembers = members.Select(x =>
{
if (!DataTypeMember.GetMemberType(x).IsAssignableTo(typeof(Greeks)))
{
return new DataTypeMember(x);
}
return new DataTypeMember(x, _greeksMembers);
}).ToList();
var duplicateKeys = dataTypeMembers.GroupBy(x => x.Member.Name.ToLowerInvariant()).Where(x => x.Count() > 1).Select(x => x.Key);
foreach (var duplicateKey in duplicateKeys)
{
throw new ArgumentException($"PandasData.ctor(): {Messages.PandasData.DuplicateKey(duplicateKey, type.FullName)}");
}
// If the custom data derives from a Market Data (e.g. Tick, TradeBar, QuoteBar), exclude its keys
keys = members.ToHashSet(x => x.Name.ToLowerInvariant());
keys = dataTypeMembers.SelectMany(x => x.GetMemberNames()).ToHashSet();
keys.ExceptWith(_baseDataProperties);
keys.ExceptWith(GetPropertiesNames(typeof(QuoteBar), type));
keys.ExceptWith(GetPropertiesNames(typeof(TradeBar), type));
keys.ExceptWith(GetPropertiesNames(typeof(Tick), type));
keys.Add("value");
_members = members.Where(x => keys.Contains(x.Name.ToLowerInvariant())).ToList();
_members = dataTypeMembers.Where(x => x.GetMemberNames().All(name => keys.Contains(name))).ToList();
_membersByType.TryAdd(type, _members);
}
}
var customColumns = new HashSet<string>(columns);
customColumns.Add("value");
var customColumns = new HashSet<string>(columns) { "value" };
customColumns.UnionWith(keys);
columns = customColumns;
@@ -195,36 +257,31 @@ namespace QuantConnect.Python
/// <param name="baseData"><see cref="IBaseData"/> object that contains security data</param>
public void Add(object baseData)
{
var endTime = ((IBaseData)baseData).EndTime;
var endTime = _isBaseData ? ((IBaseData)baseData).EndTime : default;
foreach (var member in _members)
{
// TODO field/property.GetValue is expensive
var key = member.Name.ToLowerInvariant();
var propertyMember = member as PropertyInfo;
if (propertyMember != null)
if (!member.ShouldBeUnwrapped)
{
var propertyValue = propertyMember.GetValue(baseData);
if (_isFundamentalType && propertyMember.PropertyType.IsAssignableTo(typeof(FundamentalTimeDependentProperty)))
{
propertyValue = ((FundamentalTimeDependentProperty)propertyValue).Clone(new FixedTimeProvider(endTime));
}
AddToSeries(key, endTime, propertyValue);
continue;
AddMemberToSeries(baseData, endTime, member.Member);
}
else
{
var fieldMember = member as FieldInfo;
if (fieldMember != null)
var memberValue = member.GetMemberValue(baseData);
if (memberValue != null)
{
AddToSeries(key, endTime, fieldMember.GetValue(baseData));
foreach (var childMember in member.Children)
{
AddMemberToSeries(memberValue, endTime, childMember);
}
}
}
}
var storage = (baseData as DynamicData)?.GetStorageDictionary();
var dynamicData = baseData as DynamicData;
var storage = dynamicData?.GetStorageDictionary();
if (storage != null)
{
var value = ((IBaseData) baseData).Value;
var value = dynamicData.Value;
AddToSeries("value", endTime, value);
foreach (var kvp in storage.Where(x => x.Key != "value"
@@ -234,19 +291,36 @@ namespace QuantConnect.Python
AddToSeries(kvp.Key, endTime, kvp.Value);
}
}
else
else if (baseData is Tick tick)
{
var tick = baseData as Tick;
if (tick != null)
AddTick(tick);
}
else if (baseData is TradeBar tradeBar)
{
Add(tradeBar, null);
}
else if (baseData is QuoteBar quoteBar)
{
Add(null, quoteBar);
}
}
private void AddMemberToSeries(object baseData, DateTime endTime, MemberInfo member)
{
// TODO field/property.GetValue is expensive
var key = member.Name.ToLowerInvariant();
if (member is PropertyInfo property)
{
var propertyValue = property.GetValue(baseData);
if (_isFundamentalType && property.PropertyType.IsAssignableTo(typeof(FundamentalTimeDependentProperty)))
{
AddTick(tick);
}
else
{
var tradeBar = baseData as TradeBar;
var quoteBar = baseData as QuoteBar;
Add(tradeBar, quoteBar);
propertyValue = ((FundamentalTimeDependentProperty)propertyValue).Clone(new FixedTimeProvider(endTime));
}
AddToSeries(key, endTime, propertyValue);
}
else if (member is FieldInfo field)
{
AddToSeries(key, endTime, field.GetValue(baseData));
}
}
@@ -301,6 +375,11 @@ namespace QuantConnect.Python
/// <param name="tick"><see cref="Tick"/> object that contains tick information of the security</param>
public void AddTick(Tick tick)
{
if (tick == null)
{
return;
}
var time = tick.EndTime;
// We will fill some series with null for tick types that don't have a value for that series, so that we make sure
@@ -342,15 +421,22 @@ namespace QuantConnect.Python
/// Get the pandas.DataFrame of the current <see cref="PandasData"/> state
/// </summary>
/// <param name="levels">Number of levels of the multi index</param>
/// <param name="filterMissingValueColumns">If false, make sure columns with "missing" values only are still added to the dataframe</param>
/// <returns>pandas.DataFrame object</returns>
public PyObject ToPandasDataFrame(int levels = 2)
public PyObject ToPandasDataFrame(int levels = 2, bool filterMissingValueColumns = true)
{
List<PyObject> list;
var symbol = _symbol.ID.ToString().ToPython();
var symbol = _symbol.ToPython();
// Create the index labels
var names = _defaultNames;
if (levels == 2)
if (levels == 1)
{
names = _level1Names;
list = new List<PyObject> { symbol };
}
else if (levels == 2)
{
// symbol, time
names = _level2Names;
@@ -383,7 +469,7 @@ namespace QuantConnect.Python
using var pyDict = new PyDict();
foreach (var kvp in _series)
{
if (kvp.Value.ShouldFilter) continue;
if (filterMissingValueColumns && kvp.Value.ShouldFilter) continue;
if (!indexCache.TryGetValue(kvp.Value.Times, out var index))
{
@@ -446,8 +532,11 @@ namespace QuantConnect.Python
/// </summary>
private static PyTuple CreateTupleIndex(DateTime index, List<PyObject> list)
{
DisposeIfNotEmpty(list[list.Count - 1]);
list[list.Count - 1] = index.ToPython();
if (list.Count > 1)
{
DisposeIfNotEmpty(list[list.Count - 1]);
list[list.Count - 1] = index.ToPython();
}
return new PyTuple(list.ToArray());
}
@@ -551,5 +640,62 @@ namespace QuantConnect.Python
_time = time;
}
}
private class DataTypeMember
{
public MemberInfo Member { get; }
public MemberInfo[] Children { get; }
public bool ShouldBeUnwrapped => Children != null && Children.Length > 0;
public DataTypeMember(MemberInfo member, MemberInfo[] children = null)
{
Member = member;
Children = children;
}
public IEnumerable<string> GetMemberNames()
{
// If there are no children, return the name of the member. Else ignore the member and return the children names
if (ShouldBeUnwrapped)
{
foreach (var child in Children)
{
yield return child.Name.ToLowerInvariant();
}
yield break;
}
yield return Member.Name.ToLowerInvariant();
}
public Type GetMemberType()
{
return GetMemberType(Member);
}
public object GetMemberValue(object instance)
{
return Member switch
{
PropertyInfo property => property.GetValue(instance),
FieldInfo field => field.GetValue(instance),
// Should not happen
_ => throw new InvalidOperationException($"Unexpected member type: {Member.MemberType}")
};
}
public static Type GetMemberType(MemberInfo member)
{
return member switch
{
PropertyInfo property => property.PropertyType,
FieldInfo field => field.FieldType,
// Should not happen
_ => throw new InvalidOperationException($"Unexpected member type: {member.MemberType}")
};
}
}
}
}

View File

@@ -34,21 +34,28 @@ namespace QuantConnect.Python
/// <param name="model">The model implementing the interface type</param>
public static PyObject ValidateImplementationOf<TInterface>(this PyObject model)
{
if (!typeof(TInterface).IsInterface)
{
throw new ArgumentException(
$"{nameof(PythonWrapper)}.{nameof(ValidateImplementationOf)}(): {Messages.PythonWrapper.ExpectedInterfaceTypeParameter}");
}
var notInterface = !typeof(TInterface).IsInterface;
var missingMembers = new List<string>();
var members = typeof(TInterface).GetMembers(BindingFlags.Public | BindingFlags.Instance);
using (Py.GIL())
{
foreach (var member in members)
{
if ((member is not MethodInfo method || !method.IsSpecialName) &&
var method = member as MethodInfo;
if ((method == null || !method.IsSpecialName) &&
!model.HasAttr(member.Name) && !model.HasAttr(member.Name.ToSnakeCase()))
{
if (notInterface)
{
if (method != null && !method.IsAbstract && (method.IsFinal || !method.IsVirtual || method.DeclaringType != typeof(TInterface)))
{
continue;
}
else if (member is ConstructorInfo)
{
continue;
}
}
missingMembers.Add(member.Name);
}
}

View File

@@ -35,7 +35,7 @@
<Message Text="SelectedOptimization $(SelectedOptimization)" Importance="high" />
</Target>
<ItemGroup>
<PackageReference Include="QuantConnect.pythonnet" Version="2.0.38" />
<PackageReference Include="QuantConnect.pythonnet" Version="2.0.39" />
<PackageReference Include="CloneExtensions" Version="1.3.0" />
<PackageReference Include="fasterflect" Version="3.0.0" />
<PackageReference Include="MathNet.Numerics" Version="5.0.0" />

View File

@@ -1,11 +1,11 @@
/*
/*
* 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");
*
* 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.
@@ -21,7 +21,7 @@ namespace QuantConnect.Securities.Option
{
/// <summary>
/// Provides a default implementation of <see cref="IOptionPriceModel"/> that does not compute any
/// greeks and uses the current price for the theoretical price.
/// greeks and uses the current price for the theoretical price.
/// <remarks>This is a stub implementation until the real models are implemented</remarks>
/// </summary>
public class CurrentPriceOptionPriceModel : IOptionPriceModel
@@ -38,7 +38,7 @@ namespace QuantConnect.Securities.Option
/// price of the specified option contract</returns>
public OptionPriceModelResult Evaluate(Security security, Slice slice, OptionContract contract)
{
return new OptionPriceModelResult(security.Price, new Greeks());
return new OptionPriceModelResult(security.Price, NullGreeks.Instance);
}
}
}
}

View File

@@ -1,11 +1,11 @@
/*
* 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");
*
* 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.
@@ -26,7 +26,7 @@ namespace QuantConnect.Securities.Option
/// <summary>
/// Represents the zero option price and greeks.
/// </summary>
public static OptionPriceModelResult None { get; } = new(0, new Greeks());
public static OptionPriceModelResult None { get; } = new(0, NullGreeks.Instance);
private readonly Lazy<Greeks> _greeks;
private readonly Lazy<decimal> _impliedVolatility;
@@ -69,8 +69,8 @@ namespace QuantConnect.Securities.Option
public OptionPriceModelResult(decimal theoreticalPrice, Greeks greeks)
{
TheoreticalPrice = theoreticalPrice;
_impliedVolatility = new Lazy<decimal>(() => 0m);
_greeks = new Lazy<Greeks>(() => greeks);
_impliedVolatility = new Lazy<decimal>(() => 0m, isThreadSafe: false);
_greeks = new Lazy<Greeks>(() => greeks, isThreadSafe: false);
}
/// <summary>
@@ -82,8 +82,8 @@ namespace QuantConnect.Securities.Option
public OptionPriceModelResult(decimal theoreticalPrice, Func<decimal> impliedVolatility, Func<Greeks> greeks)
{
TheoreticalPrice = theoreticalPrice;
_impliedVolatility = new Lazy<decimal>(impliedVolatility);
_greeks = new Lazy<Greeks>(greeks);
_impliedVolatility = new Lazy<decimal>(impliedVolatility, isThreadSafe: false);
_greeks = new Lazy<Greeks>(greeks, isThreadSafe: false);
}
}
}

View File

@@ -1151,6 +1151,129 @@ namespace QuantConnect.Securities.Option
return InvertStrategy(BearPutLadder(canonicalOption, higherStrike, middleStrike, lowerStrike, expiration), OptionStrategyDefinitions.BullPutLadder.Name);
}
/// <summary>
/// Method creates new Long Call Backspread strategy, that consists of two calls with the same expiration but different strikes.
/// It involves selling the lower strike call, while buying twice the number of the higher strike call.
/// </summary>
/// <param name="canonicalOption">Option symbol</param>
/// <param name="lowerStrike">The strike price of the short call</param>
/// <param name="higherStrike">The strike price of the long call</param>
/// <param name="expiration">Option expiration date</param>
/// <returns>Option strategy specification</returns>
public static OptionStrategy CallBackspread(
Symbol canonicalOption,
decimal lowerStrike,
decimal higherStrike,
DateTime expiration
)
{
CheckCanonicalOptionSymbol(canonicalOption, "CallBackspread");
CheckExpirationDate(expiration, "CallBackspread", nameof(expiration));
if (lowerStrike >= higherStrike)
{
throw new ArgumentException($"CallBackspread: strike prices must be in ascending order, {nameof(lowerStrike)}, {nameof(higherStrike)}");
}
return new OptionStrategy
{
Name = "Call Backspread",
Underlying = canonicalOption.Underlying,
CanonicalOption = canonicalOption,
OptionLegs = new List<OptionStrategy.OptionLegData>
{
new OptionStrategy.OptionLegData
{
Right = OptionRight.Call, Strike = lowerStrike, Quantity = -1, Expiration = expiration
},
new OptionStrategy.OptionLegData
{
Right = OptionRight.Call, Strike = higherStrike, Quantity = 2, Expiration = expiration
}
}
};
}
/// <summary>
/// Method creates new Long Put Backspread strategy, that consists of two puts with the same expiration but different strikes.
/// It involves selling the higher strike put, while buying twice the number of the lower strike put.
/// </summary>
/// <param name="canonicalOption">Option symbol</param>
/// <param name="higherStrike">The strike price of the short put</param>
/// <param name="lowerStrike">The strike price of the long put</param>
/// <param name="expiration">Option expiration date</param>
/// <returns>Option strategy specification</returns>
public static OptionStrategy PutBackspread(
Symbol canonicalOption,
decimal higherStrike,
decimal lowerStrike,
DateTime expiration
)
{
CheckCanonicalOptionSymbol(canonicalOption, "PutBackspread");
CheckExpirationDate(expiration, "PutBackspread", nameof(expiration));
if (higherStrike <= lowerStrike)
{
throw new ArgumentException($"PutBackspread: strike prices must be in descending order, {nameof(higherStrike)}, {nameof(lowerStrike)}");
}
return new OptionStrategy
{
Name = "Put Backspread",
Underlying = canonicalOption.Underlying,
CanonicalOption = canonicalOption,
OptionLegs = new List<OptionStrategy.OptionLegData>
{
new OptionStrategy.OptionLegData
{
Right = OptionRight.Put, Strike = higherStrike, Quantity = -1, Expiration = expiration
},
new OptionStrategy.OptionLegData
{
Right = OptionRight.Put, Strike = lowerStrike, Quantity = 2, Expiration = expiration
}
}
};
}
/// <summary>
/// Method creates new Short Call Backspread strategy, that consists of two calls with the same expiration but different strikes.
/// It involves buying the lower strike call, while shorting twice the number of the higher strike call.
/// </summary>
/// <param name="canonicalOption">Option symbol</param>
/// <param name="lowerStrike">The strike price of the long call</param>
/// <param name="higherStrike">The strike price of the short call</param>
/// <param name="expiration">Option expiration date</param>
public static OptionStrategy ShortCallBackspread(
Symbol canonicalOption,
decimal lowerStrike,
decimal higherStrike,
DateTime expiration
)
{
return InvertStrategy(CallBackspread(canonicalOption, lowerStrike, higherStrike, expiration), "Short Call Backspread");
}
/// <summary>
/// Method creates new Short Put Backspread strategy, that consists of two puts with the same expiration but different strikes.
/// It involves buying the higher strike put, while selling twice the number of the lower strike put.
/// </summary>
/// <param name="canonicalOption">Option symbol</param>
/// <param name="higherStrike">The strike price of the long put</param>
/// <param name="lowerStrike">The strike price of the short put</param>
/// <param name="expiration">Option expiration date</param>
/// <returns>Option strategy specification</returns>
public static OptionStrategy ShortPutBackspread(
Symbol canonicalOption,
decimal higherStrike,
decimal lowerStrike,
DateTime expiration
)
{
return InvertStrategy(PutBackspread(canonicalOption, higherStrike, lowerStrike, expiration), "Short Put Backspread");
}
/// <summary>
/// Checks that canonical option symbol is valid
/// </summary>

View File

@@ -73,7 +73,7 @@ namespace QuantConnect.Securities.Option
return new MaintenanceMargin(inAccountCurrency);
}
else if(_optionStrategy.Name == OptionStrategyDefinitions.CoveredCall.Name)
else if (_optionStrategy.Name == OptionStrategyDefinitions.CoveredCall.Name)
{
// MAX[In-the-money amount + Margin(long stock evaluated at min(mark price, strike(short call))), min(stock value, max(call value, long stock margin))]
var optionPosition = parameters.PositionGroup.Positions.FirstOrDefault(position => position.Symbol.SecurityType.IsOption());
@@ -208,7 +208,7 @@ namespace QuantConnect.Securities.Option
var result = GetMiddleAndLowStrikeDifference(parameters.PositionGroup, parameters.Portfolio);
return new MaintenanceMargin(result);
}
else if (_optionStrategy.Name == OptionStrategyDefinitions.IronCondor.Name || _optionStrategy.Name == OptionStrategyDefinitions.IronButterfly.Name ||
else if (_optionStrategy.Name == OptionStrategyDefinitions.IronCondor.Name || _optionStrategy.Name == OptionStrategyDefinitions.IronButterfly.Name ||
_optionStrategy.Name == OptionStrategyDefinitions.ShortIronCondor.Name || _optionStrategy.Name == OptionStrategyDefinitions.ShortIronButterfly.Name)
{
var result = GetShortPutLongPutStrikeDifferenceMargin(parameters.PositionGroup.Positions, parameters.Portfolio, parameters.PositionGroup.Quantity);
@@ -239,7 +239,7 @@ namespace QuantConnect.Securities.Option
var orderCosts = shortCallSecurity.AskPrice - longCallSecurity.BidPrice + shortPutSecurity.AskPrice - longPutSecurity.BidPrice;
var multiplier = Math.Abs(longCallPosition.Quantity) * longCallSecurity.ContractUnitOfTrade;
var closeCost = commissionFees + orderCosts * multiplier;
var strikeDifference = longCallPosition.Symbol.ID.StrikePrice - shortCallPosition.Symbol.ID.StrikePrice;
var result = Math.Max(1.02m * closeCost, strikeDifference * multiplier);
@@ -253,7 +253,7 @@ namespace QuantConnect.Securities.Option
// long calendar spread part has no margin requirement due to same strike
// only the short calendar spread's short option has margin requirement
var furtherExpiry = parameters.PositionGroup.Positions.Max(position => position.Symbol.ID.Date);
var shortCalendarSpreadShortLeg = parameters.PositionGroup.Positions.Single(position =>
var shortCalendarSpreadShortLeg = parameters.PositionGroup.Positions.Single(position =>
position.Quantity < 0 && position.Symbol.ID.Date == furtherExpiry);
var shortCalendarSpreadShortLegSecurity = (Option)parameters.Portfolio.Securities[shortCalendarSpreadShortLeg.Symbol];
var result = Math.Abs(shortCalendarSpreadShortLegSecurity.BuyingPowerModel.GetMaintenanceMargin(
@@ -302,7 +302,7 @@ namespace QuantConnect.Securities.Option
result = Math.Abs(underlyingSecurity.BuyingPowerModel.GetInitialMarginRequirement(underlyingSecurity, underlyingPosition.Quantity));
result = parameters.Portfolio.CashBook.ConvertToAccountCurrency(result, underlyingSecurity.QuoteCurrency.Symbol);
}
else if(_optionStrategy.Name == OptionStrategyDefinitions.CoveredCall.Name)
else if (_optionStrategy.Name == OptionStrategyDefinitions.CoveredCall.Name)
{
// Max(Call Value, Long Stock Initial Margin)
var optionPosition = parameters.PositionGroup.Positions.FirstOrDefault(position => position.Symbol.SecurityType.IsOption());
@@ -386,7 +386,7 @@ namespace QuantConnect.Securities.Option
{
result = GetMiddleAndLowStrikeDifference(parameters.PositionGroup, parameters.Portfolio);
}
else if (_optionStrategy.Name == OptionStrategyDefinitions.IronCondor.Name || _optionStrategy.Name == OptionStrategyDefinitions.IronButterfly.Name ||
else if (_optionStrategy.Name == OptionStrategyDefinitions.IronCondor.Name || _optionStrategy.Name == OptionStrategyDefinitions.IronButterfly.Name ||
_optionStrategy.Name == OptionStrategyDefinitions.ShortIronCondor.Name || _optionStrategy.Name == OptionStrategyDefinitions.ShortIronButterfly.Name)
{
result = GetShortPutLongPutStrikeDifferenceMargin(parameters.PositionGroup.Positions, parameters.Portfolio, parameters.PositionGroup.Quantity);
@@ -595,7 +595,7 @@ namespace QuantConnect.Securities.Option
private static decimal GetCollarConversionInitialMargin(IPositionGroup positionGroup, SecurityPortfolioManager portfolio, OptionRight optionRight)
{
// Initial Stock Margin Requirement + In the Money Call/Put Amount
var optionPosition = positionGroup.Positions.Single(position =>
var optionPosition = positionGroup.Positions.Single(position =>
position.Symbol.SecurityType.IsOption() && position.Symbol.ID.OptionRight == optionRight);
var underlyingPosition = positionGroup.Positions.Single(position => !position.Symbol.SecurityType.IsOption());
var optionSecurity = (Option)portfolio.Securities[optionPosition.Symbol];

View File

@@ -289,7 +289,7 @@ namespace QuantConnect.Securities.Option
// producing output with lazy calculations of greeks
return new OptionPriceModelResult(npv, // EvaluateOption ensure it is not NaN or Infinity
() => impliedVol.IsNaNOrInfinity() ? 0m : impliedVol.SafeDecimalCast(),
() => new Greeks(() => tryGetGreekOrReevaluate(() => option.delta(), (black) => black.delta(spot)),
() => new ModeledGreeks(() => tryGetGreekOrReevaluate(() => option.delta(), (black) => black.delta(spot)),
() => tryGetGreekOrReevaluate(() => option.gamma(), (black) => black.gamma(spot)),
() => tryGetGreekOrReevaluate(() => option.vega(), (black) => black.vega(maturity)) / 100, // per cent
() => tryGetGreekOrReevaluate(() => option.theta(), (black) => black.theta(spot, maturity)),

View File

@@ -33,7 +33,7 @@ namespace QuantConnect.Securities.Option.StrategyMatcher
typeof(OptionStrategyDefinitions)
.GetProperties(BindingFlags.Public | BindingFlags.Static)
.Where(property => property.PropertyType == typeof(OptionStrategyDefinition))
.Select(property => (OptionStrategyDefinition) property.GetValue(null))
.Select(property => (OptionStrategyDefinition)property.GetValue(null))
.ToImmutableList()
);

View File

@@ -19,7 +19,6 @@ using ProtoBuf;
using Python.Runtime;
using Newtonsoft.Json;
using QuantConnect.Securities;
using QuantConnect.Securities.IndexOption;
namespace QuantConnect
{
@@ -741,6 +740,46 @@ namespace QuantConnect
return left.Equals(right);
}
/// <summary>
/// Equals operator
/// </summary>
/// <param name="left">The left operand</param>
/// <param name="right">The right operand</param>
/// <returns>True if both symbols are equal, otherwise false</returns>
/// <remarks>This is necessary in cases like Pythonnet passing a string
/// as an object instead of using the implicit conversion</remarks>
public static bool operator ==(Symbol left, object right)
{
if (ReferenceEquals(left, right))
{
// this is a performance shortcut
return true;
}
var rightSymbol = right as Symbol;
// Use the implicit conversion for strings
if (rightSymbol == null && right is string rightStr)
{
return left == (Symbol)rightStr;
}
return left == rightSymbol;
}
/// <summary>
/// Equals operator
/// </summary>
/// <param name="left">The left operand</param>
/// <param name="right">The right operand</param>
/// <returns>True if both symbols are equal, otherwise false</returns>
/// <remarks>This is necessary in cases like Pythonnet passing a string
/// as an object instead of using the implicit conversion</remarks>
public static bool operator ==(object left, Symbol right)
{
// We already have an implementation for (Symbol left, object left), we can reuse it by inverting the operands
return right == left;
}
/// <summary>
/// Not equals operator
/// </summary>
@@ -752,6 +791,28 @@ namespace QuantConnect
return !(left == right);
}
/// <summary>
/// Not equals operator
/// </summary>
/// <param name="left">The left operand</param>
/// <param name="right">The right operand</param>
/// <returns>True if both symbols are not equal, otherwise false</returns>
public static bool operator !=(Symbol left, object right)
{
return !(left == right);
}
/// <summary>
/// Not equals operator
/// </summary>
/// <param name="left">The left operand</param>
/// <param name="right">The right operand</param>
/// <returns>True if both symbols are not equal, otherwise false</returns>
public static bool operator !=(object left, Symbol right)
{
return !(left == right);
}
#endregion
#region Implicit operators

View File

@@ -0,0 +1,234 @@
#symbol_id,symbol_value,open,high,low,close,volume,open_interest,implied_volatility,delta,gamma,vega,theta,rho
SPX WLF4IPHQKPF2|SPX 31,SPX 170616C00300000,1645.4000,1680.2000,1645.4000,1679.5000,0,,0.5645710,0.9991909,0.0000020,0.0688230,-0.0116314,4.3540311
SPX W87JLJTDKMY6|SPX 31,SPX 160219C00400000,1599.4000,1633.6500,1599.4000,1633.0500,0,,1.2263960,0.9998213,0.0000007,0.0055627,-0.0167744,0.6379273
SPX WHEDSZ06EEQ6|SPX 31,SPX 170120C00650000,1316.1500,1350.2000,1316.1500,1349.7500,0,,0.4460003,0.9967469,0.0000104,0.2085762,-0.0292000,6.8641754
SPX W87JLK5489AM|SPX 31,SPX 160219C00750000,1249.9500,1284.1500,1249.9500,1283.6000,0,,0.8045122,0.9994710,0.0000029,0.0152662,-0.0310045,1.1954716
SPX W8Z446DUDDSE|SPX 31,SPX 160318C00750000,1246.3000,1281.3500,1246.3000,1280.0500,0,375,0.7097078,0.9989528,0.0000050,0.0348394,-0.0347495,1.7648360
SPX WHEDSZ1TXR7Y|SPX 31,SPX 170120C00750000,1218.2500,1252.3500,1218.2500,1251.3000,0,,0.4216917,0.9942234,0.0000184,0.3484318,-0.0385812,7.8685124
SPX WQEBVQED3Z0U|SPX 31,SPX 171215C00750000,1194.5500,1230.4000,1194.5500,1228.0500,0,2225,0.3770008,0.9856338,0.0000337,1.0473987,-0.0464553,13.8605867
SPX WHEDSYQR3H2M|SPX 31,SPX 170120C00800000,1169.5000,1203.5000,1169.5000,1202.8500,0,,0.4111890,0.9924080,0.0000240,0.4436537,-0.0443187,8.3564435
SPX W87JLNL5H566|SPX 31,SPX 160219C00825000,1175.0500,1209.6000,1175.0500,1208.7000,0,,0.7563814,0.9991781,0.0000046,0.0229242,-0.0373710,1.3141723
SPX WDYBH707U1HQ|SPX 31,SPX 160916C00850000,1129.1000,1162.8000,1129.1000,1162.4500,0,35,0.4329086,0.9948040,0.0000198,0.2616087,-0.0438890,6.1156183
SPX W8Z44A25B04U|SPX 31,SPX 160318C00875000,1121.7000,1157.1500,1121.7000,1155.4500,0,,0.6397557,0.9980221,0.0000099,0.0622530,-0.0468518,2.0550019
SPX WQEBVU2O1LDA|SPX 31,SPX 171215C00875000,1077.6000,1112.8500,1077.6000,1110.5500,0,,0.3564302,0.9759429,0.0000553,1.6243412,-0.0618721,15.8078513
SPX WDYBH6NNEQWE|SPX 31,SPX 160916C00900000,1079.9500,1113.5500,1079.9500,1113.1500,0,35,0.4199418,0.9932746,0.0000256,0.3288676,-0.0497828,6.4546762
SPX WQEBVQ3G80XA|SPX 31,SPX 171215C00900000,1054.4000,1089.6500,1054.4000,1087.3000,0,6,0.3522833,0.9736241,0.0000604,1.7545569,-0.0650898,16.1785666
SPX WHEDT2YEK41A|SPX 31,SPX 170120C00925000,1048.2500,1081.9500,1048.2500,1081.3000,0,,0.3843426,0.9862823,0.0000430,0.7431784,-0.0603953,9.5360099
SPX WDYBH71VDDZI|SPX 31,SPX 160916C00950000,1031.2000,1064.4500,1031.2000,1064.0500,0,33,0.4082785,0.9912878,0.0000331,0.4130281,-0.0567045,6.7859533
SPX W792YEH1UXYM|SPX 31,SPX 160115C00975000,1030.4000,1064.4000,1030.4000,1064.1000,0,,0.8994549,0.9996082,0.0000031,0.0073128,-0.0407479,0.6231797
SPX WBGPST1BBV5A|SPX 31,SPX 160617C01025000,964.3500,999.2500,964.3500,997.6500,0,14,0.4292979,0.9931313,0.0000314,0.2723833,-0.0604854,4.8812934
SPX W87JLOQHWTIM|SPX 31,SPX 160219C01075000,925.5000,959.9000,925.5000,959.1500,0,,0.5770101,0.9981138,0.0000128,0.0490153,-0.0535211,1.7096209
SPX W9QOMSBZJ8A6|SPX 31,SPX 160415C01100000,896.0500,931.2000,896.0500,929.3000,0,,0.4440084,0.9956028,0.0000254,0.1471616,-0.0583435,3.4053797
SPX W792YF5UX5DA|SPX 31,SPX 160115C01125000,880.4500,914.7500,880.4500,914.2000,0,4,0.7570591,0.9993217,0.0000060,0.0121530,-0.0504513,0.7187471
SPX WHEDSZ8G3572|SPX 31,SPX 170120C01150000,833.7000,865.9500,833.7000,865.6500,0,,0.3424358,0.9654098,0.0001054,1.6219049,-0.0993420,11.4070635
SPX W87JLP71AAGE|SPX 31,SPX 160219C01175000,825.8500,860.4000,825.8500,859.3500,0,,0.5144098,0.9973656,0.0000194,0.0663447,-0.0612208,1.8667091
SPX W8Z446M4249A|SPX 31,SPX 160318C01250000,748.1500,783.6500,748.1500,781.6500,0,91,0.4205737,0.9938876,0.0000414,0.1714339,-0.0755422,2.9191418
SPX WHEDT4KAD9BI|SPX 31,SPX 170120C01275000,717.4500,748.7000,717.4500,748.3000,0,,0.3198755,0.9463878,0.0001608,2.3104699,-0.1247837,12.2571484
SPX W87JLPVUCHV2|SPX 31,SPX 160219C01325000,676.3500,710.8500,676.3500,709.8500,0,,0.4289266,0.9954479,0.0000380,0.1084310,-0.0758182,2.0996481
SPX WGFX5PIUHFKE|SPX 31,SPX 161216C01350000,647.5500,678.1500,647.5500,677.7500,0,6,0.3124158,0.9353554,0.0001997,2.5543624,-0.1434911,11.6644756
SPX W792YGB7CTPQ|SPX 31,SPX 160115C01375000,630.8000,665.1500,630.8000,664.4500,0,2,0.5385865,0.9984825,0.0000177,0.0254412,-0.0668818,0.8775487
SPX W792YAMMMXSE|SPX 31,SPX 160115C01380000,625.8000,660.1500,625.8000,659.5000,0,1,0.5339671,0.9984706,0.0000180,0.0256227,-0.0669738,0.8807319
SPX W87JLQ92N9TA|SPX 31,SPX 160219C01405000,596.9500,632.3500,596.9500,629.8500,0,,0.3903544,0.9933209,0.0000587,0.1524337,-0.0890141,2.2201115
SPX W87JLKG16CJY|SPX 31,SPX 160219C01410000,591.9000,627.3500,591.9000,624.9500,0,,0.3886194,0.9930834,0.0000609,0.1572128,-0.0905014,2.2272795
SPX W792YGHTI7OU|SPX 31,SPX 160115C01415000,590.7500,625.5500,590.7500,624.5000,0,,0.5184349,0.9978520,0.0000253,0.0348963,-0.0773331,0.9022825
SPX W9QOMYTU07SE|SPX 31,SPX 160415C01425000,575.9000,609.8500,575.9000,607.8000,0,,0.3358098,0.9781339,0.0001362,0.5959515,-0.1251014,4.3008465
SPX W87JLKGD30NI|SPX 31,SPX 160219C01430000,572.0500,607.4500,572.0500,605.0500,0,,0.3783131,0.9924785,0.0000673,0.1692770,-0.0935352,2.2571571
SPX W792YGOFNLNY|SPX 31,SPX 160115C01455000,550.9000,585.3000,550.9000,584.5500,0,,0.4819829,0.9976969,0.0000290,0.0371715,-0.0780442,0.9276687
SPX WGFX5VOGFSKU|SPX 31,SPX 161216C01475000,535.4000,564.4500,535.4000,564.0000,0,4,0.2897630,0.9039086,0.0002907,3.4483957,-0.1728517,12.1559167
SPX WQEBVQ4FY17Y|SPX 31,SPX 171215C01500000,535.4500,563.3000,535.4500,561.5500,0,1976,0.2740688,0.8508117,0.0002953,6.6684104,-0.1562808,21.6678011
SPX W87JLQR9K38U|SPX 31,SPX 160219C01515000,488.1000,522.6500,488.1000,520.8000,0,,0.3409151,0.9880499,0.0001120,0.2537433,-0.1148475,2.3777795
SPX W87JLQSX3FQM|SPX 31,SPX 160219C01525000,478.2000,513.3000,478.2000,510.6500,0,1,0.3362004,0.9874406,0.0001185,0.2649169,-0.1172789,2.3916774
SPX W8Z44D1N8K8E|SPX 31,SPX 160318C01525000,477.5500,512.2500,477.5500,509.2000,0,50,0.3196344,0.9750631,0.0001840,0.5784418,-0.1472430,3.4720851
SPX W792YH1NYDM6|SPX 31,SPX 160115C01535000,471.2000,506.2500,471.2000,504.7000,0,,0.4312298,0.9961236,0.0000518,0.0594213,-0.0966394,0.9767285
SPX WBGPSP1FMTCE|SPX 31,SPX 160617C01550000,458.5000,490.0500,458.5000,487.7500,0,2,0.2924378,0.9293262,0.0003254,1.9225134,-0.1964160,6.7264627
SPX W792YAPLSYOE|SPX 31,SPX 160115C01560000,446.1500,480.3500,446.1500,479.7000,0,,0.4089793,0.9959227,0.0000571,0.0621721,-0.0968909,0.9924591
SPX WQEBVXAFNVXQ|SPX 31,SPX 171215C01575000,477.7000,504.9500,477.7000,502.9500,0,1,0.2664059,0.8235028,0.0003389,7.4392316,-0.1670299,21.7307405
SPX W8Z446RKJ5VY|SPX 31,SPX 160318C01580000,424.4500,457.9000,424.4500,455.6000,0,,0.3036111,0.9653636,0.0002544,0.7598357,-0.1746899,3.5522891
SPX W792YAQFKMXA|SPX 31,SPX 160115C01610000,396.3500,430.3500,396.3500,429.8000,0,,0.3752410,0.9944929,0.0000814,0.0812880,-0.1090394,1.0225308
SPX W792YHEW95KE|SPX 31,SPX 160115C01615000,391.3500,425.7500,391.3500,424.8500,0,,0.3677265,0.9947505,0.0000796,0.0778979,-0.1052164,1.0260815
SPX W87JLR7SXK6M|SPX 31,SPX 160219C01615000,389.6500,424.5500,389.6500,421.6000,0,,0.2970814,0.9790806,0.0002077,0.4100980,-0.1473258,2.5069858
SPX W792YAQLIYZ2|SPX 31,SPX 160115C01620000,386.4500,420.5500,386.4500,419.8500,0,,0.3693423,0.9940498,0.0000886,0.0870680,-0.1128301,1.0283337
SPX W8Z446S8CI32|SPX 31,SPX 160318C01620000,386.4000,419.1500,386.4000,416.7500,0,,0.2920030,0.9560963,0.0003208,0.9216154,-0.1974771,3.5993014
SPX W9QOMZQWR5NY|SPX 31,SPX 160415C01625000,384.9000,416.8000,384.9000,414.4500,0,,0.2827285,0.9373480,0.0003818,1.4063101,-0.2144573,4.6461259
SPX WHEDT6666ELQ|SPX 31,SPX 170120C01625000,410.9500,437.0000,410.9500,436.7000,0,,0.2633631,0.8426314,0.0004312,5.1009916,-0.2041412,13.3354292
SPX WQEBVXIPCMEM|SPX 31,SPX 171215C01625000,440.0000,465.2000,440.0000,464.6500,0,1,0.2588607,0.8049213,0.0003711,7.9159018,-0.1717398,21.7746986
SPX W87JLRB40966|SPX 31,SPX 160219C01635000,370.2500,404.1000,370.2500,402.0000,0,,0.2925643,0.9749739,0.0002452,0.4769439,-0.1627994,2.5248841
SPX WDYBH7DG4TFY|SPX 31,SPX 160916C01650000,377.4000,405.5000,377.4000,403.3500,0,1,0.2646369,0.8596318,0.0004819,3.8983561,-0.2282365,9.6681473
SPX W87JLKK60PSE|SPX 31,SPX 160219C01660000,346.1000,379.6000,346.1000,377.2500,0,,0.2858663,0.9692561,0.0002979,0.5661490,-0.1822581,2.5452730
SPX W792YARFAN7Y|SPX 31,SPX 160115C01670000,336.4500,372.0500,336.4500,369.8000,0,,0.3349806,0.9919198,0.0001280,0.1140731,-0.1270337,1.0574753
SPX W8Z446T246BY|SPX 31,SPX 160318C01670000,339.2000,371.4500,339.2000,368.9000,0,,0.2787353,0.9403281,0.0004290,1.1764203,-0.2319473,3.6365396
SPX W9QOMZZ6FW4U|SPX 31,SPX 160415C01675000,338.9000,369.9500,338.9000,367.4000,0,,0.2708628,0.9182459,0.0004888,1.7247810,-0.2450943,4.6711559
SPX WLF4IX6941NY|SPX 31,SPX 170616C01675000,386.5500,411.3000,386.5500,410.2000,0,206,0.2559680,0.7979195,0.0004432,6.9952647,-0.1969952,17.1180194
SPX WQEBVXQZ1CVI|SPX 31,SPX 171215C01675000,403.6500,428.1500,403.6500,427.3500,0,,0.2536030,0.7837099,0.0004028,8.4161832,-0.1774755,21.6610361
SPX W792YARL8Z9Q|SPX 31,SPX 160115C01680000,326.6000,362.3500,326.6000,359.7000,0,,0.3282050,0.9913742,0.0001383,0.1208094,-0.1303536,1.0631443
SPX W87JLJVIYZLA|SPX 31,SPX 160219C01700000,307.9000,340.7500,307.9000,338.2500,2,100,0.2710299,0.9596416,0.0003928,0.7077202,-0.2084670,2.5764236
SPX W87JLRMOROMM|SPX 31,SPX 160219C01705000,303.1500,336.0000,303.1500,333.4000,0,5,0.2695824,0.9580145,0.0004078,0.7307676,-0.2129538,2.5788553
SPX W87JLKKZSE1A|SPX 31,SPX 160219C01710000,298.3500,330.6000,298.3500,328.7000,0,391,0.2671723,0.9568556,0.0004206,0.7470356,-0.2152381,2.5829192
SPX W87JLKLHNE6M|SPX 31,SPX 160219C01740000,270.3000,302.3000,270.3000,299.8000,0,1,0.2586189,0.9452439,0.0005257,0.9038196,-0.2446421,2.5911932
SPX W9QOMT33VZ7Y|SPX 31,SPX 160415C01750000,271.8500,301.3000,271.8500,298.4000,0,1,0.2529977,0.8794222,0.0006951,2.2908550,-0.2939513,4.6385652
SPX W792YI21S0HA|SPX 31,SPX 160115C01755000,252.8000,287.7000,252.8000,285.3500,0,30,0.2809842,0.9843871,0.0002704,0.2021996,-0.1687400,1.1017952
SPX W87JLKLTK2A6|SPX 31,SPX 160219C01760000,251.8500,283.2500,251.8500,280.6500,0,2,0.2534856,0.9354897,0.0006099,1.0277508,-0.2675560,2.5897937
SPX WGFX5X22K7E6|SPX 31,SPX 161216C01775000,288.5000,312.8000,288.5000,311.1000,0,208,0.2415411,0.7701669,0.0006211,6.1408160,-0.2396644,11.9639122
SPX WLF4IXV2692M|SPX 31,SPX 170616C01825000,278.7500,301.0500,278.7500,299.5000,0,,0.2370116,0.7189723,0.0005730,8.3738196,-0.2135787,16.3893229
SPX W792YILW86EM|SPX 31,SPX 160115C01875000,138.2000,168.1000,138.2000,167.7500,0,311,0.2206215,0.9383794,0.0010687,0.6274656,-0.3440539,1.1170559
SPX W792YIQUU7VY|SPX 31,SPX 160115C01905000,111.5000,139.4500,111.5000,139.4500,0,43,0.2052160,0.9110505,0.0015206,0.8304474,-0.4117672,1.0997141
SPX WDYBHFGINR72|SPX 31,SPX 160916C01925000,167.1000,186.6500,167.1000,185.2000,0,1248,0.2168822,0.6706878,0.0009543,6.3263057,-0.2870967,8.4434270
SPX WGFX5XQVMESU|SPX 31,SPX 161216C01925000,184.2500,203.4500,184.2500,201.9500,0,6050,0.2202923,0.6618350,0.0008204,7.3976920,-0.2569692,10.8628904
SPX W792YIVTG9DA|SPX 31,SPX 160115C01935000,86.9000,111.9500,86.9000,111.9500,0,37,0.1942960,0.8648286,0.0021680,1.1210321,-0.5113530,1.0569459
SPX W792YIXGZLV2|SPX 31,SPX 160115C01945000,78.9500,103.2000,78.9500,103.0000,0,25,0.1920156,0.8434360,0.0024216,1.2374284,-0.5527540,1.0345885
SPX W792YJ2FLNCE|SPX 31,SPX 160115C01975000,56.7000,77.7500,56.7000,77.6500,3,6213,0.1793074,0.7701806,0.0032812,1.5657520,-0.6416950,0.9553907
SPX W8Z44F5PYIY6|SPX 31,SPX 160318C01985000,79.9500,97.2000,79.9500,96.3000,1,1144,0.1918408,0.6403834,0.0019655,3.7092035,-0.4447822,2.8345966
SPX W8Z446YCMVWU|SPX 31,SPX 160318C01990000,76.7500,93.6000,76.7500,92.8000,0,1746,0.1905150,0.6308826,0.0019966,3.7418845,-0.4451046,2.7970127
SPX W792YJ5QOCBY|SPX 31,SPX 160115C01995000,43.4500,61.8000,43.4500,61.7000,2,3807,0.1720926,0.7044251,0.0038900,1.7815384,-0.6937457,0.8796007
SPX W87JLSYNCQY6|SPX 31,SPX 160219C01995000,61.3500,78.0000,61.3500,77.6000,0,3,0.1797382,0.6411392,0.0025501,3.0469899,-0.5026754,1.9554142
SPX W792YAX1Q0WE|SPX 31,SPX 160115C02010000,34.4500,50.7500,34.4500,50.5500,40,1496,0.1654320,0.6473269,0.0043521,1.9160549,-0.7130899,0.8122092
SPX W8Z44FAOKKFI|SPX 31,SPX 160318C02015000,61.6500,76.9000,61.6500,76.0000,6473,6757,0.1826994,0.5808721,0.0021562,3.8752027,-0.4399529,2.5964864
SPX W8Z44FDZN9F2|SPX 31,SPX 160318C02035000,50.6000,64.5000,50.6000,63.5000,20,7510,0.1771730,0.5371121,0.0022605,3.9396506,-0.4320663,2.4152438
SPX WDYBH7K2A7F2|SPX 31,SPX 160916C02050000,92.7500,106.4500,92.7500,105.6500,0,3123,0.1480432,0.5314403,0.0015365,6.9532140,-0.2185950,7.1943522
SPX W87JLKQS63RI|SPX 31,SPX 160219C02060000,26.9000,37.6500,26.9000,36.9500,41,3466,0.1385793,0.4488341,0.0035017,3.2259496,-0.4070410,1.4042845
SPX W8Z446ZIB89A|SPX 31,SPX 160318C02060000,38.3000,50.0000,38.3000,49.1000,0,3158,0.1441809,0.4691114,0.0027814,3.9449177,-0.3541393,2.1460035
SPX W87JLTBVNIWE|SPX 31,SPX 160219C02075000,21.0500,30.1000,21.0500,29.4500,202,8591,0.1335993,0.3931053,0.0035301,3.1352633,-0.3799933,1.2347037
SPX WQEBVZL4J8MM|SPX 31,SPX 171215C02075000,159.5000,174.0500,159.5000,173.9000,0,2280,0.1502318,0.5464233,0.0009189,11.3736365,-0.1438674,18.6344625
SPX W87JLKR42RV2|SPX 31,SPX 160219C02080000,19.2000,27.8000,19.2000,27.2000,6,615,0.1318164,0.3739989,0.0035252,3.0891213,-0.3689916,1.1761985
SPX WDYBH7KK57KE|SPX 31,SPX 160916C02080000,77.7000,90.0500,77.7000,89.3000,0,,0.1449510,0.4844475,0.0015730,6.9695845,-0.2128389,6.6060019
SPX W87JLKRRW426|SPX 31,SPX 160219C02120000,8.4000,13.1000,7.9500,12.4500,78,449,0.1202474,0.2256706,0.0030642,2.4494331,-0.2645901,0.7157904
SPX W87JLTK5C9DA|SPX 31,SPX 160219C02125000,7.4500,11.5000,6.8500,11.1000,1934,10590,0.1186198,0.2078700,0.0029620,2.3357530,-0.2486666,0.6599968
SPX W8Z44FUJ0QCU|SPX 31,SPX 160318C02135000,12.3500,18.2000,11.9000,17.0000,2,522,0.1231776,0.2423887,0.0025583,3.0999410,-0.2341397,1.1292115
SPX W792YAZ74DJI|SPX 31,SPX 160115C02140000,0.8500,1.1750,0.6250,1.1250,139,6129,0.1120017,0.0474727,0.0017125,0.5104426,-0.1249653,0.0612411
SPX W8Z44FXU3FCE|SPX 31,SPX 160318C02155000,8.4500,12.7000,7.8000,11.7000,0,41,0.1185776,0.1868202,0.0022835,2.6635791,-0.1929683,0.8735870
SPX W792YAZJ11N2|SPX 31,SPX 160115C02160000,0.5250,0.9000,0.4750,0.5750,280,11869,0.1149455,0.0258133,0.0010124,0.3096968,-0.0776062,0.0333233
SPX W87JLTQRHNCE|SPX 31,SPX 160219C02165000,2.6500,5.1500,2.1000,3.7500,138,3735,0.1083499,0.0924711,0.0018755,1.3508982,-0.1304557,0.2955089
SPX W792YAZOZDOU|SPX 31,SPX 160115C02170000,0.4750,0.7000,0.3250,0.4500,59,8098,0.1181081,0.0202848,0.0008043,0.2527893,-0.0650134,0.0261875
SPX W87JLKSRM4CU|SPX 31,SPX 160219C02180000,1.7500,3.9250,0.9250,2.3000,262,623,0.1051642,0.0628441,0.0014405,1.0070383,-0.0941741,0.2012153
SPX W792YK15VXPQ|SPX 31,SPX 160115C02185000,0.4250,0.5750,0.1250,0.3750,17,1679,0.1257968,0.0162874,0.0006263,0.2096652,-0.0573423,0.0210184
SPX W792YB00W1SE|SPX 31,SPX 160115C02190000,0.2250,0.5250,0.1500,0.3500,252,1852,0.1281431,0.0150769,0.0005754,0.1962236,-0.0546421,0.0194543
SPX WBGPSPD0E8SU|SPX 31,SPX 160617C02250000,7.8500,11.0500,6.9500,9.8000,65,13213,0.1134352,0.1262099,0.0012854,2.9456098,-0.1009768,1.2029193
SPX WDYBHHAO5MY6|SPX 31,SPX 160916C02325000,7.9000,10.8000,6.8500,9.4000,0,4776,0.1110559,0.1049692,0.0009363,3.1784400,-0.0713729,1.5047417
SPX W87JLKVKTT72|SPX 31,SPX 160219C02350000,0.2500,0.2750,0.1750,0.2000,0,1549,0.1371840,0.0056798,0.0001448,0.1320484,-0.0158306,0.0181985
SPX WBGPSOFRR41A|SPX 31,SPX 160617C02400000,0.5500,0.9750,0.5250,0.8750,2,6075,0.1049012,0.0167364,0.0002790,0.5912789,-0.0183964,0.1615706
SPX WHEDT9UH663Y|SPX 31,SPX 170120C02425000,7.7500,10.2000,6.8500,9.0000,0,2,0.1103905,0.0869899,0.0006767,3.3555799,-0.0515788,1.8196500
SPX WQEBW170CDWU|SPX 31,SPX 171215C02425000,38.2500,43.1000,38.2500,42.9500,0,285,0.1271522,0.2211194,0.0008136,8.5238328,-0.0860999,8.0904228
SPX W87JLKX8D5OU|SPX 31,SPX 160219C02450000,0.2000,0.2250,0.1250,0.1500,5,5,0.1675611,0.0036438,0.0000798,0.0888465,-0.0129531,0.0116403
SPX WGFX5Q11E8ZY|SPX 31,SPX 161216C02450000,4.4500,6.5000,3.2000,5.1000,0,1555,0.1073466,0.0572345,0.0005286,2.3224112,-0.0377441,1.0987418
SPX WHEDSZVLM03Y|SPX 31,SPX 170120C02550000,1.6000,3.5500,1.0750,2.4500,0,60,0.1053714,0.0294781,0.0003003,1.4212355,-0.0205668,0.6229424
SPX WQEBVR84S7WU|SPX 31,SPX 171215C02550000,18.4500,21.1500,18.2000,20.9500,0,1002,0.1197581,0.1303540,0.0006166,6.0836361,-0.0570684,4.8529920
SPX W9QOMSEGU90U|SPX 31,SPX 160415C02600000,0.4000,0.4000,0.2000,0.2000,0,,0.1574953,0.0037085,0.0000616,0.1263486,-0.0089016,0.0230657
SPX WLF4IQP2E972|SPX 31,SPX 170616C02650000,3.0250,4.3500,2.4250,3.3500,0,124,0.1071022,0.0335799,0.0002808,1.8545378,-0.0201287,0.9657172
SPX WHEDSYU26626|SPX 31,SPX 170120C02800000,0.7500,1.4500,0.1750,0.7500,0,42,0.1214194,0.0090302,0.0000947,0.5166668,-0.0084376,0.1908371
SPX WLF4IPLVF2NI|SPX 31,SPX 170616C02800000,1.1750,2.6500,0.8750,1.7000,0,32,0.1139066,0.0174242,0.0001522,1.0691848,-0.0121749,0.5017116
SPX WGFX5OX0PJDA|SPX 31,SPX 161216C03000000,0.2000,0.2000,0.1750,0.1750,0,3407,0.1309221,0.0023137,0.0000273,0.1463881,-0.0027910,0.0447262
SPX WQEBVQ2GK5SE|SPX 31,SPX 171215C03000000,1.0500,1.9250,0.8500,1.8500,0,619,0.1171266,0.0162029,0.0001204,1.1614247,-0.0102573,0.6180910
SPX WHEDSYV1W6CU|SPX 31,SPX 170120C03400000,1.1000,2.4000,0.2000,1.1000,0,,0.1937197,0.0085389,0.0000565,0.4919384,-0.0125294,0.1762280
SPX WQEBVQ7R0Q7I|SPX 31,SPX 171215C03500000,0.8000,0.8000,0.8000,0.8000,0,855,0.1427460,0.0063931,0.0000439,0.5162667,-0.0054291,0.2424916
SPX 30GIDYEOYNA5Q|SPX 31,SPX 170120P00200000,0.6250,2.0250,0.5500,0.6250,0,2500,0.8443776,-0.0009787,0.0000018,0.0699676,-0.0074186,-0.0283154
SPX 30GIDYEP4LM7I|SPX 31,SPX 170120P00300000,0.6750,1.3750,0.2750,0.6750,0,3,0.7005073,-0.0013026,0.0000029,0.0909172,-0.0079835,-0.0359899
SPX 308349M1AZKTQ|SPX 31,SPX 160318P00400000,0.1000,0.1500,0.0750,0.0750,2200,2449,1.0398633,-0.0002530,0.0000009,0.0093601,-0.0056187,-0.0013980
SPX 30PIC1625MU5Q|SPX 31,SPX 171215P00600000,2.5500,2.5500,2.0750,2.1000,0,4598,0.3838042,-0.0050724,0.0000133,0.4203998,-0.0108120,-0.2465638
SPX 307BJR02NYQ6M|SPX 31,SPX 160219P00650000,0.1500,0.3750,0.1000,0.1000,0,5594,0.9151450,-0.0004642,0.0000022,0.0135268,-0.0105762,-0.0016734
SPX 308349M1SUKZ2|SPX 31,SPX 160318P00700000,0.3250,0.5000,0.2500,0.3250,0,140,0.7828174,-0.0013311,0.0000056,0.0433964,-0.0195842,-0.0071909
SPX 30PIC162BL67I|SPX 31,SPX 171215P00700000,5.7000,6.6500,3.2000,5.2250,0,762,0.3857143,-0.0113956,0.0000270,0.8572045,-0.0220744,-0.5639604
SPX 307BJR04BI2OE|SPX 31,SPX 160219P00750000,0.1750,0.4000,0.0750,0.1000,200,5105,0.8045122,-0.0005290,0.0000029,0.0152662,-0.0104893,-0.0018845
SPX 30FJXB584J5ZI|SPX 31,SPX 161216P00750000,1.5500,1.8750,1.3500,1.4500,3,729,0.4265415,-0.0046894,0.0000158,0.2762895,-0.0160952,-0.1084097
SPX 308349M1YSX0U|SPX 31,SPX 160318P00800000,0.2500,0.2500,0.2000,0.2250,0,850,0.6660016,-0.0011170,0.0000056,0.0369614,-0.0141828,-0.0059213
SPX 30GIDYF2OQX3I|SPX 31,SPX 170120P00850000,3.6750,4.2500,1.8750,3.1750,0,7,0.3998820,-0.0096719,0.0000305,0.5486448,-0.0271888,-0.2473751
SPX 308UOS8AUWDKE|SPX 31,SPX 160415P00900000,0.4250,0.5000,0.2500,0.3500,0,,0.5318746,-0.0018288,0.0000096,0.0667115,-0.0154010,-0.0127802
SPX 30D2BMMMUOKA6|SPX 31,SPX 160916P00900000,2.3000,3.6250,1.1500,1.8000,0,29,0.4199418,-0.0067254,0.0000256,0.3288676,-0.0253059,-0.1140584
SPX 30GIDYIXLTXF2|SPX 31,SPX 170120P00925000,5.1500,5.5000,2.9250,4.5000,0,13,0.3843426,-0.0137177,0.0000430,0.7431784,-0.0353252,-0.3507602
SPX 30KJ4O9PF2U0E|SPX 31,SPX 170616P00925000,9.1000,9.7500,6.4000,8.1000,0,12,0.3637835,-0.0207223,0.0000552,1.2390154,-0.0402500,-0.7467432
SPX 306D33QEPWD1Q|SPX 31,SPX 160115P00950000,0.0750,0.2000,0.0750,0.2000,0,8518,1.0431385,-0.0012301,0.0000076,0.0210001,-0.0468044,-0.0017335
SPX 30PIC16GVGHE6|SPX 31,SPX 171215P00950000,16.2000,16.2000,12.8000,14.7000,0,4,0.3444228,-0.0315524,0.0000718,2.0363875,-0.0463168,-1.5649583
SPX 306D33UG94RCE|SPX 31,SPX 160115P00975000,0.0750,0.2000,0.0500,0.0500,0,1343,0.8994549,-0.0003918,0.0000031,0.0073128,-0.0140527,-0.0005434
SPX 30FJXB4VW2ONI|SPX 31,SPX 161216P01000000,6.2000,7.1500,3.8000,5.3000,0,19663,0.3764142,-0.0169775,0.0000553,0.8519946,-0.0435273,-0.3929798
SPX 30PIC16IIZTVY|SPX 31,SPX 171215P01050000,22.8500,22.8500,18.9000,20.7000,0,344,0.3303574,-0.0443633,0.0000988,2.6897160,-0.0583724,-2.2038466
SPX 308349QYFBRE6|SPX 31,SPX 160318P01075000,0.6500,0.8000,0.3500,0.5750,0,73,0.5123902,-0.0034421,0.0000204,0.1026910,-0.0302546,-0.0179677
SPX 30PIC1B77R33I|SPX 31,SPX 171215P01125000,28.9000,28.9000,25.5000,26.3500,0,40,0.3206743,-0.0562694,0.0001231,3.2511130,-0.0681918,-2.7998683
SPX 30GIDYKB7YC8E|SPX 31,SPX 170120P01225000,17.1500,17.4500,13.5500,14.7500,0,1,0.3283348,-0.0450194,0.0001363,2.0096120,-0.0807390,-1.1506805
SPX 30GIDYF9AWB2M|SPX 31,SPX 170120P01250000,18.7000,18.9000,15.0000,16.1000,0,6050,0.3241007,-0.0491715,0.0001482,2.1569074,-0.0854434,-1.2569280
SPX 307BJR0CR5572|SPX 31,SPX 160219P01260000,0.7000,0.8000,0.3250,0.4500,0,13,0.4663332,-0.0036481,0.0000287,0.0889417,-0.0353161,-0.0126139
SPX 306D33QK0F2MM|SPX 31,SPX 160115P01270000,0.2000,0.3250,0.0750,0.0750,0,932,0.6111681,-0.0008357,0.0000091,0.0147294,-0.0192157,-0.0011388
SPX 306D33Q15R25Q|SPX 31,SPX 160115P01300000,0.1750,0.3000,0.0750,0.0750,0,19034,0.5829447,-0.0008749,0.0000099,0.0153634,-0.0191148,-0.0011899
SPX 30PIC163BB6I6|SPX 31,SPX 171215P01300000,47.6500,47.6500,42.9500,43.5000,0,3169,0.2969671,-0.0912619,0.0001925,4.7096920,-0.0903860,-4.5491285
SPX 308349S3RRFQM|SPX 31,SPX 160318P01325000,1.7750,1.7750,0.7250,1.1250,2,3552,0.3872169,-0.0083068,0.0000590,0.2247105,-0.0498798,-0.0427379
SPX 30GIDYFAYFNKE|SPX 31,SPX 170120P01350000,26.2000,26.2000,21.6000,22.5000,0,3,0.3069835,-0.0686883,0.0002034,2.8045133,-0.1047024,-1.7560280
SPX 308349MNGQAA6|SPX 31,SPX 160318P01380000,2.3250,2.3250,0.7500,1.4500,1,24,0.3667209,-0.0109883,0.0000795,0.2869682,-0.0602726,-0.0564429
SPX 306D33QMNOFF2|SPX 31,SPX 160115P01430000,0.3000,0.4750,0.1750,0.2000,0,552,0.5113301,-0.0024623,0.0000290,0.0394902,-0.0430688,-0.0033419
SPX 306D33QMTMRGU|SPX 31,SPX 160115P01440000,0.3250,0.4750,0.1500,0.1750,0,561,0.4955332,-0.0022421,0.0000275,0.0362796,-0.0383422,-0.0030384
SPX 30D2BMN9CBXU6|SPX 31,SPX 160916P01450000,22.4000,22.4000,17.4000,18.3500,0,1071,0.3028158,-0.0706492,0.0002554,2.3641894,-0.1289329,-1.1946741
SPX 30GIDYFCLZ026|SPX 31,SPX 170120P01450000,35.7500,35.7500,29.9500,30.8500,0,201,0.2902959,-0.0940248,0.0002726,3.5550322,-0.1247479,-2.4044279
SPX 30PIC16P557V2|SPX 31,SPX 171215P01450000,70.1000,70.1000,63.9000,63.9000,0,574,0.2782710,-0.1320766,0.0002678,6.1390476,-0.1089578,-6.5997131
SPX 307BJR6GJLTNY|SPX 31,SPX 160219P01455000,1.5250,1.5250,0.6500,0.8750,0,2,0.3659108,-0.0084182,0.0000768,0.1869014,-0.0580937,-0.0288457
SPX 306D33QNHG3NY|SPX 31,SPX 160115P01480000,0.3750,0.5250,0.1750,0.2000,0,580,0.4657679,-0.0026908,0.0000345,0.0427875,-0.0424922,-0.0036400
SPX 308349MP49MRY|SPX 31,SPX 160318P01480000,3.8500,3.8500,1.4500,2.4500,0,10,0.3334475,-0.0191770,0.0001413,0.4633849,-0.0883165,-0.0983126
SPX 308349MPA7YTQ|SPX 31,SPX 160318P01490000,4.0500,4.0500,1.5750,2.5750,0,3,0.3300468,-0.0202416,0.0001494,0.4851356,-0.0914973,-0.1037477
SPX 307BJR6QGTWMM|SPX 31,SPX 160219P01515000,2.1250,3.3000,0.8750,1.2000,0,273,0.3409151,-0.0119501,0.0001120,0.2537433,-0.0734070,-0.0408799
SPX 308349MPS2YZ2|SPX 31,SPX 160318P01520000,4.8000,4.8000,1.9500,3.0500,3,10,0.3208775,-0.0241289,0.0001783,0.5626700,-0.1030953,-0.1236270
SPX 306D33WZ7OUI6|SPX 31,SPX 160115P01525000,0.4250,0.5000,0.1750,0.2250,699,5304,0.4310307,-0.0032271,0.0000439,0.0504036,-0.0463059,-0.0043561
SPX 30AKPYBB7H17Y|SPX 31,SPX 160617P01525000,16.6500,16.8000,11.9000,12.7000,0,1685,0.2976933,-0.0634037,0.0002939,1.7676770,-0.1444567,-0.6897765
SPX 30D2BMNAZVABY|SPX 31,SPX 160916P01550000,31.6500,31.6500,24.9500,26.1000,0,6313,0.2828323,-0.0998917,0.0003546,3.0658873,-0.1552669,-1.6884516
SPX 306D33X5TU8HA|SPX 31,SPX 160115P01565000,0.4750,1.9000,0.2000,0.3000,0,836,0.4084018,-0.0044194,0.0000615,0.0668168,-0.0581412,-0.0059602
SPX 307BJR70E1ZLA|SPX 31,SPX 160219P01575000,3.0500,4.0500,1.2000,1.6250,122,590,0.3152644,-0.0168458,0.0001627,0.3410775,-0.0911333,-0.0575203
SPX 307BJR721LC32|SPX 31,SPX 160219P01585000,3.2500,4.2000,1.0500,1.7250,120,180,0.3114357,-0.0179751,0.0001741,0.3605102,-0.0951334,-0.0613636
SPX 30D2BMMO0CWMM|SPX 31,SPX 160916P01600000,37.5500,37.5500,29.9000,31.0000,45,6697,0.2735601,-0.1185646,0.0004147,3.4678194,-0.1692781,-2.0046058
SPX 308349THDVUJY|SPX 31,SPX 160318P01625000,8.7500,8.7500,4.4750,5.8000,0,3101,0.2920030,-0.0459574,0.0003329,0.9561637,-0.1589159,-0.2354242
SPX 30AKPY52AFZ7Y|SPX 31,SPX 160617P01650000,27.8000,27.8000,20.6000,21.5000,0,13620,0.2707476,-0.1071860,0.0004796,2.6232658,-0.1936445,-1.1664779
SPX 307BJR0JV5JBI|SPX 31,SPX 160219P01690000,6.4500,6.4500,3.4000,3.4000,0,71,0.2729638,-0.0368083,0.0003618,0.6565590,-0.1513829,-0.1254444
SPX 307BJQZUQ8SZ2|SPX 31,SPX 160219P01700000,6.9000,6.9000,3.4000,3.7500,6158,18442,0.2710299,-0.0403584,0.0003928,0.7077202,-0.1619661,-0.1375836
SPX 306D33XSZD3E6|SPX 31,SPX 160115P01705000,1.1750,1.1750,0.5000,0.6000,2000,2775,0.3133436,-0.0106094,0.0001736,0.1447693,-0.0964663,-0.0142313
SPX 308UOSG6NEFZI|SPX 31,SPX 160415P01725000,22.3000,22.3000,14.9500,15.9000,0,79,0.2588558,-0.1059929,0.0006197,2.0895153,-0.2301147,-0.7271863
SPX 30GIDYMLWTOXA|SPX 31,SPX 170120P01725000,79.4000,79.4000,68.5500,69.3000,0,92,0.2483602,-0.2064883,0.0005421,6.0476693,-0.1769886,-5.3019957
SPX 307BJR0KOX7KE|SPX 31,SPX 160219P01740000,9.1500,9.5500,4.5000,5.1000,5,242,0.2586189,-0.0547561,0.0005257,0.9038196,-0.1970470,-0.1866730
SPX 308349MTF2C26|SPX 31,SPX 160318P01740000,17.0500,17.0500,10.3000,11.4000,0,640,0.2595655,-0.0905001,0.0006334,1.6172631,-0.2376634,-0.4635874
SPX 307BJR0L0TVNY|SPX 31,SPX 160219P01760000,10.5500,10.8000,5.3000,6.0500,21,125,0.2534856,-0.0645103,0.0006099,1.0277508,-0.2194139,-0.2200020
SPX 307BJR0LCQJRI|SPX 31,SPX 160219P01780000,12.1500,12.1500,6.4500,7.0500,2,771,0.2472524,-0.0750139,0.0007023,1.1543217,-0.2401216,-0.2558441
SPX 306D33Y7V77U6|SPX 31,SPX 160115P01795000,2.8250,3.5750,1.1500,1.1750,7,708,0.2580984,-0.0230741,0.0004104,0.2818623,-0.1543594,-0.0308682
SPX 307BJR82FEYY6|SPX 31,SPX 160219P01805000,14.4000,14.4000,8.0500,8.5000,78,705,0.2391202,-0.0902500,0.0008346,1.3267678,-0.2665147,-0.3078272
SPX 306D33QSXX5AM|SPX 31,SPX 160115P01810000,3.3500,3.3500,1.0750,1.3750,5,4542,0.2502900,-0.0272511,0.0004865,0.3240449,-0.1720044,-0.0364482
SPX 307BJR0LULJWU|SPX 31,SPX 160219P01810000,14.9500,14.9500,7.8000,8.8500,90,657,0.2377142,-0.0938400,0.0008642,1.3656482,-0.2726242,-0.3200978
SPX 308349MUKQOEM|SPX 31,SPX 160318P01810000,25.3000,25.3000,16.6500,17.3000,10,66,0.2402146,-0.1360801,0.0009163,2.1652120,-0.2930407,-0.6974356
SPX 30GIDYN2G75V2|SPX 31,SPX 170120P01825000,104.3500,104.3500,92.1500,92.1500,0,1293,0.2341101,-0.2670830,0.0006628,6.9695491,-0.1894292,-6.8779061
SPX 308349MV8K0LQ|SPX 31,SPX 160318P01850000,31.5500,31.5500,20.5500,21.9000,72,45165,0.2287598,-0.1708180,0.0011188,2.5175600,-0.3232809,-0.8758051
SPX 307BJR8CCN1WU|SPX 31,SPX 160219P01865000,22.0000,22.0000,12.9500,13.3000,20,56,0.2192485,-0.1402251,0.0012465,1.8167400,-0.3330349,-0.4784354
SPX 308349UMQBIWE|SPX 31,SPX 160318P01875000,36.2000,36.2000,24.3000,25.4000,0,12666,0.2222305,-0.1972509,0.0012596,2.7536321,-0.3425611,-1.0119070
SPX 307BJR8FNPQWE|SPX 31,SPX 160219P01885000,25.3000,25.3000,15.1500,15.6000,0,54,0.2132588,-0.1630226,0.0014165,2.0081747,-0.3573504,-0.5564415
SPX 30D2BMMOI7WRY|SPX 31,SPX 160916P01900000,99.1500,99.1500,84.8000,84.8500,2,11412,0.2222040,-0.3070082,0.0009043,6.1418876,-0.2347999,-5.2256279
SPX 30KJ4O5JL3VLA|SPX 31,SPX 170616P01900000,158.4500,158.4500,142.9500,143.3000,0,2138,0.2286266,-0.3277939,0.0006362,8.9685613,-0.1671467,-12.0352779
SPX 307BJR8IYSFVY|SPX 31,SPX 160219P01905000,29.1000,29.1000,17.8000,18.3500,5,1327,0.2075139,-0.1894886,0.0016012,2.2088872,-0.3815945,-0.6471338
SPX 30AKPYD5CYWZ2|SPX 31,SPX 160617P01925000,80.7500,80.7500,65.2500,65.8500,2,13145,0.2127640,-0.3103932,0.0011673,5.0171623,-0.2817946,-3.3931857
SPX 30PIC1EVIQULQ|SPX 31,SPX 171215P01925000,199.0000,199.0000,183.0000,183.4500,0,52,0.2296949,-0.3442662,0.0005584,10.5672544,-0.1435190,-17.5456483
SPX 30GIDYFKVNQJ2|SPX 31,SPX 170120P01950000,145.2500,145.2500,127.3000,128.4500,0,911,0.2168368,-0.3599549,0.0008140,7.9287154,-0.1943503,-9.3170030
SPX 307BJR8SW0IUM|SPX 31,SPX 160219P01965000,44.5000,44.5000,29.2000,29.6000,0,56,0.1901740,-0.2928870,0.0022178,2.8038710,-0.4396276,-1.0024895
SPX 306D33QVR4U4U|SPX 31,SPX 160115P01980000,27.3500,27.3500,13.3500,13.6000,116,8380,0.1774544,-0.2449790,0.0034339,1.6216499,-0.6017653,-0.3284500
SPX 30GIDYEOYPFBI|SPX 31,SPX 170120P02000000,165.2000,165.2000,145.8500,146.5500,0,1406,0.2106717,-0.4024716,0.0008667,8.2012553,-0.1925597,-10.4498772
SPX 306D33Z890UPA|SPX 31,SPX 160115P02015000,40.6500,40.6500,22.1000,22.2000,132,1911,0.1624016,-0.3729958,0.0045185,1.9528468,-0.6572466,-0.5009800
SPX 306D33QWEY6BY|SPX 31,SPX 160115P02020000,43.0500,43.0500,23.4000,23.8000,203,4859,0.1607398,-0.3951520,0.0046440,1.9865465,-0.6606104,-0.5309671
SPX 308349VGHZRSE|SPX 31,SPX 160318P02055000,96.7500,96.7500,73.8500,74.4000,0,3194,0.1436139,-0.5172686,0.0027982,3.9530763,-0.2980601,-2.6439984
SPX 306D33ZI68XNY|SPX 31,SPX 160115P02075000,76.6000,76.6000,48.4500,48.6500,138,15372,0.1302403,-0.6899382,0.0052513,1.8201273,-0.4674408,-0.9311358
SPX 30GIDYO7SMU7I|SPX 31,SPX 170120P02075000,199.6500,199.6500,176.9000,178.1000,0,459,0.1443269,-0.4879257,0.0013036,8.4513182,-0.1238483,-12.1462246
SPX 308349VS2R78U|SPX 31,SPX 160318P02125000,141.1000,141.1000,111.6500,112.7000,0,2005,0.1255134,-0.7282786,0.0026645,3.2898223,-0.1956009,-3.7528466
SPX 30AKPY5AK4POU|SPX 31,SPX 160617P02150000,186.4500,186.4500,159.3000,159.3000,0,2938,0.1302054,-0.6862551,0.0019162,5.0405047,-0.1429440,-7.4618434
SPX 30FJXBEVFBWJ2|SPX 31,SPX 161216P02175000,248.5000,248.5000,221.8500,222.9000,0,206,0.1372965,-0.6306911,0.0013584,7.6342048,-0.1056634,-14.4357949
SPX 30PIC1G0V6IY6|SPX 31,SPX 171215P02175000,317.5000,317.5000,293.8500,295.5500,0,2,0.1444271,-0.5471694,0.0009556,11.3711186,-0.0769349,-26.4628765
SPX 307BJR0RYVXQM|SPX 31,SPX 160219P02180000,180.2500,180.2500,145.4500,146.9500,0,2,0.1051642,-0.9371559,0.0014405,1.0070383,-0.0345435,-3.2790998
SPX 306D34020P3LA|SPX 31,SPX 160115P02195000,189.1500,189.1500,154.4000,155.4500,0,2,0.1274493,-0.9877998,0.0004819,0.1634542,0.0148439,-1.3884289
SPX 307BJQZVK0H7Y|SPX 31,SPX 160219P02200000,199.2500,199.2500,164.3500,165.9000,0,462,0.1055729,-0.9592075,0.0010172,0.7138919,-0.0066290,-3.3814846
SPX 307BJR0SGQXVY|SPX 31,SPX 160219P02210000,208.8500,208.8500,174.3500,175.6500,0,,0.1030093,-0.9710228,0.0007871,0.5390252,0.0112908,-3.4352116
SPX 30FJXBF3P0MZY|SPX 31,SPX 161216P02225000,281.2000,281.2000,251.6500,253.7000,0,53,0.1291852,-0.7054864,0.0013191,6.9753209,-0.0802204,-16.2270317
SPX 306D33R01XJF2|SPX 31,SPX 160115P02240000,234.0000,234.0000,199.5500,200.3000,0,,0.1556804,-0.9906471,0.0003130,0.1296842,0.0176101,-1.4209162
SPX 30KJ4O6HNIOLQ|SPX 31,SPX 170616P02250000,332.8500,332.8500,306.6500,306.6500,0,1,0.1354007,-0.6645271,0.0010841,9.0515885,-0.0693236,-23.7502506
SPX 307BJRA4ULL66|SPX 31,SPX 160219P02255000,253.2500,253.2500,218.8000,219.9000,0,27,0.1072147,-0.9889949,0.0003314,0.2362197,0.0393797,-3.5646897
SPX 307BJR0TGGY6M|SPX 31,SPX 160219P02270000,268.2000,268.2000,233.7500,234.6500,0,42,0.1097526,-0.9915136,0.0002580,0.1882298,0.0439272,-3.5967280
SPX 306D340F8ZVJI|SPX 31,SPX 160115P02275000,268.9000,268.9000,234.8500,235.2000,1,989,0.1502243,-0.9977869,0.0000897,0.0358539,0.0506404,-1.4524972
SPX 307BJRA85OA5Q|SPX 31,SPX 160219P02275000,273.1500,273.1500,238.6500,239.8000,0,,0.1165480,-0.9890666,0.0003032,0.2348800,0.0381765,-3.5968935
SPX 307BJRA9T7MNI|SPX 31,SPX 160219P02285000,283.2500,283.2500,248.5000,249.8000,0,,0.1157191,-0.9918963,0.0002350,0.1807532,0.0441380,-3.6219236
SPX 308349M4G3XRI|SPX 31,SPX 160318P02300000,300.9000,300.9000,265.5500,267.3500,0,8,0.1035636,-0.9898057,0.0002639,0.2688163,0.0461874,-5.3809359
SPX 308349N3CAF0U|SPX 31,SPX 160318P02340000,341.1000,341.1000,306.1500,307.4500,0,,0.1132381,-0.9924401,0.0001857,0.2068420,0.0499831,-5.4878901
SPX 306D33R1VF7YM|SPX 31,SPX 160115P02350000,344.0000,344.0000,309.1000,310.1000,0,1886,0.1973292,-0.9974908,0.0000765,0.0401692,0.0472415,-1.5001055
SPX 30GIDYFRHT4I6|SPX 31,SPX 170120P02350000,381.8500,381.8500,349.5500,351.0000,0,,0.1170745,-0.8454231,0.0009586,5.0411630,-0.0192518,-21.9173430
SPX 30D2BMXI546SU|SPX 31,SPX 160916P02375000,391.1500,391.1500,355.9500,357.9000,0,,0.1071692,-0.9375024,0.0006564,2.1501176,0.0183033,-16.4332837
SPX 30D2BMMPBZL0U|SPX 31,SPX 160916P02400000,414.8000,414.8000,379.5500,381.4500,0,1,0.1056372,-0.9528673,0.0005327,1.7200003,0.0288819,-16.8356699
SPX 306D33R3IYKGE|SPX 31,SPX 160115P02450000,443.8500,443.8500,409.2000,410.1000,0,139,0.3519454,-0.9762871,0.0003038,0.2923100,-0.1485294,-1.5791527
SPX 30PIC177C21AM|SPX 31,SPX 171215P02550000,586.6000,586.6000,556.1000,556.1000,0,,0.1197581,-0.8696460,0.0006166,6.0836361,0.0114237,-44.6917555
SPX 306D33Q3H3QUM|SPX 31,SPX 160115P02700000,693.6000,693.6000,658.9500,659.9000,0,15,0.3536146,-0.9989883,0.0000187,0.0175562,0.0605847,-1.7259446
SPX 30GIDYG1F17GU|SPX 31,SPX 170120P02950000,959.0500,959.0500,924.9500,925.3500,0,32,0.1368213,-0.9928582,0.0000684,0.4203798,0.0722799,-31.3804655
SPX 30AKPY4BI21JI|SPX 31,SPX 160617P03000000,1003.7000,1003.7000,969.6500,970.1500,0,1,0.1885837,-0.9977076,0.0000268,0.1019835,0.0762484,-14.4853822
SPX 30KJ4O5LKJW6M|SPX 31,SPX 170616P03100000,1108.9500,1108.9500,1074.8000,1075.0000,0,,0.1352842,-0.9911172,0.0000715,0.5966810,0.0757556,-45.0474478
1 #symbol_id symbol_value open high low close volume open_interest implied_volatility delta gamma vega theta rho
2 SPX WLF4IPHQKPF2|SPX 31 SPX 170616C00300000 1645.4000 1680.2000 1645.4000 1679.5000 0 0.5645710 0.9991909 0.0000020 0.0688230 -0.0116314 4.3540311
3 SPX W87JLJTDKMY6|SPX 31 SPX 160219C00400000 1599.4000 1633.6500 1599.4000 1633.0500 0 1.2263960 0.9998213 0.0000007 0.0055627 -0.0167744 0.6379273
4 SPX WHEDSZ06EEQ6|SPX 31 SPX 170120C00650000 1316.1500 1350.2000 1316.1500 1349.7500 0 0.4460003 0.9967469 0.0000104 0.2085762 -0.0292000 6.8641754
5 SPX W87JLK5489AM|SPX 31 SPX 160219C00750000 1249.9500 1284.1500 1249.9500 1283.6000 0 0.8045122 0.9994710 0.0000029 0.0152662 -0.0310045 1.1954716
6 SPX W8Z446DUDDSE|SPX 31 SPX 160318C00750000 1246.3000 1281.3500 1246.3000 1280.0500 0 375 0.7097078 0.9989528 0.0000050 0.0348394 -0.0347495 1.7648360
7 SPX WHEDSZ1TXR7Y|SPX 31 SPX 170120C00750000 1218.2500 1252.3500 1218.2500 1251.3000 0 0.4216917 0.9942234 0.0000184 0.3484318 -0.0385812 7.8685124
8 SPX WQEBVQED3Z0U|SPX 31 SPX 171215C00750000 1194.5500 1230.4000 1194.5500 1228.0500 0 2225 0.3770008 0.9856338 0.0000337 1.0473987 -0.0464553 13.8605867
9 SPX WHEDSYQR3H2M|SPX 31 SPX 170120C00800000 1169.5000 1203.5000 1169.5000 1202.8500 0 0.4111890 0.9924080 0.0000240 0.4436537 -0.0443187 8.3564435
10 SPX W87JLNL5H566|SPX 31 SPX 160219C00825000 1175.0500 1209.6000 1175.0500 1208.7000 0 0.7563814 0.9991781 0.0000046 0.0229242 -0.0373710 1.3141723
11 SPX WDYBH707U1HQ|SPX 31 SPX 160916C00850000 1129.1000 1162.8000 1129.1000 1162.4500 0 35 0.4329086 0.9948040 0.0000198 0.2616087 -0.0438890 6.1156183
12 SPX W8Z44A25B04U|SPX 31 SPX 160318C00875000 1121.7000 1157.1500 1121.7000 1155.4500 0 0.6397557 0.9980221 0.0000099 0.0622530 -0.0468518 2.0550019
13 SPX WQEBVU2O1LDA|SPX 31 SPX 171215C00875000 1077.6000 1112.8500 1077.6000 1110.5500 0 0.3564302 0.9759429 0.0000553 1.6243412 -0.0618721 15.8078513
14 SPX WDYBH6NNEQWE|SPX 31 SPX 160916C00900000 1079.9500 1113.5500 1079.9500 1113.1500 0 35 0.4199418 0.9932746 0.0000256 0.3288676 -0.0497828 6.4546762
15 SPX WQEBVQ3G80XA|SPX 31 SPX 171215C00900000 1054.4000 1089.6500 1054.4000 1087.3000 0 6 0.3522833 0.9736241 0.0000604 1.7545569 -0.0650898 16.1785666
16 SPX WHEDT2YEK41A|SPX 31 SPX 170120C00925000 1048.2500 1081.9500 1048.2500 1081.3000 0 0.3843426 0.9862823 0.0000430 0.7431784 -0.0603953 9.5360099
17 SPX WDYBH71VDDZI|SPX 31 SPX 160916C00950000 1031.2000 1064.4500 1031.2000 1064.0500 0 33 0.4082785 0.9912878 0.0000331 0.4130281 -0.0567045 6.7859533
18 SPX W792YEH1UXYM|SPX 31 SPX 160115C00975000 1030.4000 1064.4000 1030.4000 1064.1000 0 0.8994549 0.9996082 0.0000031 0.0073128 -0.0407479 0.6231797
19 SPX WBGPST1BBV5A|SPX 31 SPX 160617C01025000 964.3500 999.2500 964.3500 997.6500 0 14 0.4292979 0.9931313 0.0000314 0.2723833 -0.0604854 4.8812934
20 SPX W87JLOQHWTIM|SPX 31 SPX 160219C01075000 925.5000 959.9000 925.5000 959.1500 0 0.5770101 0.9981138 0.0000128 0.0490153 -0.0535211 1.7096209
21 SPX W9QOMSBZJ8A6|SPX 31 SPX 160415C01100000 896.0500 931.2000 896.0500 929.3000 0 0.4440084 0.9956028 0.0000254 0.1471616 -0.0583435 3.4053797
22 SPX W792YF5UX5DA|SPX 31 SPX 160115C01125000 880.4500 914.7500 880.4500 914.2000 0 4 0.7570591 0.9993217 0.0000060 0.0121530 -0.0504513 0.7187471
23 SPX WHEDSZ8G3572|SPX 31 SPX 170120C01150000 833.7000 865.9500 833.7000 865.6500 0 0.3424358 0.9654098 0.0001054 1.6219049 -0.0993420 11.4070635
24 SPX W87JLP71AAGE|SPX 31 SPX 160219C01175000 825.8500 860.4000 825.8500 859.3500 0 0.5144098 0.9973656 0.0000194 0.0663447 -0.0612208 1.8667091
25 SPX W8Z446M4249A|SPX 31 SPX 160318C01250000 748.1500 783.6500 748.1500 781.6500 0 91 0.4205737 0.9938876 0.0000414 0.1714339 -0.0755422 2.9191418
26 SPX WHEDT4KAD9BI|SPX 31 SPX 170120C01275000 717.4500 748.7000 717.4500 748.3000 0 0.3198755 0.9463878 0.0001608 2.3104699 -0.1247837 12.2571484
27 SPX W87JLPVUCHV2|SPX 31 SPX 160219C01325000 676.3500 710.8500 676.3500 709.8500 0 0.4289266 0.9954479 0.0000380 0.1084310 -0.0758182 2.0996481
28 SPX WGFX5PIUHFKE|SPX 31 SPX 161216C01350000 647.5500 678.1500 647.5500 677.7500 0 6 0.3124158 0.9353554 0.0001997 2.5543624 -0.1434911 11.6644756
29 SPX W792YGB7CTPQ|SPX 31 SPX 160115C01375000 630.8000 665.1500 630.8000 664.4500 0 2 0.5385865 0.9984825 0.0000177 0.0254412 -0.0668818 0.8775487
30 SPX W792YAMMMXSE|SPX 31 SPX 160115C01380000 625.8000 660.1500 625.8000 659.5000 0 1 0.5339671 0.9984706 0.0000180 0.0256227 -0.0669738 0.8807319
31 SPX W87JLQ92N9TA|SPX 31 SPX 160219C01405000 596.9500 632.3500 596.9500 629.8500 0 0.3903544 0.9933209 0.0000587 0.1524337 -0.0890141 2.2201115
32 SPX W87JLKG16CJY|SPX 31 SPX 160219C01410000 591.9000 627.3500 591.9000 624.9500 0 0.3886194 0.9930834 0.0000609 0.1572128 -0.0905014 2.2272795
33 SPX W792YGHTI7OU|SPX 31 SPX 160115C01415000 590.7500 625.5500 590.7500 624.5000 0 0.5184349 0.9978520 0.0000253 0.0348963 -0.0773331 0.9022825
34 SPX W9QOMYTU07SE|SPX 31 SPX 160415C01425000 575.9000 609.8500 575.9000 607.8000 0 0.3358098 0.9781339 0.0001362 0.5959515 -0.1251014 4.3008465
35 SPX W87JLKGD30NI|SPX 31 SPX 160219C01430000 572.0500 607.4500 572.0500 605.0500 0 0.3783131 0.9924785 0.0000673 0.1692770 -0.0935352 2.2571571
36 SPX W792YGOFNLNY|SPX 31 SPX 160115C01455000 550.9000 585.3000 550.9000 584.5500 0 0.4819829 0.9976969 0.0000290 0.0371715 -0.0780442 0.9276687
37 SPX WGFX5VOGFSKU|SPX 31 SPX 161216C01475000 535.4000 564.4500 535.4000 564.0000 0 4 0.2897630 0.9039086 0.0002907 3.4483957 -0.1728517 12.1559167
38 SPX WQEBVQ4FY17Y|SPX 31 SPX 171215C01500000 535.4500 563.3000 535.4500 561.5500 0 1976 0.2740688 0.8508117 0.0002953 6.6684104 -0.1562808 21.6678011
39 SPX W87JLQR9K38U|SPX 31 SPX 160219C01515000 488.1000 522.6500 488.1000 520.8000 0 0.3409151 0.9880499 0.0001120 0.2537433 -0.1148475 2.3777795
40 SPX W87JLQSX3FQM|SPX 31 SPX 160219C01525000 478.2000 513.3000 478.2000 510.6500 0 1 0.3362004 0.9874406 0.0001185 0.2649169 -0.1172789 2.3916774
41 SPX W8Z44D1N8K8E|SPX 31 SPX 160318C01525000 477.5500 512.2500 477.5500 509.2000 0 50 0.3196344 0.9750631 0.0001840 0.5784418 -0.1472430 3.4720851
42 SPX W792YH1NYDM6|SPX 31 SPX 160115C01535000 471.2000 506.2500 471.2000 504.7000 0 0.4312298 0.9961236 0.0000518 0.0594213 -0.0966394 0.9767285
43 SPX WBGPSP1FMTCE|SPX 31 SPX 160617C01550000 458.5000 490.0500 458.5000 487.7500 0 2 0.2924378 0.9293262 0.0003254 1.9225134 -0.1964160 6.7264627
44 SPX W792YAPLSYOE|SPX 31 SPX 160115C01560000 446.1500 480.3500 446.1500 479.7000 0 0.4089793 0.9959227 0.0000571 0.0621721 -0.0968909 0.9924591
45 SPX WQEBVXAFNVXQ|SPX 31 SPX 171215C01575000 477.7000 504.9500 477.7000 502.9500 0 1 0.2664059 0.8235028 0.0003389 7.4392316 -0.1670299 21.7307405
46 SPX W8Z446RKJ5VY|SPX 31 SPX 160318C01580000 424.4500 457.9000 424.4500 455.6000 0 0.3036111 0.9653636 0.0002544 0.7598357 -0.1746899 3.5522891
47 SPX W792YAQFKMXA|SPX 31 SPX 160115C01610000 396.3500 430.3500 396.3500 429.8000 0 0.3752410 0.9944929 0.0000814 0.0812880 -0.1090394 1.0225308
48 SPX W792YHEW95KE|SPX 31 SPX 160115C01615000 391.3500 425.7500 391.3500 424.8500 0 0.3677265 0.9947505 0.0000796 0.0778979 -0.1052164 1.0260815
49 SPX W87JLR7SXK6M|SPX 31 SPX 160219C01615000 389.6500 424.5500 389.6500 421.6000 0 0.2970814 0.9790806 0.0002077 0.4100980 -0.1473258 2.5069858
50 SPX W792YAQLIYZ2|SPX 31 SPX 160115C01620000 386.4500 420.5500 386.4500 419.8500 0 0.3693423 0.9940498 0.0000886 0.0870680 -0.1128301 1.0283337
51 SPX W8Z446S8CI32|SPX 31 SPX 160318C01620000 386.4000 419.1500 386.4000 416.7500 0 0.2920030 0.9560963 0.0003208 0.9216154 -0.1974771 3.5993014
52 SPX W9QOMZQWR5NY|SPX 31 SPX 160415C01625000 384.9000 416.8000 384.9000 414.4500 0 0.2827285 0.9373480 0.0003818 1.4063101 -0.2144573 4.6461259
53 SPX WHEDT6666ELQ|SPX 31 SPX 170120C01625000 410.9500 437.0000 410.9500 436.7000 0 0.2633631 0.8426314 0.0004312 5.1009916 -0.2041412 13.3354292
54 SPX WQEBVXIPCMEM|SPX 31 SPX 171215C01625000 440.0000 465.2000 440.0000 464.6500 0 1 0.2588607 0.8049213 0.0003711 7.9159018 -0.1717398 21.7746986
55 SPX W87JLRB40966|SPX 31 SPX 160219C01635000 370.2500 404.1000 370.2500 402.0000 0 0.2925643 0.9749739 0.0002452 0.4769439 -0.1627994 2.5248841
56 SPX WDYBH7DG4TFY|SPX 31 SPX 160916C01650000 377.4000 405.5000 377.4000 403.3500 0 1 0.2646369 0.8596318 0.0004819 3.8983561 -0.2282365 9.6681473
57 SPX W87JLKK60PSE|SPX 31 SPX 160219C01660000 346.1000 379.6000 346.1000 377.2500 0 0.2858663 0.9692561 0.0002979 0.5661490 -0.1822581 2.5452730
58 SPX W792YARFAN7Y|SPX 31 SPX 160115C01670000 336.4500 372.0500 336.4500 369.8000 0 0.3349806 0.9919198 0.0001280 0.1140731 -0.1270337 1.0574753
59 SPX W8Z446T246BY|SPX 31 SPX 160318C01670000 339.2000 371.4500 339.2000 368.9000 0 0.2787353 0.9403281 0.0004290 1.1764203 -0.2319473 3.6365396
60 SPX W9QOMZZ6FW4U|SPX 31 SPX 160415C01675000 338.9000 369.9500 338.9000 367.4000 0 0.2708628 0.9182459 0.0004888 1.7247810 -0.2450943 4.6711559
61 SPX WLF4IX6941NY|SPX 31 SPX 170616C01675000 386.5500 411.3000 386.5500 410.2000 0 206 0.2559680 0.7979195 0.0004432 6.9952647 -0.1969952 17.1180194
62 SPX WQEBVXQZ1CVI|SPX 31 SPX 171215C01675000 403.6500 428.1500 403.6500 427.3500 0 0.2536030 0.7837099 0.0004028 8.4161832 -0.1774755 21.6610361
63 SPX W792YARL8Z9Q|SPX 31 SPX 160115C01680000 326.6000 362.3500 326.6000 359.7000 0 0.3282050 0.9913742 0.0001383 0.1208094 -0.1303536 1.0631443
64 SPX W87JLJVIYZLA|SPX 31 SPX 160219C01700000 307.9000 340.7500 307.9000 338.2500 2 100 0.2710299 0.9596416 0.0003928 0.7077202 -0.2084670 2.5764236
65 SPX W87JLRMOROMM|SPX 31 SPX 160219C01705000 303.1500 336.0000 303.1500 333.4000 0 5 0.2695824 0.9580145 0.0004078 0.7307676 -0.2129538 2.5788553
66 SPX W87JLKKZSE1A|SPX 31 SPX 160219C01710000 298.3500 330.6000 298.3500 328.7000 0 391 0.2671723 0.9568556 0.0004206 0.7470356 -0.2152381 2.5829192
67 SPX W87JLKLHNE6M|SPX 31 SPX 160219C01740000 270.3000 302.3000 270.3000 299.8000 0 1 0.2586189 0.9452439 0.0005257 0.9038196 -0.2446421 2.5911932
68 SPX W9QOMT33VZ7Y|SPX 31 SPX 160415C01750000 271.8500 301.3000 271.8500 298.4000 0 1 0.2529977 0.8794222 0.0006951 2.2908550 -0.2939513 4.6385652
69 SPX W792YI21S0HA|SPX 31 SPX 160115C01755000 252.8000 287.7000 252.8000 285.3500 0 30 0.2809842 0.9843871 0.0002704 0.2021996 -0.1687400 1.1017952
70 SPX W87JLKLTK2A6|SPX 31 SPX 160219C01760000 251.8500 283.2500 251.8500 280.6500 0 2 0.2534856 0.9354897 0.0006099 1.0277508 -0.2675560 2.5897937
71 SPX WGFX5X22K7E6|SPX 31 SPX 161216C01775000 288.5000 312.8000 288.5000 311.1000 0 208 0.2415411 0.7701669 0.0006211 6.1408160 -0.2396644 11.9639122
72 SPX WLF4IXV2692M|SPX 31 SPX 170616C01825000 278.7500 301.0500 278.7500 299.5000 0 0.2370116 0.7189723 0.0005730 8.3738196 -0.2135787 16.3893229
73 SPX W792YILW86EM|SPX 31 SPX 160115C01875000 138.2000 168.1000 138.2000 167.7500 0 311 0.2206215 0.9383794 0.0010687 0.6274656 -0.3440539 1.1170559
74 SPX W792YIQUU7VY|SPX 31 SPX 160115C01905000 111.5000 139.4500 111.5000 139.4500 0 43 0.2052160 0.9110505 0.0015206 0.8304474 -0.4117672 1.0997141
75 SPX WDYBHFGINR72|SPX 31 SPX 160916C01925000 167.1000 186.6500 167.1000 185.2000 0 1248 0.2168822 0.6706878 0.0009543 6.3263057 -0.2870967 8.4434270
76 SPX WGFX5XQVMESU|SPX 31 SPX 161216C01925000 184.2500 203.4500 184.2500 201.9500 0 6050 0.2202923 0.6618350 0.0008204 7.3976920 -0.2569692 10.8628904
77 SPX W792YIVTG9DA|SPX 31 SPX 160115C01935000 86.9000 111.9500 86.9000 111.9500 0 37 0.1942960 0.8648286 0.0021680 1.1210321 -0.5113530 1.0569459
78 SPX W792YIXGZLV2|SPX 31 SPX 160115C01945000 78.9500 103.2000 78.9500 103.0000 0 25 0.1920156 0.8434360 0.0024216 1.2374284 -0.5527540 1.0345885
79 SPX W792YJ2FLNCE|SPX 31 SPX 160115C01975000 56.7000 77.7500 56.7000 77.6500 3 6213 0.1793074 0.7701806 0.0032812 1.5657520 -0.6416950 0.9553907
80 SPX W8Z44F5PYIY6|SPX 31 SPX 160318C01985000 79.9500 97.2000 79.9500 96.3000 1 1144 0.1918408 0.6403834 0.0019655 3.7092035 -0.4447822 2.8345966
81 SPX W8Z446YCMVWU|SPX 31 SPX 160318C01990000 76.7500 93.6000 76.7500 92.8000 0 1746 0.1905150 0.6308826 0.0019966 3.7418845 -0.4451046 2.7970127
82 SPX W792YJ5QOCBY|SPX 31 SPX 160115C01995000 43.4500 61.8000 43.4500 61.7000 2 3807 0.1720926 0.7044251 0.0038900 1.7815384 -0.6937457 0.8796007
83 SPX W87JLSYNCQY6|SPX 31 SPX 160219C01995000 61.3500 78.0000 61.3500 77.6000 0 3 0.1797382 0.6411392 0.0025501 3.0469899 -0.5026754 1.9554142
84 SPX W792YAX1Q0WE|SPX 31 SPX 160115C02010000 34.4500 50.7500 34.4500 50.5500 40 1496 0.1654320 0.6473269 0.0043521 1.9160549 -0.7130899 0.8122092
85 SPX W8Z44FAOKKFI|SPX 31 SPX 160318C02015000 61.6500 76.9000 61.6500 76.0000 6473 6757 0.1826994 0.5808721 0.0021562 3.8752027 -0.4399529 2.5964864
86 SPX W8Z44FDZN9F2|SPX 31 SPX 160318C02035000 50.6000 64.5000 50.6000 63.5000 20 7510 0.1771730 0.5371121 0.0022605 3.9396506 -0.4320663 2.4152438
87 SPX WDYBH7K2A7F2|SPX 31 SPX 160916C02050000 92.7500 106.4500 92.7500 105.6500 0 3123 0.1480432 0.5314403 0.0015365 6.9532140 -0.2185950 7.1943522
88 SPX W87JLKQS63RI|SPX 31 SPX 160219C02060000 26.9000 37.6500 26.9000 36.9500 41 3466 0.1385793 0.4488341 0.0035017 3.2259496 -0.4070410 1.4042845
89 SPX W8Z446ZIB89A|SPX 31 SPX 160318C02060000 38.3000 50.0000 38.3000 49.1000 0 3158 0.1441809 0.4691114 0.0027814 3.9449177 -0.3541393 2.1460035
90 SPX W87JLTBVNIWE|SPX 31 SPX 160219C02075000 21.0500 30.1000 21.0500 29.4500 202 8591 0.1335993 0.3931053 0.0035301 3.1352633 -0.3799933 1.2347037
91 SPX WQEBVZL4J8MM|SPX 31 SPX 171215C02075000 159.5000 174.0500 159.5000 173.9000 0 2280 0.1502318 0.5464233 0.0009189 11.3736365 -0.1438674 18.6344625
92 SPX W87JLKR42RV2|SPX 31 SPX 160219C02080000 19.2000 27.8000 19.2000 27.2000 6 615 0.1318164 0.3739989 0.0035252 3.0891213 -0.3689916 1.1761985
93 SPX WDYBH7KK57KE|SPX 31 SPX 160916C02080000 77.7000 90.0500 77.7000 89.3000 0 0.1449510 0.4844475 0.0015730 6.9695845 -0.2128389 6.6060019
94 SPX W87JLKRRW426|SPX 31 SPX 160219C02120000 8.4000 13.1000 7.9500 12.4500 78 449 0.1202474 0.2256706 0.0030642 2.4494331 -0.2645901 0.7157904
95 SPX W87JLTK5C9DA|SPX 31 SPX 160219C02125000 7.4500 11.5000 6.8500 11.1000 1934 10590 0.1186198 0.2078700 0.0029620 2.3357530 -0.2486666 0.6599968
96 SPX W8Z44FUJ0QCU|SPX 31 SPX 160318C02135000 12.3500 18.2000 11.9000 17.0000 2 522 0.1231776 0.2423887 0.0025583 3.0999410 -0.2341397 1.1292115
97 SPX W792YAZ74DJI|SPX 31 SPX 160115C02140000 0.8500 1.1750 0.6250 1.1250 139 6129 0.1120017 0.0474727 0.0017125 0.5104426 -0.1249653 0.0612411
98 SPX W8Z44FXU3FCE|SPX 31 SPX 160318C02155000 8.4500 12.7000 7.8000 11.7000 0 41 0.1185776 0.1868202 0.0022835 2.6635791 -0.1929683 0.8735870
99 SPX W792YAZJ11N2|SPX 31 SPX 160115C02160000 0.5250 0.9000 0.4750 0.5750 280 11869 0.1149455 0.0258133 0.0010124 0.3096968 -0.0776062 0.0333233
100 SPX W87JLTQRHNCE|SPX 31 SPX 160219C02165000 2.6500 5.1500 2.1000 3.7500 138 3735 0.1083499 0.0924711 0.0018755 1.3508982 -0.1304557 0.2955089
101 SPX W792YAZOZDOU|SPX 31 SPX 160115C02170000 0.4750 0.7000 0.3250 0.4500 59 8098 0.1181081 0.0202848 0.0008043 0.2527893 -0.0650134 0.0261875
102 SPX W87JLKSRM4CU|SPX 31 SPX 160219C02180000 1.7500 3.9250 0.9250 2.3000 262 623 0.1051642 0.0628441 0.0014405 1.0070383 -0.0941741 0.2012153
103 SPX W792YK15VXPQ|SPX 31 SPX 160115C02185000 0.4250 0.5750 0.1250 0.3750 17 1679 0.1257968 0.0162874 0.0006263 0.2096652 -0.0573423 0.0210184
104 SPX W792YB00W1SE|SPX 31 SPX 160115C02190000 0.2250 0.5250 0.1500 0.3500 252 1852 0.1281431 0.0150769 0.0005754 0.1962236 -0.0546421 0.0194543
105 SPX WBGPSPD0E8SU|SPX 31 SPX 160617C02250000 7.8500 11.0500 6.9500 9.8000 65 13213 0.1134352 0.1262099 0.0012854 2.9456098 -0.1009768 1.2029193
106 SPX WDYBHHAO5MY6|SPX 31 SPX 160916C02325000 7.9000 10.8000 6.8500 9.4000 0 4776 0.1110559 0.1049692 0.0009363 3.1784400 -0.0713729 1.5047417
107 SPX W87JLKVKTT72|SPX 31 SPX 160219C02350000 0.2500 0.2750 0.1750 0.2000 0 1549 0.1371840 0.0056798 0.0001448 0.1320484 -0.0158306 0.0181985
108 SPX WBGPSOFRR41A|SPX 31 SPX 160617C02400000 0.5500 0.9750 0.5250 0.8750 2 6075 0.1049012 0.0167364 0.0002790 0.5912789 -0.0183964 0.1615706
109 SPX WHEDT9UH663Y|SPX 31 SPX 170120C02425000 7.7500 10.2000 6.8500 9.0000 0 2 0.1103905 0.0869899 0.0006767 3.3555799 -0.0515788 1.8196500
110 SPX WQEBW170CDWU|SPX 31 SPX 171215C02425000 38.2500 43.1000 38.2500 42.9500 0 285 0.1271522 0.2211194 0.0008136 8.5238328 -0.0860999 8.0904228
111 SPX W87JLKX8D5OU|SPX 31 SPX 160219C02450000 0.2000 0.2250 0.1250 0.1500 5 5 0.1675611 0.0036438 0.0000798 0.0888465 -0.0129531 0.0116403
112 SPX WGFX5Q11E8ZY|SPX 31 SPX 161216C02450000 4.4500 6.5000 3.2000 5.1000 0 1555 0.1073466 0.0572345 0.0005286 2.3224112 -0.0377441 1.0987418
113 SPX WHEDSZVLM03Y|SPX 31 SPX 170120C02550000 1.6000 3.5500 1.0750 2.4500 0 60 0.1053714 0.0294781 0.0003003 1.4212355 -0.0205668 0.6229424
114 SPX WQEBVR84S7WU|SPX 31 SPX 171215C02550000 18.4500 21.1500 18.2000 20.9500 0 1002 0.1197581 0.1303540 0.0006166 6.0836361 -0.0570684 4.8529920
115 SPX W9QOMSEGU90U|SPX 31 SPX 160415C02600000 0.4000 0.4000 0.2000 0.2000 0 0.1574953 0.0037085 0.0000616 0.1263486 -0.0089016 0.0230657
116 SPX WLF4IQP2E972|SPX 31 SPX 170616C02650000 3.0250 4.3500 2.4250 3.3500 0 124 0.1071022 0.0335799 0.0002808 1.8545378 -0.0201287 0.9657172
117 SPX WHEDSYU26626|SPX 31 SPX 170120C02800000 0.7500 1.4500 0.1750 0.7500 0 42 0.1214194 0.0090302 0.0000947 0.5166668 -0.0084376 0.1908371
118 SPX WLF4IPLVF2NI|SPX 31 SPX 170616C02800000 1.1750 2.6500 0.8750 1.7000 0 32 0.1139066 0.0174242 0.0001522 1.0691848 -0.0121749 0.5017116
119 SPX WGFX5OX0PJDA|SPX 31 SPX 161216C03000000 0.2000 0.2000 0.1750 0.1750 0 3407 0.1309221 0.0023137 0.0000273 0.1463881 -0.0027910 0.0447262
120 SPX WQEBVQ2GK5SE|SPX 31 SPX 171215C03000000 1.0500 1.9250 0.8500 1.8500 0 619 0.1171266 0.0162029 0.0001204 1.1614247 -0.0102573 0.6180910
121 SPX WHEDSYV1W6CU|SPX 31 SPX 170120C03400000 1.1000 2.4000 0.2000 1.1000 0 0.1937197 0.0085389 0.0000565 0.4919384 -0.0125294 0.1762280
122 SPX WQEBVQ7R0Q7I|SPX 31 SPX 171215C03500000 0.8000 0.8000 0.8000 0.8000 0 855 0.1427460 0.0063931 0.0000439 0.5162667 -0.0054291 0.2424916
123 SPX 30GIDYEOYNA5Q|SPX 31 SPX 170120P00200000 0.6250 2.0250 0.5500 0.6250 0 2500 0.8443776 -0.0009787 0.0000018 0.0699676 -0.0074186 -0.0283154
124 SPX 30GIDYEP4LM7I|SPX 31 SPX 170120P00300000 0.6750 1.3750 0.2750 0.6750 0 3 0.7005073 -0.0013026 0.0000029 0.0909172 -0.0079835 -0.0359899
125 SPX 308349M1AZKTQ|SPX 31 SPX 160318P00400000 0.1000 0.1500 0.0750 0.0750 2200 2449 1.0398633 -0.0002530 0.0000009 0.0093601 -0.0056187 -0.0013980
126 SPX 30PIC1625MU5Q|SPX 31 SPX 171215P00600000 2.5500 2.5500 2.0750 2.1000 0 4598 0.3838042 -0.0050724 0.0000133 0.4203998 -0.0108120 -0.2465638
127 SPX 307BJR02NYQ6M|SPX 31 SPX 160219P00650000 0.1500 0.3750 0.1000 0.1000 0 5594 0.9151450 -0.0004642 0.0000022 0.0135268 -0.0105762 -0.0016734
128 SPX 308349M1SUKZ2|SPX 31 SPX 160318P00700000 0.3250 0.5000 0.2500 0.3250 0 140 0.7828174 -0.0013311 0.0000056 0.0433964 -0.0195842 -0.0071909
129 SPX 30PIC162BL67I|SPX 31 SPX 171215P00700000 5.7000 6.6500 3.2000 5.2250 0 762 0.3857143 -0.0113956 0.0000270 0.8572045 -0.0220744 -0.5639604
130 SPX 307BJR04BI2OE|SPX 31 SPX 160219P00750000 0.1750 0.4000 0.0750 0.1000 200 5105 0.8045122 -0.0005290 0.0000029 0.0152662 -0.0104893 -0.0018845
131 SPX 30FJXB584J5ZI|SPX 31 SPX 161216P00750000 1.5500 1.8750 1.3500 1.4500 3 729 0.4265415 -0.0046894 0.0000158 0.2762895 -0.0160952 -0.1084097
132 SPX 308349M1YSX0U|SPX 31 SPX 160318P00800000 0.2500 0.2500 0.2000 0.2250 0 850 0.6660016 -0.0011170 0.0000056 0.0369614 -0.0141828 -0.0059213
133 SPX 30GIDYF2OQX3I|SPX 31 SPX 170120P00850000 3.6750 4.2500 1.8750 3.1750 0 7 0.3998820 -0.0096719 0.0000305 0.5486448 -0.0271888 -0.2473751
134 SPX 308UOS8AUWDKE|SPX 31 SPX 160415P00900000 0.4250 0.5000 0.2500 0.3500 0 0.5318746 -0.0018288 0.0000096 0.0667115 -0.0154010 -0.0127802
135 SPX 30D2BMMMUOKA6|SPX 31 SPX 160916P00900000 2.3000 3.6250 1.1500 1.8000 0 29 0.4199418 -0.0067254 0.0000256 0.3288676 -0.0253059 -0.1140584
136 SPX 30GIDYIXLTXF2|SPX 31 SPX 170120P00925000 5.1500 5.5000 2.9250 4.5000 0 13 0.3843426 -0.0137177 0.0000430 0.7431784 -0.0353252 -0.3507602
137 SPX 30KJ4O9PF2U0E|SPX 31 SPX 170616P00925000 9.1000 9.7500 6.4000 8.1000 0 12 0.3637835 -0.0207223 0.0000552 1.2390154 -0.0402500 -0.7467432
138 SPX 306D33QEPWD1Q|SPX 31 SPX 160115P00950000 0.0750 0.2000 0.0750 0.2000 0 8518 1.0431385 -0.0012301 0.0000076 0.0210001 -0.0468044 -0.0017335
139 SPX 30PIC16GVGHE6|SPX 31 SPX 171215P00950000 16.2000 16.2000 12.8000 14.7000 0 4 0.3444228 -0.0315524 0.0000718 2.0363875 -0.0463168 -1.5649583
140 SPX 306D33UG94RCE|SPX 31 SPX 160115P00975000 0.0750 0.2000 0.0500 0.0500 0 1343 0.8994549 -0.0003918 0.0000031 0.0073128 -0.0140527 -0.0005434
141 SPX 30FJXB4VW2ONI|SPX 31 SPX 161216P01000000 6.2000 7.1500 3.8000 5.3000 0 19663 0.3764142 -0.0169775 0.0000553 0.8519946 -0.0435273 -0.3929798
142 SPX 30PIC16IIZTVY|SPX 31 SPX 171215P01050000 22.8500 22.8500 18.9000 20.7000 0 344 0.3303574 -0.0443633 0.0000988 2.6897160 -0.0583724 -2.2038466
143 SPX 308349QYFBRE6|SPX 31 SPX 160318P01075000 0.6500 0.8000 0.3500 0.5750 0 73 0.5123902 -0.0034421 0.0000204 0.1026910 -0.0302546 -0.0179677
144 SPX 30PIC1B77R33I|SPX 31 SPX 171215P01125000 28.9000 28.9000 25.5000 26.3500 0 40 0.3206743 -0.0562694 0.0001231 3.2511130 -0.0681918 -2.7998683
145 SPX 30GIDYKB7YC8E|SPX 31 SPX 170120P01225000 17.1500 17.4500 13.5500 14.7500 0 1 0.3283348 -0.0450194 0.0001363 2.0096120 -0.0807390 -1.1506805
146 SPX 30GIDYF9AWB2M|SPX 31 SPX 170120P01250000 18.7000 18.9000 15.0000 16.1000 0 6050 0.3241007 -0.0491715 0.0001482 2.1569074 -0.0854434 -1.2569280
147 SPX 307BJR0CR5572|SPX 31 SPX 160219P01260000 0.7000 0.8000 0.3250 0.4500 0 13 0.4663332 -0.0036481 0.0000287 0.0889417 -0.0353161 -0.0126139
148 SPX 306D33QK0F2MM|SPX 31 SPX 160115P01270000 0.2000 0.3250 0.0750 0.0750 0 932 0.6111681 -0.0008357 0.0000091 0.0147294 -0.0192157 -0.0011388
149 SPX 306D33Q15R25Q|SPX 31 SPX 160115P01300000 0.1750 0.3000 0.0750 0.0750 0 19034 0.5829447 -0.0008749 0.0000099 0.0153634 -0.0191148 -0.0011899
150 SPX 30PIC163BB6I6|SPX 31 SPX 171215P01300000 47.6500 47.6500 42.9500 43.5000 0 3169 0.2969671 -0.0912619 0.0001925 4.7096920 -0.0903860 -4.5491285
151 SPX 308349S3RRFQM|SPX 31 SPX 160318P01325000 1.7750 1.7750 0.7250 1.1250 2 3552 0.3872169 -0.0083068 0.0000590 0.2247105 -0.0498798 -0.0427379
152 SPX 30GIDYFAYFNKE|SPX 31 SPX 170120P01350000 26.2000 26.2000 21.6000 22.5000 0 3 0.3069835 -0.0686883 0.0002034 2.8045133 -0.1047024 -1.7560280
153 SPX 308349MNGQAA6|SPX 31 SPX 160318P01380000 2.3250 2.3250 0.7500 1.4500 1 24 0.3667209 -0.0109883 0.0000795 0.2869682 -0.0602726 -0.0564429
154 SPX 306D33QMNOFF2|SPX 31 SPX 160115P01430000 0.3000 0.4750 0.1750 0.2000 0 552 0.5113301 -0.0024623 0.0000290 0.0394902 -0.0430688 -0.0033419
155 SPX 306D33QMTMRGU|SPX 31 SPX 160115P01440000 0.3250 0.4750 0.1500 0.1750 0 561 0.4955332 -0.0022421 0.0000275 0.0362796 -0.0383422 -0.0030384
156 SPX 30D2BMN9CBXU6|SPX 31 SPX 160916P01450000 22.4000 22.4000 17.4000 18.3500 0 1071 0.3028158 -0.0706492 0.0002554 2.3641894 -0.1289329 -1.1946741
157 SPX 30GIDYFCLZ026|SPX 31 SPX 170120P01450000 35.7500 35.7500 29.9500 30.8500 0 201 0.2902959 -0.0940248 0.0002726 3.5550322 -0.1247479 -2.4044279
158 SPX 30PIC16P557V2|SPX 31 SPX 171215P01450000 70.1000 70.1000 63.9000 63.9000 0 574 0.2782710 -0.1320766 0.0002678 6.1390476 -0.1089578 -6.5997131
159 SPX 307BJR6GJLTNY|SPX 31 SPX 160219P01455000 1.5250 1.5250 0.6500 0.8750 0 2 0.3659108 -0.0084182 0.0000768 0.1869014 -0.0580937 -0.0288457
160 SPX 306D33QNHG3NY|SPX 31 SPX 160115P01480000 0.3750 0.5250 0.1750 0.2000 0 580 0.4657679 -0.0026908 0.0000345 0.0427875 -0.0424922 -0.0036400
161 SPX 308349MP49MRY|SPX 31 SPX 160318P01480000 3.8500 3.8500 1.4500 2.4500 0 10 0.3334475 -0.0191770 0.0001413 0.4633849 -0.0883165 -0.0983126
162 SPX 308349MPA7YTQ|SPX 31 SPX 160318P01490000 4.0500 4.0500 1.5750 2.5750 0 3 0.3300468 -0.0202416 0.0001494 0.4851356 -0.0914973 -0.1037477
163 SPX 307BJR6QGTWMM|SPX 31 SPX 160219P01515000 2.1250 3.3000 0.8750 1.2000 0 273 0.3409151 -0.0119501 0.0001120 0.2537433 -0.0734070 -0.0408799
164 SPX 308349MPS2YZ2|SPX 31 SPX 160318P01520000 4.8000 4.8000 1.9500 3.0500 3 10 0.3208775 -0.0241289 0.0001783 0.5626700 -0.1030953 -0.1236270
165 SPX 306D33WZ7OUI6|SPX 31 SPX 160115P01525000 0.4250 0.5000 0.1750 0.2250 699 5304 0.4310307 -0.0032271 0.0000439 0.0504036 -0.0463059 -0.0043561
166 SPX 30AKPYBB7H17Y|SPX 31 SPX 160617P01525000 16.6500 16.8000 11.9000 12.7000 0 1685 0.2976933 -0.0634037 0.0002939 1.7676770 -0.1444567 -0.6897765
167 SPX 30D2BMNAZVABY|SPX 31 SPX 160916P01550000 31.6500 31.6500 24.9500 26.1000 0 6313 0.2828323 -0.0998917 0.0003546 3.0658873 -0.1552669 -1.6884516
168 SPX 306D33X5TU8HA|SPX 31 SPX 160115P01565000 0.4750 1.9000 0.2000 0.3000 0 836 0.4084018 -0.0044194 0.0000615 0.0668168 -0.0581412 -0.0059602
169 SPX 307BJR70E1ZLA|SPX 31 SPX 160219P01575000 3.0500 4.0500 1.2000 1.6250 122 590 0.3152644 -0.0168458 0.0001627 0.3410775 -0.0911333 -0.0575203
170 SPX 307BJR721LC32|SPX 31 SPX 160219P01585000 3.2500 4.2000 1.0500 1.7250 120 180 0.3114357 -0.0179751 0.0001741 0.3605102 -0.0951334 -0.0613636
171 SPX 30D2BMMO0CWMM|SPX 31 SPX 160916P01600000 37.5500 37.5500 29.9000 31.0000 45 6697 0.2735601 -0.1185646 0.0004147 3.4678194 -0.1692781 -2.0046058
172 SPX 308349THDVUJY|SPX 31 SPX 160318P01625000 8.7500 8.7500 4.4750 5.8000 0 3101 0.2920030 -0.0459574 0.0003329 0.9561637 -0.1589159 -0.2354242
173 SPX 30AKPY52AFZ7Y|SPX 31 SPX 160617P01650000 27.8000 27.8000 20.6000 21.5000 0 13620 0.2707476 -0.1071860 0.0004796 2.6232658 -0.1936445 -1.1664779
174 SPX 307BJR0JV5JBI|SPX 31 SPX 160219P01690000 6.4500 6.4500 3.4000 3.4000 0 71 0.2729638 -0.0368083 0.0003618 0.6565590 -0.1513829 -0.1254444
175 SPX 307BJQZUQ8SZ2|SPX 31 SPX 160219P01700000 6.9000 6.9000 3.4000 3.7500 6158 18442 0.2710299 -0.0403584 0.0003928 0.7077202 -0.1619661 -0.1375836
176 SPX 306D33XSZD3E6|SPX 31 SPX 160115P01705000 1.1750 1.1750 0.5000 0.6000 2000 2775 0.3133436 -0.0106094 0.0001736 0.1447693 -0.0964663 -0.0142313
177 SPX 308UOSG6NEFZI|SPX 31 SPX 160415P01725000 22.3000 22.3000 14.9500 15.9000 0 79 0.2588558 -0.1059929 0.0006197 2.0895153 -0.2301147 -0.7271863
178 SPX 30GIDYMLWTOXA|SPX 31 SPX 170120P01725000 79.4000 79.4000 68.5500 69.3000 0 92 0.2483602 -0.2064883 0.0005421 6.0476693 -0.1769886 -5.3019957
179 SPX 307BJR0KOX7KE|SPX 31 SPX 160219P01740000 9.1500 9.5500 4.5000 5.1000 5 242 0.2586189 -0.0547561 0.0005257 0.9038196 -0.1970470 -0.1866730
180 SPX 308349MTF2C26|SPX 31 SPX 160318P01740000 17.0500 17.0500 10.3000 11.4000 0 640 0.2595655 -0.0905001 0.0006334 1.6172631 -0.2376634 -0.4635874
181 SPX 307BJR0L0TVNY|SPX 31 SPX 160219P01760000 10.5500 10.8000 5.3000 6.0500 21 125 0.2534856 -0.0645103 0.0006099 1.0277508 -0.2194139 -0.2200020
182 SPX 307BJR0LCQJRI|SPX 31 SPX 160219P01780000 12.1500 12.1500 6.4500 7.0500 2 771 0.2472524 -0.0750139 0.0007023 1.1543217 -0.2401216 -0.2558441
183 SPX 306D33Y7V77U6|SPX 31 SPX 160115P01795000 2.8250 3.5750 1.1500 1.1750 7 708 0.2580984 -0.0230741 0.0004104 0.2818623 -0.1543594 -0.0308682
184 SPX 307BJR82FEYY6|SPX 31 SPX 160219P01805000 14.4000 14.4000 8.0500 8.5000 78 705 0.2391202 -0.0902500 0.0008346 1.3267678 -0.2665147 -0.3078272
185 SPX 306D33QSXX5AM|SPX 31 SPX 160115P01810000 3.3500 3.3500 1.0750 1.3750 5 4542 0.2502900 -0.0272511 0.0004865 0.3240449 -0.1720044 -0.0364482
186 SPX 307BJR0LULJWU|SPX 31 SPX 160219P01810000 14.9500 14.9500 7.8000 8.8500 90 657 0.2377142 -0.0938400 0.0008642 1.3656482 -0.2726242 -0.3200978
187 SPX 308349MUKQOEM|SPX 31 SPX 160318P01810000 25.3000 25.3000 16.6500 17.3000 10 66 0.2402146 -0.1360801 0.0009163 2.1652120 -0.2930407 -0.6974356
188 SPX 30GIDYN2G75V2|SPX 31 SPX 170120P01825000 104.3500 104.3500 92.1500 92.1500 0 1293 0.2341101 -0.2670830 0.0006628 6.9695491 -0.1894292 -6.8779061
189 SPX 308349MV8K0LQ|SPX 31 SPX 160318P01850000 31.5500 31.5500 20.5500 21.9000 72 45165 0.2287598 -0.1708180 0.0011188 2.5175600 -0.3232809 -0.8758051
190 SPX 307BJR8CCN1WU|SPX 31 SPX 160219P01865000 22.0000 22.0000 12.9500 13.3000 20 56 0.2192485 -0.1402251 0.0012465 1.8167400 -0.3330349 -0.4784354
191 SPX 308349UMQBIWE|SPX 31 SPX 160318P01875000 36.2000 36.2000 24.3000 25.4000 0 12666 0.2222305 -0.1972509 0.0012596 2.7536321 -0.3425611 -1.0119070
192 SPX 307BJR8FNPQWE|SPX 31 SPX 160219P01885000 25.3000 25.3000 15.1500 15.6000 0 54 0.2132588 -0.1630226 0.0014165 2.0081747 -0.3573504 -0.5564415
193 SPX 30D2BMMOI7WRY|SPX 31 SPX 160916P01900000 99.1500 99.1500 84.8000 84.8500 2 11412 0.2222040 -0.3070082 0.0009043 6.1418876 -0.2347999 -5.2256279
194 SPX 30KJ4O5JL3VLA|SPX 31 SPX 170616P01900000 158.4500 158.4500 142.9500 143.3000 0 2138 0.2286266 -0.3277939 0.0006362 8.9685613 -0.1671467 -12.0352779
195 SPX 307BJR8IYSFVY|SPX 31 SPX 160219P01905000 29.1000 29.1000 17.8000 18.3500 5 1327 0.2075139 -0.1894886 0.0016012 2.2088872 -0.3815945 -0.6471338
196 SPX 30AKPYD5CYWZ2|SPX 31 SPX 160617P01925000 80.7500 80.7500 65.2500 65.8500 2 13145 0.2127640 -0.3103932 0.0011673 5.0171623 -0.2817946 -3.3931857
197 SPX 30PIC1EVIQULQ|SPX 31 SPX 171215P01925000 199.0000 199.0000 183.0000 183.4500 0 52 0.2296949 -0.3442662 0.0005584 10.5672544 -0.1435190 -17.5456483
198 SPX 30GIDYFKVNQJ2|SPX 31 SPX 170120P01950000 145.2500 145.2500 127.3000 128.4500 0 911 0.2168368 -0.3599549 0.0008140 7.9287154 -0.1943503 -9.3170030
199 SPX 307BJR8SW0IUM|SPX 31 SPX 160219P01965000 44.5000 44.5000 29.2000 29.6000 0 56 0.1901740 -0.2928870 0.0022178 2.8038710 -0.4396276 -1.0024895
200 SPX 306D33QVR4U4U|SPX 31 SPX 160115P01980000 27.3500 27.3500 13.3500 13.6000 116 8380 0.1774544 -0.2449790 0.0034339 1.6216499 -0.6017653 -0.3284500
201 SPX 30GIDYEOYPFBI|SPX 31 SPX 170120P02000000 165.2000 165.2000 145.8500 146.5500 0 1406 0.2106717 -0.4024716 0.0008667 8.2012553 -0.1925597 -10.4498772
202 SPX 306D33Z890UPA|SPX 31 SPX 160115P02015000 40.6500 40.6500 22.1000 22.2000 132 1911 0.1624016 -0.3729958 0.0045185 1.9528468 -0.6572466 -0.5009800
203 SPX 306D33QWEY6BY|SPX 31 SPX 160115P02020000 43.0500 43.0500 23.4000 23.8000 203 4859 0.1607398 -0.3951520 0.0046440 1.9865465 -0.6606104 -0.5309671
204 SPX 308349VGHZRSE|SPX 31 SPX 160318P02055000 96.7500 96.7500 73.8500 74.4000 0 3194 0.1436139 -0.5172686 0.0027982 3.9530763 -0.2980601 -2.6439984
205 SPX 306D33ZI68XNY|SPX 31 SPX 160115P02075000 76.6000 76.6000 48.4500 48.6500 138 15372 0.1302403 -0.6899382 0.0052513 1.8201273 -0.4674408 -0.9311358
206 SPX 30GIDYO7SMU7I|SPX 31 SPX 170120P02075000 199.6500 199.6500 176.9000 178.1000 0 459 0.1443269 -0.4879257 0.0013036 8.4513182 -0.1238483 -12.1462246
207 SPX 308349VS2R78U|SPX 31 SPX 160318P02125000 141.1000 141.1000 111.6500 112.7000 0 2005 0.1255134 -0.7282786 0.0026645 3.2898223 -0.1956009 -3.7528466
208 SPX 30AKPY5AK4POU|SPX 31 SPX 160617P02150000 186.4500 186.4500 159.3000 159.3000 0 2938 0.1302054 -0.6862551 0.0019162 5.0405047 -0.1429440 -7.4618434
209 SPX 30FJXBEVFBWJ2|SPX 31 SPX 161216P02175000 248.5000 248.5000 221.8500 222.9000 0 206 0.1372965 -0.6306911 0.0013584 7.6342048 -0.1056634 -14.4357949
210 SPX 30PIC1G0V6IY6|SPX 31 SPX 171215P02175000 317.5000 317.5000 293.8500 295.5500 0 2 0.1444271 -0.5471694 0.0009556 11.3711186 -0.0769349 -26.4628765
211 SPX 307BJR0RYVXQM|SPX 31 SPX 160219P02180000 180.2500 180.2500 145.4500 146.9500 0 2 0.1051642 -0.9371559 0.0014405 1.0070383 -0.0345435 -3.2790998
212 SPX 306D34020P3LA|SPX 31 SPX 160115P02195000 189.1500 189.1500 154.4000 155.4500 0 2 0.1274493 -0.9877998 0.0004819 0.1634542 0.0148439 -1.3884289
213 SPX 307BJQZVK0H7Y|SPX 31 SPX 160219P02200000 199.2500 199.2500 164.3500 165.9000 0 462 0.1055729 -0.9592075 0.0010172 0.7138919 -0.0066290 -3.3814846
214 SPX 307BJR0SGQXVY|SPX 31 SPX 160219P02210000 208.8500 208.8500 174.3500 175.6500 0 0.1030093 -0.9710228 0.0007871 0.5390252 0.0112908 -3.4352116
215 SPX 30FJXBF3P0MZY|SPX 31 SPX 161216P02225000 281.2000 281.2000 251.6500 253.7000 0 53 0.1291852 -0.7054864 0.0013191 6.9753209 -0.0802204 -16.2270317
216 SPX 306D33R01XJF2|SPX 31 SPX 160115P02240000 234.0000 234.0000 199.5500 200.3000 0 0.1556804 -0.9906471 0.0003130 0.1296842 0.0176101 -1.4209162
217 SPX 30KJ4O6HNIOLQ|SPX 31 SPX 170616P02250000 332.8500 332.8500 306.6500 306.6500 0 1 0.1354007 -0.6645271 0.0010841 9.0515885 -0.0693236 -23.7502506
218 SPX 307BJRA4ULL66|SPX 31 SPX 160219P02255000 253.2500 253.2500 218.8000 219.9000 0 27 0.1072147 -0.9889949 0.0003314 0.2362197 0.0393797 -3.5646897
219 SPX 307BJR0TGGY6M|SPX 31 SPX 160219P02270000 268.2000 268.2000 233.7500 234.6500 0 42 0.1097526 -0.9915136 0.0002580 0.1882298 0.0439272 -3.5967280
220 SPX 306D340F8ZVJI|SPX 31 SPX 160115P02275000 268.9000 268.9000 234.8500 235.2000 1 989 0.1502243 -0.9977869 0.0000897 0.0358539 0.0506404 -1.4524972
221 SPX 307BJRA85OA5Q|SPX 31 SPX 160219P02275000 273.1500 273.1500 238.6500 239.8000 0 0.1165480 -0.9890666 0.0003032 0.2348800 0.0381765 -3.5968935
222 SPX 307BJRA9T7MNI|SPX 31 SPX 160219P02285000 283.2500 283.2500 248.5000 249.8000 0 0.1157191 -0.9918963 0.0002350 0.1807532 0.0441380 -3.6219236
223 SPX 308349M4G3XRI|SPX 31 SPX 160318P02300000 300.9000 300.9000 265.5500 267.3500 0 8 0.1035636 -0.9898057 0.0002639 0.2688163 0.0461874 -5.3809359
224 SPX 308349N3CAF0U|SPX 31 SPX 160318P02340000 341.1000 341.1000 306.1500 307.4500 0 0.1132381 -0.9924401 0.0001857 0.2068420 0.0499831 -5.4878901
225 SPX 306D33R1VF7YM|SPX 31 SPX 160115P02350000 344.0000 344.0000 309.1000 310.1000 0 1886 0.1973292 -0.9974908 0.0000765 0.0401692 0.0472415 -1.5001055
226 SPX 30GIDYFRHT4I6|SPX 31 SPX 170120P02350000 381.8500 381.8500 349.5500 351.0000 0 0.1170745 -0.8454231 0.0009586 5.0411630 -0.0192518 -21.9173430
227 SPX 30D2BMXI546SU|SPX 31 SPX 160916P02375000 391.1500 391.1500 355.9500 357.9000 0 0.1071692 -0.9375024 0.0006564 2.1501176 0.0183033 -16.4332837
228 SPX 30D2BMMPBZL0U|SPX 31 SPX 160916P02400000 414.8000 414.8000 379.5500 381.4500 0 1 0.1056372 -0.9528673 0.0005327 1.7200003 0.0288819 -16.8356699
229 SPX 306D33R3IYKGE|SPX 31 SPX 160115P02450000 443.8500 443.8500 409.2000 410.1000 0 139 0.3519454 -0.9762871 0.0003038 0.2923100 -0.1485294 -1.5791527
230 SPX 30PIC177C21AM|SPX 31 SPX 171215P02550000 586.6000 586.6000 556.1000 556.1000 0 0.1197581 -0.8696460 0.0006166 6.0836361 0.0114237 -44.6917555
231 SPX 306D33Q3H3QUM|SPX 31 SPX 160115P02700000 693.6000 693.6000 658.9500 659.9000 0 15 0.3536146 -0.9989883 0.0000187 0.0175562 0.0605847 -1.7259446
232 SPX 30GIDYG1F17GU|SPX 31 SPX 170120P02950000 959.0500 959.0500 924.9500 925.3500 0 32 0.1368213 -0.9928582 0.0000684 0.4203798 0.0722799 -31.3804655
233 SPX 30AKPY4BI21JI|SPX 31 SPX 160617P03000000 1003.7000 1003.7000 969.6500 970.1500 0 1 0.1885837 -0.9977076 0.0000268 0.1019835 0.0762484 -14.4853822
234 SPX 30KJ4O5LKJW6M|SPX 31 SPX 170616P03100000 1108.9500 1108.9500 1074.8000 1075.0000 0 0.1352842 -0.9911172 0.0000715 0.5966810 0.0757556 -45.0474478

View File

@@ -0,0 +1,273 @@
#symbol_id,symbol_value,open,high,low,close,volume,open_interest,implied_volatility,delta,gamma,vega,theta,rho
SPX X0JMQES2VX66|SPX 31,SPX 181221C00300000,1631.1500,1646.4000,1626.5000,1646.4000,0,3,0.5074832,0.9961985,0.0000062,0.4044020,-0.0170694,8.4016626
SPX W8Z44629O3HQ|SPX 31,SPX 160318C00500000,1529.5000,1554.7000,1529.5000,1551.9500,0,44,0.9496134,0.9995536,0.0000017,0.0159735,-0.0225226,1.1641986
SPX WHEDSYQ98GXA|SPX 31,SPX 170120C00500000,1497.4000,1524.2000,1497.4000,1519.9000,0,,0.5337475,0.9978515,0.0000059,0.1449944,-0.0232440,5.2738365
SPX W8Z446AJAOSU|SPX 31,SPX 160318C00550000,1479.6000,1504.8000,1479.6000,1502.1000,0,32,0.9009002,0.9994409,0.0000022,0.0196735,-0.0253789,1.2802607
SPX W9QOMSB5RK1A|SPX 31,SPX 160415C00600000,1427.3500,1455.3500,1427.3500,1450.0000,0,,0.7585941,0.9991593,0.0000033,0.0330273,-0.0273840,1.8516596
SPX WDYBH6WWRCI6|SPX 31,SPX 160916C00650000,1360.1000,1387.3000,1360.1000,1382.7000,0,,0.5110809,0.9979943,0.0000070,0.1123068,-0.0282824,4.6918128
SPX WBGPSOO7C1E6|SPX 31,SPX 160617C00750000,1270.4000,1297.6000,1270.4000,1293.0500,0,1832,0.5279093,0.9984403,0.0000067,0.0725575,-0.0312097,3.5890924
SPX WQEBVTUECUWE|SPX 31,SPX 171215C00825000,1157.3500,1183.8000,1157.3500,1179.2000,0,,0.3640240,0.9814946,0.0000429,1.3162543,-0.0540443,15.0822757
SPX WLF4IPIQAPPQ|SPX 31,SPX 170616C00900000,1096.2500,1123.7000,1096.2500,1118.4000,0,,0.3680870,0.9825946,0.0000465,1.0804654,-0.0599242,12.4956358
SPX WDYBH6MBU7NY|SPX 31,SPX 160916C01000000,1015.0000,1042.1500,1015.0000,1037.4500,0,250,0.3992342,0.9896513,0.0000389,0.4851699,-0.0627592,7.0947658
SPX W87JLOI8831Q|SPX 31,SPX 160219C01025000,1009.0500,1035.5500,1009.0500,1031.4500,0,,0.6201123,0.9985451,0.0000094,0.0388357,-0.0489404,1.6033199
SPX WLF4IPYLSPAM|SPX 31,SPX 170616C01050000,954.6000,981.3000,954.6000,976.2000,0,,0.3423531,0.9690246,0.0000813,1.7549149,-0.0818528,14.1903006
SPX WGFX5OYCA2LQ|SPX 31,SPX 161216C01100000,913.3000,939.5000,913.3000,935.2000,0,400,0.3578960,0.9761501,0.0000767,1.1491187,-0.0856704,10.1379875
SPX W87JLKBQDN9Q|SPX 31,SPX 160219C01150000,884.2500,910.6000,884.2500,906.6500,0,,0.5345471,0.9979737,0.0000147,0.0525059,-0.0557988,1.7975328
SPX WLF4IUVK8OZ2|SPX 31,SPX 170616C01175000,838.6000,863.7500,838.6000,859.7500,0,,0.3228105,0.9524202,0.0001223,2.4897469,-0.1028839,15.4089756
SPX W8Z4463FCFU6|SPX 31,SPX 160318C01200000,831.4500,859.0000,831.4500,853.8500,0,3,0.4518739,0.9953701,0.0000299,0.1347870,-0.0681934,2.7759611
SPX WGFX5OYI8ENI|SPX 31,SPX 161216C01200000,818.0500,844.0000,818.0500,839.6500,0,415,0.3411811,0.9642814,0.0001126,1.6070758,-0.1067282,10.8324282
SPX W87JLPFAZ0XA|SPX 31,SPX 160219C01225000,809.4500,835.9000,809.4500,831.7500,0,,0.4962165,0.9971019,0.0000218,0.0725777,-0.0647254,1.9122346
SPX WBGPSTYE2T0U|SPX 31,SPX 160617C01225000,800.5500,828.6000,800.5500,822.6500,0,1,0.3713871,0.9849667,0.0000712,0.5444489,-0.0897895,5.7256255
SPX WHEDT4C0OIUM|SPX 31,SPX 170120C01225000,795.0000,820.5500,795.0000,816.3000,0,,0.3286970,0.9583192,0.0001265,1.9094129,-0.1102476,11.9865846
SPX W792YAKBA93I|SPX 31,SPX 160115C01240000,799.3000,825.3000,799.3000,821.3000,0,,0.6686491,0.9992268,0.0000078,0.0135822,-0.0542099,0.7582937
SPX W792YFUNZCRY|SPX 31,SPX 160115C01275000,764.4000,790.3000,764.4000,786.3000,0,16,0.6344248,0.9991855,0.0000086,0.0142485,-0.0550716,0.7796738
SPX WGFX5URDOUPA|SPX 31,SPX 161216C01275000,747.5000,773.0000,747.5000,768.7000,0,,0.3247342,0.9543778,0.0001443,1.9603408,-0.1204412,11.3323806
SPX W8Z446MLX4EM|SPX 31,SPX 160318C01280000,751.7000,779.6000,751.7000,774.2000,0,,0.4149083,0.9936816,0.0000430,0.1776970,-0.0777887,2.9540047
SPX WHEDSYRKV5BI|SPX 31,SPX 170120C01300000,725.1500,750.2500,725.1500,746.1000,0,,0.3130411,0.9472322,0.0001605,2.3069748,-0.1235802,12.5031701
SPX W87JLKEDN026|SPX 31,SPX 160219C01310000,724.7000,751.7000,724.7000,746.9500,0,,0.4459521,0.9962025,0.0000310,0.0925426,-0.0715782,2.0425778
SPX W9QOMYDAMQUM|SPX 31,SPX 160415C01325000,706.2000,733.5000,706.2000,728.4500,0,,0.3698967,0.9883636,0.0000715,0.3498595,-0.0925584,4.0222549
SPX WQEBVW5387LA|SPX 31,SPX 171215C01325000,706.4000,730.0500,706.4000,726.1000,0,,0.2923231,0.9085509,0.0001936,4.7721211,-0.1257910,21.1168754
SPX W87JLKFDD0CU|SPX 31,SPX 160219C01370000,664.9000,691.4000,664.9000,687.1500,0,,0.4105680,0.9954710,0.0000394,0.1083394,-0.0759756,2.1342755
SPX W792YGB7CTPQ|SPX 31,SPX 160115C01375000,664.4500,690.4000,664.4500,686.4000,0,2,0.5410294,0.9990506,0.0000116,0.0164045,-0.0574348,0.8407385
SPX W87JLKFJBCEM|SPX 31,SPX 160219C01380000,655.0500,683.3500,655.0500,677.2000,0,,0.4083245,0.9950368,0.0000430,0.1175581,-0.0792923,2.1484801
SPX W87JLQ92N9TA|SPX 31,SPX 160219C01405000,629.8500,658.4000,629.8500,652.3000,0,,0.4013579,0.9939208,0.0000524,0.1407725,-0.0873169,2.1838920
SPX WHEDT593FGQ6|SPX 31,SPX 170120C01425000,611.0000,635.2000,611.0000,631.1000,0,,0.2934548,0.9198775,0.0002367,3.1896020,-0.1523536,13.1303125
SPX W87JLQE19BAM|SPX 31,SPX 160219C01435000,600.2000,625.8000,600.2000,622.4000,0,,0.3847895,0.9932495,0.0000599,0.1544442,-0.0906506,2.2287107
SPX W9QOMSY59XQM|SPX 31,SPX 160415C01450000,583.5000,610.5500,583.5000,605.3000,0,,0.3338572,0.9776867,0.0001383,0.6110601,-0.1282258,4.3359258
SPX W792YAO47Y8E|SPX 31,SPX 160115C01470000,569.6000,595.5000,569.6000,591.5000,0,,0.4875229,0.9980046,0.0000254,0.0323302,-0.0753704,0.8975430
SPX W8Z44CTDJTRI|SPX 31,SPX 160318C01475000,558.6000,585.4000,558.6000,580.8000,0,,0.3400749,0.9838327,0.0001190,0.4031742,-0.1196535,3.3587000
SPX WHEDT5HD4772|SPX 31,SPX 170120C01475000,566.3500,590.2000,566.3500,586.0000,0,,0.2853202,0.9064639,0.0002733,3.5808133,-0.1637199,13.3177065
SPX X0JMQLJIOBJI|SPX 31,SPX 181221C01475000,609.0500,618.3500,605.9500,618.3500,0,,0.2696868,0.8455862,0.0002467,8.4922175,-0.1325455,30.4086411
SPX W8Z4463X7FZI|SPX 31,SPX 160318C01500000,534.0000,560.2500,534.0000,556.3000,0,1504,0.3326526,0.9812327,0.0001381,0.4579276,-0.1290964,3.4037238
SPX WLF4IPJQ0Q0E|SPX 31,SPX 170616C01500000,551.8000,574.3500,551.8000,570.0000,0,1,0.2755165,0.8778523,0.0002927,5.0875098,-0.1619495,17.4271506
SPX W87JLQPM0QR2|SPX 31,SPX 160219C01505000,530.5500,557.2000,530.5500,552.6500,0,,0.3500967,0.9907999,0.0000865,0.2027820,-0.1025015,2.3302907
SPX W8Z446QEUTJI|SPX 31,SPX 160318C01510000,524.0500,550.2000,524.0500,546.3500,0,,0.3288294,0.9803218,0.0001455,0.4767526,-0.1319158,3.4224222
SPX W792YH00F14E|SPX 31,SPX 160115C01525000,514.6500,540.7000,514.6500,536.5000,0,5,0.4455192,0.9974946,0.0000342,0.0397341,-0.0811854,0.9305621
SPX WQEBVX25Z5GU|SPX 31,SPX 171215C01525000,542.1500,563.1000,542.1500,559.2500,0,1,0.2697516,0.8507823,0.0002966,6.7474371,-0.1565204,22.0581851
SPX W87JLKI0MD5A|SPX 31,SPX 160219C01530000,505.7500,531.9500,505.7500,527.9000,0,,0.3437577,0.9886221,0.0001060,0.2440627,-0.1143044,2.3621018
SPX W792YAP9WAKU|SPX 31,SPX 160115C01540000,499.7000,525.6000,499.7000,521.6000,0,,0.4381645,0.9971220,0.0000394,0.0450340,-0.0861127,0.9392608
SPX WHEDSZF28J66|SPX 31,SPX 170120C01550000,500.6000,523.6000,500.6000,519.5500,0,,0.2726148,0.8833753,0.0003356,4.2012595,-0.1799592,13.5232913
SPX W8Z446R8MHSE|SPX 31,SPX 160318C01560000,475.1000,501.2000,475.1000,497.2500,0,,0.3126946,0.9740120,0.0001934,0.6027087,-0.1514686,3.5068689
SPX W87JLKIOFPCE|SPX 31,SPX 160219C01570000,466.4000,492.2500,466.4000,488.2000,0,,0.3222835,0.9867387,0.0001291,0.2787013,-0.1204507,2.4185607
SPX WGFX5W4ZT9IM|SPX 31,SPX 161216C01575000,475.8500,499.0000,475.8500,494.7500,0,17,0.2715159,0.8803158,0.0003595,4.0841130,-0.1896667,12.5247352
SPX X0JMQM021SHA|SPX 31,SPX 181221C01575000,535.0500,543.9500,532.4500,543.8500,0,,0.2571128,0.8153407,0.0002902,9.5258955,-0.1402562,30.8896301
SPX W792YAQ3NYTQ|SPX 31,SPX 160115C01590000,449.8000,475.8000,449.8000,471.6000,0,,0.4037884,0.9961837,0.0000551,0.0580393,-0.0957067,0.9686610
SPX W87JLKJ0CDFY|SPX 31,SPX 160219C01590000,446.2500,472.4000,446.2500,468.3000,0,,0.3142690,0.9850053,0.0001472,0.3098241,-0.1274740,2.4440843
SPX W792YA2GC8XA|SPX 31,SPX 160115C01600000,439.9000,465.8000,439.9000,461.6500,0,106,0.3906100,0.9964248,0.0000537,0.0547397,-0.0914034,0.9751048
SPX W792YAQFKMXA|SPX 31,SPX 160115C01610000,429.8000,457.6000,429.8000,451.7000,0,,0.3902630,0.9957001,0.0000634,0.0645818,-0.1001796,0.9802810
SPX W87JLR7SXK6M|SPX 31,SPX 160219C01615000,421.6000,447.9500,421.6000,443.7000,0,,0.3045453,0.9824146,0.0001741,0.3551425,-0.1374089,2.4745558
SPX WQEBVXIPCMEM|SPX 31,SPX 171215C01625000,464.6500,484.3500,464.6500,480.4500,0,1,0.2558983,0.8158444,0.0003582,7.7297159,-0.1676970,22.2373311
SPX X0JMQM8BQIY6|SPX 31,SPX 181221C01625000,499.9000,507.9500,497.1000,507.9500,0,,0.2518610,0.7983074,0.0003127,10.0531464,-0.1441027,30.9570128
SPX W8Z446SQ7I8E|SPX 31,SPX 160318C01650000,388.1000,413.5500,388.1000,409.7000,1,71,0.2893290,0.9542610,0.0003325,0.9587400,-0.2048303,3.6156888
SPX W792YHLIEJJI|SPX 31,SPX 160115C01655000,384.6000,410.8000,384.6000,406.7500,0,,0.3544613,0.9949072,0.0000812,0.0751068,-0.1045376,1.0068188
SPX W87JLREF2Y5Q|SPX 31,SPX 160219C01655000,382.3500,408.4000,382.3500,404.2500,0,,0.2908948,0.9765686,0.0002325,0.4529576,-0.1587335,2.5175301
SPX W8Z446SW5UA6|SPX 31,SPX 160318C01660000,378.3500,404.0500,378.3500,400.0500,0,,0.2846467,0.9524647,0.0003486,0.9888375,-0.2073862,3.6299733
SPX W792YHOTH8J2|SPX 31,SPX 160115C01675000,364.8000,391.0500,364.8000,386.8000,0,34,0.3402366,0.9943077,0.0000933,0.0829177,-0.1086036,1.0182923
SPX W9QOMZZ6FW4U|SPX 31,SPX 160415C01675000,367.4000,392.9000,367.4000,388.3500,0,,0.2738891,0.9286392,0.0004325,1.5676932,-0.2307990,4.6957227
SPX WGFX5WLJ6QGE|SPX 31,SPX 161216C01675000,391.1500,412.9500,391.1500,408.7500,0,,0.2563563,0.8385066,0.0004668,5.0070798,-0.2140187,12.5169081
SPX WHEDT6EFV52M|SPX 31,SPX 170120C01675000,395.3500,416.8500,395.3500,412.6500,0,,0.2528824,0.8335597,0.0004606,5.3496063,-0.2064510,13.5694331
SPX W8Z446TE0UFI|SPX 31,SPX 160318C01690000,350.1000,375.9000,350.1000,371.2500,0,1,0.2761911,0.9431858,0.0004139,1.1393316,-0.2270985,3.6525066
SPX W792YA2MAKZ2|SPX 31,SPX 160115C01700000,339.9000,365.9000,339.9000,361.8500,0,311,0.3214053,0.9935754,0.0001100,0.0923050,-0.1125005,1.0326595
SPX X0JMQEUE8LV2|SPX 31,SPX 181221C01700000,448.8000,455.8500,445.7500,455.8000,0,1,0.2450907,0.7704791,0.0003464,10.8360306,-0.1496605,30.8430248
SPX W9QON07G4MLQ|SPX 31,SPX 160415C01725000,321.1500,346.0500,321.1500,341.4500,0,,0.2614368,0.9076727,0.0005502,1.9039095,-0.2610512,4.7063562
SPX WHEDT6MPJVJI|SPX 31,SPX 170120C01725000,355.1000,375.6500,355.1000,371.6000,0,1,0.2454425,0.8090500,0.0005175,5.8331907,-0.2162178,13.4667924
SPX X0JMQMOV3ZVY|SPX 31,SPX 181221C01725000,432.0000,439.2000,428.9500,438.7500,0,,0.2433516,0.7605382,0.0003571,11.0932312,-0.1515622,30.7349475
SPX W8Z446UDQUQ6|SPX 31,SPX 160318C01750000,294.0500,319.0500,294.0500,314.3500,7,45,0.2593627,0.9189735,0.0005797,1.4985060,-0.2706208,3.6686071
SPX X0JMQFKIVCI6|SPX 31,SPX 181221C01750000,415.8500,422.7500,412.4000,422.1000,0,,0.2426309,0.7500428,0.0003665,11.3524393,-0.1539045,30.5511238
SPX W9QON0FPTD2M|SPX 31,SPX 160415C01775000,276.0500,300.3000,276.0500,295.6000,0,,0.2489763,0.8809810,0.0006944,2.2880519,-0.2925166,4.6774919
SPX WBGPSWHCMW6M|SPX 31,SPX 160617C01775000,285.5000,308.6500,285.5000,303.9500,0,11,0.2454818,0.8409723,0.0006880,3.4774442,-0.2805412,6.7950711
SPX WDYBHERPLJSE|SPX 31,SPX 160916C01775000,298.5000,320.0000,298.3000,315.4000,0,2,0.2412837,0.8078139,0.0006411,4.8281103,-0.2538920,9.6345019
SPX WBGPSOES13QM|SPX 31,SPX 160617C01800000,264.5000,285.5500,264.5000,282.4500,0,212,0.2404605,0.8243601,0.0007488,3.7074586,-0.2909177,6.7327094
SPX WHEDSYSEMTKE|SPX 31,SPX 170120C01800000,297.2500,316.4500,296.5500,312.3500,0,152,0.2363250,0.7657780,0.0006057,6.5733972,-0.2308410,13.1317596
SPX W87JLS4VOI26|SPX 31,SPX 160219C01815000,228.9000,253.6000,228.9000,249.5000,0,,0.2398703,0.9218293,0.0007442,1.1955025,-0.2949797,2.5831120
SPX W8Z446VJF72M|SPX 31,SPX 160318C01820000,230.3000,254.4000,230.3000,249.6500,0,,0.2400233,0.8776343,0.0008464,2.0246241,-0.3270445,3.6201698
SPX W87JLS6J7UJY|SPX 31,SPX 160219C01825000,219.6000,243.7000,219.6000,240.0500,2,15,0.2354393,0.9167474,0.0007951,1.2537416,-0.3022888,2.5816670
SPX WBGPSWPMBMNI|SPX 31,SPX 160617C01825000,243.9500,264.4500,243.8500,261.3000,0,32,0.2349557,0.8066513,0.0008136,3.9357835,-0.2999205,6.6586146
SPX WLF4IQBU3H8U|SPX 31,SPX 170616C01850000,281.8500,299.5500,281.2500,295.2000,0,25,0.2319993,0.7196672,0.0005780,8.4598352,-0.2124570,16.6704526
SPX W792YAUKF05Q|SPX 31,SPX 160115C01860000,182.3000,206.1500,182.3000,203.1000,0,7,0.2297447,0.9693723,0.0005896,0.3536994,-0.2308289,1.0993640
SPX X0JMQNDO67AM|SPX 31,SPX 181221C01875000,339.6500,344.8500,333.8500,342.5500,0,,0.2328493,0.6965429,0.0004201,12.4864643,-0.1600990,29.6733916
SPX W87JLJVUVNOU|SPX 31,SPX 160219C01900000,152.6000,174.0000,152.6000,171.2000,453,409,0.2124098,0.8521335,0.0013285,1.8899103,-0.3931311,2.4800267
SPX WBGPSOEXZFSE|SPX 31,SPX 160617C01900000,184.8000,203.4000,184.8000,200.4500,2,4677,0.2200827,0.7422108,0.0010226,4.6338883,-0.3248972,6.3084196
SPX WQEBVYWBH17Y|SPX 31,SPX 171215C01925000,258.0500,273.3000,257.6000,269.4000,0,54,0.2268889,0.6702006,0.0005495,10.5143773,-0.1934728,20.4781233
SPX WDYBH7IEQUXA|SPX 31,SPX 160916C01950000,168.0500,183.8000,168.0500,181.0000,0,3366,0.2126691,0.6715419,0.0009620,6.3862373,-0.2859906,8.5559844
SPX W792YAWDWOPA|SPX 31,SPX 160115C01970000,81.7500,101.2000,81.7500,98.7000,4,471,0.1844062,0.8555364,0.0024128,1.1617374,-0.5245266,1.0192411
SPX W8Z44F42F6GE|SPX 31,SPX 160318C01975000,103.5500,120.6500,103.5500,118.4500,0,3416,0.1973444,0.7038633,0.0017545,3.4505923,-0.4350236,3.0878533
SPX WBGPSXEFDU26|SPX 31,SPX 160617C01975000,130.7500,147.1000,130.7500,144.3000,0,3770,0.2039944,0.6615905,0.0012495,5.2482595,-0.3362820,5.7774594
SPX WLF4IYJV8GHA|SPX 31,SPX 170616C01975000,201.4000,214.6000,201.4000,212.0000,0,250,0.2183557,0.6387036,0.0006830,9.4083285,-0.2186447,15.4297552
SPX WQEBVZ4L5ROU|SPX 31,SPX 171215C01975000,228.3500,240.7000,228.3500,238.7500,0,718,0.2227069,0.6409332,0.0005779,10.8547759,-0.1948605,19.8886486
SPX W8Z446Y6OJV2|SPX 31,SPX 160318C01980000,99.9500,116.7500,99.9500,114.6500,0,30,0.1958987,0.6957117,0.0017892,3.4932184,-0.4366364,3.0574413
SPX W8Z44F7DHVFY|SPX 31,SPX 160318C01995000,89.4000,105.6500,89.4000,103.4000,60,3770,0.1922501,0.6696214,0.0018878,3.6170085,-0.4419366,2.9572184
SPX W9QOMSAI0CZY|SPX 31,SPX 160415C02000000,96.2000,111.7500,96.2000,109.6000,0,,0.1925584,0.6470722,0.0016771,4.2740542,-0.3961182,3.7555243
SPX W792YAX1Q0WE|SPX 31,SPX 160115C02010000,50.5500,66.8000,50.5500,64.7000,20,1503,0.1681608,0.7504179,0.0036949,1.6223361,-0.6504843,0.9071438
SPX W87JLT59I4XA|SPX 31,SPX 160219C02035000,51.1500,65.2500,51.1500,63.3000,0,30,0.1714312,0.6054112,0.0027438,3.1501563,-0.5029366,1.8489926
SPX W87JLKQG9FNY|SPX 31,SPX 160219C02040000,48.2000,61.9000,48.2000,60.0000,5,962,0.1699414,0.5920046,0.0027919,3.1775868,-0.5022421,1.8107291
SPX W87JLTBVNIWE|SPX 31,SPX 160219C02075000,29.4500,40.2500,29.4500,38.5500,40,8696,0.1287903,0.4820367,0.0037813,3.2614874,-0.3923286,1.5033698
SPX W8Z446ZU7WCU|SPX 31,SPX 160318C02080000,38.7500,49.9000,38.7500,47.9500,0,104,0.1326167,0.4801887,0.0030096,3.9777480,-0.3348289,2.2067355
SPX WDYBH7KK57KE|SPX 31,SPX 160916C02080000,89.3000,100.4000,89.3000,98.2000,0,,0.1397427,0.5229886,0.0016132,7.0366255,-0.2107788,7.1889247
SPX W9QOMSDN2KRY|SPX 31,SPX 160415C02100000,39.1500,49.1000,39.1500,47.3500,1,23,0.1310734,0.4381153,0.0026138,4.5342506,-0.2856155,2.6627046
SPX WHEDSYSWHTPQ|SPX 31,SPX 170120C02100000,105.1500,114.4000,105.1500,113.0000,0,1766,0.1366404,0.5103678,0.0013620,8.5464406,-0.1742698,10.1621199
SPX W792YAYV7PFY|SPX 31,SPX 160115C02120000,2.4750,4.6500,1.9500,4.4000,472,9459,0.1039753,0.1591405,0.0045635,1.2389010,-0.2968691,0.1985974
SPX W87JLTLSVLV2|SPX 31,SPX 160219C02135000,8.7000,14.0500,7.7000,12.5000,0,49,0.1107916,0.2391383,0.0034220,2.5390820,-0.2583766,0.7562169
SPX W87JLTNGEYCU|SPX 31,SPX 160219C02145000,6.6500,11.1500,5.7500,9.7000,1,271,0.1077472,0.2005290,0.0031801,2.2947455,-0.2265855,0.6353636
SPX X0JMQFR50QHA|SPX 31,SPX 181221C02150000,193.6500,198.4000,189.8500,197.8000,1,1,0.1435104,0.5322814,0.0007755,14.2066581,-0.1180188,27.0974021
SPX W8Z44FXU3FCE|SPX 31,SPX 160318C02155000,11.7000,17.5500,10.9500,15.5000,5,39,0.1137538,0.2383234,0.0027270,3.0915948,-0.2190418,1.1143824
SPX W792YJXUT8Q6|SPX 31,SPX 160115C02165000,0.5000,2.7750,0.4000,0.7250,48,1321,0.1039807,0.0348387,0.0014488,0.3933415,-0.0933895,0.0436212
SPX X0JMQORAAM3Y|SPX 31,SPX 181221C02175000,180.8500,187.0000,178.3500,186.4000,0,1,0.1469106,0.5157464,0.0007595,14.2422423,-0.1196811,26.2383014
SPX W87JLKSXKGEM|SPX 31,SPX 160219C02190000,1.7500,4.4750,0.9750,2.4250,3698,4836,0.0971003,0.0700238,0.0016901,1.0990872,-0.0969144,0.2233679
SPX W8Z44652VSBY|SPX 31,SPX 160318C02200000,4.2000,7.3500,3.3000,5.5500,216,71439,0.1027410,0.1132262,0.0018716,1.9163968,-0.1215767,0.5337181
SPX WBGPSOFFUFXQ|SPX 31,SPX 160617C02200000,19.9000,25.6500,19.0000,23.8000,5,30602,0.1167701,0.2468895,0.0018839,4.5295401,-0.1632652,2.3484533
SPX WHEDSYT2G5RI|SPX 31,SPX 170120C02200000,60.7000,67.3500,60.5000,65.8500,0,751,0.1269072,0.3685821,0.0013866,8.0811590,-0.1494453,7.5086265
SPX W8Z44725KL1Q|SPX 31,SPX 160318C02220000,2.5500,5.0750,2.2500,3.3000,152,1065,0.0995576,0.0752523,0.0014279,1.4167777,-0.0867827,0.3556164
SPX W792YK7S1BOU|SPX 31,SPX 160115C02225000,0.1250,1.6750,0.1250,0.1250,77,19922,0.1198492,0.0063583,0.0002923,0.0914618,-0.0248628,0.0079658
SPX WDYBHGU4S60E|SPX 31,SPX 160916C02225000,29.3000,35.1500,28.6500,33.2000,0,4225,0.1187515,0.2693588,0.0015741,5.8347416,-0.1439110,3.8324835
SPX WLF4IZP7O4TQ|SPX 31,SPX 170616C02225000,77.3500,83.1000,77.3500,81.9000,0,3,0.1321118,0.3844090,0.0011514,9.5966239,-0.1368132,10.5376231
SPX WHEDSZQMZYMM|SPX 31,SPX 170120C02250000,43.3500,48.3500,42.8000,47.2500,0,8,0.1243573,0.3017962,0.0013082,7.4711338,-0.1338522,6.1982258
SPX W87JLU5NBRSE|SPX 31,SPX 160219C02255000,0.3250,2.4500,0.2000,0.3750,0,414,0.0981084,0.0134813,0.0004302,0.2826900,-0.0249259,0.0431490
SPX W87JLKU38SR2|SPX 31,SPX 160219C02260000,0.2250,2.4250,0.2000,0.3500,0,298,0.0993784,0.0125615,0.0003996,0.2659361,-0.0237362,0.0402023
SPX W792YKJCSR5A|SPX 31,SPX 160115C02295000,0.0500,2.2750,0.0500,0.2500,0,142,0.1764869,0.0084405,0.0002548,0.1174045,-0.0467946,0.0105228
SPX WDYBH6PYRFLA|SPX 31,SPX 160916C02300000,12.8500,16.2500,11.5500,14.6000,500,5004,0.1093811,0.1515255,0.0012147,4.1471893,-0.0930024,2.1843531
SPX WGFX5P0BQ372|SPX 31,SPX 161216C02300000,24.6000,28.6000,23.8000,27.1000,200,21960,0.1158902,0.2122446,0.0012234,5.9318313,-0.1071760,4.0360413
SPX W87JLKUX0GZY|SPX 31,SPX 160219C02310000,0.2500,2.3500,0.2000,0.3000,0,1,0.1178357,0.0093764,0.0002613,0.2061776,-0.0216981,0.0299484
SPX WHEDT9DXSP66|SPX 31,SPX 170120C02325000,23.8500,27.3500,23.0500,26.0500,0,,0.1155299,0.1999425,0.0011306,5.9985432,-0.0986796,4.1665165
SPX WHEDT9M7HFN2|SPX 31,SPX 170120C02375000,15.0500,17.9000,13.9000,16.3500,0,11,0.1103924,0.1418318,0.0009492,4.8120632,-0.0750964,2.9794942
SPX WHEDT9UH663Y|SPX 31,SPX 170120C02425000,9.0000,11.5500,7.5000,9.7500,0,2,0.1059794,0.0949607,0.0007440,3.6209592,-0.0538833,2.0084387
SPX WBGPSPGBGXSE|SPX 31,SPX 160617C02450000,0.4500,0.4750,0.2750,0.4000,0,926,0.0991231,0.0086194,0.0001645,0.3358187,-0.0099136,0.0840392
SPX WGFX5P0NMRAM|SPX 31,SPX 161216C02500000,2.9500,5.0000,2.4000,3.0750,1,6152,0.1007874,0.0384180,0.0004045,1.7056840,-0.0260743,0.7485320
SPX X0JMQQD63RE6|SPX 31,SPX 181221C02525000,62.8000,67.8500,61.3000,64.4500,2,3,0.1296722,0.2572209,0.0006962,11.5245654,-0.0811240,13.9773667
SPX WGFX5Q2OXLHQ|SPX 31,SPX 161216C02550000,1.7500,3.8750,0.9750,1.8000,0,7907,0.1003838,0.0240803,0.0002758,1.1584400,-0.0175375,0.4704008
SPX WLF4IPLJIEJY|SPX 31,SPX 170616C02600000,5.2000,7.3500,3.3000,5.4000,0,21,0.1046483,0.0513295,0.0004007,2.6451709,-0.0283685,1.4886942
SPX WLF4IPLPGQLQ|SPX 31,SPX 170616C02700000,2.2500,4.2500,1.1500,2.3250,0,72,0.1029224,0.0248259,0.0002248,1.4593851,-0.0152388,0.7243138
SPX X0JMQG128TFY|SPX 31,SPX 181221C02750000,24.4000,29.7500,23.1500,25.9500,3,3,0.1208248,0.1305622,0.0004915,7.5806486,-0.0485609,7.2982136
SPX WHEDT00K81LA|SPX 31,SPX 170120C02850000,0.7250,2.5250,0.7000,0.7250,0,2,0.1227461,0.0085897,0.0000887,0.5000141,-0.0082672,0.1832839
SPX WLF4IPMDA2SU|SPX 31,SPX 170616C03100000,0.9500,2.8250,0.2000,0.9500,0,114,0.1316807,0.0090069,0.0000735,0.6109159,-0.0079270,0.2611785
SPX WLF4IPMP6QWE|SPX 31,SPX 170616C03300000,1.2250,2.9250,1.2250,1.2250,0,2,0.1540328,0.0098909,0.0000682,0.6630438,-0.0099760,0.2841633
SPX 30D2BMMLUYJZI|SPX 31,SPX 160916P00300000,0.1750,0.1750,0.1750,0.1750,0,210,0.7504850,-0.0004259,0.0000012,0.0270621,-0.0037692,-0.0077220
SPX 30KJ4O5GXUISU|SPX 31,SPX 170616P00300000,0.3750,0.4000,0.3250,0.3500,0,18,0.5643011,-0.0007518,0.0000018,0.0650577,-0.0033449,-0.0281577
SPX 308349M1GXWVI|SPX 31,SPX 160318P00500000,0.1250,0.3250,0.1250,0.1250,64,11573,0.9496134,-0.0004464,0.0000017,0.0159735,-0.0088559,-0.0024476
SPX 30AKPY4BTWKHA|SPX 31,SPX 160617P00500000,0.2000,0.2250,0.1750,0.1750,25,793,0.6808133,-0.0005914,0.0000021,0.0297829,-0.0057102,-0.0067436
SPX 30ZNMVURM2ENI|SPX 31,SPX 181221P00500000,5.8000,7.5000,3.5500,5.0000,0,,0.4081407,-0.0081330,0.0000153,0.7945726,-0.0142334,-0.6525862
SPX 308UOS8AD1DF2|SPX 31,SPX 160415P00600000,0.2250,0.2250,0.2250,0.2250,0,,0.7585941,-0.0008407,0.0000033,0.0330273,-0.0109966,-0.0060889
SPX 307BJR02NYQ6M|SPX 31,SPX 160219P00650000,0.1000,0.3250,0.1000,0.1000,0,5594,0.9317693,-0.0004545,0.0000021,0.0133137,-0.0107842,-0.0016317
SPX 30KJ4O5HLNUZY|SPX 31,SPX 170616P00700000,2.1000,3.7500,1.4750,2.0500,0,228,0.3921103,-0.0056009,0.0000162,0.4017594,-0.0142037,-0.2015160
SPX 30KJ4O5SUGH72|SPX 31,SPX 170616P00750000,3.6750,3.6750,2.6500,3.5000,0,763,0.3969730,-0.0089347,0.0000242,0.6066250,-0.0216813,-0.3248661
SPX 307BJQZT8NSJ2|SPX 31,SPX 160219P00800000,0.1250,0.2750,0.1000,0.1500,0,1179,0.7967114,-0.0007777,0.0000041,0.0218694,-0.0151386,-0.0027589
SPX 308349M1YSX0U|SPX 31,SPX 160318P00800000,0.2250,0.2500,0.2000,0.2250,5050,5800,0.6774949,-0.0010914,0.0000054,0.0364224,-0.0143854,-0.0057954
SPX 307BJR05Z1F66|SPX 31,SPX 160219P00850000,0.1500,0.4500,0.1500,0.1500,0,2407,0.7480620,-0.0008288,0.0000046,0.0231884,-0.0150684,-0.0029247
SPX 30AKPY4P2579Q|SPX 31,SPX 160617P00850000,0.5500,0.7750,0.4250,0.6000,0,182,0.4889727,-0.0025974,0.0000114,0.1152787,-0.0158172,-0.0288079
SPX 30ZNMVV4UB1FY|SPX 31,SPX 181221P00850000,21.9000,23.0500,19.0500,19.9000,0,,0.3433168,-0.0328259,0.0000598,2.6188366,-0.0387140,-2.6260548
SPX 30ZNMVYRHPBAM|SPX 31,SPX 181221P00875000,21.6500,23.2000,20.6000,21.5000,0,,0.3390035,-0.0353579,0.0000643,2.7838346,-0.0405718,-2.8267284
SPX 308UOS8P2V0NI|SPX 31,SPX 160415P00950000,0.4250,0.4750,0.2750,0.3750,0,,0.5114475,-0.0020125,0.0000108,0.0733538,-0.0164228,-0.0140677
SPX 30D2BMR2LVLNY|SPX 31,SPX 160916P00975000,2.6000,4.4250,1.5500,2.4750,0,29,0.4052078,-0.0092009,0.0000346,0.4378176,-0.0325888,-0.1572684
SPX 30KJ4O9XORKHA|SPX 31,SPX 170616P00975000,9.9000,11.1000,7.0500,9.2000,0,12,0.3550765,-0.0234891,0.0000622,1.3930885,-0.0441901,-0.8538664
SPX 306D33UOITHTA|SPX 31,SPX 160115P01025000,0.0500,2.2750,0.0500,0.2000,0,6700,0.9811261,-0.0013208,0.0000087,0.0221988,-0.0486124,-0.0017931
SPX 30AKPY4SD7W9A|SPX 31,SPX 160617P01050000,1.4500,3.4000,0.9500,1.3750,0,68,0.4184210,-0.0064553,0.0000302,0.2603040,-0.0304755,-0.0710316
SPX 30D2BMN2Q6JV2|SPX 31,SPX 160916P01050000,3.7000,5.3500,2.1000,3.4750,0,18,0.3876036,-0.0130172,0.0000489,0.5921010,-0.0420876,-0.2222980
SPX 30ZNMVV85DQFI|SPX 31,SPX 181221P01050000,36.6000,38.3000,34.9000,35.7000,0,,0.3154613,-0.0586771,0.0001039,4.1822590,-0.0560383,-4.6967459
SPX 308UOSD75GVVY|SPX 31,SPX 160415P01075000,0.6750,0.7500,0.5000,0.6250,0,,0.4592157,-0.0035773,0.0000203,0.1233070,-0.0247551,-0.0248769
SPX 30D2BMMN6L8DQ|SPX 31,SPX 160916P01100000,4.6500,6.0000,2.4500,4.3000,2,4000,0.3759760,-0.0161831,0.0000608,0.7141191,-0.0491778,-0.2761688
SPX 308UOSDNOUCTQ|SPX 31,SPX 160415P01175000,1.0250,1.1500,0.6000,0.9250,0,2,0.4200148,-0.0055788,0.0000330,0.1833738,-0.0336291,-0.0386411
SPX 30D2BMRZOMJJI|SPX 31,SPX 160916P01175000,6.4000,7.9500,4.2000,5.8500,0,182,0.3593222,-0.0222168,0.0000834,0.9349968,-0.0614122,-0.3788122
SPX 30PIC1BFHFTKE|SPX 31,SPX 171215P01175000,30.5500,30.5500,27.3500,28.5000,0,11,0.3119575,-0.0607422,0.0001328,3.4928229,-0.0712045,-3.0450064
SPX 307BJQZTWH4Q6|SPX 31,SPX 160219P01200000,0.3750,1.9500,0.2250,0.3250,0,9217,0.5067796,-0.0024897,0.0000186,0.0632766,-0.0278007,-0.0085883
SPX 30FJXBAIB9XM6|SPX 31,SPX 161216P01225000,12.9500,14.0500,9.9500,11.9000,0,783,0.3340339,-0.0382134,0.0001215,1.6982736,-0.0766621,-0.8910613
SPX 308349MLBBXN2|SPX 31,SPX 160318P01250000,0.8750,2.9000,0.7000,0.8250,0,6222,0.4289796,-0.0056537,0.0000377,0.1610195,-0.0401159,-0.0292247
SPX 30AKPY4VOAL8U|SPX 31,SPX 160617P01250000,3.6000,5.4500,2.1250,3.4250,0,3671,0.3644051,-0.0167467,0.0000796,0.5972442,-0.0606603,-0.1836113
SPX 307BJR0CR5572|SPX 31,SPX 160219P01260000,0.4500,0.7250,0.2500,0.3750,0,13,0.4715169,-0.0030452,0.0000240,0.0758902,-0.0310070,-0.0104691
SPX 307BJR0D31TAM|SPX 31,SPX 160219P01280000,0.4500,0.7250,0.2500,0.4000,0,22,0.4608201,-0.0033034,0.0000265,0.0816552,-0.0325998,-0.0113458
SPX 30ZNMVUSXP31Q|SPX 31,SPX 181221P01300000,67.8000,69.7500,65.7000,65.8500,0,,0.2855017,-0.1068397,0.0001805,6.5786591,-0.0780517,-8.5719073
SPX 306D33QLC1R0U|SPX 31,SPX 160115P01350000,0.1250,0.3000,0.0750,0.0750,0,13112,0.5637653,-0.0009124,0.0000107,0.0158153,-0.0198799,-0.0011999
SPX 30ZNMVVD3ZRWU|SPX 31,SPX 181221P01350000,76.1000,77.9500,73.6000,73.7000,0,,0.2811332,-0.1194678,0.0001985,7.1246469,-0.0828113,-9.6058041
SPX 308349SC1G67I|SPX 31,SPX 160318P01375000,1.3250,3.0500,0.6500,1.2250,2,2278,0.3730344,-0.0092479,0.0000668,0.2484955,-0.0537384,-0.0475144
SPX 306D33QLTWR66|SPX 31,SPX 160115P01380000,0.1250,0.4250,0.0750,0.0750,340,959,0.5365255,-0.0009571,0.0000118,0.0165262,-0.0197669,-0.0012565
SPX 308349MNGQAA6|SPX 31,SPX 160318P01380000,1.4500,3.0750,0.6750,1.2750,2,26,0.3719807,-0.0096026,0.0000693,0.2568109,-0.0553754,-0.0493402
SPX 306D33WC25ZLA|SPX 31,SPX 160115P01385000,0.1250,0.4250,0.1000,0.1000,387,1062,0.5454214,-0.0012308,0.0000146,0.0208121,-0.0253057,-0.0016181
SPX 306D33WFD8OKU|SPX 31,SPX 160115P01405000,0.1500,0.4250,0.1250,0.1250,0,990,0.5378942,-0.0015340,0.0000181,0.0254498,-0.0305146,-0.0020169
SPX 307BJR689X372|SPX 31,SPX 160219P01405000,0.7250,2.8000,0.5500,0.6750,0,1,0.4013579,-0.0060792,0.0000524,0.1407725,-0.0488842,-0.0207839
SPX 308349MO4JMHA|SPX 31,SPX 160318P01420000,1.7000,3.4000,0.8750,1.5500,0,12,0.3579567,-0.0118708,0.0000866,0.3088943,-0.0640500,-0.0609345
SPX 307BJR6BKZS6M|SPX 31,SPX 160219P01425000,0.7750,2.8250,0.4000,0.7250,0,29,0.3914255,-0.0066420,0.0000581,0.1522469,-0.0515471,-0.0226880
SPX 308349SKB4WOE|SPX 31,SPX 160318P01425000,1.7250,3.4750,1.0000,1.5750,0,880,0.3557919,-0.0121117,0.0000886,0.3143244,-0.0647757,-0.0621564
SPX 307BJR0G27U6M|SPX 31,SPX 160219P01460000,0.8750,2.9000,0.7000,0.8000,0,78,0.3728973,-0.0076031,0.0000687,0.1715284,-0.0552989,-0.0259242
SPX 308349MOSCYOE|SPX 31,SPX 160318P01460000,2.1500,3.8000,1.2250,1.8250,2,174,0.3424546,-0.0143259,0.0001065,0.3633979,-0.0720314,-0.0734315
SPX 306D33WU92T0U|SPX 31,SPX 160115P01495000,0.2000,0.4750,0.1500,0.1500,64,945,0.4652147,-0.0020861,0.0000277,0.0336612,-0.0348879,-0.0027306
SPX 30PIC163N7ULQ|SPX 31,SPX 171215P01500000,72.2000,72.2000,66.3500,67.4000,0,6111,0.2711097,-0.1401088,0.0002829,6.4671284,-0.1115899,-7.0564656
SPX 307BJR6S4D94E|SPX 31,SPX 160219P01525000,1.2500,3.2750,0.7500,1.1250,5110,5937,0.3460727,-0.0110965,0.0001030,0.2388071,-0.0713761,-0.0377694
SPX 30D2BMTLKFOTQ|SPX 31,SPX 160916P01525000,23.9000,24.4000,19.4500,21.5500,0,305,0.2876333,-0.0833589,0.0003018,2.7092849,-0.1404313,-1.4176620
SPX 30ZNMW1QZMVE6|SPX 31,SPX 181221P01525000,111.3000,113.4000,105.6500,106.0500,0,,0.2622195,-0.1685015,0.0002686,8.9898151,-0.0953793,-13.5809293
SPX 306D33QON4G0E|SPX 31,SPX 160115P01550000,0.2500,1.5750,0.1750,0.1750,61,11827,0.4236083,-0.0026284,0.0000375,0.0414934,-0.0391430,-0.0034318
SPX 30KJ4O662R95A|SPX 31,SPX 170616P01550000,60.5000,60.5000,54.4000,55.8500,0,501,0.2704491,-0.1400122,0.0003277,5.5907883,-0.1304404,-5.1158323
SPX 306D33QOZ143Y|SPX 31,SPX 160115P01570000,0.2750,1.7750,0.2500,0.2500,0,909,0.4215045,-0.0036659,0.0000509,0.0559837,-0.0525419,-0.0047900
SPX 307BJR75CO12M|SPX 31,SPX 160219P01605000,1.9750,3.9000,1.0000,1.5750,0,394,0.3089999,-0.0166487,0.0001638,0.3389127,-0.0902946,-0.0564882
SPX 307BJR0IPH6Z2|SPX 31,SPX 160219P01620000,2.1500,4.0250,1.0250,1.7000,0,107,0.3026600,-0.0181748,0.0001802,0.3652703,-0.0952852,-0.0616376
SPX 307BJR7ABA2JY|SPX 31,SPX 160219P01635000,2.3500,2.3500,1.0750,1.8250,240,246,0.2959842,-0.0197481,0.0001978,0.3919977,-0.0999627,-0.0669370
SPX 306D33QQ4PGGE|SPX 31,SPX 160115P01640000,0.4000,0.5500,0.3000,0.3000,0,1190,0.3675918,-0.0049267,0.0000760,0.0729203,-0.0596403,-0.0064154
SPX 308349MRXHBM6|SPX 31,SPX 160318P01650000,6.5500,8.1000,5.3500,5.7500,1139,21871,0.2893290,-0.0457390,0.0003325,0.9587400,-0.1597304,-0.2342436
SPX 308UOSFYDPPIM|SPX 31,SPX 160415P01675000,12.2500,13.4000,8.5500,10.6500,0,,0.2738891,-0.0713608,0.0004325,1.5676932,-0.1850508,-0.4904919
SPX 307BJR7P746ZY|SPX 31,SPX 160219P01725000,4.5000,6.1500,2.5250,3.6000,52,1885,0.2677540,-0.0392484,0.0003873,0.6944198,-0.1597448,-0.1329913
SPX 30GIDYMLWTOXA|SPX 31,SPX 170120P01725000,69.3000,69.3000,61.6000,63.2000,0,92,0.2454425,-0.1909500,0.0005175,5.8331907,-0.1694642,-4.9244493
SPX 30KJ4ODDQ2LIM|SPX 31,SPX 170616P01725000,94.5000,94.5000,86.0000,87.4000,0,609,0.2454746,-0.2118306,0.0004698,7.2756837,-0.1509142,-7.7511093
SPX 30PIC1DYFZWQ6|SPX 31,SPX 171215P01725000,120.8000,120.8000,111.7000,112.9500,0,1795,0.2463032,-0.2270563,0.0004215,8.7544838,-0.1333196,-11.5074903
SPX 30D2BMUQWVD66|SPX 31,SPX 160916P01775000,55.9000,55.9000,48.3500,50.3000,0,2749,0.2412837,-0.1921861,0.0006411,4.8281103,-0.2056167,-3.2725822
SPX 306D33QSG255A|SPX 31,SPX 160115P01780000,1.1000,3.0250,0.6250,0.7000,84,1099,0.2770400,-0.0137652,0.0002484,0.1797130,-0.1105115,-0.0178396
SPX 306D33Y9IQKBY|SPX 31,SPX 160115P01805000,1.2500,3.1500,0.7500,0.8250,34,3528,0.2605199,-0.0168698,0.0003146,0.2140160,-0.1236745,-0.0218432
SPX 30D2BMNFYHBTA|SPX 31,SPX 160916P01850000,71.7000,71.7000,62.1500,64.6500,30,1419,0.2294411,-0.2439605,0.0007737,5.5413440,-0.2221946,-4.1636278
SPX 30GIDYFJ84E1A|SPX 31,SPX 170120P01850000,98.1500,98.1500,88.2500,89.7000,0,415,0.2280445,-0.2653782,0.0006707,7.0243384,-0.1861497,-6.8684036
SPX 306D33YHSFASU|SPX 31,SPX 160115P01855000,2.2000,3.8750,0.9250,1.3000,56,3097,0.2309732,-0.0281261,0.0005464,0.3295382,-0.1685411,-0.0363719
SPX 306D33QULGHSE|SPX 31,SPX 160115P01910000,4.6500,6.0000,1.9500,2.8500,157,3543,0.2079109,-0.0609224,0.0011347,0.6160057,-0.2828092,-0.0788043
SPX 306D33YRPNDRI|SPX 31,SPX 160115P01915000,5.1500,6.3000,1.8000,3.0500,80,2430,0.2055810,-0.0651837,0.0012097,0.6493142,-0.2946630,-0.0843170
SPX 306D33QURETU6|SPX 31,SPX 160115P01920000,5.6500,6.7500,2.8000,3.3250,160,2738,0.2041169,-0.0705736,0.0012954,0.6904026,-0.3109756,-0.0913032
SPX 307BJR0NO38GE|SPX 31,SPX 160219P01920000,20.6500,20.6500,14.5500,16.2500,7,1973,0.2069531,-0.1727444,0.0015095,2.0922062,-0.3671840,-0.5860724
SPX 30FJXBDQ2W86M|SPX 31,SPX 161216P01925000,113.3500,113.3500,102.1000,103.6500,30,6420,0.2187866,-0.3170605,0.0007960,7.2863506,-0.2016481,-7.4442610
SPX 307BJR0NZZWJY|SPX 31,SPX 160219P01940000,24.2500,24.2500,17.4500,19.1000,234,915,0.2011153,-0.2008926,0.0017056,2.2972420,-0.3908089,-0.6819380
SPX 30D2BMNHM0OB2|SPX 31,SPX 160916P01950000,99.3000,99.3000,87.8500,89.7000,0,3489,0.2126691,-0.3284581,0.0009620,6.3862373,-0.2329558,-5.6236291
SPX 30ZNMVVN17UVI|SPX 31,SPX 181221P01950000,238.0000,242.2500,226.3000,230.6500,2,3,0.2222438,-0.3378726,0.0004603,13.0594785,-0.1074988,-27.5840726
SPX 306D33Z1MVGQ6|SPX 31,SPX 160115P01975000,12.6500,12.6500,7.6000,7.7500,3604,51558,0.1828379,-0.1554880,0.0025558,1.2201338,-0.4897439,-0.2014163
SPX 308UOSHBZU4BY|SPX 31,SPX 160415P01975000,57.5000,57.5000,47.3500,49.4000,0,,0.1993533,-0.3150786,0.0015491,4.0872195,-0.3401933,-2.1741605
SPX 30AKPYDDMNNFY|SPX 31,SPX 160617P01975000,80.3000,80.3000,69.2500,71.3000,0,9022,0.2039944,-0.3384095,0.0012495,5.2482595,-0.2824332,-3.7195560
SPX 306D33Z9WK772|SPX 31,SPX 160115P02025000,25.5000,25.5000,15.0000,16.3000,3814,29961,0.1614736,-0.3028958,0.0042322,1.7843410,-0.6265764,-0.3930779
SPX 308349MYDODJI|SPX 31,SPX 160318P02040000,68.0500,68.0500,55.2500,57.2500,686,13944,0.1785631,-0.4178762,0.0021904,3.8979745,-0.3824880,-2.1507932
SPX 306D33ZD7MW6M|SPX 31,SPX 160115P02045000,33.1000,33.1000,20.6500,21.9500,201,3205,0.1533605,-0.3888042,0.0048918,1.9588121,-0.6490181,-0.5052018
SPX 30PIC16Z2DATQ|SPX 31,SPX 171215P02050000,233.6500,233.6500,218.3500,220.1000,0,2141,0.2177865,-0.4049872,0.0006128,11.2552980,-0.1406896,-20.9333879
SPX 30ZNMVVOOR7DA|SPX 31,SPX 181221P02050000,279.3500,284.2500,273.1000,273.7000,325,325,0.2272899,-0.3857177,0.0004710,13.6644455,-0.1125423,-32.2398016
SPX 306D33ZGIPL66|SPX 31,SPX 160115P02065000,42.8500,42.8500,27.6000,29.2000,239,1247,0.1259150,-0.4903427,0.0061987,2.0379216,-0.5452585,-0.6357648
SPX 307BJR0Q5E972|SPX 31,SPX 160219P02070000,66.6000,66.6000,51.6000,53.7500,169,371,0.1300598,-0.4989275,0.0037482,3.2647858,-0.3406889,-1.6873901
SPX 307BJR0QT7LE6|SPX 31,SPX 160219P02110000,90.1500,90.1500,71.5000,73.7000,0,50,0.1182678,-0.6591567,0.0037894,3.0014068,-0.2703705,-2.2387955
SPX 306D33QY8FUVI|SPX 31,SPX 160115P02130000,92.0000,92.0000,68.8500,71.0500,0,82,0.1010510,-0.8879592,0.0036899,0.9735601,-0.1678844,-1.1642975
SPX 308349MZV9DZI|SPX 31,SPX 160318P02130000,115.9500,115.9500,96.8500,99.0500,0,2,0.1206240,-0.6800760,0.0029694,3.5696921,-0.2114156,-3.4821263
SPX 307BJR9L05F8U|SPX 31,SPX 160219P02135000,108.4000,108.4000,87.3500,89.8500,0,14,0.1107916,-0.7608617,0.0034220,2.5390820,-0.1999753,-2.5939489
SPX 308349VX1D8Q6|SPX 31,SPX 160318P02155000,134.2000,134.2000,112.7500,115.3500,0,,0.1137538,-0.7616766,0.0027270,3.0915948,-0.1601387,-3.9138625
SPX 308349N0J2Q6M|SPX 31,SPX 160318P02170000,146.0500,146.0500,123.1000,126.2000,0,,0.1097928,-0.8078418,0.0024930,2.7278814,-0.1266688,-4.1620575
SPX 306D33ZYPMELQ|SPX 31,SPX 160115P02175000,135.6000,135.6000,111.0500,113.7500,0,352,0.1071506,-0.9734009,0.0011243,0.3145482,-0.0172881,-1.2985608
SPX 30AKPYEAPELBI|SPX 31,SPX 160617P02175000,175.7000,175.7000,155.1500,158.2000,3,530,0.1220085,-0.6972861,0.0019941,5.0094064,-0.1302085,-7.5953487
SPX 30FJXBEVFBWJ2|SPX 31,SPX 161216P02175000,222.9000,222.9000,203.4000,206.2500,0,206,0.1303749,-0.6040359,0.0014448,7.8810604,-0.1048367,-13.8048730
SPX 30PIC1G0V6IY6|SPX 31,SPX 171215P02175000,295.5500,295.5500,275.5500,278.9000,0,2,0.1412592,-0.5254904,0.0009705,11.5617837,-0.0777832,-25.4725807
SPX 30ZNMVUUFA3HQ|SPX 31,SPX 181221P02200000,351.0000,360.0000,343.5000,346.2500,31,31,0.1459020,-0.5028949,0.0007653,14.2529712,-0.0598557,-38.5327238
SPX 306D3406ZB52M|SPX 31,SPX 160115P02225000,185.3000,185.3000,160.3500,163.4000,0,140,0.1198492,-0.9936417,0.0002923,0.0914618,0.0360587,-1.3545196
SPX 30AKPYEIZ3BSE|SPX 31,SPX 160617P02225000,212.5500,212.5500,189.2500,192.9000,0,140,0.1127631,-0.8038957,0.0017098,3.9698130,-0.0768704,-8.8251965
SPX 308349N1ISQHA|SPX 31,SPX 160318P02230000,199.3500,199.3500,174.2000,177.1500,0,,0.0978264,-0.9405065,0.0012117,1.1813385,-0.0100340,-4.9217535
SPX 308349N1UPEKU|SPX 31,SPX 160318P02250000,218.2000,218.2000,192.4500,196.1500,1,93,0.0958760,-0.9628105,0.0008484,0.8106909,0.0139091,-5.0736312
SPX 30AKPY5C7O26M|SPX 31,SPX 160617P02250000,232.9500,232.9500,209.0000,212.5000,0,1340,0.1086362,-0.8505992,0.0014917,3.3367370,-0.0495508,-9.3855166
SPX 30D2BMNMKMPSE|SPX 31,SPX 160916P02250000,251.8000,251.8000,228.6000,232.4500,0,,0.1163369,-0.7709011,0.0014741,5.3529300,-0.0675084,-13.0877984
SPX 306D33R0DU7IM|SPX 31,SPX 160115P02260000,220.2500,220.2500,195.3500,198.3500,0,,0.1556556,-0.9897124,0.0003435,0.1395984,0.0127259,-1.3710739
SPX 307BJR0TAIM4U|SPX 31,SPX 160219P02260000,224.9000,224.9000,199.2500,202.5500,0,,0.0993784,-0.9874385,0.0003996,0.2659361,0.0380844,-3.5061091
SPX 306D33R0JSJKE|SPX 31,SPX 160115P02270000,230.2000,230.2000,204.9500,208.3000,85,87,0.1444830,-0.9956174,0.0001741,0.0656906,0.0406894,-1.3845592
SPX 308349WGVTENI|SPX 31,SPX 160318P02275000,242.5000,242.5000,216.7000,220.4000,0,317,0.0953412,-0.9790341,0.0005294,0.5030698,0.0329241,-5.2087166
SPX 30PIC164YUIZY|SPX 31,SPX 171215P02300000,369.3500,369.3500,347.3000,350.3000,0,1,0.1317910,-0.6494106,0.0009684,10.7631144,-0.0539887,-31.9245900
SPX 308349N30DQXA|SPX 31,SPX 160318P02320000,287.3500,287.3500,260.5500,264.9500,0,,0.1002823,-0.9902418,0.0002606,0.2604427,0.0475724,-5.3668876
SPX 30ZNMW5FAMMWE|SPX 31,SPX 181221P02325000,421.1500,427.5500,412.2000,415.2000,0,,0.1390319,-0.5984965,0.0007785,13.8166897,-0.0453172,-46.4998419
SPX 30PIC1740ZCB2|SPX 31,SPX 171215P02350000,402.6500,402.6500,379.8500,382.7500,0,250,0.1286517,-0.6972093,0.0009345,10.1393045,-0.0424925,-34.5268268
SPX 30PIC1GXXXGTQ|SPX 31,SPX 171215P02375000,419.6500,419.6500,396.8000,399.8500,0,1,0.1269808,-0.7206556,0.0009118,9.7645585,-0.0362304,-35.8240089
SPX 30GIDYFT5CGZY|SPX 31,SPX 170120P02450000,437.7500,437.7500,411.8500,415.7500,0,,0.1044499,-0.9230939,0.0006446,3.0920581,0.0212060,-24.4899650
SPX 30ZNMVVVAWLCE|SPX 31,SPX 181221P02450000,500.4000,508.0000,490.9500,493.6000,0,,0.1321086,-0.6928202,0.0007445,12.5541861,-0.0258106,-54.7053839
SPX 30FJXBGHB51TA|SPX 31,SPX 161216P02525000,507.6000,507.6000,480.4000,485.1000,0,,0.0994484,-0.9709857,0.0003253,1.3536882,0.0481387,-23.9823052
SPX 30ZNMW6CDDKRY|SPX 31,SPX 181221P02525000,558.2500,561.0500,543.2500,546.0000,0,,0.1296722,-0.7427791,0.0006962,11.5245654,-0.0139875,-59.4273800
SPX 306D33R56HWY6|SPX 31,SPX 160115P02550000,510.0000,510.0000,483.5000,488.1000,0,19,0.3927130,-0.9815923,0.0002217,0.2338126,-0.1307973,-1.5827232
SPX 30FJXB61W7EVI|SPX 31,SPX 161216P02550000,531.8500,531.8500,504.5500,509.3500,0,,0.1003838,-0.9759197,0.0002758,1.1584400,0.0516429,-24.3214189
SPX 30GIDYFUSVTHQ|SPX 31,SPX 170120P02550000,532.1000,532.1000,505.2000,509.6000,0,,0.1005625,-0.9691639,0.0003230,1.4917295,0.0483706,-26.5278914
SPX 306D33R6U19FY|SPX 31,SPX 160115P02650000,609.9000,609.9000,583.5000,588.0000,0,,0.4535594,-0.9834688,0.0001751,0.2133032,-0.1386578,-1.6481540
SPX 308349M53X9YM|SPX 31,SPX 160318P02700000,666.3000,666.3000,639.4000,643.9500,0,,0.1908919,-0.9977202,0.0000375,0.0712754,0.0657050,-6.2891749
SPX 30ZNMVW09IMTQ|SPX 31,SPX 181221P02750000,735.2500,737.5000,720.6500,721.8000,0,,0.1208248,-0.8694378,0.0004915,7.5806486,0.0245582,-72.6475502
SPX 30AKPY4FMU9M6|SPX 31,SPX 160617P02800000,771.0000,771.0000,744.7500,748.5500,0,,0.1562682,-0.9966103,0.0000455,0.1465340,0.0696652,-13.4314000
SPX 30FJXB50CRKTQ|SPX 31,SPX 161216P02800000,777.8000,777.8000,750.6500,755.2000,0,17,0.2344222,-0.8754691,0.0004278,4.2032848,-0.0675783,-25.0065368
SPX 30KJ4O5L8N832|SPX 31,SPX 170616P02900000,878.7000,878.7000,851.7000,856.0000,0,2,0.1158120,-0.9873498,0.0001124,0.8211936,0.0688026,-41.9336798
SPX 30KJ4O6T8A426|SPX 31,SPX 170616P02950000,927.7000,927.7000,900.6000,905.0500,0,,0.1193518,-0.9888118,0.0000980,0.7382080,0.0708791,-42.7058646
SPX 30KJ4O5LWGKA6|SPX 31,SPX 170616P03300000,1271.5500,1271.5500,1244.5500,1248.9000,0,,0.1540328,-0.9901091,0.0000682,0.6630438,0.0791063,-47.8527718
1 #symbol_id symbol_value open high low close volume open_interest implied_volatility delta gamma vega theta rho
2 SPX X0JMQES2VX66|SPX 31 SPX 181221C00300000 1631.1500 1646.4000 1626.5000 1646.4000 0 3 0.5074832 0.9961985 0.0000062 0.4044020 -0.0170694 8.4016626
3 SPX W8Z44629O3HQ|SPX 31 SPX 160318C00500000 1529.5000 1554.7000 1529.5000 1551.9500 0 44 0.9496134 0.9995536 0.0000017 0.0159735 -0.0225226 1.1641986
4 SPX WHEDSYQ98GXA|SPX 31 SPX 170120C00500000 1497.4000 1524.2000 1497.4000 1519.9000 0 0.5337475 0.9978515 0.0000059 0.1449944 -0.0232440 5.2738365
5 SPX W8Z446AJAOSU|SPX 31 SPX 160318C00550000 1479.6000 1504.8000 1479.6000 1502.1000 0 32 0.9009002 0.9994409 0.0000022 0.0196735 -0.0253789 1.2802607
6 SPX W9QOMSB5RK1A|SPX 31 SPX 160415C00600000 1427.3500 1455.3500 1427.3500 1450.0000 0 0.7585941 0.9991593 0.0000033 0.0330273 -0.0273840 1.8516596
7 SPX WDYBH6WWRCI6|SPX 31 SPX 160916C00650000 1360.1000 1387.3000 1360.1000 1382.7000 0 0.5110809 0.9979943 0.0000070 0.1123068 -0.0282824 4.6918128
8 SPX WBGPSOO7C1E6|SPX 31 SPX 160617C00750000 1270.4000 1297.6000 1270.4000 1293.0500 0 1832 0.5279093 0.9984403 0.0000067 0.0725575 -0.0312097 3.5890924
9 SPX WQEBVTUECUWE|SPX 31 SPX 171215C00825000 1157.3500 1183.8000 1157.3500 1179.2000 0 0.3640240 0.9814946 0.0000429 1.3162543 -0.0540443 15.0822757
10 SPX WLF4IPIQAPPQ|SPX 31 SPX 170616C00900000 1096.2500 1123.7000 1096.2500 1118.4000 0 0.3680870 0.9825946 0.0000465 1.0804654 -0.0599242 12.4956358
11 SPX WDYBH6MBU7NY|SPX 31 SPX 160916C01000000 1015.0000 1042.1500 1015.0000 1037.4500 0 250 0.3992342 0.9896513 0.0000389 0.4851699 -0.0627592 7.0947658
12 SPX W87JLOI8831Q|SPX 31 SPX 160219C01025000 1009.0500 1035.5500 1009.0500 1031.4500 0 0.6201123 0.9985451 0.0000094 0.0388357 -0.0489404 1.6033199
13 SPX WLF4IPYLSPAM|SPX 31 SPX 170616C01050000 954.6000 981.3000 954.6000 976.2000 0 0.3423531 0.9690246 0.0000813 1.7549149 -0.0818528 14.1903006
14 SPX WGFX5OYCA2LQ|SPX 31 SPX 161216C01100000 913.3000 939.5000 913.3000 935.2000 0 400 0.3578960 0.9761501 0.0000767 1.1491187 -0.0856704 10.1379875
15 SPX W87JLKBQDN9Q|SPX 31 SPX 160219C01150000 884.2500 910.6000 884.2500 906.6500 0 0.5345471 0.9979737 0.0000147 0.0525059 -0.0557988 1.7975328
16 SPX WLF4IUVK8OZ2|SPX 31 SPX 170616C01175000 838.6000 863.7500 838.6000 859.7500 0 0.3228105 0.9524202 0.0001223 2.4897469 -0.1028839 15.4089756
17 SPX W8Z4463FCFU6|SPX 31 SPX 160318C01200000 831.4500 859.0000 831.4500 853.8500 0 3 0.4518739 0.9953701 0.0000299 0.1347870 -0.0681934 2.7759611
18 SPX WGFX5OYI8ENI|SPX 31 SPX 161216C01200000 818.0500 844.0000 818.0500 839.6500 0 415 0.3411811 0.9642814 0.0001126 1.6070758 -0.1067282 10.8324282
19 SPX W87JLPFAZ0XA|SPX 31 SPX 160219C01225000 809.4500 835.9000 809.4500 831.7500 0 0.4962165 0.9971019 0.0000218 0.0725777 -0.0647254 1.9122346
20 SPX WBGPSTYE2T0U|SPX 31 SPX 160617C01225000 800.5500 828.6000 800.5500 822.6500 0 1 0.3713871 0.9849667 0.0000712 0.5444489 -0.0897895 5.7256255
21 SPX WHEDT4C0OIUM|SPX 31 SPX 170120C01225000 795.0000 820.5500 795.0000 816.3000 0 0.3286970 0.9583192 0.0001265 1.9094129 -0.1102476 11.9865846
22 SPX W792YAKBA93I|SPX 31 SPX 160115C01240000 799.3000 825.3000 799.3000 821.3000 0 0.6686491 0.9992268 0.0000078 0.0135822 -0.0542099 0.7582937
23 SPX W792YFUNZCRY|SPX 31 SPX 160115C01275000 764.4000 790.3000 764.4000 786.3000 0 16 0.6344248 0.9991855 0.0000086 0.0142485 -0.0550716 0.7796738
24 SPX WGFX5URDOUPA|SPX 31 SPX 161216C01275000 747.5000 773.0000 747.5000 768.7000 0 0.3247342 0.9543778 0.0001443 1.9603408 -0.1204412 11.3323806
25 SPX W8Z446MLX4EM|SPX 31 SPX 160318C01280000 751.7000 779.6000 751.7000 774.2000 0 0.4149083 0.9936816 0.0000430 0.1776970 -0.0777887 2.9540047
26 SPX WHEDSYRKV5BI|SPX 31 SPX 170120C01300000 725.1500 750.2500 725.1500 746.1000 0 0.3130411 0.9472322 0.0001605 2.3069748 -0.1235802 12.5031701
27 SPX W87JLKEDN026|SPX 31 SPX 160219C01310000 724.7000 751.7000 724.7000 746.9500 0 0.4459521 0.9962025 0.0000310 0.0925426 -0.0715782 2.0425778
28 SPX W9QOMYDAMQUM|SPX 31 SPX 160415C01325000 706.2000 733.5000 706.2000 728.4500 0 0.3698967 0.9883636 0.0000715 0.3498595 -0.0925584 4.0222549
29 SPX WQEBVW5387LA|SPX 31 SPX 171215C01325000 706.4000 730.0500 706.4000 726.1000 0 0.2923231 0.9085509 0.0001936 4.7721211 -0.1257910 21.1168754
30 SPX W87JLKFDD0CU|SPX 31 SPX 160219C01370000 664.9000 691.4000 664.9000 687.1500 0 0.4105680 0.9954710 0.0000394 0.1083394 -0.0759756 2.1342755
31 SPX W792YGB7CTPQ|SPX 31 SPX 160115C01375000 664.4500 690.4000 664.4500 686.4000 0 2 0.5410294 0.9990506 0.0000116 0.0164045 -0.0574348 0.8407385
32 SPX W87JLKFJBCEM|SPX 31 SPX 160219C01380000 655.0500 683.3500 655.0500 677.2000 0 0.4083245 0.9950368 0.0000430 0.1175581 -0.0792923 2.1484801
33 SPX W87JLQ92N9TA|SPX 31 SPX 160219C01405000 629.8500 658.4000 629.8500 652.3000 0 0.4013579 0.9939208 0.0000524 0.1407725 -0.0873169 2.1838920
34 SPX WHEDT593FGQ6|SPX 31 SPX 170120C01425000 611.0000 635.2000 611.0000 631.1000 0 0.2934548 0.9198775 0.0002367 3.1896020 -0.1523536 13.1303125
35 SPX W87JLQE19BAM|SPX 31 SPX 160219C01435000 600.2000 625.8000 600.2000 622.4000 0 0.3847895 0.9932495 0.0000599 0.1544442 -0.0906506 2.2287107
36 SPX W9QOMSY59XQM|SPX 31 SPX 160415C01450000 583.5000 610.5500 583.5000 605.3000 0 0.3338572 0.9776867 0.0001383 0.6110601 -0.1282258 4.3359258
37 SPX W792YAO47Y8E|SPX 31 SPX 160115C01470000 569.6000 595.5000 569.6000 591.5000 0 0.4875229 0.9980046 0.0000254 0.0323302 -0.0753704 0.8975430
38 SPX W8Z44CTDJTRI|SPX 31 SPX 160318C01475000 558.6000 585.4000 558.6000 580.8000 0 0.3400749 0.9838327 0.0001190 0.4031742 -0.1196535 3.3587000
39 SPX WHEDT5HD4772|SPX 31 SPX 170120C01475000 566.3500 590.2000 566.3500 586.0000 0 0.2853202 0.9064639 0.0002733 3.5808133 -0.1637199 13.3177065
40 SPX X0JMQLJIOBJI|SPX 31 SPX 181221C01475000 609.0500 618.3500 605.9500 618.3500 0 0.2696868 0.8455862 0.0002467 8.4922175 -0.1325455 30.4086411
41 SPX W8Z4463X7FZI|SPX 31 SPX 160318C01500000 534.0000 560.2500 534.0000 556.3000 0 1504 0.3326526 0.9812327 0.0001381 0.4579276 -0.1290964 3.4037238
42 SPX WLF4IPJQ0Q0E|SPX 31 SPX 170616C01500000 551.8000 574.3500 551.8000 570.0000 0 1 0.2755165 0.8778523 0.0002927 5.0875098 -0.1619495 17.4271506
43 SPX W87JLQPM0QR2|SPX 31 SPX 160219C01505000 530.5500 557.2000 530.5500 552.6500 0 0.3500967 0.9907999 0.0000865 0.2027820 -0.1025015 2.3302907
44 SPX W8Z446QEUTJI|SPX 31 SPX 160318C01510000 524.0500 550.2000 524.0500 546.3500 0 0.3288294 0.9803218 0.0001455 0.4767526 -0.1319158 3.4224222
45 SPX W792YH00F14E|SPX 31 SPX 160115C01525000 514.6500 540.7000 514.6500 536.5000 0 5 0.4455192 0.9974946 0.0000342 0.0397341 -0.0811854 0.9305621
46 SPX WQEBVX25Z5GU|SPX 31 SPX 171215C01525000 542.1500 563.1000 542.1500 559.2500 0 1 0.2697516 0.8507823 0.0002966 6.7474371 -0.1565204 22.0581851
47 SPX W87JLKI0MD5A|SPX 31 SPX 160219C01530000 505.7500 531.9500 505.7500 527.9000 0 0.3437577 0.9886221 0.0001060 0.2440627 -0.1143044 2.3621018
48 SPX W792YAP9WAKU|SPX 31 SPX 160115C01540000 499.7000 525.6000 499.7000 521.6000 0 0.4381645 0.9971220 0.0000394 0.0450340 -0.0861127 0.9392608
49 SPX WHEDSZF28J66|SPX 31 SPX 170120C01550000 500.6000 523.6000 500.6000 519.5500 0 0.2726148 0.8833753 0.0003356 4.2012595 -0.1799592 13.5232913
50 SPX W8Z446R8MHSE|SPX 31 SPX 160318C01560000 475.1000 501.2000 475.1000 497.2500 0 0.3126946 0.9740120 0.0001934 0.6027087 -0.1514686 3.5068689
51 SPX W87JLKIOFPCE|SPX 31 SPX 160219C01570000 466.4000 492.2500 466.4000 488.2000 0 0.3222835 0.9867387 0.0001291 0.2787013 -0.1204507 2.4185607
52 SPX WGFX5W4ZT9IM|SPX 31 SPX 161216C01575000 475.8500 499.0000 475.8500 494.7500 0 17 0.2715159 0.8803158 0.0003595 4.0841130 -0.1896667 12.5247352
53 SPX X0JMQM021SHA|SPX 31 SPX 181221C01575000 535.0500 543.9500 532.4500 543.8500 0 0.2571128 0.8153407 0.0002902 9.5258955 -0.1402562 30.8896301
54 SPX W792YAQ3NYTQ|SPX 31 SPX 160115C01590000 449.8000 475.8000 449.8000 471.6000 0 0.4037884 0.9961837 0.0000551 0.0580393 -0.0957067 0.9686610
55 SPX W87JLKJ0CDFY|SPX 31 SPX 160219C01590000 446.2500 472.4000 446.2500 468.3000 0 0.3142690 0.9850053 0.0001472 0.3098241 -0.1274740 2.4440843
56 SPX W792YA2GC8XA|SPX 31 SPX 160115C01600000 439.9000 465.8000 439.9000 461.6500 0 106 0.3906100 0.9964248 0.0000537 0.0547397 -0.0914034 0.9751048
57 SPX W792YAQFKMXA|SPX 31 SPX 160115C01610000 429.8000 457.6000 429.8000 451.7000 0 0.3902630 0.9957001 0.0000634 0.0645818 -0.1001796 0.9802810
58 SPX W87JLR7SXK6M|SPX 31 SPX 160219C01615000 421.6000 447.9500 421.6000 443.7000 0 0.3045453 0.9824146 0.0001741 0.3551425 -0.1374089 2.4745558
59 SPX WQEBVXIPCMEM|SPX 31 SPX 171215C01625000 464.6500 484.3500 464.6500 480.4500 0 1 0.2558983 0.8158444 0.0003582 7.7297159 -0.1676970 22.2373311
60 SPX X0JMQM8BQIY6|SPX 31 SPX 181221C01625000 499.9000 507.9500 497.1000 507.9500 0 0.2518610 0.7983074 0.0003127 10.0531464 -0.1441027 30.9570128
61 SPX W8Z446SQ7I8E|SPX 31 SPX 160318C01650000 388.1000 413.5500 388.1000 409.7000 1 71 0.2893290 0.9542610 0.0003325 0.9587400 -0.2048303 3.6156888
62 SPX W792YHLIEJJI|SPX 31 SPX 160115C01655000 384.6000 410.8000 384.6000 406.7500 0 0.3544613 0.9949072 0.0000812 0.0751068 -0.1045376 1.0068188
63 SPX W87JLREF2Y5Q|SPX 31 SPX 160219C01655000 382.3500 408.4000 382.3500 404.2500 0 0.2908948 0.9765686 0.0002325 0.4529576 -0.1587335 2.5175301
64 SPX W8Z446SW5UA6|SPX 31 SPX 160318C01660000 378.3500 404.0500 378.3500 400.0500 0 0.2846467 0.9524647 0.0003486 0.9888375 -0.2073862 3.6299733
65 SPX W792YHOTH8J2|SPX 31 SPX 160115C01675000 364.8000 391.0500 364.8000 386.8000 0 34 0.3402366 0.9943077 0.0000933 0.0829177 -0.1086036 1.0182923
66 SPX W9QOMZZ6FW4U|SPX 31 SPX 160415C01675000 367.4000 392.9000 367.4000 388.3500 0 0.2738891 0.9286392 0.0004325 1.5676932 -0.2307990 4.6957227
67 SPX WGFX5WLJ6QGE|SPX 31 SPX 161216C01675000 391.1500 412.9500 391.1500 408.7500 0 0.2563563 0.8385066 0.0004668 5.0070798 -0.2140187 12.5169081
68 SPX WHEDT6EFV52M|SPX 31 SPX 170120C01675000 395.3500 416.8500 395.3500 412.6500 0 0.2528824 0.8335597 0.0004606 5.3496063 -0.2064510 13.5694331
69 SPX W8Z446TE0UFI|SPX 31 SPX 160318C01690000 350.1000 375.9000 350.1000 371.2500 0 1 0.2761911 0.9431858 0.0004139 1.1393316 -0.2270985 3.6525066
70 SPX W792YA2MAKZ2|SPX 31 SPX 160115C01700000 339.9000 365.9000 339.9000 361.8500 0 311 0.3214053 0.9935754 0.0001100 0.0923050 -0.1125005 1.0326595
71 SPX X0JMQEUE8LV2|SPX 31 SPX 181221C01700000 448.8000 455.8500 445.7500 455.8000 0 1 0.2450907 0.7704791 0.0003464 10.8360306 -0.1496605 30.8430248
72 SPX W9QON07G4MLQ|SPX 31 SPX 160415C01725000 321.1500 346.0500 321.1500 341.4500 0 0.2614368 0.9076727 0.0005502 1.9039095 -0.2610512 4.7063562
73 SPX WHEDT6MPJVJI|SPX 31 SPX 170120C01725000 355.1000 375.6500 355.1000 371.6000 0 1 0.2454425 0.8090500 0.0005175 5.8331907 -0.2162178 13.4667924
74 SPX X0JMQMOV3ZVY|SPX 31 SPX 181221C01725000 432.0000 439.2000 428.9500 438.7500 0 0.2433516 0.7605382 0.0003571 11.0932312 -0.1515622 30.7349475
75 SPX W8Z446UDQUQ6|SPX 31 SPX 160318C01750000 294.0500 319.0500 294.0500 314.3500 7 45 0.2593627 0.9189735 0.0005797 1.4985060 -0.2706208 3.6686071
76 SPX X0JMQFKIVCI6|SPX 31 SPX 181221C01750000 415.8500 422.7500 412.4000 422.1000 0 0.2426309 0.7500428 0.0003665 11.3524393 -0.1539045 30.5511238
77 SPX W9QON0FPTD2M|SPX 31 SPX 160415C01775000 276.0500 300.3000 276.0500 295.6000 0 0.2489763 0.8809810 0.0006944 2.2880519 -0.2925166 4.6774919
78 SPX WBGPSWHCMW6M|SPX 31 SPX 160617C01775000 285.5000 308.6500 285.5000 303.9500 0 11 0.2454818 0.8409723 0.0006880 3.4774442 -0.2805412 6.7950711
79 SPX WDYBHERPLJSE|SPX 31 SPX 160916C01775000 298.5000 320.0000 298.3000 315.4000 0 2 0.2412837 0.8078139 0.0006411 4.8281103 -0.2538920 9.6345019
80 SPX WBGPSOES13QM|SPX 31 SPX 160617C01800000 264.5000 285.5500 264.5000 282.4500 0 212 0.2404605 0.8243601 0.0007488 3.7074586 -0.2909177 6.7327094
81 SPX WHEDSYSEMTKE|SPX 31 SPX 170120C01800000 297.2500 316.4500 296.5500 312.3500 0 152 0.2363250 0.7657780 0.0006057 6.5733972 -0.2308410 13.1317596
82 SPX W87JLS4VOI26|SPX 31 SPX 160219C01815000 228.9000 253.6000 228.9000 249.5000 0 0.2398703 0.9218293 0.0007442 1.1955025 -0.2949797 2.5831120
83 SPX W8Z446VJF72M|SPX 31 SPX 160318C01820000 230.3000 254.4000 230.3000 249.6500 0 0.2400233 0.8776343 0.0008464 2.0246241 -0.3270445 3.6201698
84 SPX W87JLS6J7UJY|SPX 31 SPX 160219C01825000 219.6000 243.7000 219.6000 240.0500 2 15 0.2354393 0.9167474 0.0007951 1.2537416 -0.3022888 2.5816670
85 SPX WBGPSWPMBMNI|SPX 31 SPX 160617C01825000 243.9500 264.4500 243.8500 261.3000 0 32 0.2349557 0.8066513 0.0008136 3.9357835 -0.2999205 6.6586146
86 SPX WLF4IQBU3H8U|SPX 31 SPX 170616C01850000 281.8500 299.5500 281.2500 295.2000 0 25 0.2319993 0.7196672 0.0005780 8.4598352 -0.2124570 16.6704526
87 SPX W792YAUKF05Q|SPX 31 SPX 160115C01860000 182.3000 206.1500 182.3000 203.1000 0 7 0.2297447 0.9693723 0.0005896 0.3536994 -0.2308289 1.0993640
88 SPX X0JMQNDO67AM|SPX 31 SPX 181221C01875000 339.6500 344.8500 333.8500 342.5500 0 0.2328493 0.6965429 0.0004201 12.4864643 -0.1600990 29.6733916
89 SPX W87JLJVUVNOU|SPX 31 SPX 160219C01900000 152.6000 174.0000 152.6000 171.2000 453 409 0.2124098 0.8521335 0.0013285 1.8899103 -0.3931311 2.4800267
90 SPX WBGPSOEXZFSE|SPX 31 SPX 160617C01900000 184.8000 203.4000 184.8000 200.4500 2 4677 0.2200827 0.7422108 0.0010226 4.6338883 -0.3248972 6.3084196
91 SPX WQEBVYWBH17Y|SPX 31 SPX 171215C01925000 258.0500 273.3000 257.6000 269.4000 0 54 0.2268889 0.6702006 0.0005495 10.5143773 -0.1934728 20.4781233
92 SPX WDYBH7IEQUXA|SPX 31 SPX 160916C01950000 168.0500 183.8000 168.0500 181.0000 0 3366 0.2126691 0.6715419 0.0009620 6.3862373 -0.2859906 8.5559844
93 SPX W792YAWDWOPA|SPX 31 SPX 160115C01970000 81.7500 101.2000 81.7500 98.7000 4 471 0.1844062 0.8555364 0.0024128 1.1617374 -0.5245266 1.0192411
94 SPX W8Z44F42F6GE|SPX 31 SPX 160318C01975000 103.5500 120.6500 103.5500 118.4500 0 3416 0.1973444 0.7038633 0.0017545 3.4505923 -0.4350236 3.0878533
95 SPX WBGPSXEFDU26|SPX 31 SPX 160617C01975000 130.7500 147.1000 130.7500 144.3000 0 3770 0.2039944 0.6615905 0.0012495 5.2482595 -0.3362820 5.7774594
96 SPX WLF4IYJV8GHA|SPX 31 SPX 170616C01975000 201.4000 214.6000 201.4000 212.0000 0 250 0.2183557 0.6387036 0.0006830 9.4083285 -0.2186447 15.4297552
97 SPX WQEBVZ4L5ROU|SPX 31 SPX 171215C01975000 228.3500 240.7000 228.3500 238.7500 0 718 0.2227069 0.6409332 0.0005779 10.8547759 -0.1948605 19.8886486
98 SPX W8Z446Y6OJV2|SPX 31 SPX 160318C01980000 99.9500 116.7500 99.9500 114.6500 0 30 0.1958987 0.6957117 0.0017892 3.4932184 -0.4366364 3.0574413
99 SPX W8Z44F7DHVFY|SPX 31 SPX 160318C01995000 89.4000 105.6500 89.4000 103.4000 60 3770 0.1922501 0.6696214 0.0018878 3.6170085 -0.4419366 2.9572184
100 SPX W9QOMSAI0CZY|SPX 31 SPX 160415C02000000 96.2000 111.7500 96.2000 109.6000 0 0.1925584 0.6470722 0.0016771 4.2740542 -0.3961182 3.7555243
101 SPX W792YAX1Q0WE|SPX 31 SPX 160115C02010000 50.5500 66.8000 50.5500 64.7000 20 1503 0.1681608 0.7504179 0.0036949 1.6223361 -0.6504843 0.9071438
102 SPX W87JLT59I4XA|SPX 31 SPX 160219C02035000 51.1500 65.2500 51.1500 63.3000 0 30 0.1714312 0.6054112 0.0027438 3.1501563 -0.5029366 1.8489926
103 SPX W87JLKQG9FNY|SPX 31 SPX 160219C02040000 48.2000 61.9000 48.2000 60.0000 5 962 0.1699414 0.5920046 0.0027919 3.1775868 -0.5022421 1.8107291
104 SPX W87JLTBVNIWE|SPX 31 SPX 160219C02075000 29.4500 40.2500 29.4500 38.5500 40 8696 0.1287903 0.4820367 0.0037813 3.2614874 -0.3923286 1.5033698
105 SPX W8Z446ZU7WCU|SPX 31 SPX 160318C02080000 38.7500 49.9000 38.7500 47.9500 0 104 0.1326167 0.4801887 0.0030096 3.9777480 -0.3348289 2.2067355
106 SPX WDYBH7KK57KE|SPX 31 SPX 160916C02080000 89.3000 100.4000 89.3000 98.2000 0 0.1397427 0.5229886 0.0016132 7.0366255 -0.2107788 7.1889247
107 SPX W9QOMSDN2KRY|SPX 31 SPX 160415C02100000 39.1500 49.1000 39.1500 47.3500 1 23 0.1310734 0.4381153 0.0026138 4.5342506 -0.2856155 2.6627046
108 SPX WHEDSYSWHTPQ|SPX 31 SPX 170120C02100000 105.1500 114.4000 105.1500 113.0000 0 1766 0.1366404 0.5103678 0.0013620 8.5464406 -0.1742698 10.1621199
109 SPX W792YAYV7PFY|SPX 31 SPX 160115C02120000 2.4750 4.6500 1.9500 4.4000 472 9459 0.1039753 0.1591405 0.0045635 1.2389010 -0.2968691 0.1985974
110 SPX W87JLTLSVLV2|SPX 31 SPX 160219C02135000 8.7000 14.0500 7.7000 12.5000 0 49 0.1107916 0.2391383 0.0034220 2.5390820 -0.2583766 0.7562169
111 SPX W87JLTNGEYCU|SPX 31 SPX 160219C02145000 6.6500 11.1500 5.7500 9.7000 1 271 0.1077472 0.2005290 0.0031801 2.2947455 -0.2265855 0.6353636
112 SPX X0JMQFR50QHA|SPX 31 SPX 181221C02150000 193.6500 198.4000 189.8500 197.8000 1 1 0.1435104 0.5322814 0.0007755 14.2066581 -0.1180188 27.0974021
113 SPX W8Z44FXU3FCE|SPX 31 SPX 160318C02155000 11.7000 17.5500 10.9500 15.5000 5 39 0.1137538 0.2383234 0.0027270 3.0915948 -0.2190418 1.1143824
114 SPX W792YJXUT8Q6|SPX 31 SPX 160115C02165000 0.5000 2.7750 0.4000 0.7250 48 1321 0.1039807 0.0348387 0.0014488 0.3933415 -0.0933895 0.0436212
115 SPX X0JMQORAAM3Y|SPX 31 SPX 181221C02175000 180.8500 187.0000 178.3500 186.4000 0 1 0.1469106 0.5157464 0.0007595 14.2422423 -0.1196811 26.2383014
116 SPX W87JLKSXKGEM|SPX 31 SPX 160219C02190000 1.7500 4.4750 0.9750 2.4250 3698 4836 0.0971003 0.0700238 0.0016901 1.0990872 -0.0969144 0.2233679
117 SPX W8Z44652VSBY|SPX 31 SPX 160318C02200000 4.2000 7.3500 3.3000 5.5500 216 71439 0.1027410 0.1132262 0.0018716 1.9163968 -0.1215767 0.5337181
118 SPX WBGPSOFFUFXQ|SPX 31 SPX 160617C02200000 19.9000 25.6500 19.0000 23.8000 5 30602 0.1167701 0.2468895 0.0018839 4.5295401 -0.1632652 2.3484533
119 SPX WHEDSYT2G5RI|SPX 31 SPX 170120C02200000 60.7000 67.3500 60.5000 65.8500 0 751 0.1269072 0.3685821 0.0013866 8.0811590 -0.1494453 7.5086265
120 SPX W8Z44725KL1Q|SPX 31 SPX 160318C02220000 2.5500 5.0750 2.2500 3.3000 152 1065 0.0995576 0.0752523 0.0014279 1.4167777 -0.0867827 0.3556164
121 SPX W792YK7S1BOU|SPX 31 SPX 160115C02225000 0.1250 1.6750 0.1250 0.1250 77 19922 0.1198492 0.0063583 0.0002923 0.0914618 -0.0248628 0.0079658
122 SPX WDYBHGU4S60E|SPX 31 SPX 160916C02225000 29.3000 35.1500 28.6500 33.2000 0 4225 0.1187515 0.2693588 0.0015741 5.8347416 -0.1439110 3.8324835
123 SPX WLF4IZP7O4TQ|SPX 31 SPX 170616C02225000 77.3500 83.1000 77.3500 81.9000 0 3 0.1321118 0.3844090 0.0011514 9.5966239 -0.1368132 10.5376231
124 SPX WHEDSZQMZYMM|SPX 31 SPX 170120C02250000 43.3500 48.3500 42.8000 47.2500 0 8 0.1243573 0.3017962 0.0013082 7.4711338 -0.1338522 6.1982258
125 SPX W87JLU5NBRSE|SPX 31 SPX 160219C02255000 0.3250 2.4500 0.2000 0.3750 0 414 0.0981084 0.0134813 0.0004302 0.2826900 -0.0249259 0.0431490
126 SPX W87JLKU38SR2|SPX 31 SPX 160219C02260000 0.2250 2.4250 0.2000 0.3500 0 298 0.0993784 0.0125615 0.0003996 0.2659361 -0.0237362 0.0402023
127 SPX W792YKJCSR5A|SPX 31 SPX 160115C02295000 0.0500 2.2750 0.0500 0.2500 0 142 0.1764869 0.0084405 0.0002548 0.1174045 -0.0467946 0.0105228
128 SPX WDYBH6PYRFLA|SPX 31 SPX 160916C02300000 12.8500 16.2500 11.5500 14.6000 500 5004 0.1093811 0.1515255 0.0012147 4.1471893 -0.0930024 2.1843531
129 SPX WGFX5P0BQ372|SPX 31 SPX 161216C02300000 24.6000 28.6000 23.8000 27.1000 200 21960 0.1158902 0.2122446 0.0012234 5.9318313 -0.1071760 4.0360413
130 SPX W87JLKUX0GZY|SPX 31 SPX 160219C02310000 0.2500 2.3500 0.2000 0.3000 0 1 0.1178357 0.0093764 0.0002613 0.2061776 -0.0216981 0.0299484
131 SPX WHEDT9DXSP66|SPX 31 SPX 170120C02325000 23.8500 27.3500 23.0500 26.0500 0 0.1155299 0.1999425 0.0011306 5.9985432 -0.0986796 4.1665165
132 SPX WHEDT9M7HFN2|SPX 31 SPX 170120C02375000 15.0500 17.9000 13.9000 16.3500 0 11 0.1103924 0.1418318 0.0009492 4.8120632 -0.0750964 2.9794942
133 SPX WHEDT9UH663Y|SPX 31 SPX 170120C02425000 9.0000 11.5500 7.5000 9.7500 0 2 0.1059794 0.0949607 0.0007440 3.6209592 -0.0538833 2.0084387
134 SPX WBGPSPGBGXSE|SPX 31 SPX 160617C02450000 0.4500 0.4750 0.2750 0.4000 0 926 0.0991231 0.0086194 0.0001645 0.3358187 -0.0099136 0.0840392
135 SPX WGFX5P0NMRAM|SPX 31 SPX 161216C02500000 2.9500 5.0000 2.4000 3.0750 1 6152 0.1007874 0.0384180 0.0004045 1.7056840 -0.0260743 0.7485320
136 SPX X0JMQQD63RE6|SPX 31 SPX 181221C02525000 62.8000 67.8500 61.3000 64.4500 2 3 0.1296722 0.2572209 0.0006962 11.5245654 -0.0811240 13.9773667
137 SPX WGFX5Q2OXLHQ|SPX 31 SPX 161216C02550000 1.7500 3.8750 0.9750 1.8000 0 7907 0.1003838 0.0240803 0.0002758 1.1584400 -0.0175375 0.4704008
138 SPX WLF4IPLJIEJY|SPX 31 SPX 170616C02600000 5.2000 7.3500 3.3000 5.4000 0 21 0.1046483 0.0513295 0.0004007 2.6451709 -0.0283685 1.4886942
139 SPX WLF4IPLPGQLQ|SPX 31 SPX 170616C02700000 2.2500 4.2500 1.1500 2.3250 0 72 0.1029224 0.0248259 0.0002248 1.4593851 -0.0152388 0.7243138
140 SPX X0JMQG128TFY|SPX 31 SPX 181221C02750000 24.4000 29.7500 23.1500 25.9500 3 3 0.1208248 0.1305622 0.0004915 7.5806486 -0.0485609 7.2982136
141 SPX WHEDT00K81LA|SPX 31 SPX 170120C02850000 0.7250 2.5250 0.7000 0.7250 0 2 0.1227461 0.0085897 0.0000887 0.5000141 -0.0082672 0.1832839
142 SPX WLF4IPMDA2SU|SPX 31 SPX 170616C03100000 0.9500 2.8250 0.2000 0.9500 0 114 0.1316807 0.0090069 0.0000735 0.6109159 -0.0079270 0.2611785
143 SPX WLF4IPMP6QWE|SPX 31 SPX 170616C03300000 1.2250 2.9250 1.2250 1.2250 0 2 0.1540328 0.0098909 0.0000682 0.6630438 -0.0099760 0.2841633
144 SPX 30D2BMMLUYJZI|SPX 31 SPX 160916P00300000 0.1750 0.1750 0.1750 0.1750 0 210 0.7504850 -0.0004259 0.0000012 0.0270621 -0.0037692 -0.0077220
145 SPX 30KJ4O5GXUISU|SPX 31 SPX 170616P00300000 0.3750 0.4000 0.3250 0.3500 0 18 0.5643011 -0.0007518 0.0000018 0.0650577 -0.0033449 -0.0281577
146 SPX 308349M1GXWVI|SPX 31 SPX 160318P00500000 0.1250 0.3250 0.1250 0.1250 64 11573 0.9496134 -0.0004464 0.0000017 0.0159735 -0.0088559 -0.0024476
147 SPX 30AKPY4BTWKHA|SPX 31 SPX 160617P00500000 0.2000 0.2250 0.1750 0.1750 25 793 0.6808133 -0.0005914 0.0000021 0.0297829 -0.0057102 -0.0067436
148 SPX 30ZNMVURM2ENI|SPX 31 SPX 181221P00500000 5.8000 7.5000 3.5500 5.0000 0 0.4081407 -0.0081330 0.0000153 0.7945726 -0.0142334 -0.6525862
149 SPX 308UOS8AD1DF2|SPX 31 SPX 160415P00600000 0.2250 0.2250 0.2250 0.2250 0 0.7585941 -0.0008407 0.0000033 0.0330273 -0.0109966 -0.0060889
150 SPX 307BJR02NYQ6M|SPX 31 SPX 160219P00650000 0.1000 0.3250 0.1000 0.1000 0 5594 0.9317693 -0.0004545 0.0000021 0.0133137 -0.0107842 -0.0016317
151 SPX 30KJ4O5HLNUZY|SPX 31 SPX 170616P00700000 2.1000 3.7500 1.4750 2.0500 0 228 0.3921103 -0.0056009 0.0000162 0.4017594 -0.0142037 -0.2015160
152 SPX 30KJ4O5SUGH72|SPX 31 SPX 170616P00750000 3.6750 3.6750 2.6500 3.5000 0 763 0.3969730 -0.0089347 0.0000242 0.6066250 -0.0216813 -0.3248661
153 SPX 307BJQZT8NSJ2|SPX 31 SPX 160219P00800000 0.1250 0.2750 0.1000 0.1500 0 1179 0.7967114 -0.0007777 0.0000041 0.0218694 -0.0151386 -0.0027589
154 SPX 308349M1YSX0U|SPX 31 SPX 160318P00800000 0.2250 0.2500 0.2000 0.2250 5050 5800 0.6774949 -0.0010914 0.0000054 0.0364224 -0.0143854 -0.0057954
155 SPX 307BJR05Z1F66|SPX 31 SPX 160219P00850000 0.1500 0.4500 0.1500 0.1500 0 2407 0.7480620 -0.0008288 0.0000046 0.0231884 -0.0150684 -0.0029247
156 SPX 30AKPY4P2579Q|SPX 31 SPX 160617P00850000 0.5500 0.7750 0.4250 0.6000 0 182 0.4889727 -0.0025974 0.0000114 0.1152787 -0.0158172 -0.0288079
157 SPX 30ZNMVV4UB1FY|SPX 31 SPX 181221P00850000 21.9000 23.0500 19.0500 19.9000 0 0.3433168 -0.0328259 0.0000598 2.6188366 -0.0387140 -2.6260548
158 SPX 30ZNMVYRHPBAM|SPX 31 SPX 181221P00875000 21.6500 23.2000 20.6000 21.5000 0 0.3390035 -0.0353579 0.0000643 2.7838346 -0.0405718 -2.8267284
159 SPX 308UOS8P2V0NI|SPX 31 SPX 160415P00950000 0.4250 0.4750 0.2750 0.3750 0 0.5114475 -0.0020125 0.0000108 0.0733538 -0.0164228 -0.0140677
160 SPX 30D2BMR2LVLNY|SPX 31 SPX 160916P00975000 2.6000 4.4250 1.5500 2.4750 0 29 0.4052078 -0.0092009 0.0000346 0.4378176 -0.0325888 -0.1572684
161 SPX 30KJ4O9XORKHA|SPX 31 SPX 170616P00975000 9.9000 11.1000 7.0500 9.2000 0 12 0.3550765 -0.0234891 0.0000622 1.3930885 -0.0441901 -0.8538664
162 SPX 306D33UOITHTA|SPX 31 SPX 160115P01025000 0.0500 2.2750 0.0500 0.2000 0 6700 0.9811261 -0.0013208 0.0000087 0.0221988 -0.0486124 -0.0017931
163 SPX 30AKPY4SD7W9A|SPX 31 SPX 160617P01050000 1.4500 3.4000 0.9500 1.3750 0 68 0.4184210 -0.0064553 0.0000302 0.2603040 -0.0304755 -0.0710316
164 SPX 30D2BMN2Q6JV2|SPX 31 SPX 160916P01050000 3.7000 5.3500 2.1000 3.4750 0 18 0.3876036 -0.0130172 0.0000489 0.5921010 -0.0420876 -0.2222980
165 SPX 30ZNMVV85DQFI|SPX 31 SPX 181221P01050000 36.6000 38.3000 34.9000 35.7000 0 0.3154613 -0.0586771 0.0001039 4.1822590 -0.0560383 -4.6967459
166 SPX 308UOSD75GVVY|SPX 31 SPX 160415P01075000 0.6750 0.7500 0.5000 0.6250 0 0.4592157 -0.0035773 0.0000203 0.1233070 -0.0247551 -0.0248769
167 SPX 30D2BMMN6L8DQ|SPX 31 SPX 160916P01100000 4.6500 6.0000 2.4500 4.3000 2 4000 0.3759760 -0.0161831 0.0000608 0.7141191 -0.0491778 -0.2761688
168 SPX 308UOSDNOUCTQ|SPX 31 SPX 160415P01175000 1.0250 1.1500 0.6000 0.9250 0 2 0.4200148 -0.0055788 0.0000330 0.1833738 -0.0336291 -0.0386411
169 SPX 30D2BMRZOMJJI|SPX 31 SPX 160916P01175000 6.4000 7.9500 4.2000 5.8500 0 182 0.3593222 -0.0222168 0.0000834 0.9349968 -0.0614122 -0.3788122
170 SPX 30PIC1BFHFTKE|SPX 31 SPX 171215P01175000 30.5500 30.5500 27.3500 28.5000 0 11 0.3119575 -0.0607422 0.0001328 3.4928229 -0.0712045 -3.0450064
171 SPX 307BJQZTWH4Q6|SPX 31 SPX 160219P01200000 0.3750 1.9500 0.2250 0.3250 0 9217 0.5067796 -0.0024897 0.0000186 0.0632766 -0.0278007 -0.0085883
172 SPX 30FJXBAIB9XM6|SPX 31 SPX 161216P01225000 12.9500 14.0500 9.9500 11.9000 0 783 0.3340339 -0.0382134 0.0001215 1.6982736 -0.0766621 -0.8910613
173 SPX 308349MLBBXN2|SPX 31 SPX 160318P01250000 0.8750 2.9000 0.7000 0.8250 0 6222 0.4289796 -0.0056537 0.0000377 0.1610195 -0.0401159 -0.0292247
174 SPX 30AKPY4VOAL8U|SPX 31 SPX 160617P01250000 3.6000 5.4500 2.1250 3.4250 0 3671 0.3644051 -0.0167467 0.0000796 0.5972442 -0.0606603 -0.1836113
175 SPX 307BJR0CR5572|SPX 31 SPX 160219P01260000 0.4500 0.7250 0.2500 0.3750 0 13 0.4715169 -0.0030452 0.0000240 0.0758902 -0.0310070 -0.0104691
176 SPX 307BJR0D31TAM|SPX 31 SPX 160219P01280000 0.4500 0.7250 0.2500 0.4000 0 22 0.4608201 -0.0033034 0.0000265 0.0816552 -0.0325998 -0.0113458
177 SPX 30ZNMVUSXP31Q|SPX 31 SPX 181221P01300000 67.8000 69.7500 65.7000 65.8500 0 0.2855017 -0.1068397 0.0001805 6.5786591 -0.0780517 -8.5719073
178 SPX 306D33QLC1R0U|SPX 31 SPX 160115P01350000 0.1250 0.3000 0.0750 0.0750 0 13112 0.5637653 -0.0009124 0.0000107 0.0158153 -0.0198799 -0.0011999
179 SPX 30ZNMVVD3ZRWU|SPX 31 SPX 181221P01350000 76.1000 77.9500 73.6000 73.7000 0 0.2811332 -0.1194678 0.0001985 7.1246469 -0.0828113 -9.6058041
180 SPX 308349SC1G67I|SPX 31 SPX 160318P01375000 1.3250 3.0500 0.6500 1.2250 2 2278 0.3730344 -0.0092479 0.0000668 0.2484955 -0.0537384 -0.0475144
181 SPX 306D33QLTWR66|SPX 31 SPX 160115P01380000 0.1250 0.4250 0.0750 0.0750 340 959 0.5365255 -0.0009571 0.0000118 0.0165262 -0.0197669 -0.0012565
182 SPX 308349MNGQAA6|SPX 31 SPX 160318P01380000 1.4500 3.0750 0.6750 1.2750 2 26 0.3719807 -0.0096026 0.0000693 0.2568109 -0.0553754 -0.0493402
183 SPX 306D33WC25ZLA|SPX 31 SPX 160115P01385000 0.1250 0.4250 0.1000 0.1000 387 1062 0.5454214 -0.0012308 0.0000146 0.0208121 -0.0253057 -0.0016181
184 SPX 306D33WFD8OKU|SPX 31 SPX 160115P01405000 0.1500 0.4250 0.1250 0.1250 0 990 0.5378942 -0.0015340 0.0000181 0.0254498 -0.0305146 -0.0020169
185 SPX 307BJR689X372|SPX 31 SPX 160219P01405000 0.7250 2.8000 0.5500 0.6750 0 1 0.4013579 -0.0060792 0.0000524 0.1407725 -0.0488842 -0.0207839
186 SPX 308349MO4JMHA|SPX 31 SPX 160318P01420000 1.7000 3.4000 0.8750 1.5500 0 12 0.3579567 -0.0118708 0.0000866 0.3088943 -0.0640500 -0.0609345
187 SPX 307BJR6BKZS6M|SPX 31 SPX 160219P01425000 0.7750 2.8250 0.4000 0.7250 0 29 0.3914255 -0.0066420 0.0000581 0.1522469 -0.0515471 -0.0226880
188 SPX 308349SKB4WOE|SPX 31 SPX 160318P01425000 1.7250 3.4750 1.0000 1.5750 0 880 0.3557919 -0.0121117 0.0000886 0.3143244 -0.0647757 -0.0621564
189 SPX 307BJR0G27U6M|SPX 31 SPX 160219P01460000 0.8750 2.9000 0.7000 0.8000 0 78 0.3728973 -0.0076031 0.0000687 0.1715284 -0.0552989 -0.0259242
190 SPX 308349MOSCYOE|SPX 31 SPX 160318P01460000 2.1500 3.8000 1.2250 1.8250 2 174 0.3424546 -0.0143259 0.0001065 0.3633979 -0.0720314 -0.0734315
191 SPX 306D33WU92T0U|SPX 31 SPX 160115P01495000 0.2000 0.4750 0.1500 0.1500 64 945 0.4652147 -0.0020861 0.0000277 0.0336612 -0.0348879 -0.0027306
192 SPX 30PIC163N7ULQ|SPX 31 SPX 171215P01500000 72.2000 72.2000 66.3500 67.4000 0 6111 0.2711097 -0.1401088 0.0002829 6.4671284 -0.1115899 -7.0564656
193 SPX 307BJR6S4D94E|SPX 31 SPX 160219P01525000 1.2500 3.2750 0.7500 1.1250 5110 5937 0.3460727 -0.0110965 0.0001030 0.2388071 -0.0713761 -0.0377694
194 SPX 30D2BMTLKFOTQ|SPX 31 SPX 160916P01525000 23.9000 24.4000 19.4500 21.5500 0 305 0.2876333 -0.0833589 0.0003018 2.7092849 -0.1404313 -1.4176620
195 SPX 30ZNMW1QZMVE6|SPX 31 SPX 181221P01525000 111.3000 113.4000 105.6500 106.0500 0 0.2622195 -0.1685015 0.0002686 8.9898151 -0.0953793 -13.5809293
196 SPX 306D33QON4G0E|SPX 31 SPX 160115P01550000 0.2500 1.5750 0.1750 0.1750 61 11827 0.4236083 -0.0026284 0.0000375 0.0414934 -0.0391430 -0.0034318
197 SPX 30KJ4O662R95A|SPX 31 SPX 170616P01550000 60.5000 60.5000 54.4000 55.8500 0 501 0.2704491 -0.1400122 0.0003277 5.5907883 -0.1304404 -5.1158323
198 SPX 306D33QOZ143Y|SPX 31 SPX 160115P01570000 0.2750 1.7750 0.2500 0.2500 0 909 0.4215045 -0.0036659 0.0000509 0.0559837 -0.0525419 -0.0047900
199 SPX 307BJR75CO12M|SPX 31 SPX 160219P01605000 1.9750 3.9000 1.0000 1.5750 0 394 0.3089999 -0.0166487 0.0001638 0.3389127 -0.0902946 -0.0564882
200 SPX 307BJR0IPH6Z2|SPX 31 SPX 160219P01620000 2.1500 4.0250 1.0250 1.7000 0 107 0.3026600 -0.0181748 0.0001802 0.3652703 -0.0952852 -0.0616376
201 SPX 307BJR7ABA2JY|SPX 31 SPX 160219P01635000 2.3500 2.3500 1.0750 1.8250 240 246 0.2959842 -0.0197481 0.0001978 0.3919977 -0.0999627 -0.0669370
202 SPX 306D33QQ4PGGE|SPX 31 SPX 160115P01640000 0.4000 0.5500 0.3000 0.3000 0 1190 0.3675918 -0.0049267 0.0000760 0.0729203 -0.0596403 -0.0064154
203 SPX 308349MRXHBM6|SPX 31 SPX 160318P01650000 6.5500 8.1000 5.3500 5.7500 1139 21871 0.2893290 -0.0457390 0.0003325 0.9587400 -0.1597304 -0.2342436
204 SPX 308UOSFYDPPIM|SPX 31 SPX 160415P01675000 12.2500 13.4000 8.5500 10.6500 0 0.2738891 -0.0713608 0.0004325 1.5676932 -0.1850508 -0.4904919
205 SPX 307BJR7P746ZY|SPX 31 SPX 160219P01725000 4.5000 6.1500 2.5250 3.6000 52 1885 0.2677540 -0.0392484 0.0003873 0.6944198 -0.1597448 -0.1329913
206 SPX 30GIDYMLWTOXA|SPX 31 SPX 170120P01725000 69.3000 69.3000 61.6000 63.2000 0 92 0.2454425 -0.1909500 0.0005175 5.8331907 -0.1694642 -4.9244493
207 SPX 30KJ4ODDQ2LIM|SPX 31 SPX 170616P01725000 94.5000 94.5000 86.0000 87.4000 0 609 0.2454746 -0.2118306 0.0004698 7.2756837 -0.1509142 -7.7511093
208 SPX 30PIC1DYFZWQ6|SPX 31 SPX 171215P01725000 120.8000 120.8000 111.7000 112.9500 0 1795 0.2463032 -0.2270563 0.0004215 8.7544838 -0.1333196 -11.5074903
209 SPX 30D2BMUQWVD66|SPX 31 SPX 160916P01775000 55.9000 55.9000 48.3500 50.3000 0 2749 0.2412837 -0.1921861 0.0006411 4.8281103 -0.2056167 -3.2725822
210 SPX 306D33QSG255A|SPX 31 SPX 160115P01780000 1.1000 3.0250 0.6250 0.7000 84 1099 0.2770400 -0.0137652 0.0002484 0.1797130 -0.1105115 -0.0178396
211 SPX 306D33Y9IQKBY|SPX 31 SPX 160115P01805000 1.2500 3.1500 0.7500 0.8250 34 3528 0.2605199 -0.0168698 0.0003146 0.2140160 -0.1236745 -0.0218432
212 SPX 30D2BMNFYHBTA|SPX 31 SPX 160916P01850000 71.7000 71.7000 62.1500 64.6500 30 1419 0.2294411 -0.2439605 0.0007737 5.5413440 -0.2221946 -4.1636278
213 SPX 30GIDYFJ84E1A|SPX 31 SPX 170120P01850000 98.1500 98.1500 88.2500 89.7000 0 415 0.2280445 -0.2653782 0.0006707 7.0243384 -0.1861497 -6.8684036
214 SPX 306D33YHSFASU|SPX 31 SPX 160115P01855000 2.2000 3.8750 0.9250 1.3000 56 3097 0.2309732 -0.0281261 0.0005464 0.3295382 -0.1685411 -0.0363719
215 SPX 306D33QULGHSE|SPX 31 SPX 160115P01910000 4.6500 6.0000 1.9500 2.8500 157 3543 0.2079109 -0.0609224 0.0011347 0.6160057 -0.2828092 -0.0788043
216 SPX 306D33YRPNDRI|SPX 31 SPX 160115P01915000 5.1500 6.3000 1.8000 3.0500 80 2430 0.2055810 -0.0651837 0.0012097 0.6493142 -0.2946630 -0.0843170
217 SPX 306D33QURETU6|SPX 31 SPX 160115P01920000 5.6500 6.7500 2.8000 3.3250 160 2738 0.2041169 -0.0705736 0.0012954 0.6904026 -0.3109756 -0.0913032
218 SPX 307BJR0NO38GE|SPX 31 SPX 160219P01920000 20.6500 20.6500 14.5500 16.2500 7 1973 0.2069531 -0.1727444 0.0015095 2.0922062 -0.3671840 -0.5860724
219 SPX 30FJXBDQ2W86M|SPX 31 SPX 161216P01925000 113.3500 113.3500 102.1000 103.6500 30 6420 0.2187866 -0.3170605 0.0007960 7.2863506 -0.2016481 -7.4442610
220 SPX 307BJR0NZZWJY|SPX 31 SPX 160219P01940000 24.2500 24.2500 17.4500 19.1000 234 915 0.2011153 -0.2008926 0.0017056 2.2972420 -0.3908089 -0.6819380
221 SPX 30D2BMNHM0OB2|SPX 31 SPX 160916P01950000 99.3000 99.3000 87.8500 89.7000 0 3489 0.2126691 -0.3284581 0.0009620 6.3862373 -0.2329558 -5.6236291
222 SPX 30ZNMVVN17UVI|SPX 31 SPX 181221P01950000 238.0000 242.2500 226.3000 230.6500 2 3 0.2222438 -0.3378726 0.0004603 13.0594785 -0.1074988 -27.5840726
223 SPX 306D33Z1MVGQ6|SPX 31 SPX 160115P01975000 12.6500 12.6500 7.6000 7.7500 3604 51558 0.1828379 -0.1554880 0.0025558 1.2201338 -0.4897439 -0.2014163
224 SPX 308UOSHBZU4BY|SPX 31 SPX 160415P01975000 57.5000 57.5000 47.3500 49.4000 0 0.1993533 -0.3150786 0.0015491 4.0872195 -0.3401933 -2.1741605
225 SPX 30AKPYDDMNNFY|SPX 31 SPX 160617P01975000 80.3000 80.3000 69.2500 71.3000 0 9022 0.2039944 -0.3384095 0.0012495 5.2482595 -0.2824332 -3.7195560
226 SPX 306D33Z9WK772|SPX 31 SPX 160115P02025000 25.5000 25.5000 15.0000 16.3000 3814 29961 0.1614736 -0.3028958 0.0042322 1.7843410 -0.6265764 -0.3930779
227 SPX 308349MYDODJI|SPX 31 SPX 160318P02040000 68.0500 68.0500 55.2500 57.2500 686 13944 0.1785631 -0.4178762 0.0021904 3.8979745 -0.3824880 -2.1507932
228 SPX 306D33ZD7MW6M|SPX 31 SPX 160115P02045000 33.1000 33.1000 20.6500 21.9500 201 3205 0.1533605 -0.3888042 0.0048918 1.9588121 -0.6490181 -0.5052018
229 SPX 30PIC16Z2DATQ|SPX 31 SPX 171215P02050000 233.6500 233.6500 218.3500 220.1000 0 2141 0.2177865 -0.4049872 0.0006128 11.2552980 -0.1406896 -20.9333879
230 SPX 30ZNMVVOOR7DA|SPX 31 SPX 181221P02050000 279.3500 284.2500 273.1000 273.7000 325 325 0.2272899 -0.3857177 0.0004710 13.6644455 -0.1125423 -32.2398016
231 SPX 306D33ZGIPL66|SPX 31 SPX 160115P02065000 42.8500 42.8500 27.6000 29.2000 239 1247 0.1259150 -0.4903427 0.0061987 2.0379216 -0.5452585 -0.6357648
232 SPX 307BJR0Q5E972|SPX 31 SPX 160219P02070000 66.6000 66.6000 51.6000 53.7500 169 371 0.1300598 -0.4989275 0.0037482 3.2647858 -0.3406889 -1.6873901
233 SPX 307BJR0QT7LE6|SPX 31 SPX 160219P02110000 90.1500 90.1500 71.5000 73.7000 0 50 0.1182678 -0.6591567 0.0037894 3.0014068 -0.2703705 -2.2387955
234 SPX 306D33QY8FUVI|SPX 31 SPX 160115P02130000 92.0000 92.0000 68.8500 71.0500 0 82 0.1010510 -0.8879592 0.0036899 0.9735601 -0.1678844 -1.1642975
235 SPX 308349MZV9DZI|SPX 31 SPX 160318P02130000 115.9500 115.9500 96.8500 99.0500 0 2 0.1206240 -0.6800760 0.0029694 3.5696921 -0.2114156 -3.4821263
236 SPX 307BJR9L05F8U|SPX 31 SPX 160219P02135000 108.4000 108.4000 87.3500 89.8500 0 14 0.1107916 -0.7608617 0.0034220 2.5390820 -0.1999753 -2.5939489
237 SPX 308349VX1D8Q6|SPX 31 SPX 160318P02155000 134.2000 134.2000 112.7500 115.3500 0 0.1137538 -0.7616766 0.0027270 3.0915948 -0.1601387 -3.9138625
238 SPX 308349N0J2Q6M|SPX 31 SPX 160318P02170000 146.0500 146.0500 123.1000 126.2000 0 0.1097928 -0.8078418 0.0024930 2.7278814 -0.1266688 -4.1620575
239 SPX 306D33ZYPMELQ|SPX 31 SPX 160115P02175000 135.6000 135.6000 111.0500 113.7500 0 352 0.1071506 -0.9734009 0.0011243 0.3145482 -0.0172881 -1.2985608
240 SPX 30AKPYEAPELBI|SPX 31 SPX 160617P02175000 175.7000 175.7000 155.1500 158.2000 3 530 0.1220085 -0.6972861 0.0019941 5.0094064 -0.1302085 -7.5953487
241 SPX 30FJXBEVFBWJ2|SPX 31 SPX 161216P02175000 222.9000 222.9000 203.4000 206.2500 0 206 0.1303749 -0.6040359 0.0014448 7.8810604 -0.1048367 -13.8048730
242 SPX 30PIC1G0V6IY6|SPX 31 SPX 171215P02175000 295.5500 295.5500 275.5500 278.9000 0 2 0.1412592 -0.5254904 0.0009705 11.5617837 -0.0777832 -25.4725807
243 SPX 30ZNMVUUFA3HQ|SPX 31 SPX 181221P02200000 351.0000 360.0000 343.5000 346.2500 31 31 0.1459020 -0.5028949 0.0007653 14.2529712 -0.0598557 -38.5327238
244 SPX 306D3406ZB52M|SPX 31 SPX 160115P02225000 185.3000 185.3000 160.3500 163.4000 0 140 0.1198492 -0.9936417 0.0002923 0.0914618 0.0360587 -1.3545196
245 SPX 30AKPYEIZ3BSE|SPX 31 SPX 160617P02225000 212.5500 212.5500 189.2500 192.9000 0 140 0.1127631 -0.8038957 0.0017098 3.9698130 -0.0768704 -8.8251965
246 SPX 308349N1ISQHA|SPX 31 SPX 160318P02230000 199.3500 199.3500 174.2000 177.1500 0 0.0978264 -0.9405065 0.0012117 1.1813385 -0.0100340 -4.9217535
247 SPX 308349N1UPEKU|SPX 31 SPX 160318P02250000 218.2000 218.2000 192.4500 196.1500 1 93 0.0958760 -0.9628105 0.0008484 0.8106909 0.0139091 -5.0736312
248 SPX 30AKPY5C7O26M|SPX 31 SPX 160617P02250000 232.9500 232.9500 209.0000 212.5000 0 1340 0.1086362 -0.8505992 0.0014917 3.3367370 -0.0495508 -9.3855166
249 SPX 30D2BMNMKMPSE|SPX 31 SPX 160916P02250000 251.8000 251.8000 228.6000 232.4500 0 0.1163369 -0.7709011 0.0014741 5.3529300 -0.0675084 -13.0877984
250 SPX 306D33R0DU7IM|SPX 31 SPX 160115P02260000 220.2500 220.2500 195.3500 198.3500 0 0.1556556 -0.9897124 0.0003435 0.1395984 0.0127259 -1.3710739
251 SPX 307BJR0TAIM4U|SPX 31 SPX 160219P02260000 224.9000 224.9000 199.2500 202.5500 0 0.0993784 -0.9874385 0.0003996 0.2659361 0.0380844 -3.5061091
252 SPX 306D33R0JSJKE|SPX 31 SPX 160115P02270000 230.2000 230.2000 204.9500 208.3000 85 87 0.1444830 -0.9956174 0.0001741 0.0656906 0.0406894 -1.3845592
253 SPX 308349WGVTENI|SPX 31 SPX 160318P02275000 242.5000 242.5000 216.7000 220.4000 0 317 0.0953412 -0.9790341 0.0005294 0.5030698 0.0329241 -5.2087166
254 SPX 30PIC164YUIZY|SPX 31 SPX 171215P02300000 369.3500 369.3500 347.3000 350.3000 0 1 0.1317910 -0.6494106 0.0009684 10.7631144 -0.0539887 -31.9245900
255 SPX 308349N30DQXA|SPX 31 SPX 160318P02320000 287.3500 287.3500 260.5500 264.9500 0 0.1002823 -0.9902418 0.0002606 0.2604427 0.0475724 -5.3668876
256 SPX 30ZNMW5FAMMWE|SPX 31 SPX 181221P02325000 421.1500 427.5500 412.2000 415.2000 0 0.1390319 -0.5984965 0.0007785 13.8166897 -0.0453172 -46.4998419
257 SPX 30PIC1740ZCB2|SPX 31 SPX 171215P02350000 402.6500 402.6500 379.8500 382.7500 0 250 0.1286517 -0.6972093 0.0009345 10.1393045 -0.0424925 -34.5268268
258 SPX 30PIC1GXXXGTQ|SPX 31 SPX 171215P02375000 419.6500 419.6500 396.8000 399.8500 0 1 0.1269808 -0.7206556 0.0009118 9.7645585 -0.0362304 -35.8240089
259 SPX 30GIDYFT5CGZY|SPX 31 SPX 170120P02450000 437.7500 437.7500 411.8500 415.7500 0 0.1044499 -0.9230939 0.0006446 3.0920581 0.0212060 -24.4899650
260 SPX 30ZNMVVVAWLCE|SPX 31 SPX 181221P02450000 500.4000 508.0000 490.9500 493.6000 0 0.1321086 -0.6928202 0.0007445 12.5541861 -0.0258106 -54.7053839
261 SPX 30FJXBGHB51TA|SPX 31 SPX 161216P02525000 507.6000 507.6000 480.4000 485.1000 0 0.0994484 -0.9709857 0.0003253 1.3536882 0.0481387 -23.9823052
262 SPX 30ZNMW6CDDKRY|SPX 31 SPX 181221P02525000 558.2500 561.0500 543.2500 546.0000 0 0.1296722 -0.7427791 0.0006962 11.5245654 -0.0139875 -59.4273800
263 SPX 306D33R56HWY6|SPX 31 SPX 160115P02550000 510.0000 510.0000 483.5000 488.1000 0 19 0.3927130 -0.9815923 0.0002217 0.2338126 -0.1307973 -1.5827232
264 SPX 30FJXB61W7EVI|SPX 31 SPX 161216P02550000 531.8500 531.8500 504.5500 509.3500 0 0.1003838 -0.9759197 0.0002758 1.1584400 0.0516429 -24.3214189
265 SPX 30GIDYFUSVTHQ|SPX 31 SPX 170120P02550000 532.1000 532.1000 505.2000 509.6000 0 0.1005625 -0.9691639 0.0003230 1.4917295 0.0483706 -26.5278914
266 SPX 306D33R6U19FY|SPX 31 SPX 160115P02650000 609.9000 609.9000 583.5000 588.0000 0 0.4535594 -0.9834688 0.0001751 0.2133032 -0.1386578 -1.6481540
267 SPX 308349M53X9YM|SPX 31 SPX 160318P02700000 666.3000 666.3000 639.4000 643.9500 0 0.1908919 -0.9977202 0.0000375 0.0712754 0.0657050 -6.2891749
268 SPX 30ZNMVW09IMTQ|SPX 31 SPX 181221P02750000 735.2500 737.5000 720.6500 721.8000 0 0.1208248 -0.8694378 0.0004915 7.5806486 0.0245582 -72.6475502
269 SPX 30AKPY4FMU9M6|SPX 31 SPX 160617P02800000 771.0000 771.0000 744.7500 748.5500 0 0.1562682 -0.9966103 0.0000455 0.1465340 0.0696652 -13.4314000
270 SPX 30FJXB50CRKTQ|SPX 31 SPX 161216P02800000 777.8000 777.8000 750.6500 755.2000 0 17 0.2344222 -0.8754691 0.0004278 4.2032848 -0.0675783 -25.0065368
271 SPX 30KJ4O5L8N832|SPX 31 SPX 170616P02900000 878.7000 878.7000 851.7000 856.0000 0 2 0.1158120 -0.9873498 0.0001124 0.8211936 0.0688026 -41.9336798
272 SPX 30KJ4O6T8A426|SPX 31 SPX 170616P02950000 927.7000 927.7000 900.6000 905.0500 0 0.1193518 -0.9888118 0.0000980 0.7382080 0.0708791 -42.7058646
273 SPX 30KJ4O5LWGKA6|SPX 31 SPX 170616P03300000 1271.5500 1271.5500 1244.5500 1248.9000 0 0.1540328 -0.9901091 0.0000682 0.6630438 0.0791063 -47.8527718

View File

@@ -48,6 +48,8 @@ namespace QuantConnect.Lean.Engine
private IAlgorithm _algorithm;
private readonly object _lock;
private readonly bool _liveMode;
private bool _cancelRequested;
private CancellationTokenSource _cancellationTokenSource;
/// <summary>
/// Publicly accessible algorithm status
@@ -111,14 +113,17 @@ namespace QuantConnect.Lean.Engine
/// <param name="results">Result handler object</param>
/// <param name="realtime">Realtime processing object</param>
/// <param name="leanManager">ILeanManager implementation that is updated periodically with the IAlgorithm instance</param>
/// <param name="token">Cancellation token</param>
/// <param name="cancellationTokenSource">Cancellation token source to monitor</param>
/// <remarks>Modify with caution</remarks>
public void Run(AlgorithmNodePacket job, IAlgorithm algorithm, ISynchronizer synchronizer, ITransactionHandler transactions, IResultHandler results, IRealTimeHandler realtime, ILeanManager leanManager, CancellationToken token)
public void Run(AlgorithmNodePacket job, IAlgorithm algorithm, ISynchronizer synchronizer, ITransactionHandler transactions, IResultHandler results, IRealTimeHandler realtime, ILeanManager leanManager, CancellationTokenSource cancellationTokenSource)
{
//Initialize:
DataPoints = 0;
_algorithm = algorithm;
var token = cancellationTokenSource.Token;
_cancellationTokenSource = cancellationTokenSource;
var backtestMode = (job.Type == PacketType.BacktestNode);
var methodInvokers = new Dictionary<Type, MethodInvoker>();
var marginCallFrequency = TimeSpan.FromMinutes(5);
@@ -607,6 +612,22 @@ namespace QuantConnect.Lean.Engine
{
_algorithm.SetStatus(state);
}
if (_cancellationTokenSource != null && !_cancellationTokenSource.IsCancellationRequested && !_cancelRequested)
{
if (state == AlgorithmStatus.Deleted)
{
_cancelRequested = true;
// if the algorithm was deleted, let's give the algorithm a few seconds to shutdown and cancel it out
_cancellationTokenSource.CancelAfter(TimeSpan.FromSeconds(5));
}
else if (state == AlgorithmStatus.Stopped)
{
_cancelRequested = true;
// if the algorithm was stopped, let's give the algorithm a few seconds to shutdown and cancel it out
_cancellationTokenSource.CancelAfter(TimeSpan.FromMinutes(1));
}
}
}
}

View File

@@ -24,6 +24,8 @@ namespace QuantConnect.Lean.Engine.DataFeeds
/// </summary>
public class DefaultDataProvider : IDataProvider, IDisposable
{
private bool _oneTimeWarningLog;
/// <summary>
/// Event raised each time data fetch is finished (successfully or not)
/// </summary>
@@ -37,6 +39,7 @@ namespace QuantConnect.Lean.Engine.DataFeeds
public virtual Stream Fetch(string key)
{
var success = true;
var errorMessage = string.Empty;
try
{
return new FileStream(FileExtension.ToNormalizedPath(key), FileMode.Open, FileAccess.Read, FileShare.Read);
@@ -44,8 +47,17 @@ namespace QuantConnect.Lean.Engine.DataFeeds
catch (Exception exception)
{
success = false;
if (exception is DirectoryNotFoundException
|| exception is FileNotFoundException)
errorMessage = exception.Message;
if (exception is DirectoryNotFoundException)
{
if (!_oneTimeWarningLog)
{
_oneTimeWarningLog = true;
Logging.Log.Debug($"DefaultDataProvider.Fetch(): DirectoryNotFoundException: please review data paths, current 'Globals.DataFolder': {Globals.DataFolder}");
}
return null;
}
else if (exception is FileNotFoundException)
{
return null;
}
@@ -54,7 +66,7 @@ namespace QuantConnect.Lean.Engine.DataFeeds
}
finally
{
OnNewDataRequest(new DataProviderNewDataRequestEventArgs(key, success));
OnNewDataRequest(new DataProviderNewDataRequestEventArgs(key, success, errorMessage));
}
}

View File

@@ -196,11 +196,6 @@ namespace QuantConnect.Lean.Engine.DataFeeds
factory = new TimeTriggeredUniverseSubscriptionEnumeratorFactory(request.Universe as ITimeTriggeredUniverse,
_marketHoursDatabase,
_timeProvider);
if (request.Universe is UserDefinedUniverse)
{
return factory.CreateEnumerator(request, _dataProvider);
}
}
else if (request.Configuration.Type == typeof(FundamentalUniverse))
{

View File

@@ -452,7 +452,7 @@ namespace QuantConnect.Lean.Engine.DataFeeds
{
foreach (var addedContract in chain.Contracts)
{
addedContract.Value.UnderlyingLastPrice = chain.Underlying.Price;
addedContract.Value.Update(chain.Underlying);
}
}
foreach (var contractSymbol in universeData.FilteredContracts ?? Enumerable.Empty<Symbol>())
@@ -465,7 +465,7 @@ namespace QuantConnect.Lean.Engine.DataFeeds
OptionContract contract;
if (!chain.Contracts.TryGetValue(baseData.Symbol, out contract))
{
contract = OptionContract.Create(baseData, security, chain.Underlying.Price);
contract = OptionContract.Create(baseData, security, chain.Underlying);
chain.Contracts[baseData.Symbol] = contract;
@@ -481,19 +481,19 @@ namespace QuantConnect.Lean.Engine.DataFeeds
case MarketDataType.Tick:
var tick = (Tick)baseData;
chain.Ticks.Add(tick.Symbol, tick);
UpdateContract(contract, tick);
contract.Update(tick);
break;
case MarketDataType.TradeBar:
var tradeBar = (TradeBar)baseData;
chain.TradeBars[symbol] = tradeBar;
UpdateContract(contract, tradeBar);
contract.Update(tradeBar);
break;
case MarketDataType.QuoteBar:
var quote = (QuoteBar)baseData;
chain.QuoteBars[symbol] = quote;
UpdateContract(contract, quote);
contract.Update(quote);
break;
case MarketDataType.Base:
@@ -572,55 +572,6 @@ namespace QuantConnect.Lean.Engine.DataFeeds
return true;
}
private static void UpdateContract(OptionContract contract, QuoteBar quote)
{
if (quote.Ask != null && quote.Ask.Close != 0m)
{
contract.AskPrice = quote.Ask.Close;
contract.AskSize = (long)quote.LastAskSize;
}
if (quote.Bid != null && quote.Bid.Close != 0m)
{
contract.BidPrice = quote.Bid.Close;
contract.BidSize = (long)quote.LastBidSize;
}
}
private static void UpdateContract(OptionContract contract, Tick tick)
{
if (tick.TickType == TickType.Trade)
{
contract.LastPrice = tick.Price;
}
else if (tick.TickType == TickType.Quote)
{
if (tick.AskPrice != 0m)
{
contract.AskPrice = tick.AskPrice;
contract.AskSize = (long)tick.AskSize;
}
if (tick.BidPrice != 0m)
{
contract.BidPrice = tick.BidPrice;
contract.BidSize = (long)tick.BidSize;
}
}
else if (tick.TickType == TickType.OpenInterest)
{
if (tick.Value != 0m)
{
contract.OpenInterest = tick.Value;
}
}
}
private static void UpdateContract(OptionContract contract, TradeBar tradeBar)
{
if (tradeBar.Close == 0m) return;
contract.LastPrice = tradeBar.Close;
contract.Volume = (long)tradeBar.Volume;
}
private static void UpdateContract(FuturesContract contract, QuoteBar quote)
{
if (quote.Ask != null && quote.Ask.Close != 0m)

View File

@@ -334,7 +334,7 @@ namespace QuantConnect.Lean.Engine
// -> Using this Data Feed,
// -> Send Orders to this TransactionHandler,
// -> Send Results to ResultHandler.
algorithmManager.Run(job, algorithm, synchronizer, AlgorithmHandlers.Transactions, AlgorithmHandlers.Results, AlgorithmHandlers.RealTime, SystemHandlers.LeanManager, isolator.CancellationToken);
algorithmManager.Run(job, algorithm, synchronizer, AlgorithmHandlers.Transactions, AlgorithmHandlers.Results, AlgorithmHandlers.RealTime, SystemHandlers.LeanManager, isolator.CancellationTokenSource);
}
catch (Exception err)
{

View File

@@ -43,7 +43,7 @@
<Message Text="SelectedOptimization $(SelectedOptimization)" Importance="high" />
</Target>
<ItemGroup>
<PackageReference Include="QuantConnect.pythonnet" Version="2.0.38" />
<PackageReference Include="QuantConnect.pythonnet" Version="2.0.39" />
<PackageReference Include="fasterflect" Version="3.0.0" />
<PackageReference Include="MathNet.Numerics" Version="5.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />

View File

@@ -209,7 +209,7 @@ namespace QuantConnect.Lean.Engine.RealTime
/// </summary>
public override void Exit()
{
_realTimeThread.StopSafely(TimeSpan.FromMinutes(5), _cancellationTokenSource);
_realTimeThread.StopSafely(TimeSpan.FromMinutes(1), _cancellationTokenSource);
_cancellationTokenSource.DisposeSafely();
base.Exit();
}

View File

@@ -91,8 +91,7 @@ namespace QuantConnect.Lean.Engine.Server
{
if (Algorithm.LiveMode)
{
_commandHandler = new FileCommandHandler();
_commandHandler.Initialize(_job, Algorithm);
SetCommandHandler();
}
}
@@ -119,5 +118,14 @@ namespace QuantConnect.Lean.Engine.Server
{
_commandHandler.DisposeSafely();
}
/// <summary>
/// Set the command handler to use, protected for testing purposes
/// </summary>
protected virtual void SetCommandHandler()
{
_commandHandler = new FileCommandHandler();
_commandHandler.Initialize(_job, Algorithm);
}
}
}

View File

@@ -32,7 +32,7 @@
<Message Text="SelectedOptimization $(SelectedOptimization)" Importance="high" />
</Target>
<ItemGroup>
<PackageReference Include="QuantConnect.pythonnet" Version="2.0.38" />
<PackageReference Include="QuantConnect.pythonnet" Version="2.0.39" />
<PackageReference Include="MathNet.Numerics" Version="5.0.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -208,18 +208,19 @@
"tt-log-fix-messages": false,
// Trade Station configuration
"trade-station-api-key": "",
"trade-station-api-secret": "",
"trade-station-code-from-url": "",
"trade-station-client-id": "",
"trade-station-client-secret": "",
"trade-station-redirect-url": "http://localhost",
"trade-station-refresh-token": "",
"trade-station-api-url": "https://sim-api.tradestation.com",
"trade-station-account-type": "Cash|Margin|Futures",
// [Optional] Trade Station Proxy Settings
"trade-station-use-proxy": false,
"trade-station-proxy-address-port": "",
"trade-station-proxy-username": "",
"trade-station-proxy-password": "",
"trade-station-account-id": "",
// Alpaca configuration
"alpaca-api-key": "",
"alpaca-api-secret": "",
"alpaca-access-token": "",
"alpaca-paper-trading": true,
// Exante trading configuration
// client-id, application-id, shared-key are required to access Exante REST API
@@ -532,6 +533,34 @@
"history-provider": [ "BrokerageHistoryProvider", "SubscriptionDataReaderHistoryProvider" ]
},
"live-trade-station": {
"live-mode": true,
// real brokerage implementations require the BrokerageTransactionHandler
"live-mode-brokerage": "TradeStationBrokerage",
"data-queue-handler": [ "TradeStationBrokerage" ],
"setup-handler": "QuantConnect.Lean.Engine.Setup.BrokerageSetupHandler",
"result-handler": "QuantConnect.Lean.Engine.Results.LiveTradingResultHandler",
"data-feed-handler": "QuantConnect.Lean.Engine.DataFeeds.LiveTradingDataFeed",
"real-time-handler": "QuantConnect.Lean.Engine.RealTime.LiveTradingRealTimeHandler",
"transaction-handler": "QuantConnect.Lean.Engine.TransactionHandlers.BrokerageTransactionHandler",
"history-provider": [ "BrokerageHistoryProvider", "SubscriptionDataReaderHistoryProvider" ]
},
"live-alpaca": {
"live-mode": true,
// real brokerage implementations require the BrokerageTransactionHandler
"live-mode-brokerage": "AlpacaBrokerage",
"data-queue-handler": [ "AlpacaBrokerage" ],
"setup-handler": "QuantConnect.Lean.Engine.Setup.BrokerageSetupHandler",
"result-handler": "QuantConnect.Lean.Engine.Results.LiveTradingResultHandler",
"data-feed-handler": "QuantConnect.Lean.Engine.DataFeeds.LiveTradingDataFeed",
"real-time-handler": "QuantConnect.Lean.Engine.RealTime.LiveTradingRealTimeHandler",
"transaction-handler": "QuantConnect.Lean.Engine.TransactionHandlers.BrokerageTransactionHandler",
"history-provider": [ "BrokerageHistoryProvider", "SubscriptionDataReaderHistoryProvider" ]
},
"live-futures-bybit": {
"live-mode": true,

View File

@@ -41,7 +41,7 @@
<PackageLicenseFile>LICENSE</PackageLicenseFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="QuantConnect.pythonnet" Version="2.0.38" />
<PackageReference Include="QuantConnect.pythonnet" Version="2.0.39" />
<PackageReference Include="Deedle" Version="2.1.0" />
<PackageReference Include="MathNet.Numerics" Version="5.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />

View File

@@ -31,7 +31,8 @@ namespace QuantConnect.Research
/// Create a new instance of <see cref="FutureHistory"/>.
/// </summary>
/// <param name="data"></param>
public FutureHistory(IEnumerable<Slice> data) : base(data, new Lazy<PyObject>(() => new PandasConverter().GetDataFrame(data)))
public FutureHistory(IEnumerable<Slice> data)
: base(data, new Lazy<PyObject>(() => new PandasConverter().GetDataFrame(data), isThreadSafe: false))
{
}

View File

@@ -31,7 +31,8 @@ namespace QuantConnect.Research
/// Create a new instance of <see cref="OptionHistory"/>.
/// </summary>
/// <param name="data"></param>
public OptionHistory(IEnumerable<Slice> data) : base(data, new Lazy<PyObject>(() => new PandasConverter().GetDataFrame(data)))
public OptionHistory(IEnumerable<Slice> data)
: base(data, new Lazy<PyObject>(() => new PandasConverter().GetDataFrame(data), isThreadSafe: false))
{
}

View File

@@ -34,7 +34,7 @@
<ItemGroup>
<PackageReference Include="Plotly.NET" Version="3.0.1" />
<PackageReference Include="Plotly.NET.Interactive" Version="3.0.2" />
<PackageReference Include="QuantConnect.pythonnet" Version="2.0.38" />
<PackageReference Include="QuantConnect.pythonnet" Version="2.0.39" />
<PackageReference Include="NodaTime" Version="3.0.5" />
</ItemGroup>
<ItemGroup>

View File

@@ -14,8 +14,10 @@
*/
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using Python.Runtime;
using QuantConnect.Algorithm;
using QuantConnect.Data;
using QuantConnect.Interfaces;
@@ -71,5 +73,67 @@ namespace QuantConnect.Tests.Algorithm
CollectionAssert.AreEquivalent(optionContractsSymbols, optionContractsData.Select(x => x.Symbol));
}
[TestCaseSource(nameof(OptionChainTestCases))]
public void GetsFullDataOptionChainAsDataFrame(Symbol symbol, DateTime date)
{
_algorithm.SetPandasConverter();
_algorithm.SetDateTime(date.ConvertToUtc(_algorithm.TimeZone));
using var _ = Py.GIL();
var module = PyModule.FromString(nameof(GetsFullDataOptionChainAsDataFrame), @"
def get_option_chain_data_from_dataframe(algorithm, canonical):
option_chain_df = algorithm.option_chain(canonical).data_frame
# Will make it more complex than it needs to be,
# just so that we can test indexing by symbol using df.loc[]
for (symbol,) in option_chain_df.index:
symbol_data = option_chain_df.loc[(symbol)]
if symbol_data.shape[0] != 1:
raise ValueError(f'Expected 1 row for {symbol}, got {symbol_data.shape[0]}')
yield {
'symbol': symbol,
'expiry': symbol_data['expiry'].values[0],
'strike': symbol_data['strike'].values[0],
'right': symbol_data['right'].values[0],
'style': symbol_data['style'].values[0],
'lastprice': symbol_data['lastprice'].values[0],
'askprice': symbol_data['askprice'].values[0],
'bidprice': symbol_data['bidprice'].values[0],
'openinterest': symbol_data['openinterest'].values[0],
'impliedvolatility': symbol_data['impliedvolatility'].values[0],
'delta': symbol_data['delta'].values[0],
'gamma': symbol_data['gamma'].values[0],
'vega': symbol_data['vega'].values[0],
'theta': symbol_data['theta'].values[0],
'rho': symbol_data['rho'].values[0],
'underlyingsymbol': symbol_data['underlyingsymbol'].values[0],
'underlyinglastprice': symbol_data['underlyinglastprice'].values[0],
}
");
using var pyAlgorithm = _algorithm.ToPython();
using var pySymbol = symbol.ToPython();
using var pyOptionChainData = module.GetAttr("get_option_chain_data_from_dataframe").Invoke(pyAlgorithm, pySymbol);
var optionChain = new List<Symbol>();
Assert.DoesNotThrow(() =>
{
foreach (PyObject item in pyOptionChainData.GetIterator())
{
var contractSymbol = item["symbol"].GetAndDispose<Symbol>();
optionChain.Add(contractSymbol);
item.DisposeSafely();
}
});
var optionContractsSymbols = _optionChainProvider.GetOptionContractList(symbol, date.Date).ToList();
CollectionAssert.AreEquivalent(optionContractsSymbols, optionChain);
}
}
}

View File

@@ -415,62 +415,135 @@ def getTickHistory(algorithm, symbol, start, end):
Assert.AreEqual(expectedCount == 1 ? TickType.Trade : TickType.Quote, _testHistoryProvider.HistryRequests.First().TickType);
}
[TestCase(Resolution.Second, Language.CSharp, true)]
[TestCase(Resolution.Minute, Language.CSharp, true)]
[TestCase(Resolution.Hour, Language.CSharp, true)]
[TestCase(Resolution.Daily, Language.CSharp, true)]
[TestCase(Resolution.Second, Language.Python, true)]
[TestCase(Resolution.Minute, Language.Python, true)]
[TestCase(Resolution.Hour, Language.Python, true)]
[TestCase(Resolution.Daily, Language.Python, true)]
[TestCase(Resolution.Second, Language.CSharp, false)]
[TestCase(Resolution.Minute, Language.CSharp, false)]
[TestCase(Resolution.Hour, Language.CSharp, false)]
[TestCase(Resolution.Daily, Language.CSharp, false)]
[TestCase(Resolution.Second, Language.Python, false)]
[TestCase(Resolution.Minute, Language.Python, false)]
[TestCase(Resolution.Hour, Language.Python, false)]
[TestCase(Resolution.Daily, Language.Python, false)]
public void BarCountHistoryRequestIsCorrectlyBuilt(Resolution resolution, Language language, bool symbolAlreadyAdded)
private static IEnumerable<TestCaseData> BarCountHistoryRequestTestCases
{
_algorithm.SetStartDate(2013, 10, 07);
get
{
var spyDate = new DateTime(2013, 10, 07);
yield return new TestCaseData(Resolution.Second, Language.CSharp, Symbols.SPY, true, spyDate, null, false);
yield return new TestCaseData(Resolution.Minute, Language.CSharp, Symbols.SPY, true, spyDate, null, false);
yield return new TestCaseData(Resolution.Hour, Language.CSharp, Symbols.SPY, true, spyDate, null, false);
yield return new TestCaseData(Resolution.Daily, Language.CSharp, Symbols.SPY, true, spyDate, null, false);
yield return new TestCaseData(Resolution.Second, Language.Python, Symbols.SPY, true, spyDate, null, false);
yield return new TestCaseData(Resolution.Minute, Language.Python, Symbols.SPY, true, spyDate, null, false);
yield return new TestCaseData(Resolution.Hour, Language.Python, Symbols.SPY, true, spyDate, null, false);
yield return new TestCaseData(Resolution.Daily, Language.Python, Symbols.SPY, true, spyDate, null, false);
yield return new TestCaseData(Resolution.Second, Language.CSharp, Symbols.SPY, false, spyDate, null, false);
yield return new TestCaseData(Resolution.Minute, Language.CSharp, Symbols.SPY, false, spyDate, null, false);
yield return new TestCaseData(Resolution.Hour, Language.CSharp, Symbols.SPY, false, spyDate, null, false);
yield return new TestCaseData(Resolution.Daily, Language.CSharp, Symbols.SPY, false, spyDate, null, false);
yield return new TestCaseData(Resolution.Second, Language.Python, Symbols.SPY, false, spyDate, null, false);
yield return new TestCaseData(Resolution.Minute, Language.Python, Symbols.SPY, false, spyDate, null, false);
yield return new TestCaseData(Resolution.Hour, Language.Python, Symbols.SPY, false, spyDate, null, false);
yield return new TestCaseData(Resolution.Daily, Language.Python, Symbols.SPY, false, spyDate, null, false);
yield return new TestCaseData(Resolution.Second, Language.CSharp, Symbols.SPY, true, spyDate, null, true);
yield return new TestCaseData(Resolution.Minute, Language.CSharp, Symbols.SPY, true, spyDate, null, true);
yield return new TestCaseData(Resolution.Hour, Language.CSharp, Symbols.SPY, true, spyDate, null, true);
yield return new TestCaseData(Resolution.Daily, Language.CSharp, Symbols.SPY, true, spyDate, null, true);
yield return new TestCaseData(Resolution.Second, Language.Python, Symbols.SPY, true, spyDate, null, true);
yield return new TestCaseData(Resolution.Minute, Language.Python, Symbols.SPY, true, spyDate, null, true);
yield return new TestCaseData(Resolution.Hour, Language.Python, Symbols.SPY, true, spyDate, null, true);
yield return new TestCaseData(Resolution.Daily, Language.Python, Symbols.SPY, true, spyDate, null, true);
yield return new TestCaseData(Resolution.Second, Language.CSharp, Symbols.SPY, false, spyDate, null, true);
yield return new TestCaseData(Resolution.Minute, Language.CSharp, Symbols.SPY, false, spyDate, null, true);
yield return new TestCaseData(Resolution.Hour, Language.CSharp, Symbols.SPY, false, spyDate, null, true);
yield return new TestCaseData(Resolution.Daily, Language.CSharp, Symbols.SPY, false, spyDate, null, true);
yield return new TestCaseData(Resolution.Second, Language.Python, Symbols.SPY, false, spyDate, null, true);
yield return new TestCaseData(Resolution.Minute, Language.Python, Symbols.SPY, false, spyDate, null, true);
yield return new TestCaseData(Resolution.Hour, Language.Python, Symbols.SPY, false, spyDate, null, true);
yield return new TestCaseData(Resolution.Daily, Language.Python, Symbols.SPY, false, spyDate, null, true);
var spxCanonicalOption = Symbol.CreateCanonicalOption(Symbols.SPX);
var spxDate = new DateTime(2021, 01, 12);
yield return new TestCaseData(Resolution.Daily, Language.CSharp, spxCanonicalOption, true, spxDate, null, true);
yield return new TestCaseData(Resolution.Daily, Language.Python, spxCanonicalOption, true, spxDate, null, true);
yield return new TestCaseData(null, Language.CSharp, spxCanonicalOption, true, spxDate, Resolution.Daily, true);
yield return new TestCaseData(null, Language.Python, spxCanonicalOption, true, spxDate, Resolution.Daily, true);
yield return new TestCaseData(Resolution.Daily, Language.CSharp, spxCanonicalOption, false, spxDate, null, true);
yield return new TestCaseData(Resolution.Daily, Language.Python, spxCanonicalOption, false, spxDate, null, true);
yield return new TestCaseData(null, Language.CSharp, spxCanonicalOption, false, spxDate, Resolution.Daily, true);
yield return new TestCaseData(null, Language.Python, spxCanonicalOption, false, spxDate, Resolution.Daily, true);
}
}
[TestCaseSource(nameof(BarCountHistoryRequestTestCases))]
public void BarCountHistoryRequestIsCorrectlyBuilt(Resolution? resolution, Language language, Symbol symbol,
bool symbolAlreadyAdded, DateTime dateTime, Resolution? defaultResolution, bool multiSymbol)
{
_algorithm.SetStartDate(dateTime);
var symbol = Symbols.SPY;
if (symbolAlreadyAdded)
{
// it should not matter
_algorithm.AddEquity("SPY");
_algorithm.AddSecurity(symbol);
}
if (language == Language.CSharp)
{
_algorithm.History(symbol, 10, resolution);
if (multiSymbol)
{
_algorithm.History(new[] { symbol }, 10, resolution);
}
else
{
_algorithm.History(symbol, 10, resolution);
}
}
else
{
using (Py.GIL())
{
_algorithm.SetPandasConverter();
_algorithm.History(symbol.ToPython(), 10, resolution);
if (multiSymbol)
{
using var pySymbols = new[] { symbol }.ToPyListUnSafe();
_algorithm.History(pySymbols, 10, resolution);
pySymbols[0].Dispose();
}
else
{
using var pySymbol = symbol.ToPython();
_algorithm.History(pySymbol, 10, resolution);
}
}
}
Resolution? fillForwardResolution = null;
if (resolution != Resolution.Tick)
{
fillForwardResolution = resolution;
fillForwardResolution = resolution ?? defaultResolution;
}
var expectedCount = resolution == Resolution.Hour || resolution == Resolution.Daily ? 1 : 2;
Assert.AreEqual(expectedCount, _testHistoryProvider.HistryRequests.Count);
Assert.AreEqual(Symbols.SPY, _testHistoryProvider.HistryRequests.First().Symbol);
Assert.AreEqual(resolution, _testHistoryProvider.HistryRequests.First().Resolution);
Assert.IsFalse(_testHistoryProvider.HistryRequests.First().IncludeExtendedMarketHours);
Assert.IsFalse(_testHistoryProvider.HistryRequests.First().IsCustomData);
Assert.AreEqual(fillForwardResolution, _testHistoryProvider.HistryRequests.First().FillForwardResolution);
Assert.AreEqual(DataNormalizationMode.Adjusted, _testHistoryProvider.HistryRequests.First().DataNormalizationMode);
if (symbol.SecurityType == SecurityType.Equity)
{
var expectedCount = resolution == Resolution.Hour || resolution == Resolution.Daily ? 1 : 2;
Assert.AreEqual(expectedCount, _testHistoryProvider.HistryRequests.Count);
var request = _testHistoryProvider.HistryRequests.First();
Assert.AreEqual(symbol, request.Symbol);
Assert.AreEqual(resolution, request.Resolution);
Assert.IsFalse(request.IncludeExtendedMarketHours);
Assert.IsFalse(request.IsCustomData);
Assert.AreEqual(fillForwardResolution, request.FillForwardResolution);
Assert.AreEqual(DataNormalizationMode.Adjusted, request.DataNormalizationMode);
Assert.AreEqual(expectedCount == 1 ? TickType.Trade : TickType.Quote, _testHistoryProvider.HistryRequests.First().TickType);
Assert.AreEqual(expectedCount == 1 ? TickType.Trade : TickType.Quote, request.TickType);
}
else if (symbol.SecurityType == SecurityType.IndexOption)
{
Assert.AreEqual(1, _testHistoryProvider.HistryRequests.Count);
var request = _testHistoryProvider.HistryRequests.Single();
Assert.AreEqual(symbol, request.Symbol);
Assert.AreEqual(resolution ?? defaultResolution, request.Resolution);
Assert.AreEqual(typeof(OptionUniverse), request.DataType);
Assert.IsFalse(request.IncludeExtendedMarketHours);
Assert.IsFalse(request.IsCustomData);
// For OptionUniverse, exchange and data time zones are set to the same value
Assert.AreEqual(request.ExchangeHours.TimeZone, request.DataTimeZone);
}
}
[TestCase(Language.CSharp, true)]
@@ -783,12 +856,15 @@ def getOpenInterestHistory(algorithm, symbol, start, end, resolution):
{
var result = _algorithm.History(new[] { optionSymbol }, start, end, historyResolution, fillForward:false).ToList();
Assert.AreEqual(53, result.Count);
Assert.IsTrue(result.Any(slice => slice.ContainsKey(optionSymbol)));
Assert.Multiple(() =>
{
Assert.AreEqual(53, result.Count);
Assert.IsTrue(result.Any(slice => slice.ContainsKey(optionSymbol)));
var openInterests = result.Select(slice => slice.Get(typeof(OpenInterest)) as DataDictionary<OpenInterest>).Where(dataDictionary => dataDictionary.Count > 0).ToList();
var openInterests = result.Select(slice => slice.Get(typeof(OpenInterest)) as DataDictionary<OpenInterest>).Where(dataDictionary => dataDictionary.Count > 0).ToList();
Assert.AreEqual(0, openInterests.Count);
Assert.AreEqual(0, openInterests.Count);
});
}
else
{

View File

@@ -86,7 +86,7 @@ namespace QuantConnect.Tests.API
return;
}
Log.Debug("ApiTestBase.Setup(): Waiting for test compile to complete");
compile = WaitForCompilerResponse(TestProject.ProjectId, compile.CompileId);
compile = WaitForCompilerResponse(ApiClient, TestProject.ProjectId, compile.CompileId);
if (!compile.Success)
{
Assert.Warn("Could not create compile for the test project, tests using it will fail.");
@@ -134,14 +134,14 @@ namespace QuantConnect.Tests.API
/// <param name="projectId">Id of the project</param>
/// <param name="compileId">Id of the compilation of the project</param>
/// <returns></returns>
protected Compile WaitForCompilerResponse(int projectId, string compileId)
protected static Compile WaitForCompilerResponse(Api.Api apiClient, int projectId, string compileId, int seconds = 60)
{
Compile compile;
var finish = DateTime.UtcNow.AddSeconds(60);
var compile = new Compile();
var finish = DateTime.UtcNow.AddSeconds(seconds);
do
{
Thread.Sleep(1000);
compile = ApiClient.ReadCompile(projectId, compileId);
Thread.Sleep(100);
compile = apiClient.ReadCompile(projectId, compileId);
} while (compile.State != CompileState.BuildSuccess && DateTime.UtcNow < finish);
return compile;
@@ -169,7 +169,7 @@ namespace QuantConnect.Tests.API
/// <summary>
/// Reload configuration, making sure environment variables are loaded into the config
/// </summary>
private static void ReloadConfiguration()
internal static void ReloadConfiguration()
{
// nunit 3 sets the current folder to a temp folder we need it to be the test bin output folder
var dir = TestContext.CurrentContext.TestDirectory;

120
Tests/Api/CommandTests.cs Normal file
View File

@@ -0,0 +1,120 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using NUnit.Framework;
using QuantConnect.Api;
using System.Threading;
using System.Collections.Generic;
namespace QuantConnect.Tests.API
{
[TestFixture, Explicit("Requires configured api access, a live node to run on, and brokerage configurations.")]
public class CommandTests
{
private Api.Api _apiClient;
[OneTimeSetUp]
public void Setup()
{
ApiTestBase.ReloadConfiguration();
_apiClient = new Api.Api();
_apiClient.Initialize(Globals.UserId, Globals.UserToken, Globals.DataFolder);
}
[TestCase("MyCommand")]
[TestCase("MyCommand2")]
[TestCase("MyCommand3")]
[TestCase("")]
public void LiveCommand(string commandType)
{
var command = new Dictionary<string, object>
{
{ "quantity", 0.1 },
{ "target", "BTCUSD" },
{ "$type", commandType }
};
var projectId = RunLiveAlgorithm();
try
{
// allow algo to be deployed and prices to be set so we can trade
Thread.Sleep(TimeSpan.FromSeconds(10));
var result = _apiClient.CreateLiveCommand(projectId, command);
Assert.IsTrue(result.Success);
}
finally
{
_apiClient.StopLiveAlgorithm(projectId);
_apiClient.DeleteProject(projectId);
}
}
private int RunLiveAlgorithm()
{
var settings = new Dictionary<string, object>()
{
{ "id", "QuantConnectBrokerage" },
{ "environment", "paper" },
{ "user", "" },
{ "password", "" },
{ "account", "" }
};
var file = new ProjectFile
{
Name = "Main.cs",
Code = @"from AlgorithmImports import *
class MyCommand():
quantity = 0
target = ''
def run(self, algo: QCAlgorithm) -> bool | None:
self.execute_order(algo)
def execute_order(self, algo):
algo.order(self.target, self.quantity)
class MyCommand2():
quantity = 0
target = ''
def run(self, algo: QCAlgorithm) -> bool | None:
algo.order(self.target, self.quantity)
return True
class MyCommand3():
quantity = 0
target = ''
def run(self, algo: QCAlgorithm) -> bool | None:
algo.order(self.target, self.quantity)
return False
class DeterminedSkyBlueGorilla(QCAlgorithm):
def initialize(self):
self.set_start_date(2023, 3, 17)
self.add_crypto(""BTCUSD"", Resolution.SECOND)
self.add_command(MyCommand)
self.add_command(MyCommand2)
self.add_command(MyCommand3)
def on_command(self, data):
self.order(data.target, data.quantity)"
};
// Run the live algorithm
return LiveTradingTests.RunLiveAlgorithm(_apiClient, settings, file, stopLiveAlgos: false, language: Language.Python);
}
}
}

View File

@@ -721,42 +721,48 @@ namespace QuantConnect.Tests.API
/// <param name="dataProviders">Dictionary with the data providers and their corresponding credentials</param>
/// <returns>The id of the project created with the algorithm in</returns>
private int RunLiveAlgorithm(Dictionary<string, object> settings, ProjectFile file, bool stopLiveAlgos, Dictionary<string, object> dataProviders = null)
{
return RunLiveAlgorithm(ApiClient, settings, file, stopLiveAlgos, dataProviders);
}
internal static int RunLiveAlgorithm(Api.Api apiClient, Dictionary<string, object> settings, ProjectFile file, bool stopLiveAlgos,
Dictionary<string, object> dataProviders = null, Language language = Language.CSharp)
{
// Create a new project
var project = ApiClient.CreateProject($"Test project - {DateTime.Now.ToStringInvariant()}", Language.CSharp, TestOrganization);
var project = apiClient.CreateProject($"Test project - {DateTime.Now.ToStringInvariant()}", language, Globals.OrganizationID);
var projectId = project.Projects.First().ProjectId;
// Update Project Files
var updateProjectFileContent = ApiClient.UpdateProjectFileContent(projectId, "Main.cs", file.Code);
var updateProjectFileContent = apiClient.UpdateProjectFileContent(projectId, language == Language.CSharp ? "Main.cs" : "main.py", file.Code);
Assert.IsTrue(updateProjectFileContent.Success);
// Create compile
var compile = ApiClient.CreateCompile(projectId);
var compile = apiClient.CreateCompile(projectId);
Assert.IsTrue(compile.Success);
// Wait at max 30 seconds for project to compile
var compileCheck = WaitForCompilerResponse(projectId, compile.CompileId, 30);
var compileCheck = WaitForCompilerResponse(apiClient, projectId, compile.CompileId, 30);
Assert.IsTrue(compileCheck.Success);
Assert.IsTrue(compileCheck.State == CompileState.BuildSuccess);
// Get a live node to launch the algorithm on
var nodesResponse = ApiClient.ReadProjectNodes(projectId);
var nodesResponse = apiClient.ReadProjectNodes(projectId);
Assert.IsTrue(nodesResponse.Success);
var freeNode = nodesResponse.Nodes.LiveNodes.Where(x => x.Busy == false);
Assert.IsNotEmpty(freeNode, "No free Live Nodes found");
// Create live default algorithm
var createLiveAlgorithm = ApiClient.CreateLiveAlgorithm(projectId, compile.CompileId, freeNode.FirstOrDefault().Id, settings, dataProviders: dataProviders);
var createLiveAlgorithm = apiClient.CreateLiveAlgorithm(projectId, compile.CompileId, freeNode.FirstOrDefault().Id, settings, dataProviders: dataProviders);
Assert.IsTrue(createLiveAlgorithm.Success);
if (stopLiveAlgos)
{
// Liquidate live algorithm; will also stop algorithm
var liquidateLive = ApiClient.LiquidateLiveAlgorithm(projectId);
var liquidateLive = apiClient.LiquidateLiveAlgorithm(projectId);
Assert.IsTrue(liquidateLive.Success);
// Delete the project
var deleteProject = ApiClient.DeleteProject(projectId);
var deleteProject = apiClient.DeleteProject(projectId);
Assert.IsTrue(deleteProject.Success);
}
@@ -820,7 +826,7 @@ namespace QuantConnect.Tests.API
Assert.IsTrue(compile.Success);
// Wait at max 30 seconds for project to compile
var compileCheck = WaitForCompilerResponse(projectId, compile.CompileId, 30);
var compileCheck = WaitForCompilerResponse(ApiClient, projectId, compile.CompileId, 30);
Assert.IsTrue(compileCheck.Success);
Assert.IsTrue(compileCheck.State == CompileState.BuildSuccess);
@@ -863,26 +869,6 @@ def CreateLiveAlgorithmFromPython(apiClient, projectId, compileId, nodeId):
}
}
/// <summary>
/// Wait for the compiler to respond to a specified compile request
/// </summary>
/// <param name="projectId">Id of the project</param>
/// <param name="compileId">Id of the compilation of the project</param>
/// <param name="seconds">Seconds to allow for compile time</param>
/// <returns></returns>
private Compile WaitForCompilerResponse(int projectId, string compileId, int seconds)
{
var compile = new Compile();
var finish = DateTime.Now.AddSeconds(seconds);
while (DateTime.Now < finish)
{
Thread.Sleep(1000);
compile = ApiClient.ReadCompile(projectId, compileId);
if (compile.State == CompileState.BuildSuccess) break;
}
return compile;
}
/// <summary>
/// Wait to receive at least one order
/// </summary>

View File

@@ -220,7 +220,7 @@ namespace QuantConnect.Tests.API
Assert.IsTrue(compile.Success);
// Wait at max 30 seconds for project to compile
var compileCheck = WaitForCompilerResponse(projectId, compile.CompileId);
var compileCheck = WaitForCompilerResponse(ApiClient, projectId, compile.CompileId);
Assert.IsTrue(compileCheck.Success);
Assert.IsTrue(compileCheck.State == CompileState.BuildSuccess);

View File

@@ -257,7 +257,7 @@ namespace QuantConnect.Tests.API
Assert.AreEqual(CompileState.InQueue, compileCreate.State);
// Read out the compile
var compileSuccess = WaitForCompilerResponse(project.Projects.First().ProjectId, compileCreate.CompileId);
var compileSuccess = WaitForCompilerResponse(ApiClient, project.Projects.First().ProjectId, compileCreate.CompileId);
Assert.IsTrue(compileSuccess.Success);
Assert.AreEqual(CompileState.BuildSuccess, compileSuccess.State);
@@ -265,7 +265,7 @@ namespace QuantConnect.Tests.API
file.Code += "[Jibberish at end of the file to cause a build error]";
ApiClient.UpdateProjectFileContent(project.Projects.First().ProjectId, file.Name, file.Code);
var compileError = ApiClient.CreateCompile(project.Projects.First().ProjectId);
compileError = WaitForCompilerResponse(project.Projects.First().ProjectId, compileError.CompileId);
compileError = WaitForCompilerResponse(ApiClient, project.Projects.First().ProjectId, compileError.CompileId);
Assert.IsTrue(compileError.Success); // Successfully processed rest request.
Assert.AreEqual(CompileState.BuildError, compileError.State); //Resulting in build fail.
@@ -336,7 +336,7 @@ namespace QuantConnect.Tests.API
$"Error updating project file:\n {string.Join("\n ", updateProjectFileContent.Errors)}");
var compileCreate = ApiClient.CreateCompile(project.ProjectId);
var compileSuccess = WaitForCompilerResponse(project.ProjectId, compileCreate.CompileId);
var compileSuccess = WaitForCompilerResponse(ApiClient, project.ProjectId, compileCreate.CompileId);
Assert.IsTrue(compileSuccess.Success, $"Error compiling project:\n {string.Join("\n ", compileSuccess.Errors)}");
var backtestName = $"ReadBacktestOrders Backtest {GetTimestamp()}";
@@ -559,7 +559,7 @@ namespace QuantConnect.Tests.API
Assert.IsTrue(compile.Success);
// Wait at max 30 seconds for project to compile
var compileCheck = WaitForCompilerResponse(projectId, compile.CompileId);
var compileCheck = WaitForCompilerResponse(ApiClient, projectId, compile.CompileId);
Assert.IsTrue(compileCheck.Success);
Assert.IsTrue(compileCheck.State == CompileState.BuildSuccess);
@@ -642,7 +642,7 @@ namespace QuantConnect.Tests.API
Assert.IsTrue(compile.Success);
// Wait at max 30 seconds for project to compile
var compileCheck = WaitForCompilerResponse(projectId, compile.CompileId);
var compileCheck = WaitForCompilerResponse(ApiClient, projectId, compile.CompileId);
Assert.IsTrue(compileCheck.Success);
Assert.IsTrue(compileCheck.State == CompileState.BuildSuccess);
@@ -726,7 +726,7 @@ namespace QuantConnect.Tests.API
compileId = compile.CompileId;
// Wait at max 30 seconds for project to compile
var compileCheck = WaitForCompilerResponse(projectId, compile.CompileId);
var compileCheck = WaitForCompilerResponse(ApiClient, projectId, compile.CompileId);
Assert.IsTrue(compileCheck.Success);
Assert.IsTrue(compileCheck.State == CompileState.BuildSuccess);
}

View File

@@ -130,6 +130,7 @@ namespace QuantConnect.Tests.Brokerages.Paper
var realTime = new BacktestingRealTimeHandler();
using var nullLeanManager = new AlgorithmManagerTests.NullLeanManager();
using var tokenSource = new CancellationTokenSource();
// run algorithm manager
manager.Run(job,
algorithm,
@@ -138,7 +139,7 @@ namespace QuantConnect.Tests.Brokerages.Paper
results,
realTime,
nullLeanManager,
new CancellationToken()
tokenSource
);
var postDividendCash = algorithm.Portfolio.CashBook[Currencies.USD].Amount;

View File

@@ -0,0 +1,129 @@
/*
* 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.IO;
using NUnit.Framework;
using Newtonsoft.Json;
using QuantConnect.Statistics;
using QuantConnect.Configuration;
using System.Collections.Generic;
using QuantConnect.Algorithm.CSharp;
using QuantConnect.Lean.Engine.Server;
using System;
namespace QuantConnect.Tests.Common.Commands
{
[TestFixture]
public class CallbackCommandTests
{
[TestCase(Language.CSharp)]
[TestCase(Language.Python)]
public void CommanCallback(Language language)
{
var parameter = new RegressionTests.AlgorithmStatisticsTestParameters(typeof(CallbackCommandRegressionAlgorithm).Name,
new Dictionary<string, string> {
{PerformanceMetrics.TotalOrders, "3"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "0.212%"},
{"Drawdown", "0.000%"},
{"Expectancy", "0"},
{"Net Profit", "0.003%"},
{"Sharpe Ratio", "-5.552"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "66.765%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "-0.01"},
{"Beta", "0.003"},
{"Annual Standard Deviation", "0.001"},
{"Annual Variance", "0"},
{"Information Ratio", "-8.919"},
{"Tracking Error", "0.222"},
{"Treynor Ratio", "-1.292"},
{"Total Fees", "$3.00"},
{"Estimated Strategy Capacity", "$670000000.00"},
{"Lowest Capacity Asset", "IBM R735QTJ8XC9X"},
{"Portfolio Turnover", "0.06%"}
},
language,
AlgorithmStatus.Completed);
Config.Set("lean-manager-type", typeof(TestLocalLeanManager).Name);
var result = AlgorithmRunner.RunLocalBacktest(parameter.Algorithm,
parameter.Statistics,
parameter.Language,
parameter.ExpectedFinalStatus);
}
internal class TestLocalLeanManager : LocalLeanManager
{
private bool _sentCommands;
public override void Update()
{
if (!_sentCommands && Algorithm.Time.TimeOfDay > TimeSpan.FromHours(9.50))
{
_sentCommands = true;
var commands = new List<Dictionary<string, object>>
{
new()
{
{ "$type", "" },
{ "id", 1 },
{ "Symbol", "SPY" },
{ "Parameters", new Dictionary<string, decimal> { { "quantity", 1 } } },
{ "unused", 99 }
},
new()
{
{ "$type", "VoidCommand" },
{ "id", null },
{ "Quantity", 1 },
{ "targettime", Algorithm.Time },
{ "target", new [] { "BAC" } },
{ "Parameters", new Dictionary<string, string> { { "tag", "a tag" }, { "something", "else" } } },
},
new()
{
{ "id", "2" },
{ "$type", "BoolCommand" },
{ "Result", true },
{ "unused", new [] { 99 } }
},
new()
{
{ "$type", "BoolCommand" },
{ "Result", null },
}
};
for (var i = 1; i <= commands.Count; i++)
{
var command = commands[i - 1];
command["id"] = i;
File.WriteAllText($"command-{i}.json", JsonConvert.SerializeObject(command));
}
base.Update();
}
}
public override void OnAlgorithmStart()
{
SetCommandHandler();
}
}
}
}

View File

@@ -113,6 +113,33 @@ namespace QuantConnect.Tests.Common.Data
Assert.IsFalse(subscriptionManager.IsSubscribed(Symbols.AAPL, TickType.Quote));
}
[TestCase(TickType.Trade, MarketDataType.TradeBar, 1)]
[TestCase(TickType.Trade, MarketDataType.QuoteBar, 0)]
[TestCase(TickType.Quote, MarketDataType.QuoteBar, 1)]
[TestCase(TickType.OpenInterest, MarketDataType.Tick, 1)]
[TestCase(TickType.OpenInterest, MarketDataType.TradeBar, 0)]
public void GetSubscribeSymbolsBySpecificTickType(TickType tickType, MarketDataType dataType, int expectedCount)
{
using var fakeDataQueueHandler = new FakeDataQueuehandlerSubscriptionManager((tickType) => tickType!.ToString());
switch (dataType)
{
case MarketDataType.TradeBar:
fakeDataQueueHandler.Subscribe(GetSubscriptionDataConfig<TradeBar>(Symbols.AAPL, Resolution.Minute));
break;
case MarketDataType.QuoteBar:
fakeDataQueueHandler.Subscribe(GetSubscriptionDataConfig<QuoteBar>(Symbols.AAPL, Resolution.Minute));
break;
case MarketDataType.Tick:
fakeDataQueueHandler.Subscribe(GetSubscriptionDataConfig<OpenInterest>(Symbols.AAPL, Resolution.Minute));
break;
}
var subscribeSymbols = fakeDataQueueHandler.GetSubscribedSymbols(tickType).ToList();
Assert.That(subscribeSymbols.Count, Is.EqualTo(expectedCount));
}
#region helper
private SubscriptionDataConfig GetSubscriptionDataConfig(Type T, Symbol symbol, Resolution resolution, TickType? tickType = null)

View File

@@ -1,4 +1,4 @@
/*
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
@@ -21,7 +21,7 @@ using QuantConnect.Util;
namespace QuantConnect.Tests.Common
{
[TestFixture]
[TestFixture, Parallelizable(ParallelScope.All)]
public class IsolatorTests
{
[Test]
@@ -45,6 +45,38 @@ namespace QuantConnect.Tests.Common
}
}
[Test]
public void Cancellation()
{
var isolator = new Isolator();
var executed = false;
var ended = false;
var canceled = false;
var result = false;
isolator.CancellationTokenSource.CancelAfter(TimeSpan.FromMilliseconds(100));
try
{
result = isolator.ExecuteWithTimeLimit(
TimeSpan.FromSeconds(5),
() => {
executed = true;
Thread.Sleep(5000);
ended = true;
},
5000,
sleepIntervalMillis: 10
);
}
catch (OperationCanceledException)
{
canceled = true;
}
Assert.IsTrue(canceled);
Assert.IsFalse(result);
Assert.IsTrue(executed);
Assert.IsFalse(ended);
}
[TestCase(Language.Python, true)]
[TestCase(Language.Python, false)]
[TestCase(Language.CSharp, true)]
@@ -98,4 +130,4 @@ namespace QuantConnect.Tests.Common
}
}
}
}

View File

@@ -212,7 +212,7 @@ namespace QuantConnect.Tests.Common
var equity = GetEquity(spy, underlyingPrice, underlyingVol, tz);
var contract = new OptionContract(option, Symbols.SPY) { Time = evaluationDate };
var contract = new OptionContract(option) { Time = evaluationDate };
var optionCall = GetOption(SPY_C_192_Feb19_2016E, equity, tz);
optionCall.SetMarketPrice(new Tick { Value = price });
@@ -515,7 +515,7 @@ namespace QuantConnect.Tests.Common
[TestCase(OptionStyle.European, "CrankNicolsonFD", 0.01d, 0.01d, 0.01d, 0.33d, 642d)]
[TestCase(OptionStyle.European, "Integral", 0.01d, 0.12d, 0.01d, 0.33d, 4622d)]
public void MatchesIBGreeksNearATMPut(OptionStyle style, string qlModelName, double errorIV, double errorDelta, double errorGamma, double errorVega, double errorTheta)
{
{
var filename = style == OptionStyle.American ? "SPY230811P00450000" : "SPX230811P04500000";
var symbol = Symbols.SPY; // dummy
var strike = Parse.Decimal(filename[10..]) / 1000m;
@@ -812,7 +812,7 @@ namespace QuantConnect.Tests.Common
MatchesIBGreeksTest(symbol, optionSymbol, filename, qlModelName, errorIV, errorDelta, errorGamma, errorVega, errorTheta);
}
private void MatchesIBGreeksTest(Symbol symbol, Symbol optionSymbol, string filename, string qlModelName,
private void MatchesIBGreeksTest(Symbol symbol, Symbol optionSymbol, string filename, string qlModelName,
double errorIV, double errorDelta, double errorGamma, double errorVega, double errorTheta)
{
var tz = TimeZones.NewYork;
@@ -879,7 +879,7 @@ namespace QuantConnect.Tests.Common
// Expect minor error due to interest rate and dividend yield used in IB
Assert.AreEqual(impliedVolEstimate, ibImpliedVol, 0.001);
}
[Test]
public void PriceModelEvaluateSpeedTest()
{
@@ -971,7 +971,7 @@ namespace QuantConnect.Tests.Common
public OptionContract GetOptionContract(Symbol symbol, Symbol underlying, DateTime evaluationDate)
{
var option = CreateOption(symbol);
return new OptionContract(option, underlying) { Time = evaluationDate };
return new OptionContract(option) { Time = evaluationDate };
}
public static Option GetOption(Symbol symbol, Equity underlying, NodaTime.DateTimeZone tz)

View File

@@ -44,9 +44,9 @@ namespace QuantConnect.Tests.Common.Data
// get the risk free rate
var estimator = new FedRateQLRiskFreeRateEstimator();
var result = estimator.Estimate(option,
new Slice(evaluationDate, new List<BaseData> { tick }, evaluationDate),
new OptionContract(option, spx));
var result = estimator.Estimate(option,
new Slice(evaluationDate, new List<BaseData> { tick }, evaluationDate),
new OptionContract(option));
Assert.AreEqual(rate, result);
}

View File

@@ -196,7 +196,7 @@ SPX YL0WVJMRW51Q|SPX 31,SPX 240816C05420000,181.5800,181.5800,154.8300,154.830
return _testOptionsData.Single(x => x.Symbol == contract);
}
private BaseGreeks GetGreeks(Symbol contract)
private Greeks GetGreeks(Symbol contract)
{
return GetContractData(contract).Greeks;
}

View File

@@ -1412,5 +1412,173 @@ namespace QuantConnect.Tests.Common.Securities.Options
Assert.AreEqual(expiration, lowStrikeLeg.Expiration);
Assert.AreEqual(1, lowStrikeLeg.Quantity);
}
[TestCase(325, 300)]
[TestCase(300, 300)]
public void FailsBuildingCallBackspreadStrategy(decimal strike1, decimal strike2)
{
var canonicalOptionSymbol = Symbols.SPY_Option_Chain;
var underlying = Symbols.SPY;
var expiration = new DateTime(2023, 08, 18);
// Unordered and repeated strikes
Assert.Throws<ArgumentException>(
() => OptionStrategies.CallBackspread(canonicalOptionSymbol, strike1, strike2, expiration));
}
[Test]
public void BuildCallBackspreadStrategy()
{
var canonicalOptionSymbol = Symbols.SPY_Option_Chain;
var underlying = Symbols.SPY;
var strike1 = 300m;
var strike2 = 325m;
var expiration = new DateTime(2023, 08, 18);
var strategy = OptionStrategies.CallBackspread(canonicalOptionSymbol, strike1, strike2, expiration);
Assert.AreEqual("Call Backspread", strategy.Name);
Assert.AreEqual(underlying, strategy.Underlying);
Assert.AreEqual(canonicalOptionSymbol, strategy.CanonicalOption);
Assert.AreEqual(2, strategy.OptionLegs.Count);
Assert.AreEqual(0, strategy.UnderlyingLegs.Count);
var lowStrikeLeg = strategy.OptionLegs.Single(x => x.Strike == strike1);
Assert.AreEqual(OptionRight.Call, lowStrikeLeg.Right);
Assert.AreEqual(expiration, lowStrikeLeg.Expiration);
Assert.AreEqual(-1, lowStrikeLeg.Quantity);
var highStrikeLeg = strategy.OptionLegs.Single(x => x.Strike == strike2);
Assert.AreEqual(OptionRight.Call, highStrikeLeg.Right);
Assert.AreEqual(expiration, highStrikeLeg.Expiration);
Assert.AreEqual(2, highStrikeLeg.Quantity);
}
[TestCase(325, 350)]
[TestCase(300, 300)]
public void FailsBuildingPutBackspreadStrategy(decimal strike1, decimal strike2)
{
var canonicalOptionSymbol = Symbols.SPY_Option_Chain;
var underlying = Symbols.SPY;
var expiration = new DateTime(2023, 08, 18);
// Unordered and repeated strikes
Assert.Throws<ArgumentException>(
() => OptionStrategies.PutBackspread(canonicalOptionSymbol, strike1, strike2, expiration));
}
[Test]
public void BuildsPutBackspreadStrategy()
{
var canonicalOptionSymbol = Symbols.SPY_Option_Chain;
var underlying = Symbols.SPY;
var strike1 = 350m;
var strike2 = 325m;
var expiration = new DateTime(2023, 08, 18);
var strategy = OptionStrategies.PutBackspread(canonicalOptionSymbol, strike1, strike2, expiration);
Assert.AreEqual("Put Backspread", strategy.Name);
Assert.AreEqual(underlying, strategy.Underlying);
Assert.AreEqual(canonicalOptionSymbol, strategy.CanonicalOption);
Assert.AreEqual(2, strategy.OptionLegs.Count);
Assert.AreEqual(0, strategy.UnderlyingLegs.Count);
var highStrikeLeg = strategy.OptionLegs.Single(x => x.Strike == strike1);
Assert.AreEqual(OptionRight.Put, highStrikeLeg.Right);
Assert.AreEqual(expiration, highStrikeLeg.Expiration);
Assert.AreEqual(-1, highStrikeLeg.Quantity);
var lowStrikeLeg = strategy.OptionLegs.Single(x => x.Strike == strike2);
Assert.AreEqual(OptionRight.Put, lowStrikeLeg.Right);
Assert.AreEqual(expiration, lowStrikeLeg.Expiration);
Assert.AreEqual(2, lowStrikeLeg.Quantity);
}
[TestCase(325, 300)]
[TestCase(300, 300)]
public void FailsBuildingShortCallBackspreadStrategy(decimal strike1, decimal strike2)
{
var canonicalOptionSymbol = Symbols.SPY_Option_Chain;
var underlying = Symbols.SPY;
var expiration = new DateTime(2023, 08, 18);
// Unordered and repeated strikes
Assert.Throws<ArgumentException>(
() => OptionStrategies.ShortCallBackspread(canonicalOptionSymbol, strike1, strike2, expiration));
}
[Test]
public void BuildsShortCallBackspreadStrategy()
{
var canonicalOptionSymbol = Symbols.SPY_Option_Chain;
var underlying = Symbols.SPY;
var strike1 = 300m;
var strike2 = 325m;
var expiration = new DateTime(2023, 08, 18);
var strategy = OptionStrategies.ShortCallBackspread(canonicalOptionSymbol, strike1, strike2, expiration);
Assert.AreEqual("Short Call Backspread", strategy.Name);
Assert.AreEqual(underlying, strategy.Underlying);
Assert.AreEqual(canonicalOptionSymbol, strategy.CanonicalOption);
Assert.AreEqual(2, strategy.OptionLegs.Count);
Assert.AreEqual(0, strategy.UnderlyingLegs.Count);
var lowStrikeLeg = strategy.OptionLegs.Single(x => x.Strike == strike1);
Assert.AreEqual(OptionRight.Call, lowStrikeLeg.Right);
Assert.AreEqual(expiration, lowStrikeLeg.Expiration);
Assert.AreEqual(1, lowStrikeLeg.Quantity);
var highStrikeLeg = strategy.OptionLegs.Single(x => x.Strike == strike2);
Assert.AreEqual(OptionRight.Call, highStrikeLeg.Right);
Assert.AreEqual(expiration, highStrikeLeg.Expiration);
Assert.AreEqual(-2, highStrikeLeg.Quantity);
}
[TestCase(325, 350)]
[TestCase(300, 300)]
public void FailsBuildingShortPutBackspreadStrategy(decimal strike1, decimal strike2)
{
var canonicalOptionSymbol = Symbols.SPY_Option_Chain;
var underlying = Symbols.SPY;
var expiration = new DateTime(2023, 08, 18);
// Unordered and repeated strikes
Assert.Throws<ArgumentException>(
() => OptionStrategies.ShortPutBackspread(canonicalOptionSymbol, strike1, strike2, expiration));
}
[Test]
public void BuildsShortPutBackspreadStrategy()
{
var canonicalOptionSymbol = Symbols.SPY_Option_Chain;
var underlying = Symbols.SPY;
var strike1 = 350m;
var strike2 = 300m;
var expiration = new DateTime(2023, 08, 18);
var strategy = OptionStrategies.ShortPutBackspread(canonicalOptionSymbol, strike1, strike2, expiration);
Assert.AreEqual("Short Put Backspread", strategy.Name);
Assert.AreEqual(underlying, strategy.Underlying);
Assert.AreEqual(canonicalOptionSymbol, strategy.CanonicalOption);
Assert.AreEqual(2, strategy.OptionLegs.Count);
Assert.AreEqual(0, strategy.UnderlyingLegs.Count);
var highStrikeLeg = strategy.OptionLegs.Single(x => x.Strike == strike1);
Assert.AreEqual(OptionRight.Put, highStrikeLeg.Right);
Assert.AreEqual(expiration, highStrikeLeg.Expiration);
Assert.AreEqual(1, highStrikeLeg.Quantity);
var lowStrikeLeg = strategy.OptionLegs.Single(x => x.Strike == strike2);
Assert.AreEqual(OptionRight.Put, lowStrikeLeg.Right);
Assert.AreEqual(expiration, lowStrikeLeg.Expiration);
Assert.AreEqual(-2, lowStrikeLeg.Quantity);
}
}
}

View File

@@ -120,7 +120,6 @@ namespace QuantConnect.Tests.Engine
var results = new BacktestingResultHandler();
var realtime = new BacktestingRealTimeHandler();
using var leanManager = new NullLeanManager();
var token = new CancellationToken();
var nullSynchronizer = new NullSynchronizer(algorithm);
algorithm.Initialize();
@@ -136,7 +135,8 @@ namespace QuantConnect.Tests.Engine
Log.Trace("Starting algorithm manager loop to process " + nullSynchronizer.Count + " time slices");
var sw = Stopwatch.StartNew();
algorithmManager.Run(job, algorithm, nullSynchronizer, transactions, results, realtime, leanManager, token);
using var tokenSource = new CancellationTokenSource();
algorithmManager.Run(job, algorithm, nullSynchronizer, transactions, results, realtime, leanManager, tokenSource);
sw.Stop();
realtime.Exit();

View File

@@ -1,4 +1,4 @@
/*
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
@@ -26,6 +26,9 @@ using QuantConnect.Data.UniverseSelection;
using QuantConnect.Lean.Engine.DataFeeds;
using QuantConnect.Securities;
using QuantConnect.Tests.Common.Data.UniverseSelection;
using QuantConnect.Securities.Option;
using QuantConnect.Securities.Future;
using QuantConnect.Securities.Equity;
namespace QuantConnect.Tests.Engine.DataFeeds
{
@@ -217,15 +220,7 @@ namespace QuantConnect.Tests.Engine.DataFeeds
private IEnumerable<Slice> GetSlices(Symbol symbol, int initialVolume)
{
var subscriptionDataConfig = new SubscriptionDataConfig(typeof(ZipEntryName), symbol, Resolution.Second, TimeZones.Utc, TimeZones.Utc, true, true, false);
var security = new Security(
SecurityExchangeHours.AlwaysOpen(TimeZones.Utc),
subscriptionDataConfig,
new Cash(Currencies.USD, 0, 1m),
SymbolProperties.GetDefault(Currencies.USD),
ErrorCurrencyConverter.Instance,
RegisteredSecurityDataTypesProvider.Null,
new SecurityCache()
);
var security = GetSecurity(subscriptionDataConfig);
var refTime = DateTime.UtcNow;
return Enumerable
@@ -237,20 +232,79 @@ namespace QuantConnect.Tests.Engine.DataFeeds
var ask = new Bar(110, 110, 110, 110);
var volume = (i + 1) * initialVolume;
var packets = new List<DataFeedPacket>();
var packet = new DataFeedPacket(security, subscriptionDataConfig, new List<BaseData>
{
new QuoteBar(time, symbol, bid, i*10, ask, (i + 1) * 11),
new TradeBar(time, symbol, 100, 100, 110, 106, volume)
});
if (symbol.SecurityType == SecurityType.Option)
{
var underlying = (security as Option).Underlying;
packets.Add(new DataFeedPacket(underlying, underlying.SubscriptionDataConfig, new List<BaseData>
{
new QuoteBar(time, underlying.Symbol, bid, i*10, ask, (i + 1) * 11),
new TradeBar(time, underlying.Symbol, 100, 100, 110, 106, volume)
}));
}
packets.Add(packet);
return _timeSliceFactory.Create(
time,
new List<DataFeedPacket>
{
new DataFeedPacket(security, subscriptionDataConfig, new List<BaseData>
{
new QuoteBar(time, symbol, bid, i*10, ask, (i + 1) * 11),
new TradeBar(time, symbol, 100, 100, 110, 106, volume)
}),
},
packets,
SecurityChangesTests.CreateNonInternal(Enumerable.Empty<Security>(), Enumerable.Empty<Security>()),
new Dictionary<Universe, BaseDataCollection>())
.Slice;
});
}
private Security GetSecurity(SubscriptionDataConfig config)
{
if (config.Symbol.SecurityType == SecurityType.Option)
{
var option = new Option(
SecurityExchangeHours.AlwaysOpen(TimeZones.Utc),
config,
new Cash(Currencies.USD, 0, 1m),
new OptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)),
ErrorCurrencyConverter.Instance,
RegisteredSecurityDataTypesProvider.Null);
var underlyingConfig = new SubscriptionDataConfig(typeof(ZipEntryName), config.Symbol.Underlying, Resolution.Second,
TimeZones.Utc, TimeZones.Utc, true, true, false);
var equity = new Equity(
SecurityExchangeHours.AlwaysOpen(TimeZones.Utc),
underlyingConfig,
new Cash(Currencies.USD, 0, 1m),
SymbolProperties.GetDefault(Currencies.USD),
ErrorCurrencyConverter.Instance,
RegisteredSecurityDataTypesProvider.Null);
option.Underlying = equity;
return option;
}
if (config.Symbol.SecurityType == SecurityType.Future)
{
return new Future(
SecurityExchangeHours.AlwaysOpen(TimeZones.Utc),
config,
new Cash(Currencies.USD, 0, 1m),
SymbolProperties.GetDefault(Currencies.USD),
ErrorCurrencyConverter.Instance,
RegisteredSecurityDataTypesProvider.Null);
}
return new Security(
SecurityExchangeHours.AlwaysOpen(TimeZones.Utc),
config,
new Cash(Currencies.USD, 0, 1m),
SymbolProperties.GetDefault(Currencies.USD),
ErrorCurrencyConverter.Instance,
RegisteredSecurityDataTypesProvider.Null,
new SecurityCache()
);
}
}
}
}

View File

@@ -104,6 +104,41 @@ namespace QuantConnect.Tests.Python
}
}
[Test]
public void HandlesEnumerableWithMultipleSymbols()
{
var converter = new PandasConverter();
var data = new List<BaseData>
{
new TradeBar(new DateTime(2020, 1, 2), Symbols.IBM, 101m, 102m, 100m, 101m, 10m),
new TradeBar(new DateTime(2020, 1, 3), Symbols.IBM, 101m, 102m, 100m, 101m, 20m),
new TradeBar(new DateTime(2020, 1, 2), Symbols.SPY_C_192_Feb19_2016, 51m, 52m, 50m, 51m, 100m),
new TradeBar(new DateTime(2020, 1, 3), Symbols.SPY_C_192_Feb19_2016, 51m, 52m, 50m, 51m, 200m),
};
dynamic dataFrame = converter.GetDataFrame(data);
using (Py.GIL())
{
Assert.Multiple(() =>
{
foreach (var symbol in data.Select(x => x.Symbol).Distinct())
{
Assert.IsFalse(dataFrame.empty.AsManagedObject(typeof(bool)), $"Unexpected empty sub dataframe for {symbol}");
var subDataFrame = dataFrame.loc[symbol];
Assert.IsFalse(subDataFrame.empty.AsManagedObject(typeof(bool)));
var count = subDataFrame.__len__().AsManagedObject(typeof(int));
Assert.AreEqual(2, count, $"Unexpected rows count for {symbol} sub dataframe");
var dataCount = subDataFrame.values.__len__().AsManagedObject(typeof(int));
Assert.AreEqual(2, dataCount, $"Unexpected rows count for {symbol} sub dataframe");
}
});
}
}
[Test]
public void HandlesEmptyEnumerable()
{
@@ -3720,6 +3755,108 @@ def DataFrameIsEmpty():
parameter.ExpectedFinalStatus);
}
[Test]
public void ConcatenatesDataFrames()
{
using (Py.GIL())
{
var test = PyModule.FromString("ConcatenatesDataFrames",
@"
import pandas as pd
index1 = pd.Index(['X', 'Y'], name=""Class"")
df1 = pd.DataFrame([[1, 2], [3, 4]], index=index1, columns=[""A"", ""B""])
index2 = pd.Index(['L', 'M'], name=""Class"")
df2 = pd.DataFrame([[5, 6], [7, 8]], index=index2, columns=[""A"", ""B""])
index3 = pd.Index(['R', 'S'], name=""Class"")
df3 = pd.DataFrame([[9, 10], [11, 12]], index=index3, columns=[""A"", ""B""])
concatenated = pd.concat([df1, df2, df3])
");
using var df1 = test.GetAttr("df1");
using var df2 = test.GetAttr("df2");
using var df3 = test.GetAttr("df3");
using var expected = test.GetAttr("concatenated");
using var concatenated = PandasConverter.ConcatDataFrames(new[] { df1, df2, df3 }, sort: false, dropna: false);
Assert.AreEqual(expected.GetAttr("to_string").Invoke().GetAndDispose<string>(),
concatenated.GetAttr("to_string").Invoke().GetAndDispose<string>());
}
}
[Test]
public void ConcatenatesDataFramesWithAddedIndexLevel()
{
using (Py.GIL())
{
var test = PyModule.FromString("ConcatenatesDataFramesWithAddedIndexLevel",
@"
import pandas as pd
index1 = pd.Index(['X', 'Y'], name=""Class"")
df1 = pd.DataFrame([[1, 2], [3, 4]], index=index1, columns=[""A"", ""B""])
index2 = pd.Index(['L', 'M'], name=""Class"")
df2 = pd.DataFrame([[5, 6], [7, 8]], index=index2, columns=[""A"", ""B""])
index3 = pd.Index(['R', 'S'], name=""Class"")
df3 = pd.DataFrame([[9, 10], [11, 12]], index=index3, columns=[""A"", ""B""])
concatenated = pd.concat([df1, df2, df3], keys=['df1', 'df2', 'df3'], names=['source_df'])
");
using var df1 = test.GetAttr("df1");
using var df2 = test.GetAttr("df2");
using var df3 = test.GetAttr("df3");
using var expected = test.GetAttr("concatenated");
using var concatenated = PandasConverter.ConcatDataFrames(new[] { df1, df2, df3 },
keys: new[] { "df1", "df2", "df3" },
names: new[] { "source_df" },
sort: false,
dropna: false);
Assert.AreEqual(expected.GetAttr("to_string").Invoke().GetAndDispose<string>(),
concatenated.GetAttr("to_string").Invoke().GetAndDispose<string>());
}
}
[Test]
public void ConcatenateReturnsEmptyDataFrameIfInputListIsEmpty()
{
using (Py.GIL())
{
var test = PyModule.FromString("ConcatenateReturnsEmptyDataFrameIfInputListIsEmpty",
@"
import pandas as pd
index1 = pd.Index(['X', 'Y'], name=""Class"")
df1 = pd.DataFrame([[1, 2], [3, 4]], index=index1, columns=[""A"", ""B""])
index2 = pd.Index(['L', 'M'], name=""Class"")
df2 = pd.DataFrame([[5, 6], [7, 8]], index=index2, columns=[""A"", ""B""])
index3 = pd.Index(['R', 'S'], name=""Class"")
df3 = pd.DataFrame([[9, 10], [11, 12]], index=index3, columns=[""A"", ""B""])
concatenated = pd.concat([df1, df2, df3], keys=['df1', 'df2', 'df3'], names=['source_df'])
");
using var df1 = test.GetAttr("df1");
using var df2 = test.GetAttr("df2");
using var df3 = test.GetAttr("df3");
using var expected = test.GetAttr("concatenated");
using var concatenated = PandasConverter.ConcatDataFrames(Array.Empty<PyObject>());
Assert.IsTrue(concatenated.GetAttr("empty").GetAndDispose<bool>());
}
}
public IEnumerable<Slice> GetHistory<T>(Symbol symbol, Resolution resolution, IEnumerable<T> data)
where T : IBaseData
{

View File

@@ -53,7 +53,7 @@ namespace QuantConnect.Tests.Python
public void ContainsUserMappedTickers()
{
using (Py.GIL())
{
{
PyObject result = _pandasDataFrameTests.test_contains_user_mapped_ticker();
var test = result.As<bool>();
@@ -82,7 +82,7 @@ namespace QuantConnect.Tests.Python
PyObject result = _pandasDataFrameTests.test_expected_exception();
var exception = result.As<string>();
Assert.IsTrue(exception.Contains("No key found for either mapped or original key. Mapped Key: ['AAPL R735QTJ8XC9X']; Original Key: ['aapl']", StringComparison.InvariantCulture));
Assert.IsTrue(exception.Contains("No key found for either mapped or original key. Mapped Key: ['AAPL']; Original Key: ['aapl']", StringComparison.InvariantCulture));
}
}
}

View File

@@ -33,7 +33,7 @@
</PropertyGroup>
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<ItemGroup>
<PackageReference Include="QuantConnect.pythonnet" Version="2.0.38" />
<PackageReference Include="QuantConnect.pythonnet" Version="2.0.39" />
<PackageReference Include="Accord" Version="3.6.0" />
<PackageReference Include="Accord.Math" Version="3.6.0" />
<PackageReference Include="Common.Logging" Version="3.4.1" />

View File

@@ -97,7 +97,7 @@ namespace QuantConnect.Tests.ToolBox.RandomDataGenerator
var priceModelMock = new Mock<IOptionPriceModel>();
priceModelMock
.Setup(s => s.Evaluate(It.IsAny<Security>(), It.IsAny<Slice>(), It.IsAny<OptionContract>()))
.Returns(new OptionPriceModelResult(1000, new Greeks()));
.Returns(new OptionPriceModelResult(1000, NullGreeks.Instance));
_option.PriceModel = priceModelMock.Object;
var randomPriceGenerator = new OptionPriceModelPriceGenerator(_option);

View File

@@ -66,10 +66,9 @@ namespace QuantConnect.ToolBox.RandomDataGenerator
_option,
null,
OptionContract.Create(
_option.Symbol.Underlying,
referenceDate,
_option,
_option.Underlying.Price
new Tick(referenceDate, _option.Underlying.Symbol, _option.Underlying.Price, _option.Underlying.Price)
))
.TheoreticalPrice;
}