Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ec60cb994 | ||
|
|
86fd80a31a | ||
|
|
c556d16775 | ||
|
|
6351773a01 | ||
|
|
bf4b08e202 | ||
|
|
fa9ff399cc |
239
Algorithm.CSharp/BasicTemplateEurexFuturesAlgorithm.cs
Normal file
239
Algorithm.CSharp/BasicTemplateEurexFuturesAlgorithm.cs
Normal file
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using QuantConnect.Data;
|
||||
using QuantConnect.Data.UniverseSelection;
|
||||
using QuantConnect.Interfaces;
|
||||
using QuantConnect.Orders;
|
||||
using QuantConnect.Securities;
|
||||
using QuantConnect.Securities.Future;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// This algorithm tests and demonstrates EUREX futures subscription and trading:
|
||||
/// - It tests contracts rollover by adding a continuous future and asserting that mapping happens at some point.
|
||||
/// - It tests basic trading by buying a contract and holding it until expiration.
|
||||
/// - It tests delisting and asserts the holdings are liquidated after that.
|
||||
/// </summary>
|
||||
public class BasicTemplateEurexFuturesAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
|
||||
{
|
||||
private Future _continuousContract;
|
||||
private Symbol _mappedSymbol;
|
||||
private Symbol _contractToTrade;
|
||||
private int _mappingsCount;
|
||||
private decimal _boughtQuantity;
|
||||
private decimal _liquidatedQuantity;
|
||||
private bool _delisted;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SetStartDate(2024, 5, 30);
|
||||
SetEndDate(2024, 6, 23);
|
||||
|
||||
SetAccountCurrency(Currencies.EUR);
|
||||
SetCash(1000000);
|
||||
|
||||
_continuousContract = AddFuture(Futures.Indices.EuroStoxx50, Resolution.Minute,
|
||||
dataNormalizationMode: DataNormalizationMode.BackwardsRatio,
|
||||
dataMappingMode: DataMappingMode.FirstDayMonth,
|
||||
contractDepthOffset: 0);
|
||||
_continuousContract.SetFilter(TimeSpan.Zero, TimeSpan.FromDays(180));
|
||||
_mappedSymbol = _continuousContract.Mapped;
|
||||
|
||||
var benchmark = AddIndex("SX5E", market: Market.EUREX);
|
||||
SetBenchmark(benchmark.Symbol);
|
||||
|
||||
var seeder = new FuncSecuritySeeder(GetLastKnownPrices);
|
||||
SetSecurityInitializer(security => seeder.SeedSecurity(security));
|
||||
}
|
||||
|
||||
public override void OnData(Slice slice)
|
||||
{
|
||||
foreach (var changedEvent in slice.SymbolChangedEvents.Values)
|
||||
{
|
||||
if (++_mappingsCount > 1)
|
||||
{
|
||||
throw new RegressionTestException($"{Time} - Unexpected number of symbol changed events (mappings): {_mappingsCount}. " +
|
||||
$"Expected only 1.");
|
||||
}
|
||||
|
||||
Debug($"{Time} - SymbolChanged event: {changedEvent}");
|
||||
|
||||
if (changedEvent.OldSymbol != _mappedSymbol.ID.ToString())
|
||||
{
|
||||
throw new RegressionTestException($"{Time} - Unexpected symbol changed event old symbol: {changedEvent}");
|
||||
}
|
||||
|
||||
if (changedEvent.NewSymbol != _continuousContract.Mapped.ID.ToString())
|
||||
{
|
||||
throw new RegressionTestException($"{Time} - Unexpected symbol changed event new symbol: {changedEvent}");
|
||||
}
|
||||
|
||||
// Let's trade the previous mapped contract, so we can hold it until expiration for testing
|
||||
// (will be sooner than the new mapped contract)
|
||||
_contractToTrade = _mappedSymbol;
|
||||
_mappedSymbol = _continuousContract.Mapped;
|
||||
}
|
||||
|
||||
// Let's trade after the mapping is done
|
||||
if (_contractToTrade != null && _boughtQuantity == 0 && Securities[_contractToTrade].Exchange.ExchangeOpen)
|
||||
{
|
||||
Buy(_contractToTrade, 1);
|
||||
}
|
||||
|
||||
if (_contractToTrade != null && slice.Delistings.TryGetValue(_contractToTrade, out var delisting))
|
||||
{
|
||||
if (delisting.Type == DelistingType.Delisted)
|
||||
{
|
||||
_delisted = true;
|
||||
|
||||
if (Portfolio.Invested)
|
||||
{
|
||||
throw new RegressionTestException($"{Time} - Portfolio should not be invested after the traded contract is delisted.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnOrderEvent(OrderEvent orderEvent)
|
||||
{
|
||||
if (orderEvent.Symbol != _contractToTrade)
|
||||
{
|
||||
throw new RegressionTestException($"{Time} - Unexpected order event symbol: {orderEvent.Symbol}. Expected {_contractToTrade}");
|
||||
}
|
||||
|
||||
if (orderEvent.Direction == OrderDirection.Buy)
|
||||
{
|
||||
if (orderEvent.Status == OrderStatus.Filled)
|
||||
{
|
||||
if (_boughtQuantity != 0 && _liquidatedQuantity != 0)
|
||||
{
|
||||
throw new RegressionTestException($"{Time} - Unexpected buy order event status: {orderEvent.Status}");
|
||||
}
|
||||
_boughtQuantity = orderEvent.Quantity;
|
||||
}
|
||||
}
|
||||
else if (orderEvent.Direction == OrderDirection.Sell)
|
||||
{
|
||||
if (orderEvent.Status == OrderStatus.Filled)
|
||||
{
|
||||
if (_boughtQuantity <= 0 && _liquidatedQuantity != 0)
|
||||
{
|
||||
throw new RegressionTestException($"{Time} - Unexpected sell order event status: {orderEvent.Status}");
|
||||
}
|
||||
_liquidatedQuantity = orderEvent.Quantity;
|
||||
|
||||
if (_liquidatedQuantity != -_boughtQuantity)
|
||||
{
|
||||
throw new RegressionTestException($"{Time} - Unexpected liquidated quantity: {_liquidatedQuantity}. Expected: {-_boughtQuantity}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnSecuritiesChanged(SecurityChanges changes)
|
||||
{
|
||||
foreach (var addedSecurity in changes.AddedSecurities)
|
||||
{
|
||||
if (addedSecurity.Symbol.SecurityType == SecurityType.Future && addedSecurity.Symbol.IsCanonical())
|
||||
{
|
||||
_mappedSymbol = _continuousContract.Mapped;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnEndOfAlgorithm()
|
||||
{
|
||||
if (_mappingsCount == 0)
|
||||
{
|
||||
throw new RegressionTestException($"Unexpected number of symbol changed events (mappings): {_mappingsCount}. Expected 1.");
|
||||
}
|
||||
|
||||
if (!_delisted)
|
||||
{
|
||||
throw new RegressionTestException("Contract was not delisted");
|
||||
}
|
||||
|
||||
// Make sure we traded and that the position was liquidated on delisting
|
||||
if (_boughtQuantity <= 0 || _liquidatedQuantity >= 0)
|
||||
{
|
||||
throw new RegressionTestException($"Unexpected sold quantity: {_boughtQuantity} and liquidated quantity: {_liquidatedQuantity}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <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 List<Language> Languages { get; } = new() { Language.CSharp, Language.Python };
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 133945;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public int AlgorithmHistoryDataPoints => 26;
|
||||
|
||||
/// <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", "2"},
|
||||
{"Average Win", "0%"},
|
||||
{"Average Loss", "-0.11%"},
|
||||
{"Compounding Annual Return", "-1.667%"},
|
||||
{"Drawdown", "0.100%"},
|
||||
{"Expectancy", "-1"},
|
||||
{"Start Equity", "1000000"},
|
||||
{"End Equity", "998849.48"},
|
||||
{"Net Profit", "-0.115%"},
|
||||
{"Sharpe Ratio", "-34.455"},
|
||||
{"Sortino Ratio", "-57.336"},
|
||||
{"Probabilistic Sharpe Ratio", "0.002%"},
|
||||
{"Loss Rate", "100%"},
|
||||
{"Win Rate", "0%"},
|
||||
{"Profit-Loss Ratio", "0"},
|
||||
{"Alpha", "0"},
|
||||
{"Beta", "0"},
|
||||
{"Annual Standard Deviation", "0.002"},
|
||||
{"Annual Variance", "0"},
|
||||
{"Information Ratio", "-6.176"},
|
||||
{"Tracking Error", "0.002"},
|
||||
{"Treynor Ratio", "0"},
|
||||
{"Total Fees", "€1.02"},
|
||||
{"Estimated Strategy Capacity", "€2300000000.00"},
|
||||
{"Lowest Capacity Asset", "FESX YJHOAMPYKRS5"},
|
||||
{"Portfolio Turnover", "0.40%"},
|
||||
{"OrderListHash", "54040d29a467becaedcf59d79323321b"}
|
||||
};
|
||||
}
|
||||
}
|
||||
147
Algorithm.CSharp/CallbackCommandRegressionAlgorithm.cs
Normal file
147
Algorithm.CSharp/CallbackCommandRegressionAlgorithm.cs
Normal 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"}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public int AlgorithmHistoryDataPoints => 6;
|
||||
public int AlgorithmHistoryDataPoints => 7;
|
||||
|
||||
/// <summary>
|
||||
/// Final status of the algorithm
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 19700;
|
||||
public long DataPoints => 19701;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
|
||||
137
Algorithm.CSharp/OptionResolutionRegressionAlgorithm.cs
Normal file
137
Algorithm.CSharp/OptionResolutionRegressionAlgorithm.cs
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* 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.Linq;
|
||||
using QuantConnect.Data;
|
||||
using QuantConnect.Interfaces;
|
||||
using QuantConnect.Data.Market;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Regression algorithm asserting the resolution being used for options universe and it's data respecting universe settings
|
||||
/// </summary>
|
||||
public class OptionResolutionRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
|
||||
{
|
||||
private Symbol _optionSymbol;
|
||||
public override void Initialize()
|
||||
{
|
||||
SetStartDate(2015, 12, 24);
|
||||
SetEndDate(2015, 12, 24);
|
||||
SetCash(100000);
|
||||
|
||||
UniverseSettings.Resolution = Resolution.Daily;
|
||||
|
||||
var option = AddOption("GOOG");
|
||||
option.SetFilter(u => u.Strikes(-2, +2).Expiration(0, 180));
|
||||
_optionSymbol = option.Symbol;
|
||||
|
||||
if (UniverseManager.TryGetValue(option.Symbol, out var universe)
|
||||
&& (universe.Configuration.Resolution != Resolution.Daily || universe.UniverseSettings.Resolution != Resolution.Daily))
|
||||
{
|
||||
throw new RegressionTestException("Unexpected universe resolution configuration!");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event - v3.0 DATA EVENT HANDLER: (Pattern) Basic template for user to override for receiving all subscription data in a single event
|
||||
/// </summary>
|
||||
/// <param name="slice">The current slice of data keyed by symbol string</param>
|
||||
public override void OnData(Slice slice)
|
||||
{
|
||||
if (!Portfolio.Invested)
|
||||
{
|
||||
OptionChain chain;
|
||||
if (slice.OptionChains.TryGetValue(_optionSymbol, out chain))
|
||||
{
|
||||
// we find at the money (ATM) put contract with farthest expiration
|
||||
var atmContract = chain
|
||||
.OrderByDescending(x => x.Expiry)
|
||||
.ThenBy(x => Math.Abs(chain.Underlying.Price - x.Strike))
|
||||
.ThenByDescending(x => x.Right)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (atmContract != null)
|
||||
{
|
||||
// if found, trade it
|
||||
MarketOrder(atmContract.Symbol, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <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 List<Language> Languages { get; } = new() { Language.CSharp };
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 4274;
|
||||
|
||||
/// <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", "0%"},
|
||||
{"Drawdown", "0%"},
|
||||
{"Expectancy", "0"},
|
||||
{"Start Equity", "100000"},
|
||||
{"End Equity", "100000"},
|
||||
{"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", "$0.00"},
|
||||
{"Estimated Strategy Capacity", "$0"},
|
||||
{"Lowest Capacity Asset", ""},
|
||||
{"Portfolio Turnover", "0%"},
|
||||
{"OrderListHash", "ce4cdd4d05199b633559cd14bc6db237"}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -71,9 +71,9 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
|
||||
var option = AddOption("AAPL");
|
||||
if (SubscriptionManager.SubscriptionDataConfigService.GetSubscriptionDataConfigs(option.Symbol)
|
||||
.Any(config => config.Resolution != Resolution.Minute))
|
||||
.Any(config => config.Resolution != Resolution.Daily))
|
||||
{
|
||||
throw new RegressionTestException("Was expecting resolution to be set to Minute");
|
||||
throw new RegressionTestException("Was expecting resolution to be set to Daily");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
147
Algorithm.CSharp/ZeroDTEOptionsRegressionAlgorithm.cs
Normal file
147
Algorithm.CSharp/ZeroDTEOptionsRegressionAlgorithm.cs
Normal 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 System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using QuantConnect.Interfaces;
|
||||
using QuantConnect.Data.UniverseSelection;
|
||||
using QuantConnect.Securities;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Algorithm asserting that options are selected every day and that selection for 0DTE contracts works as expected,
|
||||
/// always including the contracts that expire the same date the option chain belongs to.
|
||||
/// </summary>
|
||||
public class ZeroDTEOptionsRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
|
||||
{
|
||||
private List<DateTime> _selectionDays;
|
||||
private int _currentSelectionDayIndex;
|
||||
|
||||
private int _previouslyAddedContracts;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SetStartDate(2024, 01, 01);
|
||||
SetEndDate(2024, 01, 10);
|
||||
SetCash(100000);
|
||||
|
||||
var equity = AddEquity("SPY");
|
||||
var option = AddOption(equity.Symbol);
|
||||
|
||||
option.SetFilter(u => u.IncludeWeeklys().Expiration(0, 0));
|
||||
|
||||
// use the underlying equity as the benchmark
|
||||
SetBenchmark(equity.Symbol);
|
||||
|
||||
_selectionDays = new List<DateTime>()
|
||||
{
|
||||
new DateTime(2024, 01, 01), // Sunday midnight, already Monday 1st, it's a holiday. Selection happens for Tuesday here
|
||||
new DateTime(2024, 01, 03), // Wednesday, midnight
|
||||
new DateTime(2024, 01, 04),
|
||||
new DateTime(2024, 01, 05),
|
||||
new DateTime(2024, 01, 06), // Friday midnight, selection happens for Monday here
|
||||
new DateTime(2024, 01, 09), // Monday midnight, already Tuesday, selection happens for Tuesday here
|
||||
new DateTime(2024, 01, 10),
|
||||
};
|
||||
}
|
||||
|
||||
public override void OnSecuritiesChanged(SecurityChanges changes)
|
||||
{
|
||||
// We expect selection every trading day
|
||||
if (Time.Date != _selectionDays[_currentSelectionDayIndex++])
|
||||
{
|
||||
throw new RegressionTestException($"Unexpected date. Expected {_selectionDays[_currentSelectionDayIndex]} but was {Time.Date}");
|
||||
}
|
||||
|
||||
var addedOptions = changes.AddedSecurities.Where(x => x.Symbol.SecurityType == SecurityType.Option && !x.Symbol.IsCanonical()).ToList();
|
||||
|
||||
if (addedOptions.Count == 0)
|
||||
{
|
||||
throw new RegressionTestException("No options were added");
|
||||
}
|
||||
|
||||
var removedOptions = changes.RemovedSecurities.Where(x => x.Symbol.SecurityType == SecurityType.Option && !x.Symbol.IsCanonical()).ToList();
|
||||
|
||||
// Since we are selecting only 0DTE contracts, they must be deselected that same day
|
||||
if (removedOptions.Count != _previouslyAddedContracts)
|
||||
{
|
||||
throw new RegressionTestException($"Unexpected number of removed contracts. Expected {_previouslyAddedContracts} but was {removedOptions.Count}");
|
||||
}
|
||||
_previouslyAddedContracts = addedOptions.Count;
|
||||
}
|
||||
|
||||
/// <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 List<Language> Languages { get; } = new() { Language.CSharp };
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 227;
|
||||
|
||||
/// <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", "0"},
|
||||
{"Average Win", "0%"},
|
||||
{"Average Loss", "0%"},
|
||||
{"Compounding Annual Return", "0%"},
|
||||
{"Drawdown", "0%"},
|
||||
{"Expectancy", "0"},
|
||||
{"Start Equity", "100000"},
|
||||
{"End Equity", "100000"},
|
||||
{"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", "$0.00"},
|
||||
{"Estimated Strategy Capacity", "$0"},
|
||||
{"Lowest Capacity Asset", ""},
|
||||
{"Portfolio Turnover", "0%"},
|
||||
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
|
||||
};
|
||||
}
|
||||
}
|
||||
120
Algorithm.Python/BasicTemplateEurexFuturesAlgorithm.py
Normal file
120
Algorithm.Python/BasicTemplateEurexFuturesAlgorithm.py
Normal 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.
|
||||
|
||||
from AlgorithmImports import *
|
||||
|
||||
### <summary>
|
||||
### This algorithm tests and demonstrates EUREX futures subscription and trading:
|
||||
### - It tests contracts rollover by adding a continuous future and asserting that mapping happens at some point.
|
||||
### - It tests basic trading by buying a contract and holding it until expiration.
|
||||
### - It tests delisting and asserts the holdings are liquidated after that.
|
||||
### </summary>
|
||||
class BasicTemplateEurexFuturesAlgorithm(QCAlgorithm):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._continuous_contract = None
|
||||
self._mapped_symbol = None
|
||||
self._contract_to_trade = None
|
||||
self._mappings_count = 0
|
||||
self._bought_quantity = 0
|
||||
self._liquidated_quantity = 0
|
||||
self._delisted = False
|
||||
|
||||
def initialize(self):
|
||||
self.set_start_date(2024, 5, 30)
|
||||
self.set_end_date(2024, 6, 23)
|
||||
|
||||
self.set_account_currency(Currencies.EUR);
|
||||
self.set_cash(1000000)
|
||||
|
||||
self._continuous_contract = self.add_future(
|
||||
Futures.Indices.EURO_STOXX_50,
|
||||
Resolution.MINUTE,
|
||||
data_normalization_mode=DataNormalizationMode.BACKWARDS_RATIO,
|
||||
data_mapping_mode=DataMappingMode.FIRST_DAY_MONTH,
|
||||
contract_depth_offset=0,
|
||||
)
|
||||
self._continuous_contract.set_filter(timedelta(days=0), timedelta(days=180))
|
||||
self._mapped_symbol = self._continuous_contract.mapped
|
||||
|
||||
benchmark = self.add_index("SX5E", market=Market.EUREX)
|
||||
self.set_benchmark(benchmark.symbol)
|
||||
|
||||
func_seeder = FuncSecuritySeeder(self.get_last_known_prices)
|
||||
self.set_security_initializer(lambda security: func_seeder.seed_security(security))
|
||||
|
||||
def on_data(self, slice):
|
||||
for changed_event in slice.symbol_changed_events.values():
|
||||
self._mappings_count += 1
|
||||
if self._mappings_count > 1:
|
||||
raise Exception(f"{self.time} - Unexpected number of symbol changed events (mappings): {self._mappings_count}. Expected only 1.")
|
||||
|
||||
self.debug(f"{self.time} - SymbolChanged event: {changed_event}")
|
||||
|
||||
if changed_event.old_symbol != str(self._mapped_symbol.id):
|
||||
raise Exception(f"{self.time} - Unexpected symbol changed event old symbol: {changed_event}")
|
||||
|
||||
if changed_event.new_symbol != str(self._continuous_contract.mapped.id):
|
||||
raise Exception(f"{self.time} - Unexpected symbol changed event new symbol: {changed_event}")
|
||||
|
||||
# Let's trade the previous mapped contract, so we can hold it until expiration for testing
|
||||
# (will be sooner than the new mapped contract)
|
||||
self._contract_to_trade = self._mapped_symbol
|
||||
self._mapped_symbol = self._continuous_contract.mapped
|
||||
|
||||
# Let's trade after the mapping is done
|
||||
if self._contract_to_trade is not None and self._bought_quantity == 0 and self.securities[self._contract_to_trade].exchange.exchange_open:
|
||||
self.buy(self._contract_to_trade, 1)
|
||||
|
||||
if self._contract_to_trade is not None and slice.delistings.contains_key(self._contract_to_trade):
|
||||
delisting = slice.delistings[self._contract_to_trade]
|
||||
if delisting.type == DelistingType.DELISTED:
|
||||
self._delisted = True
|
||||
|
||||
if self.portfolio.invested:
|
||||
raise Exception(f"{self.time} - Portfolio should not be invested after the traded contract is delisted.")
|
||||
|
||||
def on_order_event(self, order_event):
|
||||
if order_event.symbol != self._contract_to_trade:
|
||||
raise Exception(f"{self.time} - Unexpected order event symbol: {order_event.symbol}. Expected {self._contract_to_trade}")
|
||||
|
||||
if order_event.direction == OrderDirection.BUY:
|
||||
if order_event.status == OrderStatus.FILLED:
|
||||
if self._bought_quantity != 0 and self._liquidated_quantity != 0:
|
||||
raise Exception(f"{self.time} - Unexpected buy order event status: {order_event.status}")
|
||||
|
||||
self._bought_quantity = order_event.quantity
|
||||
elif order_event.direction == OrderDirection.SELL:
|
||||
if order_event.status == OrderStatus.FILLED:
|
||||
if self._bought_quantity <= 0 and self._liquidated_quantity != 0:
|
||||
raise Exception(f"{self.time} - Unexpected sell order event status: {order_event.status}")
|
||||
|
||||
self._liquidated_quantity = order_event.quantity
|
||||
if self._liquidated_quantity != -self._bought_quantity:
|
||||
raise Exception(f"{self.time} - Unexpected liquidated quantity: {self._liquidated_quantity}. Expected: {-self._bought_quantity}")
|
||||
|
||||
def on_securities_changed(self, changes):
|
||||
for added_security in changes.added_securities:
|
||||
if added_security.symbol.security_type == SecurityType.FUTURE and added_security.symbol.is_canonical():
|
||||
self._mapped_symbol = self._continuous_contract.mapped
|
||||
|
||||
def on_end_of_algorithm(self):
|
||||
if self._mappings_count == 0:
|
||||
raise Exception(f"Unexpected number of symbol changed events (mappings): {self._mappings_count}. Expected 1.")
|
||||
|
||||
if not self._delisted:
|
||||
raise Exception("Contract was not delisted")
|
||||
|
||||
# Make sure we traded and that the position was liquidated on delisting
|
||||
if self._bought_quantity <= 0 or self._liquidated_quantity >= 0:
|
||||
raise Exception(f"Unexpected sold quantity: {self._bought_quantity} and liquidated quantity: {self._liquidated_quantity}")
|
||||
73
Algorithm.Python/CallbackCommandRegressionAlgorithm.py
Normal file
73
Algorithm.Python/CallbackCommandRegressionAlgorithm.py
Normal 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
|
||||
@@ -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,23 @@ 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>
|
||||
/// Gets indicator base type
|
||||
/// </summary>
|
||||
|
||||
@@ -92,7 +92,15 @@ namespace QuantConnect.Algorithm
|
||||
{
|
||||
Security underlyingSecurity;
|
||||
var underlyingSymbol = security.Symbol.Underlying;
|
||||
|
||||
var resolution = configs.GetHighestResolution();
|
||||
var isFillForward = configs.IsFillForward();
|
||||
if (UniverseManager.TryGetValue(security.Symbol, out var universe))
|
||||
{
|
||||
// as if the universe had selected this asset, the configuration of the canonical can be different
|
||||
resolution = universe.UniverseSettings.Resolution;
|
||||
isFillForward = universe.UniverseSettings.FillForward;
|
||||
}
|
||||
|
||||
// create the underlying security object if it doesn't already exist
|
||||
if (!Securities.TryGetValue(underlyingSymbol, out underlyingSecurity))
|
||||
@@ -101,7 +109,7 @@ namespace QuantConnect.Algorithm
|
||||
underlyingSymbol.Value,
|
||||
resolution,
|
||||
underlyingSymbol.ID.Market,
|
||||
configs.IsFillForward(),
|
||||
isFillForward,
|
||||
Security.NullLeverage,
|
||||
configs.IsExtendedMarketHours(),
|
||||
dataNormalizationMode: DataNormalizationMode.Raw);
|
||||
|
||||
@@ -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 = "";
|
||||
@@ -1939,6 +1944,15 @@ namespace QuantConnect.Algorithm
|
||||
return AddOptionContract(symbol, resolution, fillForward, leverage, extendedMarketHours);
|
||||
}
|
||||
|
||||
var securityResolution = resolution;
|
||||
var securityFillForward = fillForward;
|
||||
if (isCanonical && symbol.SecurityType.IsOption() && symbol.SecurityType != SecurityType.FutureOption)
|
||||
{
|
||||
// option is daily only, for now exclude FOPs
|
||||
securityResolution = Resolution.Daily;
|
||||
securityFillForward = false;
|
||||
}
|
||||
|
||||
var isFilteredSubscription = !isCanonical;
|
||||
List<SubscriptionDataConfig> configs;
|
||||
// we pass dataNormalizationMode to SubscriptionManager.SubscriptionDataConfigService.Add conditionally,
|
||||
@@ -1946,8 +1960,8 @@ namespace QuantConnect.Algorithm
|
||||
if (dataNormalizationMode.HasValue)
|
||||
{
|
||||
configs = SubscriptionManager.SubscriptionDataConfigService.Add(symbol,
|
||||
resolution,
|
||||
fillForward,
|
||||
securityResolution,
|
||||
securityFillForward,
|
||||
extendedMarketHours,
|
||||
isFilteredSubscription,
|
||||
dataNormalizationMode: dataNormalizationMode.Value,
|
||||
@@ -1956,8 +1970,8 @@ namespace QuantConnect.Algorithm
|
||||
else
|
||||
{
|
||||
configs = SubscriptionManager.SubscriptionDataConfigService.Add(symbol,
|
||||
resolution,
|
||||
fillForward,
|
||||
securityResolution,
|
||||
securityFillForward,
|
||||
extendedMarketHours,
|
||||
isFilteredSubscription,
|
||||
contractDepthOffset: (uint)contractDepthOffset);
|
||||
@@ -1975,10 +1989,16 @@ namespace QuantConnect.Algorithm
|
||||
if (!UniverseManager.ContainsKey(symbol))
|
||||
{
|
||||
var canonicalConfig = configs.First();
|
||||
var settings = new UniverseSettings(canonicalConfig.Resolution, leverage, fillForward, extendedMarketHours, UniverseSettings.MinimumTimeInUniverse)
|
||||
var universeSettingsResolution = canonicalConfig.Resolution;
|
||||
if (symbol.SecurityType.IsOption())
|
||||
{
|
||||
universeSettingsResolution = resolution ?? UniverseSettings.Resolution;
|
||||
}
|
||||
var settings = new UniverseSettings(universeSettingsResolution, leverage, fillForward, extendedMarketHours, UniverseSettings.MinimumTimeInUniverse)
|
||||
{
|
||||
Asynchronous = UniverseSettings.Asynchronous
|
||||
};
|
||||
|
||||
if (symbol.SecurityType.IsOption())
|
||||
{
|
||||
universe = new OptionChainUniverse((Option)security, settings);
|
||||
@@ -3354,9 +3374,7 @@ namespace QuantConnect.Algorithm
|
||||
// TODO: Until future options are supported by OptionUniverse, we need to fall back to the OptionChainProvider for them
|
||||
if (canonicalSymbol.SecurityType != SecurityType.FutureOption)
|
||||
{
|
||||
// TODO: History<OptionUniverse>(canonicalSymbol, 1) should be enough,
|
||||
// the universe resolution should always be daily. Change this when this is fixed in #8317
|
||||
var history = History<OptionUniverse>(canonicalSymbol, 1, Resolution.Daily);
|
||||
var history = History<OptionUniverse>(canonicalSymbol, 1);
|
||||
optionChain = history?.SingleOrDefault()?.Data?.Cast<OptionUniverse>() ?? Enumerable.Empty<OptionUniverse>();
|
||||
}
|
||||
else
|
||||
@@ -3372,6 +3390,62 @@ namespace QuantConnect.Algorithm
|
||||
return new DataHistory<OptionUniverse>(optionChain, new Lazy<PyObject>(() => PandasConverter.GetDataFrame(optionChain)));
|
||||
}
|
||||
|
||||
/// <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)
|
||||
{
|
||||
// We got the underlying
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
24
Api/Api.cs
24
Api/Api.cs
@@ -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>
|
||||
|
||||
@@ -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 *
|
||||
|
||||
@@ -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 };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
63
Common/Commands/CallbackCommand.cs
Normal file
63
Common/Commands/CallbackCommand.cs
Normal 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";
|
||||
}
|
||||
}
|
||||
}
|
||||
91
Common/Commands/Command.cs
Normal file
91
Common/Commands/Command.cs
Normal 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -276,6 +276,16 @@ namespace QuantConnect.Data.UniverseSelection
|
||||
return new OptionUniverse(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default resolution for this data and security type
|
||||
/// </summary>
|
||||
/// <remarks>This is a method and not a property so that python
|
||||
/// custom data types can override it</remarks>
|
||||
public override Resolution DefaultResolution()
|
||||
{
|
||||
return Resolution.Daily;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the CSV string representation of this universe entry
|
||||
/// </summary>
|
||||
|
||||
@@ -262,6 +262,14 @@ namespace QuantConnect
|
||||
public static Exchange CME { get; }
|
||||
= new("CME", "CME", "Futures and Options Chicago Mercantile Exchange", QuantConnect.Market.CME, SecurityType.Future, SecurityType.FutureOption);
|
||||
|
||||
/// <summary>
|
||||
/// The European Derivatives Exchange (EUREX)
|
||||
/// </summary>
|
||||
public static Exchange EUREX { get; }
|
||||
= new("EUREX", "EUREX", "European Derivatives Exchange", QuantConnect.Market.EUREX, SecurityType.Future, SecurityType.Index);
|
||||
|
||||
/// <summary>
|
||||
|
||||
/// <summary>
|
||||
/// The Chicago Board of Trade (CBOT) is a commodity exchange
|
||||
/// </summary>
|
||||
|
||||
@@ -950,6 +950,8 @@ namespace QuantConnect
|
||||
return Exchange.COMEX;
|
||||
case "NYSELIFFE":
|
||||
return Exchange.NYSELIFFE;
|
||||
case "EUREX":
|
||||
return Exchange.EUREX;
|
||||
default:
|
||||
return Exchange.UNKNOWN;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -69,6 +69,7 @@ namespace QuantConnect
|
||||
Tuple.Create(Bybit, 37),
|
||||
Tuple.Create(Coinbase, 38),
|
||||
Tuple.Create(InteractiveBrokers, 39),
|
||||
Tuple.Create(EUREX, 40)
|
||||
};
|
||||
|
||||
static Market()
|
||||
@@ -153,6 +154,11 @@ namespace QuantConnect
|
||||
/// </summary>
|
||||
public const string CME = "cme";
|
||||
|
||||
/// <summary>
|
||||
/// EUREX
|
||||
/// </summary>
|
||||
public const string EUREX = "eurex";
|
||||
|
||||
/// <summary>
|
||||
/// Singapore Exchange
|
||||
/// </summary>
|
||||
|
||||
@@ -112,6 +112,15 @@ namespace QuantConnect
|
||||
return Invariant($"InteractiveBrokersFeeModel.UnitedStatesFutureFees(): Unsupported security type: {security.Type}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string message saying the type of the given security was unsupported
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static string EUREXFutureFeesUnsupportedSecurityType(Securities.Security security)
|
||||
{
|
||||
return Invariant($"InteractiveBrokersFeeModel.EUREXFutureFees(): Unsupported security type: {security.Type}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string message saying the quote currency of the given security was
|
||||
/// unexpected for Hong Kong futures exchange
|
||||
|
||||
@@ -42,7 +42,8 @@ namespace QuantConnect.Orders.Fees
|
||||
new()
|
||||
{
|
||||
{ Market.USA, UnitedStatesFutureFees },
|
||||
{ Market.HKFE, HongKongFutureFees }
|
||||
{ Market.HKFE, HongKongFutureFees },
|
||||
{ Market.EUREX, EUREXFutureFees }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@@ -377,6 +378,37 @@ namespace QuantConnect.Orders.Fees
|
||||
return new CashAmount(ibFeePerContract * 1.5m, security.QuoteCurrency.Symbol);
|
||||
}
|
||||
|
||||
private static CashAmount EUREXFutureFees(Security security)
|
||||
{
|
||||
IDictionary<string, decimal> fees, exchangeFees;
|
||||
decimal ibFeePerContract, exchangeFeePerContract;
|
||||
string symbol;
|
||||
|
||||
switch (security.Symbol.SecurityType)
|
||||
{
|
||||
case SecurityType.Future:
|
||||
fees = _eurexFuturesFees;
|
||||
exchangeFees = _eurexFuturesExchangeFees;
|
||||
symbol = security.Symbol.ID.Symbol;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException(Messages.InteractiveBrokersFeeModel.EUREXFutureFeesUnsupportedSecurityType(security));
|
||||
}
|
||||
|
||||
if (!fees.TryGetValue(symbol, out ibFeePerContract))
|
||||
{
|
||||
ibFeePerContract = 1.00m;
|
||||
}
|
||||
|
||||
if (!exchangeFees.TryGetValue(symbol, out exchangeFeePerContract))
|
||||
{
|
||||
exchangeFeePerContract = 0.00m;
|
||||
}
|
||||
|
||||
// Add exchange fees + IBKR regulatory fee (0.02)
|
||||
return new CashAmount(ibFeePerContract + exchangeFeePerContract + 0.02m, Currencies.EUR);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reference at https://www.interactivebrokers.com/en/pricing/commissions-futures.php?re=amer
|
||||
/// </summary>
|
||||
@@ -394,6 +426,15 @@ namespace QuantConnect.Orders.Fees
|
||||
{ "MIR", 0.15m }, { "M6C", 0.15m }, { "M6S", 0.15m }, { "MNH", 0.15m },
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Reference at https://www.interactivebrokers.com/en/pricing/commissions-futures-europe.php?re=europe
|
||||
/// </summary>
|
||||
private static readonly Dictionary<string, decimal> _eurexFuturesFees = new()
|
||||
{
|
||||
// Futures
|
||||
{ "FESX", 1.00m },
|
||||
};
|
||||
|
||||
private static readonly Dictionary<string, decimal> _usaFutureOptionsFees = new()
|
||||
{
|
||||
// Micro E-mini Future Options
|
||||
@@ -419,6 +460,12 @@ namespace QuantConnect.Orders.Fees
|
||||
{ "MIR", 0.24m }, { "M6C", 0.24m }, { "M6S", 0.24m }, { "MNH", 0.24m },
|
||||
};
|
||||
|
||||
private static readonly Dictionary<string, decimal> _eurexFuturesExchangeFees = new()
|
||||
{
|
||||
// Futures
|
||||
{ "FESX", 0.00m },
|
||||
};
|
||||
|
||||
private static readonly Dictionary<string, decimal> _usaFutureOptionsExchangeFees = new()
|
||||
{
|
||||
// E-mini Future Options
|
||||
|
||||
74
Common/Python/CommandPythonWrapper.cs
Normal file
74
Common/Python/CommandPythonWrapper.cs
Normal 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?>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,6 +282,16 @@ namespace QuantConnect.Securities
|
||||
return BackMonths().FrontMonth();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjust the reference date used for expiration filtering. By default it just returns the same date.
|
||||
/// </summary>
|
||||
/// <param name="referenceDate">The reference date to be adjusted</param>
|
||||
/// <returns>The adjusted date</returns>
|
||||
protected virtual DateTime AdjustExpirationReferenceDate(DateTime referenceDate)
|
||||
{
|
||||
return referenceDate;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies filter selecting options contracts based on a range of expiration dates relative to the current day
|
||||
/// </summary>
|
||||
@@ -294,19 +304,21 @@ namespace QuantConnect.Securities
|
||||
{
|
||||
if (LocalTime == default)
|
||||
{
|
||||
return (T) this;
|
||||
return (T)this;
|
||||
}
|
||||
|
||||
if (maxExpiry > Time.MaxTimeSpan) maxExpiry = Time.MaxTimeSpan;
|
||||
|
||||
var minExpiryToDate = LocalTime.Date + minExpiry;
|
||||
var maxExpiryToDate = LocalTime.Date + maxExpiry;
|
||||
var referenceDate = AdjustExpirationReferenceDate(LocalTime.Date);
|
||||
|
||||
var minExpiryToDate = referenceDate + minExpiry;
|
||||
var maxExpiryToDate = referenceDate + maxExpiry;
|
||||
|
||||
Data = Data
|
||||
.Where(symbol => symbol.ID.Date.Date >= minExpiryToDate && symbol.ID.Date.Date <= maxExpiryToDate)
|
||||
.ToList();
|
||||
|
||||
return (T) this;
|
||||
return (T)this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1596,6 +1596,12 @@ namespace QuantConnect.Securities
|
||||
/// MSCI USA Index Futures
|
||||
/// </summary>
|
||||
public const string MSCIUsaIndex = "MXUS";
|
||||
|
||||
/// <summary>
|
||||
/// Euro Stoxx 50 Index Futures
|
||||
/// </summary>
|
||||
/// <returns>The symbol</returns>
|
||||
public const string EuroStoxx50 = "FESX";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -291,7 +291,7 @@ namespace QuantConnect.Securities.Future
|
||||
// Monthly contracts
|
||||
// Trading terminates on the last business day of the contract month.
|
||||
var lastBusinessDay = FuturesExpiryUtilityFunctions.NthLastBusinessDay(time, 1, holidays);
|
||||
|
||||
|
||||
lastBusinessDay = FuturesExpiryUtilityFunctions.AddBusinessDaysIfHoliday(lastBusinessDay, -1, holidays);
|
||||
|
||||
return lastBusinessDay;
|
||||
@@ -353,6 +353,20 @@ namespace QuantConnect.Securities.Future
|
||||
return thirdFriday.Add(new TimeSpan(13,30,0));
|
||||
})
|
||||
},
|
||||
// EuroStoxx50 (FESX): https://www.xetra.com/resource/blob/63488/437afcd347fb020377873dd1ceac10ba/EURO-STOXX-50-Factsheet-data.pdf
|
||||
{Symbol.Create(Futures.Indices.EuroStoxx50, SecurityType.Future, Market.EUREX), (time =>
|
||||
{
|
||||
// Quarterly contracts (Mar/3, Jun/6 , Sep/9 , Dec/12) listed for 9 consecutive quarters and 3 additional December contract months.
|
||||
while (!FutureExpirationCycles.HMUZ.Contains(time.Month))
|
||||
{
|
||||
time = time.AddMonths(1);
|
||||
}
|
||||
|
||||
// Trading can occur up to 9:30 a.m. Eastern Time (ET) on the 3rd Friday of the contract month
|
||||
var thirdFriday = FuturesExpiryUtilityFunctions.ThirdFriday(time);
|
||||
return thirdFriday.Add(new TimeSpan(13,30,0));
|
||||
})
|
||||
},
|
||||
// NASDAQ100EMini (NQ): http://www.cmegroup.com/trading/equity-index/us-index/e-mini-nasdaq-100_contract_specifications.html
|
||||
{Symbol.Create(Futures.Indices.NASDAQ100EMini, SecurityType.Future, Market.CME), (time =>
|
||||
{
|
||||
@@ -465,7 +479,7 @@ namespace QuantConnect.Securities.Future
|
||||
//Contracts listed for the 2 nearest serial and 4 quarterly months.
|
||||
//Trading terminates on the second to last business day of the contract month at the end of trading on the Hong Kong Exchange Securities Market
|
||||
var secondLastBusinessDay = FuturesExpiryUtilityFunctions.NthLastBusinessDay(time,2, holidays);
|
||||
|
||||
|
||||
while (!FuturesExpiryUtilityFunctions.NotHoliday(secondLastBusinessDay, holidays))
|
||||
{
|
||||
secondLastBusinessDay = secondLastBusinessDay.AddDays(-1);
|
||||
@@ -1143,7 +1157,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.CBOT;
|
||||
var symbol = Futures.Grains.BlackSeaCornFinanciallySettledPlatts;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Monthly contracts listed for 15 consecutive months.
|
||||
// Trading terminates on the last business day of the contract month which is also a Platts publication date for the price assessment.
|
||||
return FuturesExpiryUtilityFunctions.NthLastBusinessDay(time, 1, holidays);
|
||||
@@ -1348,7 +1362,7 @@ namespace QuantConnect.Securities.Future
|
||||
var thirdWednesday = FuturesExpiryUtilityFunctions.ThirdWednesday(time);
|
||||
var secondBusinessDayPrecedingThirdWednesday = FuturesExpiryUtilityFunctions.AddBusinessDays(thirdWednesday,-2, holidays);
|
||||
secondBusinessDayPrecedingThirdWednesday = FuturesExpiryUtilityFunctions.AddBusinessDaysIfHoliday(secondBusinessDayPrecedingThirdWednesday, -1, holidays);
|
||||
|
||||
|
||||
return secondBusinessDayPrecedingThirdWednesday.Add(new TimeSpan(14,16,0));
|
||||
})
|
||||
},
|
||||
@@ -1363,7 +1377,7 @@ namespace QuantConnect.Securities.Future
|
||||
var thirdWednesday = FuturesExpiryUtilityFunctions.ThirdWednesday(time);
|
||||
var secondBusinessDayPrecedingThirdWednesday = FuturesExpiryUtilityFunctions.AddBusinessDays(thirdWednesday, -2, holidays);
|
||||
secondBusinessDayPrecedingThirdWednesday = FuturesExpiryUtilityFunctions.AddBusinessDaysIfHoliday(secondBusinessDayPrecedingThirdWednesday, -1, holidays);
|
||||
|
||||
|
||||
return secondBusinessDayPrecedingThirdWednesday.Add(new TimeSpan(14,16,0));
|
||||
})
|
||||
},
|
||||
@@ -1481,7 +1495,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.CME;
|
||||
var symbol = Futures.Currencies.StandardSizeUSDOffshoreRMBCNH;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Monthly contracts listed for 13 consecutive months and quarterly contracts (Mar, Jun, Sep, Dec) listed for the next 8 quarters.
|
||||
// Trading terminates on the second Hong Kong business day prior to the third Wednesday of the contract month at 11:00 a.m. Hong Kong local time.
|
||||
var thirdWednesday = FuturesExpiryUtilityFunctions.ThirdWednesday(time);
|
||||
@@ -1500,7 +1514,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.CME;
|
||||
var symbol = Futures.Currencies.EuroFXEmini;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Quarterly contracts (Mar, Jun, Sep, Dec) listed for 2 consecutive quarters
|
||||
while (!FutureExpirationCycles.HMUZ.Contains(time.Month))
|
||||
{
|
||||
@@ -1521,7 +1535,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.CME;
|
||||
var symbol = Futures.Currencies.EURAUD;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Quarterly contracts (Mar, Jun, Sep, Dec) listed for 6 consecutive quarters
|
||||
while (!FutureExpirationCycles.HMUZ.Contains(time.Month))
|
||||
{
|
||||
@@ -1542,7 +1556,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.CME;
|
||||
var symbol = Futures.Currencies.EURCAD;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Quarterly contracts (Mar, Jun, Sep, Dec) listed for 6 consecutive quarters
|
||||
while (!FutureExpirationCycles.HMUZ.Contains(time.Month))
|
||||
{
|
||||
@@ -1563,7 +1577,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.CME;
|
||||
var symbol = Futures.Currencies.EURSEK;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Six months in the March quarterly cycle (Mar, Jun, Sep, Dec)
|
||||
while (!FutureExpirationCycles.HMUZ.Contains(time.Month))
|
||||
{
|
||||
@@ -1605,7 +1619,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.CBOT;
|
||||
var symbol = Futures.Financials.Y30TreasuryBond;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Quarterly contracts (Mar, Jun, Sep, Dec) listed for 3 quarters
|
||||
while (!FutureExpirationCycles.HMUZ.Contains(time.Month))
|
||||
{
|
||||
@@ -1624,7 +1638,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.CBOT;
|
||||
var symbol = Futures.Financials.Y10TreasuryNote;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Quarterly contracts (Mar, Jun, Sep, Dec) listed for 3 consecutive quarters
|
||||
while (!FutureExpirationCycles.HMUZ.Contains(time.Month))
|
||||
{
|
||||
@@ -1660,7 +1674,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.CBOT;
|
||||
var symbol = Futures.Financials.Y2TreasuryNote;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Quarterly contracts (Mar, Jun, Sep, Dec) listed for 3 consecutive quarters
|
||||
while (!FutureExpirationCycles.HMUZ.Contains(time.Month))
|
||||
{
|
||||
@@ -1678,7 +1692,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.CME;
|
||||
var symbol = Futures.Financials.EuroDollar;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Quarterly contracts (Mar, Jun, Sep, Dec) listed for 40 consecutive quarters and the nearest 4 serial contract months.
|
||||
// List a new quarterly contract for trading on the last trading day of the nearby expiry.
|
||||
|
||||
@@ -1695,7 +1709,7 @@ namespace QuantConnect.Securities.Future
|
||||
{
|
||||
var market = Market.CBOT;
|
||||
var symbol = Futures.Financials.FiveYearUSDMACSwap;
|
||||
|
||||
|
||||
// Quarterly contracts (Mar, Jun, Sep, Dec) listed for 2 consecutive quarters
|
||||
while (!FutureExpirationCycles.HMUZ.Contains(time.Month))
|
||||
{
|
||||
@@ -1721,7 +1735,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.CBOT;
|
||||
var symbol = Futures.Financials.UltraUSTreasuryBond;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Quarterly contracts (Mar, Jun, Sep, Dec) listed for 3 consecutive quarters
|
||||
while (!FutureExpirationCycles.HMUZ.Contains(time.Month))
|
||||
{
|
||||
@@ -1740,7 +1754,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.CBOT;
|
||||
var symbol = Futures.Financials.UltraTenYearUSTreasuryNote;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Quarterly contracts (Mar, Jun, Sep, Dec) listed for 3 consecutive quarters
|
||||
while (!FutureExpirationCycles.HMUZ.Contains(time.Month))
|
||||
{
|
||||
@@ -1770,7 +1784,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.NYMEX;
|
||||
var symbol = Futures.Energy.ArgusPropaneFarEastIndexBALMO;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Monthly BALMO contracts listed for three cconsecutive months
|
||||
// Trading shall cease on the last business day of the contract month. Business days are based on the Singapore Public Holiday calendar.
|
||||
// TODO: Might need singapore calendar
|
||||
@@ -1783,7 +1797,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.NYMEX;
|
||||
var symbol = Futures.Energy.MiniEuropeanThreePointPercentFiveFuelOilBargesPlatts;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Monthly contracts listed for the current year and the next 4 calendar years.
|
||||
// Trading shall cease on the last business day of the contract month.
|
||||
var lastBusinessDay = FuturesExpiryUtilityFunctions.NthLastBusinessDay(time, 1, holidays);
|
||||
@@ -1798,7 +1812,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.NYMEX;
|
||||
var symbol = Futures.Energy.MiniSingaporeFuelOil180CstPlatts;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Monthly contracts listed for the current year and the next 5 calendar years.
|
||||
// Trading shall cease on the last business day of the contract month.
|
||||
// Special case exists where the last trade occurs on US holiday, but not an exchange holiday (markets closed)
|
||||
@@ -1841,7 +1855,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.NYMEX;
|
||||
var symbol = Futures.Energy.PropaneNonLDHMontBelvieuOPIS;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Monthly contracts listed for 48 consecutive months
|
||||
// Trading shall cease on the last business day of the contract month.
|
||||
return FuturesExpiryUtilityFunctions.NthLastBusinessDay(time, 1, holidays);
|
||||
@@ -1864,7 +1878,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.NYMEX;
|
||||
var symbol = Futures.Energy.PremiumUnleadedGasoline10ppmFOBMEDPlatts;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// 48 consecutive months
|
||||
var lastBusinessDay = FuturesExpiryUtilityFunctions.NthLastBusinessDay(time, 1, holidays);
|
||||
lastBusinessDay = FuturesExpiryUtilityFunctions.AddBusinessDaysIfHoliday(lastBusinessDay, -1, holidays);
|
||||
@@ -1878,7 +1892,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.NYMEX;
|
||||
var symbol = Futures.Energy.ArgusPropaneFarEastIndex;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Monthly contracts listed for 48 consecutive months
|
||||
// Trading shall cease on the last business day of the contract month.
|
||||
return FuturesExpiryUtilityFunctions.NthLastBusinessDay(time, 1, holidays);
|
||||
@@ -1890,7 +1904,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.NYMEX;
|
||||
var symbol = Futures.Energy.GasolineEurobobOxyNWEBargesArgusCrackSpreadBALMO;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Monthly BALMO contracts listed for 3 consecutive months
|
||||
// Trading ceases on the last business day of the contract month.
|
||||
return FuturesExpiryUtilityFunctions.NthLastBusinessDay(time, 1, holidays);
|
||||
@@ -1902,7 +1916,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.NYMEX;
|
||||
var symbol = Futures.Energy.MontBelvieuNaturalGasolineOPIS;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Monthly contracts listed for 56 consecutive months
|
||||
// Trading shall cease on the last business day of the contract month
|
||||
return FuturesExpiryUtilityFunctions.NthLastBusinessDay(time, 1, holidays);
|
||||
@@ -1914,7 +1928,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.NYMEX;
|
||||
var symbol = Futures.Energy.MontBelvieuNormalButaneOPISBALMO;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Monthly BALMO contracts listed for the current month and the following month listed 10 business days prior to the start of the contract month
|
||||
// Trading terminates on the last business day of the contract month.
|
||||
return FuturesExpiryUtilityFunctions.NthLastBusinessDay(time, 1, holidays);
|
||||
@@ -1926,7 +1940,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.NYMEX;
|
||||
var symbol = Futures.Energy.ConwayPropaneOPIS;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Monthly contracts listed for the current year and the next 4 calendar years.
|
||||
// Trading shall cease on the last business day of the contract month.
|
||||
return FuturesExpiryUtilityFunctions.NthLastBusinessDay(time, 1, holidays);
|
||||
@@ -1938,7 +1952,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.NYMEX;
|
||||
var symbol = Futures.Energy.MontBelvieuLDHPropaneOPISBALMO;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Monthly BALMO contracts listed for the current month and the following month listed 10 business days prior to the start of the contract month
|
||||
// Trading shall cease on the last business day of the contract month.
|
||||
return FuturesExpiryUtilityFunctions.NthLastBusinessDay(time, 1, holidays);
|
||||
@@ -1950,7 +1964,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.NYMEX;
|
||||
var symbol = Futures.Energy.ArgusPropaneFarEastIndexVsEuropeanPropaneCIFARAArgus;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Monthly contracts listed for 36 consecutive months
|
||||
// Trading shall cease on the last business day of the contract month.
|
||||
var lastBusinessDay = FuturesExpiryUtilityFunctions.NthLastBusinessDay(time, 1, holidays);
|
||||
@@ -1965,7 +1979,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.NYMEX;
|
||||
var symbol = Futures.Energy.ArgusPropaneSaudiAramco;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Monthly contracts listed for 48 consecutive months
|
||||
// Trading shall terminate on the last business day of the month prior to the contract month.
|
||||
// Business days are based on the Singapore Public Holiday Calendar.
|
||||
@@ -1998,7 +2012,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.NYMEX;
|
||||
var symbol = Futures.Energy.GroupThreeSuboctaneGasolinePlattsVsRBOB;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// 36 consecutive months
|
||||
// Trading shall cease on the last business day of the contract month
|
||||
return FuturesExpiryUtilityFunctions.NthLastBusinessDay(time, 1, holidays);
|
||||
@@ -2010,7 +2024,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.NYMEX;
|
||||
var symbol = Futures.Energy.SingaporeFuelOil180cstPlattsBALMO;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Monthly BALMO contracts listed for 3 consecutive months
|
||||
// Trading shall cease on the last business day of the contract month.
|
||||
return FuturesExpiryUtilityFunctions.NthLastBusinessDay(time, 1, holidays);
|
||||
@@ -2022,7 +2036,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.NYMEX;
|
||||
var symbol = Futures.Energy.SingaporeFuelOil380cstPlattsBALMO;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Monthly BALMO contracts listed for 3 consecutive months
|
||||
// Trading shall cease on the last business day of the contract month.
|
||||
return FuturesExpiryUtilityFunctions.NthLastBusinessDay(time, 1, holidays);
|
||||
@@ -2034,7 +2048,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.NYMEX;
|
||||
var symbol = Futures.Energy.MontBelvieuEthaneOPIS;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Monthly contracts listed for the current year and the next 4 calendar years.
|
||||
// Trading shall cease on the last business day of the contract month.
|
||||
return FuturesExpiryUtilityFunctions.NthLastBusinessDay(time, 1, holidays);
|
||||
@@ -2046,7 +2060,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.NYMEX;
|
||||
var symbol = Futures.Energy.MontBelvieuNormalButaneOPIS;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Monthly contracts listed for the current year and next 4 calendar years.
|
||||
// Trading shall cease on the last business day of the contract month.
|
||||
return FuturesExpiryUtilityFunctions.NthLastBusinessDay(time, 1, holidays);
|
||||
@@ -2071,7 +2085,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.NYMEX;
|
||||
var symbol = Futures.Energy.ArgusLLSvsWTIArgusTradeMonth;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Trading shall cease at the close of trading on the last business day that falls on or before the 25th calendar day of the month prior to the contract month. If the 25th calendar day is a weekend or holiday, trading shall cease on the first business day prior to the 25th calendar day.
|
||||
var previousMonth = time.AddMonths(-1);
|
||||
var twentyFifthDay = new DateTime(previousMonth.Year, previousMonth.Month, 25);
|
||||
@@ -2089,7 +2103,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.NYMEX;
|
||||
var symbol = Futures.Energy.SingaporeGasoilPlattsVsLowSulphurGasoilFutures;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// Monthly contracts listed for the current year and the next 2 calendar years.
|
||||
// Trading ceases on the last business day of the contract month
|
||||
var lastBusinessDay = FuturesExpiryUtilityFunctions.NthLastBusinessDay(time, 1, holidays);
|
||||
@@ -2104,7 +2118,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.NYMEX;
|
||||
var symbol = Futures.Energy.LosAngelesCARBOBGasolineOPISvsRBOBGasoline;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// 36 consecutive months
|
||||
// Trading shall cease on the last business day of the contract month
|
||||
return FuturesExpiryUtilityFunctions.NthLastBusinessDay(time, 1, holidays);
|
||||
@@ -2321,7 +2335,7 @@ namespace QuantConnect.Securities.Future
|
||||
{
|
||||
lastBusinessDay = FuturesExpiryUtilityFunctions.NthLastBusinessDay(twoMonthsPriorToContractMonth, 1, holidays);
|
||||
}
|
||||
|
||||
|
||||
lastBusinessDay = FuturesExpiryUtilityFunctions.AddBusinessDaysIfHoliday(lastBusinessDay, -1, holidays);
|
||||
|
||||
return lastBusinessDay;
|
||||
@@ -2877,7 +2891,7 @@ namespace QuantConnect.Securities.Future
|
||||
var market = Market.ICE;
|
||||
var symbol = Futures.Softs.OrangeJuice;
|
||||
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(market, symbol);
|
||||
|
||||
|
||||
// January, March, May, July, September, November.
|
||||
while (!FutureExpirationCycles.FHKNUX.Contains(time.Month))
|
||||
{
|
||||
|
||||
@@ -31,6 +31,8 @@ namespace QuantConnect.Securities
|
||||
/// </summary>
|
||||
public class OptionFilterUniverse : ContractSecurityFilterUniverse<OptionFilterUniverse, OptionUniverse>
|
||||
{
|
||||
private Option.Option _option;
|
||||
|
||||
// Fields used in relative strikes filter
|
||||
private List<decimal> _uniqueStrikes;
|
||||
private bool _refreshUniqueStrikes;
|
||||
@@ -59,6 +61,7 @@ namespace QuantConnect.Securities
|
||||
/// <param name="option">The canonical option chain security</param>
|
||||
public OptionFilterUniverse(Option.Option option)
|
||||
{
|
||||
_option = option;
|
||||
_underlyingScaleFactor = option.SymbolProperties.StrikeMultiplier;
|
||||
}
|
||||
|
||||
@@ -66,9 +69,10 @@ namespace QuantConnect.Securities
|
||||
/// Constructs OptionFilterUniverse
|
||||
/// </summary>
|
||||
/// <remarks>Used for testing only</remarks>
|
||||
public OptionFilterUniverse(IEnumerable<OptionUniverse> allData, BaseData underlying, decimal underlyingScaleFactor = 1)
|
||||
public OptionFilterUniverse(Option.Option option, IEnumerable<OptionUniverse> allData, BaseData underlying, decimal underlyingScaleFactor = 1)
|
||||
: base(allData, underlying.EndTime)
|
||||
{
|
||||
_option = option;
|
||||
UnderlyingInternal = underlying;
|
||||
_refreshUniqueStrikes = true;
|
||||
_underlyingScaleFactor = underlyingScaleFactor;
|
||||
@@ -128,6 +132,24 @@ namespace QuantConnect.Securities
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjusts the date to the next trading day if the current date is not a trading day, so that expiration filter is properly applied.
|
||||
/// e.g. Selection for Mondays happen on Friday midnight (Saturday start), so if the minimum time to expiration is, say 0,
|
||||
/// contracts expiring on Monday would be filtered out if the date is not properly adjusted to the next trading day (Monday).
|
||||
/// </summary>
|
||||
/// <param name="referenceDate">The date to be adjusted</param>
|
||||
/// <returns>The adjusted date</returns>
|
||||
protected override DateTime AdjustExpirationReferenceDate(DateTime referenceDate)
|
||||
{
|
||||
// Check whether the reference time is a tradable date:
|
||||
if (!_option.Exchange.Hours.IsDateOpen(referenceDate))
|
||||
{
|
||||
referenceDate = _option.Exchange.Hours.GetNextTradingDay(referenceDate);
|
||||
}
|
||||
|
||||
return referenceDate;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies filter selecting options contracts based on a range of strikes in relative terms
|
||||
/// </summary>
|
||||
|
||||
4
Data/future/eurex/factor_files/fesx.csv
Normal file
4
Data/future/eurex/factor_files/fesx.csv
Normal file
@@ -0,0 +1,4 @@
|
||||
{"Date":"2024-02-29T00:00:00","BackwardsRatioScale":[0.9913489916535321268273586766,1.0164323896258166699663432984,1.0],"BackwardsPanamaCanalScale":[-42.66,83.0,0.0],"ForwardPanamaCanalScale":[-123866.99,774.5,33.0],"DataMappingMode":1}
|
||||
{"Date":"2024-03-14T00:00:00","BackwardsRatioScale":[0.9944097809171575660198252019,1.0088791461489374296086137569,1.0],"BackwardsPanamaCanalScale":[-27.80,44.0,0.0],"ForwardPanamaCanalScale":[-122928.36,1387.0,151.0],"DataMappingMode":0}
|
||||
{"Date":"2024-05-31T00:00:00","BackwardsRatioScale":[0.9982410719579438328820727682,1.0164323896258166699663432984,1.0],"BackwardsPanamaCanalScale":[-8.9,83.0,0.0],"ForwardPanamaCanalScale":[-123858.09,691.5,33.0],"DataMappingMode":1}
|
||||
{"Date":"2024-06-20T00:00:00","BackwardsRatioScale":[0.9999378547042986502442711058,1.0044105854049719326383319968,1.0],"BackwardsPanamaCanalScale":[-0.31,22.0,0.0],"ForwardPanamaCanalScale":[-122928.05,1365.0,151.0],"DataMappingMode":0}
|
||||
|
Can't render this file because it contains an unexpected character in line 1 and column 2.
|
15
Data/future/eurex/map_files/fesx.csv
Normal file
15
Data/future/eurex/map_files/fesx.csv
Normal file
@@ -0,0 +1,15 @@
|
||||
18991230,fesx,EUREX
|
||||
20231130,fesx yebksyl246g5,EUREX,1
|
||||
20231214,fesx yebksyl246g5,EUREX,0
|
||||
20240229,fesx ygt6hgvf2u1x,EUREX,1
|
||||
20240314,fesx ygt6hgvf2u1x,EUREX,0
|
||||
20240531,fesx yjhoampykrs5,EUREX,1
|
||||
20240620,fesx yjhoampykrs5,EUREX,0
|
||||
20240831,fesx ylz9z50bjfdx,EUREX,1
|
||||
20240919,fesx ylz9z50bjfdx,EUREX,0
|
||||
20241130,fesx yogvnnaoi2zp,EUREX,1
|
||||
20241219,fesx yogvnnaoi2zp,EUREX,0
|
||||
20250228,fesx yqyhc5l1gqlh,EUREX,1
|
||||
20250320,fesx yqyhc5l1gqlh,EUREX,0
|
||||
20250531,fesx ytg30nvefe79,EUREX,1
|
||||
20250619,fesx ytg30nvefe79,EUREX,0
|
||||
|
2
Data/future/eurex/margins/FESX.csv
Normal file
2
Data/future/eurex/margins/FESX.csv
Normal file
@@ -0,0 +1,2 @@
|
||||
date,initial,maintenance
|
||||
20000101,3000,3000
|
||||
|
BIN
Data/future/eurex/minute/fesx/20240603_trade.zip
Normal file
BIN
Data/future/eurex/minute/fesx/20240603_trade.zip
Normal file
Binary file not shown.
BIN
Data/future/eurex/minute/fesx/20240604_trade.zip
Normal file
BIN
Data/future/eurex/minute/fesx/20240604_trade.zip
Normal file
Binary file not shown.
BIN
Data/future/eurex/minute/fesx/20240621_trade.zip
Normal file
BIN
Data/future/eurex/minute/fesx/20240621_trade.zip
Normal file
Binary file not shown.
BIN
Data/index/eurex/minute/sx5e/20240729_trade.zip
Normal file
BIN
Data/index/eurex/minute/sx5e/20240729_trade.zip
Normal file
Binary file not shown.
BIN
Data/index/eurex/minute/sx5e/20240730_trade.zip
Normal file
BIN
Data/index/eurex/minute/sx5e/20240730_trade.zip
Normal file
Binary file not shown.
@@ -118281,6 +118281,408 @@
|
||||
}
|
||||
],
|
||||
"holidays": []
|
||||
},
|
||||
"Index-eurex-[*]": {
|
||||
"dataTimeZone": "Europe/Berlin",
|
||||
"exchangeTimeZone": "Europe/Berlin",
|
||||
"sunday": [],
|
||||
"monday": [
|
||||
{
|
||||
"start": "09:00:00",
|
||||
"end": "17:30:00",
|
||||
"state": "market"
|
||||
}
|
||||
],
|
||||
"tuesday": [
|
||||
{
|
||||
"start": "09:00:00",
|
||||
"end": "17:30:00",
|
||||
"state": "market"
|
||||
}
|
||||
],
|
||||
"wednesday": [
|
||||
{
|
||||
"start": "09:00:00",
|
||||
"end": "17:30:00",
|
||||
"state": "market"
|
||||
}
|
||||
],
|
||||
"thursday": [
|
||||
{
|
||||
"start": "09:00:00",
|
||||
"end": "17:30:00",
|
||||
"state": "market"
|
||||
}
|
||||
],
|
||||
"friday": [
|
||||
{
|
||||
"start": "09:00:00",
|
||||
"end": "17:30:00",
|
||||
"state": "market"
|
||||
}
|
||||
],
|
||||
"saturday": [],
|
||||
"holidays": [
|
||||
"4/21/2000",
|
||||
"4/24/2000",
|
||||
"5/1/2000",
|
||||
"12/25/2000",
|
||||
"12/26/2000",
|
||||
"1/1/2001",
|
||||
"4/13/2001",
|
||||
"4/16/2001",
|
||||
"5/1/2001",
|
||||
"12/24/2001",
|
||||
"12/25/2001",
|
||||
"12/26/2001",
|
||||
"12/31/2001",
|
||||
"1/1/2002",
|
||||
"3/29/2002",
|
||||
"4/1/2002",
|
||||
"5/1/2002",
|
||||
"12/24/2002",
|
||||
"12/25/2002",
|
||||
"12/26/2002",
|
||||
"12/31/2002",
|
||||
"1/1/2003",
|
||||
"4/18/2003",
|
||||
"4/21/2003",
|
||||
"1/1/2004",
|
||||
"4/9/2004",
|
||||
"4/12/2004",
|
||||
"5/1/2004",
|
||||
"12/24/2004",
|
||||
"12/24/2004",
|
||||
"12/25/2004",
|
||||
"12/26/2004",
|
||||
"12/31/2004",
|
||||
"12/31/2004",
|
||||
"3/25/2005",
|
||||
"3/28/2005",
|
||||
"12/26/2005",
|
||||
"4/14/2006",
|
||||
"4/17/2006",
|
||||
"5/1/2006",
|
||||
"12/25/2006",
|
||||
"12/26/2006",
|
||||
"1/1/2007",
|
||||
"4/6/2007",
|
||||
"4/9/2007",
|
||||
"5/1/2007",
|
||||
"12/24/2007",
|
||||
"12/25/2007",
|
||||
"12/26/2007",
|
||||
"12/31/2007",
|
||||
"1/1/2008",
|
||||
"3/21/2008",
|
||||
"3/24/2008",
|
||||
"5/1/2008",
|
||||
"12/24/2008",
|
||||
"12/25/2008",
|
||||
"12/26/2008",
|
||||
"12/31/2008",
|
||||
"1/1/2009",
|
||||
"4/10/2009",
|
||||
"4/13/2009",
|
||||
"5/1/2009",
|
||||
"12/24/2009",
|
||||
"12/25/2009",
|
||||
"12/31/2009",
|
||||
"1/1/2010",
|
||||
"4/2/2010",
|
||||
"4/5/2010",
|
||||
"12/24/2010",
|
||||
"12/31/2010",
|
||||
"4/22/2011",
|
||||
"4/25/2011",
|
||||
"12/26/2011",
|
||||
"4/6/2012",
|
||||
"4/9/2012",
|
||||
"5/1/2012",
|
||||
"12/24/2012",
|
||||
"12/25/2012",
|
||||
"12/26/2012",
|
||||
"12/31/2012",
|
||||
"1/1/2013",
|
||||
"3/29/2013",
|
||||
"4/1/2013",
|
||||
"5/1/2013",
|
||||
"12/24/2013",
|
||||
"12/25/2013",
|
||||
"12/26/2013",
|
||||
"12/31/2013",
|
||||
"1/1/2014",
|
||||
"4/18/2014",
|
||||
"4/21/2014",
|
||||
"5/1/2014",
|
||||
"12/24/2014",
|
||||
"12/25/2014",
|
||||
"12/26/2014",
|
||||
"12/31/2014",
|
||||
"1/1/2015",
|
||||
"4/3/2015",
|
||||
"4/6/2015",
|
||||
"5/1/2015",
|
||||
"5/25/2015",
|
||||
"12/24/2015",
|
||||
"12/25/2015",
|
||||
"12/26/2015",
|
||||
"12/31/2015",
|
||||
"1/1/2016",
|
||||
"3/25/2016",
|
||||
"3/28/2016",
|
||||
"12/26/2016",
|
||||
"4/14/2017",
|
||||
"4/17/2017",
|
||||
"5/1/2017",
|
||||
"12/25/2017",
|
||||
"12/26/2017",
|
||||
"1/1/2018",
|
||||
"3/30/2018",
|
||||
"4/2/2018",
|
||||
"5/1/2018",
|
||||
"12/24/2018",
|
||||
"12/25/2018",
|
||||
"12/26/2018",
|
||||
"12/31/2018",
|
||||
"1/1/2019",
|
||||
"4/19/2019",
|
||||
"4/22/2019",
|
||||
"5/1/2019",
|
||||
"12/24/2019",
|
||||
"12/25/2019",
|
||||
"12/26/2019",
|
||||
"12/31/2019",
|
||||
"1/1/2020",
|
||||
"4/10/2020",
|
||||
"4/13/2020",
|
||||
"5/1/2020",
|
||||
"12/24/2020",
|
||||
"12/25/2020",
|
||||
"12/31/2020",
|
||||
"1/1/2021",
|
||||
"4/2/2021",
|
||||
"4/5/2021",
|
||||
"12/24/2021",
|
||||
"12/31/2021",
|
||||
"4/15/2022",
|
||||
"4/18/2022",
|
||||
"12/26/2022",
|
||||
"4/7/2023",
|
||||
"4/10/2023",
|
||||
"5/1/2023",
|
||||
"12/25/2023",
|
||||
"12/26/2023",
|
||||
"1/1/2024",
|
||||
"3/29/2024",
|
||||
"4/1/2024",
|
||||
"5/1/2024",
|
||||
"12/24/2024",
|
||||
"12/25/2024",
|
||||
"12/26/2024",
|
||||
"12/31/2024"
|
||||
]
|
||||
},
|
||||
"Future-eurex-FESX": {
|
||||
"dataTimeZone": "Europe/Berlin",
|
||||
"exchangeTimeZone": "Europe/Berlin",
|
||||
"sunday": [],
|
||||
"monday": [
|
||||
{
|
||||
"start": "01:10:00",
|
||||
"end": "22:00:00",
|
||||
"state": "market"
|
||||
}
|
||||
],
|
||||
"tuesday": [
|
||||
{
|
||||
"start": "01:10:00",
|
||||
"end": "22:00:00",
|
||||
"state": "market"
|
||||
}
|
||||
],
|
||||
"wednesday": [
|
||||
{
|
||||
"start": "01:10:00",
|
||||
"end": "22:00:00",
|
||||
"state": "market"
|
||||
}
|
||||
],
|
||||
"thursday": [
|
||||
{
|
||||
"start": "01:10:00",
|
||||
"end": "22:00:00",
|
||||
"state": "market"
|
||||
}
|
||||
],
|
||||
"friday": [
|
||||
{
|
||||
"start": "01:10:00",
|
||||
"end": "22:00:00",
|
||||
"state": "market"
|
||||
}
|
||||
],
|
||||
"saturday": [],
|
||||
"holidays": [
|
||||
"4/21/2000",
|
||||
"4/24/2000",
|
||||
"5/1/2000",
|
||||
"12/25/2000",
|
||||
"12/26/2000",
|
||||
"1/1/2001",
|
||||
"4/13/2001",
|
||||
"4/16/2001",
|
||||
"5/1/2001",
|
||||
"12/24/2001",
|
||||
"12/25/2001",
|
||||
"12/26/2001",
|
||||
"12/31/2001",
|
||||
"1/1/2002",
|
||||
"3/29/2002",
|
||||
"4/1/2002",
|
||||
"5/1/2002",
|
||||
"12/24/2002",
|
||||
"12/25/2002",
|
||||
"12/26/2002",
|
||||
"12/31/2002",
|
||||
"1/1/2003",
|
||||
"4/18/2003",
|
||||
"4/21/2003",
|
||||
"1/1/2004",
|
||||
"4/9/2004",
|
||||
"4/12/2004",
|
||||
"5/1/2004",
|
||||
"12/24/2004",
|
||||
"12/24/2004",
|
||||
"12/25/2004",
|
||||
"12/26/2004",
|
||||
"12/31/2004",
|
||||
"12/31/2004",
|
||||
"3/25/2005",
|
||||
"3/28/2005",
|
||||
"12/26/2005",
|
||||
"4/14/2006",
|
||||
"4/17/2006",
|
||||
"5/1/2006",
|
||||
"12/25/2006",
|
||||
"12/26/2006",
|
||||
"1/1/2007",
|
||||
"4/6/2007",
|
||||
"4/9/2007",
|
||||
"5/1/2007",
|
||||
"12/24/2007",
|
||||
"12/25/2007",
|
||||
"12/26/2007",
|
||||
"12/31/2007",
|
||||
"1/1/2008",
|
||||
"3/21/2008",
|
||||
"3/24/2008",
|
||||
"5/1/2008",
|
||||
"12/24/2008",
|
||||
"12/25/2008",
|
||||
"12/26/2008",
|
||||
"12/31/2008",
|
||||
"1/1/2009",
|
||||
"4/10/2009",
|
||||
"4/13/2009",
|
||||
"5/1/2009",
|
||||
"12/24/2009",
|
||||
"12/25/2009",
|
||||
"12/31/2009",
|
||||
"1/1/2010",
|
||||
"4/2/2010",
|
||||
"4/5/2010",
|
||||
"12/24/2010",
|
||||
"12/31/2010",
|
||||
"4/22/2011",
|
||||
"4/25/2011",
|
||||
"12/26/2011",
|
||||
"4/6/2012",
|
||||
"4/9/2012",
|
||||
"5/1/2012",
|
||||
"12/24/2012",
|
||||
"12/25/2012",
|
||||
"12/26/2012",
|
||||
"12/31/2012",
|
||||
"1/1/2013",
|
||||
"3/29/2013",
|
||||
"4/1/2013",
|
||||
"5/1/2013",
|
||||
"12/24/2013",
|
||||
"12/25/2013",
|
||||
"12/26/2013",
|
||||
"12/31/2013",
|
||||
"1/1/2014",
|
||||
"4/18/2014",
|
||||
"4/21/2014",
|
||||
"5/1/2014",
|
||||
"12/24/2014",
|
||||
"12/25/2014",
|
||||
"12/26/2014",
|
||||
"12/31/2014",
|
||||
"1/1/2015",
|
||||
"4/3/2015",
|
||||
"4/6/2015",
|
||||
"5/1/2015",
|
||||
"5/25/2015",
|
||||
"12/24/2015",
|
||||
"12/25/2015",
|
||||
"12/26/2015",
|
||||
"12/31/2015",
|
||||
"1/1/2016",
|
||||
"3/25/2016",
|
||||
"3/28/2016",
|
||||
"12/26/2016",
|
||||
"4/14/2017",
|
||||
"4/17/2017",
|
||||
"5/1/2017",
|
||||
"12/25/2017",
|
||||
"12/26/2017",
|
||||
"1/1/2018",
|
||||
"3/30/2018",
|
||||
"4/2/2018",
|
||||
"5/1/2018",
|
||||
"12/24/2018",
|
||||
"12/25/2018",
|
||||
"12/26/2018",
|
||||
"12/31/2018",
|
||||
"1/1/2019",
|
||||
"4/19/2019",
|
||||
"4/22/2019",
|
||||
"5/1/2019",
|
||||
"12/24/2019",
|
||||
"12/25/2019",
|
||||
"12/26/2019",
|
||||
"12/31/2019",
|
||||
"1/1/2020",
|
||||
"4/10/2020",
|
||||
"4/13/2020",
|
||||
"5/1/2020",
|
||||
"12/24/2020",
|
||||
"12/25/2020",
|
||||
"12/31/2020",
|
||||
"1/1/2021",
|
||||
"4/2/2021",
|
||||
"4/5/2021",
|
||||
"12/24/2021",
|
||||
"12/31/2021",
|
||||
"4/15/2022",
|
||||
"4/18/2022",
|
||||
"12/26/2022",
|
||||
"4/7/2023",
|
||||
"4/10/2023",
|
||||
"5/1/2023",
|
||||
"12/25/2023",
|
||||
"12/26/2023",
|
||||
"1/1/2024",
|
||||
"3/29/2024",
|
||||
"4/1/2024",
|
||||
"5/1/2024",
|
||||
"12/24/2024",
|
||||
"12/25/2024",
|
||||
"12/26/2024",
|
||||
"12/31/2024"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
24
Data/option/usa/universes/spy/20231228.csv
Normal file
24
Data/option/usa/universes/spy/20231228.csv
Normal file
@@ -0,0 +1,24 @@
|
||||
#symbol_id,symbol_value,open,high,low,close,volume,open_interest,implied_volatility,delta,gamma,vega,theta,rho
|
||||
SPY R735QTJ8XC9X,SPY,476.8100,477.5300,476.2600,476.6900,59498271,,,,,,,
|
||||
SPY YEPD29TW8ETI|SPY R735QTJ8XC9X,SPY 231229C00270000,206.7850,208.0850,205.9000,206.6100,46,47,0.0000001,1,0,0,0,0
|
||||
SPY YEW96XE2ROXY|SPY R735QTJ8XC9X,SPY 240105C00270000,207.1400,208.3450,206.1650,206.9000,46,46,1.2716023,1,0,0,0,0
|
||||
SPY YEPD2AYWP9WM|SPY R735QTJ8XC9X,SPY 231229C00275000,201.7150,203.0850,200.6200,201.5850,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96YJ38K12|SPY R735QTJ8XC9X,SPY 240105C00275000,202.1500,203.3400,201.1150,201.9350,0,,1.2324590,1,0,0,0,0
|
||||
SPY YEPD29U26QVA|SPY R735QTJ8XC9X,SPY 231229C00280000,196.7300,198.0350,195.8500,196.6150,10,6,0.0000001,1,0,0,0,0
|
||||
SPY YEW96XE8Q0ZQ|SPY R735QTJ8XC9X,SPY 240105C00280000,197.1600,198.3500,196.1250,196.9400,0,,1.1940285,1,0,0,0,0
|
||||
SPY YEPD2B0K8MEE|SPY R735QTJ8XC9X,SPY 231229C00285000,191.7200,193.0950,190.6500,191.6350,33,37,0.0000001,1,0,0,0,0
|
||||
SPY YEW96YKQRWIU|SPY R735QTJ8XC9X,SPY 240105C00285000,192.1700,193.3700,190.9850,191.9350,20,20,1.1562856,1,0,0,0,0
|
||||
SPY YEPD29U852X2|SPY R735QTJ8XC9X,SPY 231229C00290000,186.7900,188.1000,185.9150,186.6550,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96XEEOD1I|SPY R735QTJ8XC9X,SPY 240105C00290000,187.1750,188.3800,186.0250,186.9400,0,,1.1192060,1,0,0,0,0
|
||||
SPY YEPD2B27RYW6|SPY R735QTJ8XC9X,SPY 231229C00295000,181.7900,183.1050,180.9200,181.6750,4,4,0.0000001,1,0,0,0,0
|
||||
SPY YEW96YMEB90M|SPY R735QTJ8XC9X,SPY 240105C00295000,182.1850,183.3800,181.1150,181.9650,0,,1.0827669,1,0,0,0,0
|
||||
SPY YEPD29PXEISM|SPY R735QTJ8XC9X,SPY 231229C00300000,176.7200,178.1050,175.8600,176.6550,0,4,0.0000001,1,0,0,0,0
|
||||
SPY YEW96XA3XSX2|SPY R735QTJ8XC9X,SPY 240105C00300000,177.1950,178.3900,176.2150,176.9750,0,,1.0469466,1,0,0,0,0
|
||||
SPY YEPD2B3VBBDY|SPY R735QTJ8XC9X,SPY 231229C00305000,171.7250,173.1150,170.9200,171.6600,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96YO1ULIE|SPY R735QTJ8XC9X,SPY 240105C00305000,172.2050,173.4000,171.0100,171.9450,0,,1.0117244,1,0,0,0,0
|
||||
SPY YFA1G9SEX5RA|SPY R735QTJ8XC9X,SPY 240119C00305000,172.9300,174.2500,171.6450,172.6200,0,6,0.5837597,1,0,0,0,0
|
||||
SPY YEPD29UK1R0M|SPY R735QTJ8XC9X,SPY 231229C00310000,166.7600,168.1150,165.6950,166.6300,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96XEQL152|SPY R735QTJ8XC9X,SPY 240105C00310000,167.2150,168.4100,166.1500,166.9950,0,,0.9770808,1,0,0,0,0
|
||||
SPY YEPD2B5IUNVQ|SPY R735QTJ8XC9X,SPY 231229C00315000,161.8000,163.1200,160.9200,161.6450,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96YPPDY06|SPY R735QTJ8XC9X,SPY 240105C00315000,162.2200,163.4100,161.1500,162.0200,0,,0.9429972,1,0,0,0,0
|
||||
SPY YEPD29UQ032E|SPY R735QTJ8XC9X,SPY 231229C00320000,156.7250,158.1250,155.9200,156.6400,0,,0.0000001,1,0,0,0,0
|
||||
|
16
Data/option/usa/universes/spy/20231229.csv
Normal file
16
Data/option/usa/universes/spy/20231229.csv
Normal file
@@ -0,0 +1,16 @@
|
||||
#symbol_id,symbol_value,open,high,low,close,volume,open_interest,implied_volatility,delta,gamma,vega,theta,rho
|
||||
SPY R735QTJ8XC9X,SPY,476.4700,477.0200,473.3150,475.3100,96706712,,,,,,,
|
||||
SPY YETAUP0L4STI|SPY R735QTJ8XC9X,SPY 240102C00402000,74.5000,75.7850,71.5100,73.5200,1,,0.6225652,0.9990582,0.0001866,0.0015352,-0.0097524,-0.0007456
|
||||
SPY YEUAASDR7JZA|SPY R735QTJ8XC9X,SPY 240103C00402000,74.6900,75.8650,71.6300,73.6350,8,,0.5390879,0.9992449,0.0001939,0.0014585,-0.0055175,-0.0006899
|
||||
SPY YETAUP0R34VA|SPY R735QTJ8XC9X,SPY 240102C00403000,73.5000,74.7850,70.5400,72.5400,0,,0.6140000,0.9990404,0.0001911,0.0015516,-0.0107077,-0.0007402
|
||||
SPY YEUAASDX5W12|SPY R735QTJ8XC9X,SPY 240103C00403000,73.5900,74.8650,70.6350,72.6250,0,,0.5500093,0.9986411,0.0002501,0.0021631,-0.0108552,-0.0010937
|
||||
SPY YETAUP0X1GX2|SPY R735QTJ8XC9X,SPY 240102C00404000,72.5000,73.7800,69.5200,71.5350,0,1,0.6052588,0.9990271,0.0001953,0.0015642,-0.0113485,-0.0007372
|
||||
SPY YEUAASE3482U|SPY R735QTJ8XC9X,SPY 240103C00404000,72.6850,73.8650,69.6550,71.6300,8,,0.5241112,0.9992114,0.0002023,0.0015033,-0.0064616,-0.0006820
|
||||
SPY YETAUP12ZSYU|SPY R735QTJ8XC9X,SPY 240102C00405000,71.5000,72.7850,68.5550,70.5400,8,,0.5961598,0.9990230,0.0001989,0.0015696,-0.0113716,-0.0007268
|
||||
SPY YEUAASE92K4M|SPY R735QTJ8XC9X,SPY 240103C00405000,71.6000,72.8700,68.5850,70.6450,10,,0.5166274,0.9991950,0.0002078,0.0015250,-0.0069180,-0.0006887
|
||||
SPY YETAUP18Y50M|SPY R735QTJ8XC9X,SPY 240102C00406000,70.5000,71.7800,67.5500,69.5450,5,,0.5877552,0.9990020,0.0002047,0.0015896,-0.0125101,-0.0007239
|
||||
SPY YEUAASEF0W6E|SPY R735QTJ8XC9X,SPY 240103C00406000,70.6900,71.8700,67.6250,69.6500,6,,0.5088669,0.9991881,0.0002122,0.0015362,-0.0070462,-0.0006788
|
||||
SPY YETAUP1EWH2E|SPY R735QTJ8XC9X,SPY 240102C00407000,69.5000,70.7850,66.5500,68.5500,14,,0.5793580,0.9989810,0.0002107,0.0016087,-0.0129474,-0.0007251
|
||||
SPY YEUAASEKZ886|SPY R735QTJ8XC9X,SPY 240103C00407000,69.6900,70.8700,66.6050,68.6450,12,1,0.5016151,0.9991663,0.0002189,0.0015658,-0.0073815,-0.0006749
|
||||
SPY YETAUP1KUT46|SPY R735QTJ8XC9X,SPY 240102C00408000,68.5000,69.7850,65.5250,67.5550,8,,0.5708631,0.9989624,0.0002165,0.0016252,-0.0128765,-0.0007338
|
||||
SPY YEUAASEQXK9Y|SPY R735QTJ8XC9X,SPY 240103C00408000,68.6900,69.8700,65.6000,67.6350,0,,0.4943122,0.9991460,0.0002256,0.0015929,-0.0073707,-0.0007211
|
||||
|
20
Data/option/usa/universes/spy/20240102.csv
Normal file
20
Data/option/usa/universes/spy/20240102.csv
Normal file
@@ -0,0 +1,20 @@
|
||||
#symbol_id,symbol_value,open,high,low,close,volume,open_interest,implied_volatility,delta,gamma,vega,theta,rho
|
||||
SPY R735QTJ8XC9X,SPY,472.2100,473.6700,470.4900,472.6500,96336531,,,,,,,
|
||||
SPY YEUAASDR7JZA|SPY R735QTJ8XC9X,SPY 240103C00402000,70.2350,71.9700,68.2050,70.6750,1,6,0.0000001,1,0,0,0,0
|
||||
SPY YEV9QVQXAB52|SPY R735QTJ8XC9X,SPY 240104C00402000,70.4300,72.2050,68.4050,70.9600,0,1,1.0444474,0.9987106,0.0001826,0.0011904,-0.0503821,-0.0004696
|
||||
SPY YEUAASDX5W12|SPY R735QTJ8XC9X,SPY 240103C00403000,69.2350,70.9750,67.2100,69.6850,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEV9QVR38N6U|SPY R735QTJ8XC9X,SPY 240104C00403000,69.4300,71.2100,67.4050,69.9200,0,,1.0296539,0.9986927,0.0001877,0.0011951,-0.0546676,-0.0004655
|
||||
SPY YEUAASE3482U|SPY R735QTJ8XC9X,SPY 240103C00404000,68.2350,69.9250,66.2100,68.6950,0,5,0.0000001,1,0,0,0,0
|
||||
SPY YEV9QVR96Z8M|SPY R735QTJ8XC9X,SPY 240104C00404000,68.4300,70.1750,66.4100,68.9200,0,,1.0150155,0.9986728,0.0001932,0.0011999,-0.0575827,-0.0004614
|
||||
SPY YEUAASE92K4M|SPY R735QTJ8XC9X,SPY 240103C00405000,67.2350,68.9700,65.2200,67.6950,0,6,0.0000001,1,0,0,0,0
|
||||
SPY YEV9QVRF5BAE|SPY R735QTJ8XC9X,SPY 240104C00405000,67.4400,69.2100,65.4100,67.8950,0,,1.0001185,0.9986563,0.0001984,0.0012042,-0.0569533,-0.0004559
|
||||
SPY YEUAASEF0W6E|SPY R735QTJ8XC9X,SPY 240103C00406000,66.2350,67.9800,64.2200,66.6900,0,4,0.0000001,1,0,0,0,0
|
||||
SPY YEV9QVRL3NC6|SPY R735QTJ8XC9X,SPY 240104C00406000,66.4400,68.2150,64.4100,66.9300,0,,0.9852584,0.9986394,0.0002038,0.0012083,-0.0563180,-0.0004550
|
||||
SPY YEUAASEKZ886|SPY R735QTJ8XC9X,SPY 240103C00407000,65.2350,66.9750,63.2150,65.6800,0,8,0.0000001,1,0,0,0,0
|
||||
SPY YEV9QVRR1ZDY|SPY R735QTJ8XC9X,SPY 240104C00407000,65.4400,67.2100,63.5150,65.9250,0,,0.9704350,0.9986219,0.0002095,0.0012122,-0.0556880,-0.0004510
|
||||
SPY YEUAASEQXK9Y|SPY R735QTJ8XC9X,SPY 240103C00408000,64.2400,65.8150,62.2150,64.6900,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEV9QVRX0BFQ|SPY R735QTJ8XC9X,SPY 240104C00408000,64.4400,66.2100,62.4100,64.9500,0,1,0.9556481,0.9986041,0.0002154,0.0012163,-0.0550450,-0.0004467
|
||||
SPY YEUAASEWVWBQ|SPY R735QTJ8XC9X,SPY 240103C00409000,63.2400,64.9700,61.2150,63.6950,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEV9QVS2YNHI|SPY R735QTJ8XC9X,SPY 240104C00409000,63.4400,65.2150,61.4100,63.9600,0,,0.9408974,0.9985857,0.0002215,0.0012205,-0.0543964,-0.0004403
|
||||
SPY YEUAAQQ1YVBA|SPY R735QTJ8XC9X,SPY 240103C00410000,62.2400,63.9750,60.2150,62.6900,1,2,0.0000001,1,0,0,0,0
|
||||
SPY YEV9QU381MH2|SPY R735QTJ8XC9X,SPY 240104C00410000,62.4400,64.2100,60.4150,62.9650,0,,0.9261830,0.9985668,0.0002279,0.0012248,-0.0537200,-0.0004386
|
||||
|
23
Data/option/usa/universes/spy/20240103.csv
Normal file
23
Data/option/usa/universes/spy/20240103.csv
Normal file
@@ -0,0 +1,23 @@
|
||||
#symbol_id,symbol_value,open,high,low,close,volume,open_interest,implied_volatility,delta,gamma,vega,theta,rho
|
||||
SPY R735QTJ8XC9X,SPY,470.5000,471.1800,468.1700,468.7900,90315933,,,,,,,
|
||||
SPY YM94G4IBZOFA|SPY R735QTJ8XC9X,SPY 240930C00401000,88.9300,88.9300,84.9950,85.7100,0,42,0.1906751,0.8395376,0.0033206,0.9109065,-0.0277559,-0.1929455
|
||||
SPY YEV9QVQXAB52|SPY R735QTJ8XC9X,SPY 240104C00402000,70.9600,70.9600,66.0550,66.8950,0,1,0.0000001,1,0,0,0,0
|
||||
SPY YEW96Z43D2AU|SPY R735QTJ8XC9X,SPY 240105C00402000,70.9800,70.9800,66.2000,67.0550,0,2,0.9961277,0.9986427,0.0002028,0.0011969,-0.0564078,-0.0004561
|
||||
SPY YEV9QVR38N6U|SPY R735QTJ8XC9X,SPY 240104C00403000,69.9200,69.9200,65.0600,65.8600,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96Z49BECM|SPY R735QTJ8XC9X,SPY 240105C00403000,69.9750,69.9750,65.1300,65.9800,0,1,0.9811561,0.9986254,0.0002084,0.0012009,-0.0557766,-0.0004520
|
||||
SPY YEV9QVR96Z8M|SPY R735QTJ8XC9X,SPY 240104C00404000,68.9200,68.9200,64.0600,64.8700,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96Z4F9QEE|SPY R735QTJ8XC9X,SPY 240105C00404000,68.9850,68.9850,64.1300,64.9900,0,6,0.9662217,0.9986076,0.0002143,0.0012049,-0.0551323,-0.0004477
|
||||
SPY YEV9QVRF5BAE|SPY R735QTJ8XC9X,SPY 240104C00405000,67.8950,67.8950,63.0600,63.8750,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96Z4L82G6|SPY R735QTJ8XC9X,SPY 240105C00405000,67.9800,67.9800,63.1350,63.9900,0,2,0.9513244,0.9985892,0.0002204,0.0012091,-0.0544908,-0.0004408
|
||||
SPY YEV9QVRL3NC6|SPY R735QTJ8XC9X,SPY 240104C00406000,66.9300,66.9300,62.0650,62.8550,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96Z4R6EHY|SPY R735QTJ8XC9X,SPY 240105C00406000,66.9650,66.9650,62.1350,62.9700,1,1,0.9364639,0.9985704,0.0002267,0.0012133,-0.0538141,-0.0004393
|
||||
SPY YEV9QVRR1ZDY|SPY R735QTJ8XC9X,SPY 240104C00407000,65.9250,65.9250,61.0350,61.9600,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96Z4X4QJQ|SPY R735QTJ8XC9X,SPY 240105C00407000,65.9700,65.9700,61.1300,62.0150,0,2,0.9216401,0.9985510,0.0002334,0.0012173,-0.0531547,-0.0004358
|
||||
SPY YEV9QVRX0BFQ|SPY R735QTJ8XC9X,SPY 240104C00408000,64.9500,64.9500,60.0550,60.8650,0,1,0.0000001,1,0,0,0,0
|
||||
SPY YEW96Z5332LI|SPY R735QTJ8XC9X,SPY 240105C00408000,65.0150,65.0150,60.1350,61.0300,0,,0.9068528,0.9985310,0.0002403,0.0012213,-0.0524903,-0.0004302
|
||||
SPY YEV9QVS2YNHI|SPY R735QTJ8XC9X,SPY 240104C00409000,63.9600,63.9600,59.0650,60.0200,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96Z591ENA|SPY R735QTJ8XC9X,SPY 240105C00409000,64.0250,64.0250,59.1350,60.0400,0,1,0.8921019,0.9985105,0.0002476,0.0012254,-0.0518212,-0.0004259
|
||||
SPY YEV9QU381MH2|SPY R735QTJ8XC9X,SPY 240104C00410000,62.9650,62.9650,58.0700,58.9850,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96XGE4DMU|SPY R735QTJ8XC9X,SPY 240105C00410000,62.9550,62.9550,58.1250,59.0000,1,7,0.8773871,0.9984893,0.0002552,0.0012295,-0.0511404,-0.0004220
|
||||
SPY YEV9QVSEVBL2|SPY R735QTJ8XC9X,SPY 240104C00411000,61.9300,61.9300,57.0600,57.9550,0,1,0.0000001,1,0,0,0,0
|
||||
SPY YEW96Z5KY2QU|SPY R735QTJ8XC9X,SPY 240105C00411000,61.9900,61.9900,57.1350,58.0200,0,1,0.8627082,0.9984675,0.0002631,0.0012336,-0.0504563,-0.0004170
|
||||
|
38
Data/option/usa/universes/spy/20240104.csv
Normal file
38
Data/option/usa/universes/spy/20240104.csv
Normal file
@@ -0,0 +1,38 @@
|
||||
#symbol_id,symbol_value,open,high,low,close,volume,open_interest,implied_volatility,delta,gamma,vega,theta,rho
|
||||
SPY R735QTJ8XC9X,SPY,468.3500,470.9600,467.0500,467.2800,69508521,,,,,,,
|
||||
SPY Z8DP3QTE6IJQ|SPY R735QTJ8XC9X,SPY 261218C00265000,224.5000,231.4700,219.4200,223.5000,0,,0.2530959,0.9887201,0.0011566,0.2251360,-0.0004415,-0.1629460
|
||||
SPY YEW96YPPDY06|SPY R735QTJ8XC9X,SPY 240105C00315000,153.9250,156.0600,151.6950,152.3050,0,,0.0000001,1,0,0,0,0
|
||||
SPY Z8DP3R1NV90M|SPY R735QTJ8XC9X,SPY 261218C00315000,184.2500,189.0800,181.2300,183.0000,0,1,0.2251698,0.8960158,0.0017944,1.0649696,-0.0056454,-0.7803062
|
||||
SPY YEW96XEWJD6U|SPY R735QTJ8XC9X,SPY 240105C00320000,148.8650,151.0650,146.6950,147.3100,0,,0.0000001,1,0,0,0,0
|
||||
SPY Z8DP3PQV0O7A|SPY R735QTJ8XC9X,SPY 261218C00320000,180.0000,185.3800,177.3300,179.5000,0,1,0.2185436,0.8913955,0.0018672,1.1200809,-0.0063467,-0.7841679
|
||||
SPY YEW96YRCXAHY|SPY R735QTJ8XC9X,SPY 240105C00325000,143.8700,146.0650,141.7000,142.3350,0,,0.0000001,1,0,0,0,0
|
||||
SPY Z8DP3R3BELIE|SPY R735QTJ8XC9X,SPY 261218C00325000,176.0000,181.4350,173.4350,175.7500,0,,0.2171176,0.8800423,0.0018949,1.1885142,-0.0071088,-0.8503416
|
||||
SPY YEW96YRIVMJQ|SPY R735QTJ8XC9X,SPY 240105C00326000,142.9450,145.0650,140.7600,141.3300,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96YROTYLI|SPY R735QTJ8XC9X,SPY 240105C00327000,141.8700,144.0700,139.7600,140.3650,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96YRUSANA|SPY R735QTJ8XC9X,SPY 240105C00328000,140.8750,143.0700,138.8050,139.3300,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96YS0QMP2|SPY R735QTJ8XC9X,SPY 240105C00329000,139.8650,142.0700,137.7650,138.3100,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96XF2HP8M|SPY R735QTJ8XC9X,SPY 240105C00330000,138.8800,141.0700,136.7050,137.3850,0,7,0.0000001,1,0,0,0,0
|
||||
SPY Z8DP3PR0Z092|SPY R735QTJ8XC9X,SPY 261218C00330000,172.2500,177.5050,169.6050,171.7500,0,,0.2073876,0.8793950,0.0019980,1.1983140,-0.0068509,-0.8130756
|
||||
SPY YEW96YSCNASM|SPY R735QTJ8XC9X,SPY 240105C00331000,137.8200,140.0700,135.7650,136.3550,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96YSILMUE|SPY R735QTJ8XC9X,SPY 240105C00332000,136.8700,139.0700,134.7050,135.4050,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96YSOJYW6|SPY R735QTJ8XC9X,SPY 240105C00333000,135.8800,138.0700,133.7100,134.3150,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96YSUIAXY|SPY R735QTJ8XC9X,SPY 240105C00334000,134.8750,137.0750,132.7050,133.3350,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96YT0GMZQ|SPY R735QTJ8XC9X,SPY 240105C00335000,133.8850,136.0750,131.7650,132.3700,0,,0.0000001,1,0,0,0,0
|
||||
SPY Z8DP3R4YXY06|SPY R735QTJ8XC9X,SPY 261218C00335000,168.7500,173.5900,165.7650,167.5000,0,,0.2154184,0.8551619,0.0019415,1.3505771,-0.0080640,-0.9337619
|
||||
SPY YEW96YT6EZ1I|SPY R735QTJ8XC9X,SPY 240105C00336000,132.8900,135.0750,130.7050,131.3550,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96YTCDB3A|SPY R735QTJ8XC9X,SPY 240105C00337000,132.1100,134.0750,129.7100,130.3600,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96YTIBN52|SPY R735QTJ8XC9X,SPY 240105C00338000,130.8850,133.0750,128.7100,129.3650,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96YTO9Z6U|SPY R735QTJ8XC9X,SPY 240105C00339000,129.8750,132.0750,127.7100,128.3650,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96XF8G1AE|SPY R735QTJ8XC9X,SPY 240105C00340000,128.7650,131.0800,126.9050,127.3700,0,,0.0000001,1,0,0,0,0
|
||||
SPY YYFADOLR2PVQ|SPY R735QTJ8XC9X,SPY 251219C00340000,155.5000,158.0550,153.2450,154.2500,0,41,0.2213402,0.8793751,0.0019453,1.0481947,-0.0100939,-0.6165659
|
||||
SPY YZ6UWAUH7UDI|SPY R735QTJ8XC9X,SPY 260116C00340000,155.7500,158.0000,153.6800,154.5050,0,5,0.2217299,0.8745455,0.0019359,1.1233462,-0.0105301,-0.6370790
|
||||
SPY Z8DP3PR6XCAU|SPY R735QTJ8XC9X,SPY 261218C00340000,164.5000,169.9350,161.9350,164.0000,0,25,0.2046498,0.8550012,0.0020583,1.3530355,-0.0077142,-0.8852939
|
||||
SPY YEW96YU06NAE|SPY R735QTJ8XC9X,SPY 240105C00341000,128.0850,130.0800,125.7100,126.3350,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96YU64ZC6|SPY R735QTJ8XC9X,SPY 240105C00342000,126.8850,129.0800,124.7700,125.3650,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96YUC3BDY|SPY R735QTJ8XC9X,SPY 240105C00343000,125.8900,128.0800,123.7100,124.3750,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96YUI1NFQ|SPY R735QTJ8XC9X,SPY 240105C00344000,125.1100,127.0800,122.7750,123.3250,0,,0.0000001,1,0,0,0,0
|
||||
SPY YEW96YUNZZHI|SPY R735QTJ8XC9X,SPY 240105C00345000,123.8700,126.0800,121.7150,122.3150,0,,0.0000001,1,0,0,0,0
|
||||
SPY YTG30PGGPCVA|SPY R735QTJ8XC9X,SPY 250620C00345000,145.7500,150.1800,141.8550,144.5050,0,7,0.2244864,0.8948588,0.0019484,0.8623178,-0.0128214,-0.4456611
|
||||
SPY YYFADQ16MO2U|SPY R735QTJ8XC9X,SPY 251219C00345000,151.2500,153.9500,149.1550,150.2500,0,30,0.2165133,0.8713837,0.0020113,1.1328990,-0.0117288,-0.6071148
|
||||
SPY YZ6UWC9WRSKM|SPY R735QTJ8XC9X,SPY 260116C00345000,151.5000,153.9900,149.6850,150.5000,0,3,0.2120927,0.8724199,0.0020376,1.1392599,-0.0109666,-0.6088566
|
||||
SPY Z8DP3R6MHAHY|SPY R735QTJ8XC9X,SPY 261218C00345000,160.7500,166.0400,158.1650,160.0000,0,,0.2081333,0.8363435,0.0020331,1.5416429,-0.0095248,-0.9302435
|
||||
|
21
Data/option/usa/universes/spy/20240105.csv
Normal file
21
Data/option/usa/universes/spy/20240105.csv
Normal file
@@ -0,0 +1,21 @@
|
||||
#symbol_id,symbol_value,open,high,low,close,volume,open_interest,implied_volatility,delta,gamma,vega,theta,rho
|
||||
SPY R735QTJ8XC9X,SPY,467.4400,470.4400,466.4300,467.9200,74304611,,,,,,,
|
||||
SPY YH5ZAQHFMCPY|SPY R735QTJ8XC9X,SPY 240328C00404000,69.0350,72.4550,67.4800,69.3250,0,108,0.2033026,0.9414430,0.0028436,0.2523082,-0.0274981,-0.0470943
|
||||
SPY YJOKFC4YNRHI|SPY R735QTJ8XC9X,SPY 240628C00404000,75.4850,78.6800,74.2850,75.3250,40,136,0.1896656,0.8763471,0.0034973,0.6400785,-0.0307813,-0.1120247
|
||||
SPY YM94G4ITUOKM|SPY R735QTJ8XC9X,SPY 240930C00404000,81.6150,84.3700,80.1550,81.7550,0,4,0.1845833,0.8332365,0.0035214,0.9163969,-0.0273540,-0.1833526
|
||||
SPY YEZ7J983GBXI|SPY R735QTJ8XC9X,SPY 240108C00405000,62.4200,65.6200,61.3050,63.1200,4,,0.6647743,0.9987164,0.0002343,0.0015368,-0.0229803,-0.0006487
|
||||
SPY YF06ZCL9J33A|SPY R735QTJ8XC9X,SPY 240109C00405000,62.4800,65.7300,61.3700,63.0350,0,,0.5427059,0.9988816,0.0002437,0.0016609,-0.0126945,-0.0007335
|
||||
SPY YEZ7J989ENZA|SPY R735QTJ8XC9X,SPY 240108C00406000,61.4250,64.6650,60.3050,62.1250,0,,0.6542663,0.9986965,0.0002410,0.0015457,-0.0227714,-0.0006381
|
||||
SPY YJOKFC5AKFL2|SPY R735QTJ8XC9X,SPY 240628C00406000,73.6800,76.8550,72.5050,74.1600,0,107,0.1872376,0.8711568,0.0036292,0.6461438,-0.0307593,-0.1106796
|
||||
SPY YEZ7J98FD012|SPY R735QTJ8XC9X,SPY 240108C00407000,60.2750,63.6600,59.3000,61.2200,1,2,0.6437842,0.9986761,0.0002480,0.0015545,-0.0225352,-0.0006382
|
||||
SPY YF06ZCLLFR6U|SPY R735QTJ8XC9X,SPY 240109C00407000,60.4500,63.7350,59.3750,61.0400,0,,0.5255675,0.9988405,0.0002579,0.0016897,-0.0125766,-0.0007257
|
||||
SPY YEZ7J98LBC2U|SPY R735QTJ8XC9X,SPY 240108C00408000,59.4350,62.6100,58.3000,60.1700,1,1,0.6333279,0.9986551,0.0002553,0.0015633,-0.0223045,-0.0006369
|
||||
SPY YF06ZCLRE38M|SPY R735QTJ8XC9X,SPY 240109C00408000,59.4600,62.7750,58.3750,60.2550,0,,0.5170300,0.9988191,0.0002654,0.0017036,-0.0125052,-0.0007346
|
||||
SPY YEZ7J98R9O4M|SPY R735QTJ8XC9X,SPY 240108C00409000,58.4400,61.6550,57.3050,59.1900,0,,0.6228974,0.9986334,0.0002629,0.0015723,-0.0220815,-0.0006281
|
||||
SPY YF06ZCLXCFAE|SPY R735QTJ8XC9X,SPY 240109C00409000,58.4500,61.7950,57.3800,59.2550,0,,0.5085135,0.9987970,0.0002733,0.0017175,-0.0124366,-0.0007292
|
||||
SPY YEZ7J7JWCN46|SPY R735QTJ8XC9X,SPY 240108C00410000,57.5400,60.6650,56.3050,58.1850,2,1,0.6124924,0.9986110,0.0002710,0.0015815,-0.0218439,-0.0006191
|
||||
SPY YF06ZAX2FE9Y|SPY R735QTJ8XC9X,SPY 240109C00410000,57.4800,60.7750,56.3700,58.2550,0,,0.5000178,0.9987742,0.0002814,0.0017323,-0.0123604,-0.0007172
|
||||
SPY YEZ7J9936C86|SPY R735QTJ8XC9X,SPY 240108C00411000,56.4450,59.6550,55.3050,57.1850,1,1,0.6021128,0.9985878,0.0002794,0.0015903,-0.0215896,-0.0006170
|
||||
SPY YF06ZCM993DY|SPY R735QTJ8XC9X,SPY 240109C00411000,56.4500,59.8050,55.3800,57.0150,0,,0.4915429,0.9987506,0.0002899,0.0017470,-0.0122585,-0.0007270
|
||||
SPY YEZ7J9994O9Y|SPY R735QTJ8XC9X,SPY 240108C00412000,55.4450,58.6550,54.3100,56.1850,1,1,0.5917585,0.9985640,0.0002883,0.0015994,-0.0213436,-0.0006120
|
||||
SPY YF06ZCMF7FFQ|SPY R735QTJ8XC9X,SPY 240109C00412000,55.4850,58.7900,54.3800,56.0250,0,,0.5018704,0.9979429,0.0003795,0.0029132,-0.0218174,-0.0009296.0025941
|
||||
|
22
Data/option/usa/universes/spy/20240108.csv
Normal file
22
Data/option/usa/universes/spy/20240108.csv
Normal file
@@ -0,0 +1,22 @@
|
||||
#symbol_id,symbol_value,open,high,low,close,volume,open_interest,implied_volatility,delta,gamma,vega,theta,rho
|
||||
SPY R735QTJ8XC9X,SPY,468.3800,474.7400,468.3300,474.6000,68277421,,,,,,,
|
||||
SPY YM94G4ITUOKM|SPY R735QTJ8XC9X,SPY 240930C00404000,81.7550,88.0800,81.4400,87.3550,0,4,0.1857914,0.8549470,0.0032380,0.8669661,-0.0234441,-0.1890177
|
||||
SPY YF06ZCL9J33A|SPY R735QTJ8XC9X,SPY 240109C00405000,63.0350,70.0000,62.6550,69.5900,0,,0.0000001,1,0,0,0,0
|
||||
SPY YF16FFYFLU92|SPY R735QTJ8XC9X,SPY 240110C00405000,63.0800,70.0400,62.8150,69.6200,3,3,1.0243866,0.9986906,0.0001882,0.0012008,-0.0551000,-0.0004651
|
||||
SPY YF06ZCLFHF52|SPY R735QTJ8XC9X,SPY 240109C00406000,62.2650,69.0300,61.9450,68.6850,0,,0.0000001,1,0,0,0,0
|
||||
SPY YF16FFYLK6AU|SPY R735QTJ8XC9X,SPY 240110C00406000,62.0950,69.0200,61.7150,68.6350,0,1,1.0097577,0.9986715,0.0001936,0.0012056,-0.0575529,-0.0004610
|
||||
SPY YF06ZCLLFR6U|SPY R735QTJ8XC9X,SPY 240109C00407000,61.0400,68.0300,60.7800,67.5600,0,,0.0000001,1,0,0,0,0
|
||||
SPY YF16FFYRIICM|SPY R735QTJ8XC9X,SPY 240110C00407000,61.0950,68.0400,60.8150,67.6150,0,,0.9949344,0.9986550,0.0001988,0.0012098,-0.0569222,-0.0004568
|
||||
SPY YF06ZCLRE38M|SPY R735QTJ8XC9X,SPY 240109C00408000,60.2550,66.9650,59.9350,66.5600,0,,0.0000001,1,0,0,0,0
|
||||
SPY YF16FFYXGUEE|SPY R735QTJ8XC9X,SPY 240110C00408000,60.0950,66.9950,59.8050,66.6200,0,,0.9801477,0.9986380,0.0002043,0.0012139,-0.0562868,-0.0004553
|
||||
SPY YF06ZCLXCFAE|SPY R735QTJ8XC9X,SPY 240109C00409000,59.2550,66.0350,58.9500,65.5350,0,,0.0000001,1,0,0,0,0
|
||||
SPY YF16FFZ3F6G6|SPY R735QTJ8XC9X,SPY 240110C00409000,59.0950,66.0350,58.8100,65.6200,0,,0.9653973,0.9986206,0.0002099,0.0012179,-0.0556558,-0.0004506
|
||||
SPY YF06ZAX2FE9Y|SPY R735QTJ8XC9X,SPY 240109C00410000,58.2550,64.9650,57.9500,64.5600,1,1,0.0000001,1,0,0,0,0
|
||||
SPY YF16FEA8I5FQ|SPY R735QTJ8XC9X,SPY 240110C00410000,58.1000,65.0200,57.8150,64.6400,0,,0.9506830,0.9986027,0.0002158,0.0012220,-0.0550140,-0.0004463
|
||||
SPY Z8DP3PSCLONA|SPY R735QTJ8XC9X,SPY 261218C00410000,114.0000,119.6650,111.1650,118.9700,0,5,0.1779143,0.6985475,0.0025528,2.3278853,-0.0144928,-0.8485138
|
||||
SPY YF06ZCM993DY|SPY R735QTJ8XC9X,SPY 240109C00411000,57.0150,64.0300,56.7350,63.5700,0,,0.0000001,1,0,0,0,0
|
||||
SPY YF16FFZFBUJQ|SPY R735QTJ8XC9X,SPY 240110C00411000,57.1350,64.0200,56.8650,63.6400,0,,0.9360046,0.9985843,0.0002220,0.0012262,-0.0543628,-0.0004408
|
||||
SPY YF06ZCMF7FFQ|SPY R735QTJ8XC9X,SPY 240109C00412000,56.0250,63.0200,55.7450,62.5900,0,,0.0000001,1,0,0,0,0
|
||||
SPY YF16FFZLA6LI|SPY R735QTJ8XC9X,SPY 240110C00412000,56.2950,63.0500,56.0150,62.6250,0,,0.9213621,0.9985653,0.0002284,0.0012304,-0.0536868,-0.0004385
|
||||
SPY YF06ZCML5RHI|SPY R735QTJ8XC9X,SPY 240109C00413000,55.0150,62.0300,54.7350,61.5750,0,,0.0000001,1,0,0,0,0
|
||||
SPY YF16FFZR8INA|SPY R735QTJ8XC9X,SPY 240110C00413000,55.1000,62.0250,54.8250,61.6200,0,,0.9067552,0.9985458,0.0002351,0.0012345,-0.0530308,-0.0004344
|
||||
|
25
Data/option/usa/universes/spy/20240109.csv
Normal file
25
Data/option/usa/universes/spy/20240109.csv
Normal file
@@ -0,0 +1,25 @@
|
||||
#symbol_id,symbol_value,open,high,low,close,volume,open_interest,implied_volatility,delta,gamma,vega,theta,rho
|
||||
SPY R735QTJ8XC9X,SPY,471.8800,474.9300,471.3550,473.8800,59621043,,,,,,,
|
||||
SPY YM94G4ITUOKM|SPY R735QTJ8XC9X,SPY 240930C00404000,87.3550,88.0450,84.0350,86.5800,0,4,0.1840764,0.8551702,0.0032760,0.8618596,-0.0232696,-0.1858383
|
||||
SPY YF16FFYFLU92|SPY R735QTJ8XC9X,SPY 240110C00405000,69.6200,69.9700,65.8350,68.9000,0,3,0.0000001,1,0,0,0,0
|
||||
SPY YF25VJBLOLEU|SPY R735QTJ8XC9X,SPY 240111C00405000,69.8400,70.5600,66.0950,69.2100,0,,1.0155835,0.9986762,0.0001921,0.0012024,-0.0577236,-0.0004630
|
||||
SPY YF16FFYLK6AU|SPY R735QTJ8XC9X,SPY 240110C00406000,68.6350,68.9550,64.8400,67.9050,0,1,0.0000001,1,0,0,0,0
|
||||
SPY YF25VJBRMXGM|SPY R735QTJ8XC9X,SPY 240111C00406000,68.8200,69.5450,65.0950,68.2100,0,1,1.0007235,0.9986598,0.0001973,0.0012066,-0.0571013,-0.0004564
|
||||
SPY YF16FFYRIICM|SPY R735QTJ8XC9X,SPY 240110C00407000,67.6150,67.9700,63.8950,66.9100,0,,0.0000001,1,0,0,0,0
|
||||
SPY YF25VJBXL9IE|SPY R735QTJ8XC9X,SPY 240111C00407000,67.9500,68.3250,64.1000,67.2300,0,,0.9859002,0.9986430,0.0002027,0.0012108,-0.0564684,-0.0004566
|
||||
SPY YF35BMP3O0O6|SPY R735QTJ8XC9X,SPY 240112C00407000,67.9450,68.4000,64.1600,67.2500,2,3,0.7235212,0.9981417,0.0002706,0.0022215,-0.0275138,-0.0008316
|
||||
SPY YF16FFYXGUEE|SPY R735QTJ8XC9X,SPY 240110C00408000,66.6200,66.9700,62.8400,65.9150,0,,0.0000001,1,0,0,0,0
|
||||
SPY YF25VJC3JLK6|SPY R735QTJ8XC9X,SPY 240111C00408000,66.9400,67.3050,63.1000,66.2150,0,,0.9711134,0.9986257,0.0002083,0.0012147,-0.0558355,-0.0004526
|
||||
SPY YF35BMP9MCPY|SPY R735QTJ8XC9X,SPY 240112C00408000,66.9550,67.3700,63.1650,66.2550,0,1,0.7130112,0.9981067,0.0002779,0.0023266,-0.0272431,-0.0008218
|
||||
SPY YF16FFZ3F6G6|SPY R735QTJ8XC9X,SPY 240110C00409000,65.6200,65.9700,61.8950,64.9150,0,,0.0000001,1,0,0,0,0
|
||||
SPY YF25VJC9HXLY|SPY R735QTJ8XC9X,SPY 240111C00409000,65.9500,66.3650,62.1000,65.2350,0,,0.9563629,0.9986079,0.0002141,0.0012188,-0.0551911,-0.0004483
|
||||
SPY YF16FEA8I5FQ|SPY R735QTJ8XC9X,SPY 240110C00410000,64.6400,64.9600,60.8600,63.9100,1,1,0.0000001,1,0,0,0,0
|
||||
SPY YF25VHNEKWLI|SPY R735QTJ8XC9X,SPY 240111C00410000,64.9600,65.3050,61.1000,64.2350,0,119,0.9416485,0.9985897,0.0002202,0.0012230,-0.0545531,-0.0004414
|
||||
SPY YF16FFZFBUJQ|SPY R735QTJ8XC9X,SPY 240110C00411000,63.6400,63.9750,59.8400,62.9100,0,,0.0000001,1,0,0,0,0
|
||||
SPY YF25VJCLELPI|SPY R735QTJ8XC9X,SPY 240111C00411000,63.9550,64.3200,60.1050,63.1900,0,,0.9269701,0.9985709,0.0002265,0.0012273,-0.0538773,-0.0004396
|
||||
SPY YF16FFZLA6LI|SPY R735QTJ8XC9X,SPY 240110C00412000,62.6250,62.9600,58.8400,61.9250,0,,0.0000001,1,0,0,0,0
|
||||
SPY YF25VJCRCXRA|SPY R735QTJ8XC9X,SPY 240111C00412000,62.9550,63.3100,59.1050,62.2350,0,,0.9123275,0.9985515,0.0002331,0.0012313,-0.0532144,-0.0004361
|
||||
SPY YF35BMPXFOX2|SPY R735QTJ8XC9X,SPY 240112C00412000,62.9450,63.4000,59.1700,62.2600,0,,0.6704539,0.9979796,0.0003110,0.0025083,-0.0349754,-0.0007904
|
||||
SPY YFA1GAA3YZ1I|SPY R735QTJ8XC9X,SPY 240119C00412000,63.3450,63.8050,59.6450,62.6500,0,886,0.3608598,0.9945798,0.0007279,0.0111471,-0.0190700,-0.0034017
|
||||
SPY YF16FFZR8INA|SPY R735QTJ8XC9X,SPY 240110C00413000,61.6200,61.9600,57.8450,60.9200,0,,0.0000001,1,0,0,0,0
|
||||
SPY YF25VJCXB9T2|SPY R735QTJ8XC9X,SPY 240111C00413000,61.9650,62.3200,58.1050,61.2250,0,,0.8977205,0.9985316,0.0002401,0.0012353,-0.0525510,-0.0004308
|
||||
|
@@ -4,6 +4,9 @@ market,symbol,type,description,quote_currency,contract_multiplier,minimum_price_
|
||||
# Use # signs for comments
|
||||
#
|
||||
|
||||
eurex,FESX,future,EURO STOXX 50 Index Futures,EUR,10,1,1,,1
|
||||
eurex,[*],index,,EUR,1,0.01,1
|
||||
|
||||
fxcm,AU200AUD,cfd,S&P/ASX index of Australian listed shares,USD,0.1,0.1,1
|
||||
fxcm,DE10YBEUR,cfd,Euro-Bund,EUR,10,0.001,1
|
||||
fxcm,XCUUSD,cfd,Copper,USD,100,0.0001,1
|
||||
|
||||
|
@@ -48,6 +48,7 @@ namespace QuantConnect.Lean.Engine
|
||||
private IAlgorithm _algorithm;
|
||||
private readonly object _lock;
|
||||
private readonly bool _liveMode;
|
||||
private CancellationTokenSource _cancellationTokenSource;
|
||||
|
||||
/// <summary>
|
||||
/// Publicly accessible algorithm status
|
||||
@@ -111,14 +112,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 +611,15 @@ namespace QuantConnect.Lean.Engine
|
||||
{
|
||||
_algorithm.SetStatus(state);
|
||||
}
|
||||
|
||||
if (state == AlgorithmStatus.Deleted)
|
||||
{
|
||||
if (!_cancellationTokenSource.IsCancellationRequested)
|
||||
{
|
||||
// if the algorithm was deleted or stopped, let's give the algorithm a few seconds to shutdown and cancel it out
|
||||
_cancellationTokenSource.CancelAfter(TimeSpan.FromSeconds(5));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,11 +392,18 @@ namespace QuantConnect.Research
|
||||
{
|
||||
// canonical symbol, lets find the contracts
|
||||
var option = Securities[symbol] as Option;
|
||||
var resolutionToUseForUnderlying = resolution ?? SubscriptionManager.SubscriptionDataConfigService
|
||||
.GetSubscriptionDataConfigs(symbol)
|
||||
.GetHighestResolution();
|
||||
if (!Securities.ContainsKey(symbol.Underlying))
|
||||
{
|
||||
var resolutionToUseForUnderlying = resolution ?? SubscriptionManager.SubscriptionDataConfigService
|
||||
.GetSubscriptionDataConfigs(symbol.Underlying)
|
||||
.Select(x => (Resolution?)x.Resolution)
|
||||
.DefaultIfEmpty(null)
|
||||
.Min();
|
||||
if (!resolutionToUseForUnderlying.HasValue && UniverseManager.TryGetValue(symbol, out var universe))
|
||||
{
|
||||
resolutionToUseForUnderlying = universe.UniverseSettings.Resolution;
|
||||
}
|
||||
|
||||
if (symbol.Underlying.SecurityType == SecurityType.Equity)
|
||||
{
|
||||
// only add underlying if not present
|
||||
|
||||
@@ -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
120
Tests/Api/CommandTests.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
129
Tests/Common/Commands/CallbackCommandTests.cs
Normal file
129
Tests/Common/Commands/CallbackCommandTests.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,16 +39,16 @@ namespace QuantConnect.Tests.Common.Securities
|
||||
var filter = new FuncSecurityDerivativeFilter<Symbol>(func);
|
||||
var symbols = new[]
|
||||
{
|
||||
Symbol.CreateFuture("SPY", Market.USA, time.AddDays(0)), // 0
|
||||
Symbol.CreateFuture("SPY", Market.USA, time.AddDays(1)), // 1
|
||||
Symbol.CreateFuture("SPY", Market.USA, time.AddDays(2)), // 2
|
||||
Symbol.CreateFuture("SPY", Market.USA, time.AddDays(3)), // 3
|
||||
Symbol.CreateFuture("SPY", Market.USA, time.AddDays(4)), // 4
|
||||
Symbol.CreateFuture("SPY", Market.USA, time.AddDays(5)), // 5
|
||||
Symbol.CreateFuture("SPY", Market.USA, time.AddDays(6)), // 6
|
||||
Symbol.CreateFuture("SPY", Market.USA, time.AddDays(7)), // 7
|
||||
Symbol.CreateFuture("SPY", Market.USA, time.AddDays(8)), // 8
|
||||
Symbol.CreateFuture("SPY", Market.USA, time.AddDays(9)), // 9
|
||||
Symbol.CreateFuture("SPY", Market.CME, time.AddDays(0)), // 0
|
||||
Symbol.CreateFuture("SPY", Market.CME, time.AddDays(1)), // 1
|
||||
Symbol.CreateFuture("SPY", Market.CME, time.AddDays(2)), // 2
|
||||
Symbol.CreateFuture("SPY", Market.CME, time.AddDays(3)), // 3
|
||||
Symbol.CreateFuture("SPY", Market.CME, time.AddDays(4)), // 4
|
||||
Symbol.CreateFuture("SPY", Market.CME, time.AddDays(5)), // 5
|
||||
Symbol.CreateFuture("SPY", Market.CME, time.AddDays(6)), // 6
|
||||
Symbol.CreateFuture("SPY", Market.CME, time.AddDays(7)), // 7
|
||||
Symbol.CreateFuture("SPY", Market.CME, time.AddDays(8)), // 8
|
||||
Symbol.CreateFuture("SPY", Market.CME, time.AddDays(9)), // 9
|
||||
};
|
||||
|
||||
var filtered = filter.Filter(new FutureFilterUniverse(symbols, time)).ToList();
|
||||
|
||||
@@ -18,9 +18,12 @@ using System;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Python.Runtime;
|
||||
using QuantConnect.Data;
|
||||
using QuantConnect.Data.Market;
|
||||
using QuantConnect.Data.UniverseSelection;
|
||||
using QuantConnect.Securities;
|
||||
using QuantConnect.Securities.Index;
|
||||
using QuantConnect.Securities.Option;
|
||||
|
||||
namespace QuantConnect.Tests.Common.Securities
|
||||
{
|
||||
@@ -45,7 +48,11 @@ namespace QuantConnect.Tests.Common.Securities
|
||||
|
||||
var underlyingScaleFactor = SymbolPropertiesDatabase.FromDataFolder().GetSymbolProperties(Market.USA, symbols.First(), symbols.First().SecurityType, "USD").StrikeMultiplier;
|
||||
var data = symbols.Select(x => new OptionUniverse() { Symbol = x });
|
||||
var filterUniverse = new OptionFilterUniverse(data, underlying, underlyingScaleFactor);
|
||||
|
||||
var canonical = symbols[0].Canonical;
|
||||
var option = CreateOptionSecurity(canonical);
|
||||
|
||||
var filterUniverse = new OptionFilterUniverse(option, data, underlying, underlyingScaleFactor);
|
||||
var filtered = filter.Filter(filterUniverse).ToList();
|
||||
Assert.AreEqual(filteredNumber, filtered.Count);
|
||||
Assert.AreEqual(symbols[3], filtered[0].Symbol);
|
||||
@@ -89,8 +96,11 @@ namespace QuantConnect.Tests.Common.Securities
|
||||
Symbol.CreateOption("SPY", Market.USA, OptionStyle.American, OptionRight.Put, 20, expiry), // 9
|
||||
};
|
||||
|
||||
var canonical = symbols[0].Canonical;
|
||||
var option = CreateOptionSecurity(canonical);
|
||||
|
||||
var data = symbols.Select(x => new OptionUniverse() { Symbol = x });
|
||||
var filterUniverse = new OptionFilterUniverse(data, underlying);
|
||||
var filterUniverse = new OptionFilterUniverse(option, data, underlying);
|
||||
var filtered = filter.Filter(filterUniverse).ToList();
|
||||
Assert.AreEqual(underlyingPrice == 8 ? 5 : 4, filtered.Count);
|
||||
Assert.AreEqual(symbols[1], filtered[0].Symbol);
|
||||
@@ -133,8 +143,11 @@ namespace QuantConnect.Tests.Common.Securities
|
||||
Symbol.CreateOption("SPY", Market.USA, OptionStyle.American, OptionRight.Put, 20, expiry), // 9
|
||||
};
|
||||
|
||||
var canonical = symbols[0].Canonical;
|
||||
var option = CreateOptionSecurity(canonical);
|
||||
|
||||
var data = symbols.Select(x => new OptionUniverse() { Symbol = x });
|
||||
var filterUniverse = new OptionFilterUniverse(data, underlying);
|
||||
var filterUniverse = new OptionFilterUniverse(option, data, underlying);
|
||||
var filtered = filter.Filter(filterUniverse).ToList();
|
||||
Assert.AreEqual(3, filtered.Count);
|
||||
Assert.AreEqual(symbols[5], filtered[0].Symbol);
|
||||
@@ -164,8 +177,11 @@ namespace QuantConnect.Tests.Common.Securities
|
||||
Symbol.CreateOption("SPY", Market.USA, OptionStyle.American, OptionRight.Put, 20, expiry), // 1
|
||||
};
|
||||
|
||||
var canonical = symbols[0].Canonical;
|
||||
var option = CreateOptionSecurity(canonical);
|
||||
|
||||
var data = symbols.Select(x => new OptionUniverse() { Symbol = x });
|
||||
var filterUniverse = new OptionFilterUniverse(data, underlying);
|
||||
var filterUniverse = new OptionFilterUniverse(option, data, underlying);
|
||||
var filtered = filter.Filter(filterUniverse).ToList();
|
||||
Assert.AreEqual(0, filtered.Count);
|
||||
}
|
||||
@@ -200,8 +216,11 @@ namespace QuantConnect.Tests.Common.Securities
|
||||
Symbol.CreateOption("SPY", Market.USA, OptionStyle.American, OptionRight.Put, 20, expiry), // 9
|
||||
};
|
||||
|
||||
var canonical = symbols[0].Canonical;
|
||||
var option = CreateOptionSecurity(canonical);
|
||||
|
||||
var data = symbols.Select(x => new OptionUniverse() { Symbol = x });
|
||||
var filterUniverse = new OptionFilterUniverse(data, underlying);
|
||||
var filterUniverse = new OptionFilterUniverse(option, data, underlying);
|
||||
var filtered = filter.Filter(filterUniverse).ToList();
|
||||
Assert.AreEqual(3, filtered.Count);
|
||||
Assert.AreEqual(symbols[2], filtered[0].Symbol);
|
||||
@@ -231,8 +250,11 @@ namespace QuantConnect.Tests.Common.Securities
|
||||
Symbol.CreateOption("SPY", Market.USA, OptionStyle.American, OptionRight.Put, 20, expiry), // 1
|
||||
};
|
||||
|
||||
var canonical = symbols[0].Canonical;
|
||||
var option = CreateOptionSecurity(canonical);
|
||||
|
||||
var data = symbols.Select(x => new OptionUniverse() { Symbol = x });
|
||||
var filterUniverse = new OptionFilterUniverse(data, underlying);
|
||||
var filterUniverse = new OptionFilterUniverse(option, data, underlying);
|
||||
var filtered = filter.Filter(filterUniverse).ToList();
|
||||
Assert.AreEqual(0, filtered.Count);
|
||||
}
|
||||
@@ -252,8 +274,12 @@ namespace QuantConnect.Tests.Common.Securities
|
||||
var filter = new FuncSecurityDerivativeFilter<OptionUniverse>(func);
|
||||
var symbols = new Symbol[] { };
|
||||
|
||||
var underlyingSymbol = Symbol.Create("SPY", SecurityType.Equity, Market.USA);
|
||||
var canonical = Symbol.CreateCanonicalOption(underlyingSymbol);
|
||||
var option = CreateOptionSecurity(canonical);
|
||||
|
||||
var data = symbols.Select(x => new OptionUniverse() { Symbol = x });
|
||||
var filterUniverse = new OptionFilterUniverse(data, underlying);
|
||||
var filterUniverse = new OptionFilterUniverse(option, data, underlying);
|
||||
var filtered = filter.Filter(filterUniverse).ToList();
|
||||
Assert.AreEqual(0, filtered.Count);
|
||||
}
|
||||
@@ -285,8 +311,12 @@ namespace QuantConnect.Tests.Common.Securities
|
||||
Symbol.CreateOption("SPY", Market.USA, OptionStyle.American, OptionRight.Put, 10, time.AddDays(8)), // 8
|
||||
Symbol.CreateOption("SPY", Market.USA, OptionStyle.American, OptionRight.Put, 10, time.AddDays(9)), // 9
|
||||
};
|
||||
|
||||
var canonical = symbols[0].Canonical;
|
||||
var option = CreateOptionSecurity(canonical);
|
||||
|
||||
var data = symbols.Select(x => new OptionUniverse() { Symbol = x });
|
||||
var filterUniverse = new OptionFilterUniverse(data, underlying);
|
||||
var filterUniverse = new OptionFilterUniverse(option, data, underlying);
|
||||
var filtered = filter.Filter(filterUniverse).ToList();
|
||||
Assert.AreEqual(5, filtered.Count);
|
||||
Assert.AreEqual(symbols[3], filtered[0].Symbol);
|
||||
@@ -296,6 +326,39 @@ namespace QuantConnect.Tests.Common.Securities
|
||||
Assert.AreEqual(symbols[7], filtered[4].Symbol);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FiltersExpiryRangeAfterNonTradableDay()
|
||||
{
|
||||
var time = new DateTime(2023, 12, 30); // Saturday
|
||||
var underlying = new TradeBar { Value = 10m, Time = time.AddDays(-1), EndTime = time };
|
||||
|
||||
Func<OptionFilterUniverse, OptionFilterUniverse> universeFunc = universe => universe.Expiration(0, 5);
|
||||
|
||||
Func<IDerivativeSecurityFilterUniverse<OptionUniverse>, IDerivativeSecurityFilterUniverse<OptionUniverse>> func =
|
||||
universe => universeFunc(universe as OptionFilterUniverse);
|
||||
|
||||
var filter = new FuncSecurityDerivativeFilter<OptionUniverse>(func);
|
||||
var symbols = Enumerable.Range(3, 10)
|
||||
.SelectMany(i =>
|
||||
Enumerable.Range(1, 3).Select(j => Symbol.CreateOption("SPY", Market.USA, OptionStyle.American, OptionRight.Put, 10 * j, time.AddDays(i))))
|
||||
.ToArray();
|
||||
|
||||
var canonical = symbols[0].Canonical;
|
||||
var option = CreateOptionSecurity(canonical);
|
||||
|
||||
var data = symbols.Select(x => new OptionUniverse() { Symbol = x });
|
||||
var filterUniverse = new OptionFilterUniverse(option, data, underlying);
|
||||
var filtered = filter.Filter(filterUniverse).ToList();
|
||||
|
||||
// Expiry range is 0 to 5 days, so 6 days times 3 strikes per day
|
||||
var expectedSelections = 6 * 3;
|
||||
Assert.AreEqual(expectedSelections, filtered.Count);
|
||||
for (int i = 0; i < expectedSelections; i++)
|
||||
{
|
||||
Assert.AreEqual(symbols[i], filtered[i].Symbol);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FiltersOutWeeklys()
|
||||
{
|
||||
@@ -330,8 +393,11 @@ namespace QuantConnect.Tests.Common.Securities
|
||||
Symbol.CreateOption("SPY", Market.USA, OptionStyle.American, OptionRight.Put, 20, expiry8), // 9
|
||||
};
|
||||
|
||||
var canonical = symbols[0].Canonical;
|
||||
var option = CreateOptionSecurity(canonical);
|
||||
|
||||
var data = symbols.Select(x => new OptionUniverse() { Symbol = x });
|
||||
var filtered = filter.Filter(new OptionFilterUniverse(data, underlying)).ToList();
|
||||
var filtered = filter.Filter(new OptionFilterUniverse(option, data, underlying)).ToList();
|
||||
Assert.AreEqual(3, filtered.Count);
|
||||
Assert.AreEqual(symbols[5], filtered[0].Symbol);
|
||||
Assert.AreEqual(symbols[6], filtered[1].Symbol);
|
||||
@@ -372,8 +438,11 @@ namespace QuantConnect.Tests.Common.Securities
|
||||
Symbol.CreateOption("SPY", Market.USA, OptionStyle.American, OptionRight.Put, 20, expiry8), // 9
|
||||
};
|
||||
|
||||
var canonical = symbols[0].Canonical;
|
||||
var option = CreateOptionSecurity(canonical);
|
||||
|
||||
var data = symbols.Select(x => new OptionUniverse() { Symbol = x });
|
||||
var filtered = filter.Filter(new OptionFilterUniverse(data, underlying)).ToList();
|
||||
var filtered = filter.Filter(new OptionFilterUniverse(option, data, underlying)).ToList();
|
||||
Assert.AreEqual(3, filtered.Count);
|
||||
Assert.AreEqual(symbols[5], filtered[0].Symbol);
|
||||
Assert.AreEqual(symbols[6], filtered[1].Symbol);
|
||||
@@ -410,8 +479,11 @@ namespace QuantConnect.Tests.Common.Securities
|
||||
Symbol.CreateOption("SPY", Market.USA, OptionStyle.American, OptionRight.Put, 20, expiry4), // 9
|
||||
};
|
||||
|
||||
var canonical = symbols[0].Canonical;
|
||||
var option = CreateOptionSecurity(canonical);
|
||||
|
||||
var data = symbols.Select(x => new OptionUniverse() { Symbol = x });
|
||||
var filtered = filter.Filter(new OptionFilterUniverse(data, underlying)).ToList();
|
||||
var filtered = filter.Filter(new OptionFilterUniverse(option, data, underlying)).ToList();
|
||||
Assert.AreEqual(8, filtered.Count);
|
||||
}
|
||||
|
||||
@@ -444,8 +516,12 @@ namespace QuantConnect.Tests.Common.Securities
|
||||
Symbol.CreateOption("SPY", Market.USA, OptionStyle.American, OptionRight.Put, 15, expiry4), // 8
|
||||
Symbol.CreateOption("SPY", Market.USA, OptionStyle.American, OptionRight.Put, 20, expiry4), // 9
|
||||
};
|
||||
|
||||
var canonical = symbols[0].Canonical;
|
||||
var option = CreateOptionSecurity(canonical);
|
||||
|
||||
var data = symbols.Select(x => new OptionUniverse() { Symbol = x });
|
||||
var filterUniverse = new OptionFilterUniverse(data, underlying);
|
||||
var filterUniverse = new OptionFilterUniverse(option, data, underlying);
|
||||
var filtered = filter.Filter(filterUniverse).ToList();
|
||||
Assert.AreEqual(10, filtered.Count);
|
||||
}
|
||||
@@ -480,8 +556,11 @@ namespace QuantConnect.Tests.Common.Securities
|
||||
Symbol.CreateOption("SPY", Market.USA, OptionStyle.American, OptionRight.Put, 20, expiry4), // 9
|
||||
};
|
||||
|
||||
var canonical = symbols[0].Canonical;
|
||||
var option = CreateOptionSecurity(canonical);
|
||||
|
||||
var data = symbols.Select(x => new OptionUniverse() { Symbol = x });
|
||||
var filtered = filter.Filter(new OptionFilterUniverse(data, underlying)).ToList();
|
||||
var filtered = filter.Filter(new OptionFilterUniverse(option, data, underlying)).ToList();
|
||||
Assert.AreEqual(4, filtered.Count);
|
||||
}
|
||||
|
||||
@@ -515,8 +594,11 @@ namespace QuantConnect.Tests.Common.Securities
|
||||
Symbol.CreateOption("SPY", Market.USA, OptionStyle.American, OptionRight.Put, 20, expiry4), // 9
|
||||
};
|
||||
|
||||
var canonical = symbols[0].Canonical;
|
||||
var option = CreateOptionSecurity(canonical);
|
||||
|
||||
var data = symbols.Select(x => new OptionUniverse() { Symbol = x });
|
||||
var filterUniverse = new OptionFilterUniverse(data, underlying);
|
||||
var filterUniverse = new OptionFilterUniverse(option, data, underlying);
|
||||
var filtered = filter.Filter(filterUniverse).ToList();
|
||||
Assert.AreEqual(3, filtered.Count);
|
||||
}
|
||||
@@ -567,8 +649,11 @@ def set_filter(universe: OptionFilterUniverse) -> OptionFilterUniverse:
|
||||
Symbol.CreateOption("SPY", Market.USA, OptionStyle.American, OptionRight.Put, 20, expiry4), // 9
|
||||
};
|
||||
|
||||
var canonical = symbols[0].Canonical;
|
||||
var option = CreateOptionSecurity(canonical);
|
||||
|
||||
var data = symbols.Select(x => new OptionUniverse() { Symbol = x });
|
||||
var filterUniverse = new OptionFilterUniverse(data, underlying);
|
||||
var filterUniverse = new OptionFilterUniverse(option, data, underlying);
|
||||
var filtered = filter.Filter(filterUniverse).ToList();
|
||||
Assert.AreEqual(5, filtered.Count);
|
||||
}
|
||||
@@ -616,5 +701,40 @@ def set_filter(universe: OptionFilterUniverse) -> OptionFilterUniverse:
|
||||
new object[] {45.5m, CreateOptions("NDX", "NQX"), 5},
|
||||
new object[] {50m, CreateOptions("NDX", "NQX"), 6}
|
||||
};
|
||||
|
||||
private static Option CreateOptionSecurity(Symbol canonical)
|
||||
{
|
||||
var config = new SubscriptionDataConfig(typeof(TradeBar), canonical, Resolution.Minute, TimeZones.NewYork, TimeZones.NewYork, true, true, true);
|
||||
|
||||
if (canonical.SecurityType == SecurityType.Option)
|
||||
{
|
||||
return new Option(
|
||||
MarketHoursDatabase.FromDataFolder().GetExchangeHours(config),
|
||||
config,
|
||||
new Cash(Currencies.USD, 0, 1m),
|
||||
new OptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)),
|
||||
ErrorCurrencyConverter.Instance,
|
||||
RegisteredSecurityDataTypesProvider.Null);
|
||||
}
|
||||
|
||||
var indexConfig = new SubscriptionDataConfig(typeof(TradeBar), canonical.Underlying, Resolution.Minute, TimeZones.NewYork, TimeZones.NewYork, true, true, true);
|
||||
var index = new QuantConnect.Securities.Index.Index(
|
||||
MarketHoursDatabase.FromDataFolder().GetExchangeHours(indexConfig),
|
||||
new Cash(Currencies.USD, 0, 1m),
|
||||
indexConfig,
|
||||
SymbolProperties.GetDefault(Currencies.USD),
|
||||
ErrorCurrencyConverter.Instance,
|
||||
RegisteredSecurityDataTypesProvider.Null);
|
||||
|
||||
return new QuantConnect.Securities.IndexOption.IndexOption(
|
||||
canonical,
|
||||
MarketHoursDatabase.FromDataFolder().GetExchangeHours(config),
|
||||
new Cash(Currencies.USD, 0, 1m),
|
||||
new QuantConnect.Securities.IndexOption.IndexOptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)),
|
||||
ErrorCurrencyConverter.Instance,
|
||||
RegisteredSecurityDataTypesProvider.Null,
|
||||
new SecurityCache(),
|
||||
index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -962,7 +962,7 @@ namespace QuantConnect.Tests.Common.Securities
|
||||
var symbols = CreateOptionUniverse();
|
||||
|
||||
var data = symbols.Select(x => new OptionUniverse() { Symbol = x });
|
||||
var filterUniverse = new OptionFilterUniverse(data, underlying);
|
||||
var filterUniverse = new OptionFilterUniverse(null, data, underlying);
|
||||
filterUniverse.Refresh(filterUniverse.Data, underlying, underlying.EndTime);
|
||||
|
||||
if (fails)
|
||||
|
||||
@@ -99,7 +99,7 @@ SPX YL0WVJMRW51Q|SPX 31,SPX 240816C05420000,181.5800,181.5800,154.8300,154.830
|
||||
var expectedContracts = 11;
|
||||
|
||||
// Set up
|
||||
var universe = new OptionFilterUniverse(_testOptionsData, _underlying);
|
||||
var universe = new OptionFilterUniverse(null, _testOptionsData, _underlying);
|
||||
universe.Refresh(_testOptionsData, _underlying, _underlying.EndTime);
|
||||
|
||||
// Filter
|
||||
@@ -122,7 +122,7 @@ SPX YL0WVJMRW51Q|SPX 31,SPX 240816C05420000,181.5800,181.5800,154.8300,154.830
|
||||
var expectedContracts = 2;
|
||||
|
||||
// Set up
|
||||
var universe = new OptionFilterUniverse(_testOptionsData, _underlying);
|
||||
var universe = new OptionFilterUniverse(null, _testOptionsData, _underlying);
|
||||
universe.Refresh(_testOptionsData, _underlying, _underlying.EndTime);
|
||||
|
||||
// Filter
|
||||
@@ -145,7 +145,7 @@ SPX YL0WVJMRW51Q|SPX 31,SPX 240816C05420000,181.5800,181.5800,154.8300,154.830
|
||||
public void FiltersContractsByIndividualGreek(string greekName, decimal greekMinValue, decimal greekMaxValue, int expectedContracts)
|
||||
{
|
||||
// Set up
|
||||
var universe = new OptionFilterUniverse(_testOptionsData, _underlying);
|
||||
var universe = new OptionFilterUniverse(null, _testOptionsData, _underlying);
|
||||
universe.Refresh(_testOptionsData, _underlying, _underlying.EndTime);
|
||||
|
||||
// Filter
|
||||
@@ -174,7 +174,7 @@ SPX YL0WVJMRW51Q|SPX 31,SPX 240816C05420000,181.5800,181.5800,154.8300,154.830
|
||||
var expectedContracts = 11;
|
||||
|
||||
// Set up
|
||||
var universe = new OptionFilterUniverse(_testOptionsData, _underlying);
|
||||
var universe = new OptionFilterUniverse(null, _testOptionsData, _underlying);
|
||||
universe.Refresh(_testOptionsData, _underlying, _underlying.EndTime);
|
||||
|
||||
// Filter
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user