diff --git a/Algorithm.CSharp/RegressionTests/Collective2IndexOptionAlgorithm.cs b/Algorithm.CSharp/RegressionTests/Collective2IndexOptionAlgorithm.cs
index 7ee87b88bba4..03fd9ef93d24 100644
--- a/Algorithm.CSharp/RegressionTests/Collective2IndexOptionAlgorithm.cs
+++ b/Algorithm.CSharp/RegressionTests/Collective2IndexOptionAlgorithm.cs
@@ -1,23 +1,45 @@
+/*
+ * 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 System.Threading.Tasks;
using QuantConnect.Algorithm.Framework.Portfolio.SignalExports;
using QuantConnect.Data;
using QuantConnect.Indicators;
using QuantConnect.Interfaces;
-using QuantConnect.Securities.Option;
namespace QuantConnect.Algorithm.CSharp.RegressionTests
{
public class Collective2IndexOptionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
- private const string _collective2ApiKey = "8923ABC5-F221-4458-AF97-7CECF5BE3106";
- private const int _collective2SystemId = 145772785;
+ ///
+ /// Collective2 APIv4 KEY: This value is provided by Collective2 in your account section (See https://collective2.com/account-info)
+ /// See API documentation at https://trade.collective2.com/c2-api
+ ///
+ private const string _collective2ApiKey = "YOUR APIV4 KEY";
+
+
+ ///
+ /// Collective2 System ID: This value is found beside the system's name (strategy's name) on the main system page
+ ///
+ private const int _collective2SystemId = 0;
private ExponentialMovingAverage _fast;
private Symbol _spxw;
private Symbol _spxwOption;
+ private Symbol _symbol;
public override void Initialize()
{
@@ -32,14 +54,13 @@ public override void Initialize()
Market.USA,
OptionStyle.European,
OptionRight.Call,
- 3200m,
- new DateTime(2021, 1, 15));
+ 3800m,
+ new DateTime(2021, 1, 04));
- var foo = AddIndexOptionContract(_spxwOption, Resolution.Minute);
+ _symbol = AddIndexOptionContract(_spxwOption, Resolution.Minute).Symbol;
- _fast = EMA("SPXW", 10, Resolution.Minute);
+ _fast = EMA("SPXW", 3, Resolution.Minute);
- // Configurar Collective2
var test = new Collective2SignalExport(_collective2ApiKey, _collective2SystemId);
SignalExport.AddSignalExportProviders(test);
SetWarmUp(100);
@@ -47,22 +68,19 @@ public override void Initialize()
public override void OnData(Slice slice)
{
- //SetHoldings("SPXW", 0.1);
- //var chain = slice.OptionChains[_spxwOption];
- var test = Portfolio;
if (!Portfolio[_spxw].Invested)
{
MarketOrder(_spxw, -1);
SignalExport.SetTargetPortfolioFromPortfolio();
}
}
- public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.RuntimeError;
+ public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
public bool CanRunLocally { get; } = true;
public virtual List Languages { get; } = new() { Language.CSharp };
- public long DataPoints => 80;
+ public long DataPoints => 493;
public int AlgorithmHistoryDataPoints => 0;
@@ -87,8 +105,8 @@ public override void OnData(Slice slice)
{"Beta", "0"},
{"Annual Standard Deviation", "0"},
{"Annual Variance", "0"},
- {"Information Ratio", "-9.604"},
- {"Tracking Error", "0.097"},
+ {"Information Ratio", "-5.208"},
+ {"Tracking Error", "0.103"},
{"Treynor Ratio", "0"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$0"},
diff --git a/Common/Algorithm/Framework/Portfolio/SignalExports/Collective2SignalExport.cs b/Common/Algorithm/Framework/Portfolio/SignalExports/Collective2SignalExport.cs
index 17ddba237758..e2aa7bb7108d 100644
--- a/Common/Algorithm/Framework/Portfolio/SignalExports/Collective2SignalExport.cs
+++ b/Common/Algorithm/Framework/Portfolio/SignalExports/Collective2SignalExport.cs
@@ -145,10 +145,6 @@ protected bool ConvertHoldingsToCollective2(SignalExportTargetParameters paramet
else if (target.Symbol.SecurityType.IsOption())
{
symbol = SymbolRepresentation.GenerateOptionTicker(target.Symbol);
- if (target.Symbol.SecurityType == SecurityType.IndexOption)
- {
- symbol = target.Symbol.Canonical.Value.Replace("?", string.Empty);
- }
}
positions.Add(new Collective2Position
diff --git a/Common/Algorithm/Framework/Portfolio/SignalExports/SignalExportManager.cs b/Common/Algorithm/Framework/Portfolio/SignalExports/SignalExportManager.cs
index a298d6ff0d55..1a9c18576206 100644
--- a/Common/Algorithm/Framework/Portfolio/SignalExports/SignalExportManager.cs
+++ b/Common/Algorithm/Framework/Portfolio/SignalExports/SignalExportManager.cs
@@ -109,7 +109,7 @@ protected bool GetPortfolioTargets(out PortfolioTarget[] targets)
/// True if the portfolio targets could be sent to the different signal export providers successfully, false otherwise
public bool SetTargetPortfolio(params PortfolioTarget[] portfolioTargets)
{
- if (_algorithm.LiveMode)
+ if (!_algorithm.LiveMode)
{
if (!_isLiveWarningModeLog)
{
@@ -156,12 +156,8 @@ private IEnumerable GetPortfolioTargets(decimal totalPortfolioV
continue;
}
- //var marginParameters = MaintenanceMarginParameters.ForQuantityAtCurrentPrice(security, holding.Quantity);
var marginParameters = new InitialMarginParameters(security, holding.Quantity);
var adjustedPercent = security.BuyingPowerModel.GetInitialMarginRequirement(marginParameters) / totalPortfolioValue;
- //test
- //adjustedPercent = 0.3m;
-
// See PortfolioTarget.Percent:
// we normalize the target buying power by the leverage so we work in the land of margin
diff --git a/Common/SymbolRepresentation.cs b/Common/SymbolRepresentation.cs
index 1619bdd05edc..2c5752092dee 100644
--- a/Common/SymbolRepresentation.cs
+++ b/Common/SymbolRepresentation.cs
@@ -44,7 +44,7 @@ public class FutureTickerProperties
///
/// Underlying name
///
- public string Underlying { get; set; }
+ public string Underlying { get; set; }
///
/// Short expiration year
@@ -167,8 +167,7 @@ public static Symbol ParseFutureSymbol(string ticker, int? futureYear = null)
if (!SymbolPropertiesDatabase.FromDataFolder().TryGetMarket(underlying, SecurityType.Future, out var market))
{
- Log.Debug($@"SymbolRepresentation.ParseFutureSymbol(): {
- Messages.SymbolRepresentation.FailedToGetMarketForTickerAndUnderlying(ticker, underlying)}");
+ Log.Debug($@"SymbolRepresentation.ParseFutureSymbol(): {Messages.SymbolRepresentation.FailedToGetMarketForTickerAndUnderlying(ticker, underlying)}");
return null;
}
@@ -269,7 +268,8 @@ public static string GenerateFutureTicker(string underlying, DateTime expiration
month = expirationMonth.Month;
year = doubleDigitsYear ? expirationMonth.Year % 100 : expirationMonth.Year % 10;
}
- else {
+ else
+ {
// These futures expire in the month before or in the contract month
month += contractMonthDelta;
@@ -389,7 +389,7 @@ public static Symbol ParseOptionTickerOSI(string ticker, SecurityType securityTy
// let it fallback to it's default handling, which include mapping
optionTicker = null;
}
- else if(securityType == SecurityType.IndexOption)
+ else if (securityType == SecurityType.IndexOption)
{
underlyingSid = SecurityIdentifier.GenerateIndex(OptionSymbol.MapToUnderlying(optionTicker, securityType), market);
underlyingSymbolValue = underlyingSid.Symbol;
@@ -478,6 +478,10 @@ public static bool TryDecomposeOptionTickerOSI(string ticker, SecurityType secur
/// The option ticker
public static string GenerateOptionTicker(Symbol symbol)
{
+ if (symbol.SecurityType == SecurityType.IndexOption)
+ {
+ return symbol.Canonical.Value.Replace("?", string.Empty);
+ }
var letter = _optionSymbology.Where(x => x.Value.Item2 == symbol.ID.OptionRight && x.Value.Item1 == symbol.ID.Date.Month).Select(x => x.Key).Single();
var twoYearDigit = symbol.ID.Date.ToString("yy");
return $"{SecurityIdentifier.Ticker(symbol.Underlying, symbol.ID.Date)}{twoYearDigit}{symbol.ID.Date.Day:00}{letter}{symbol.ID.StrikePrice.ToStringInvariant()}";
@@ -590,10 +594,10 @@ public static OptionTickerProperties ParseOptionTickerIQFeed(string ticker)
/// Tickers from live trading may not provide the four-digit year.
private static int GetExpirationYear(int? futureYear, FutureTickerProperties parsed)
{
- if(futureYear.HasValue)
+ if (futureYear.HasValue)
{
var referenceYear = 1900 + parsed.ExpirationYearShort;
- while(referenceYear < futureYear.Value)
+ while (referenceYear < futureYear.Value)
{
referenceYear += 10;
}
diff --git a/Tests/Common/SymbolRepresentationTests.cs b/Tests/Common/SymbolRepresentationTests.cs
index e38f09332e46..a2844643340e 100644
--- a/Tests/Common/SymbolRepresentationTests.cs
+++ b/Tests/Common/SymbolRepresentationTests.cs
@@ -155,6 +155,15 @@ public void ParseInvalidFuturesTickers()
Assert.AreEqual(result, null);
}
+ [Test]
+ public void GenerateOptionTickerWithIndexOptionReturnsCorrectTicker()
+ {
+ var expected = "AAPL";
+ var symbol = Symbol.Create("AAPL", SecurityType.IndexOption, Market.USA, null, null);
+ var result = SymbolRepresentation.GenerateOptionTicker(symbol);
+ Assert.AreEqual(expected, result);
+ }
+
[TestCase(Futures.Energy.ArgusLLSvsWTIArgusTradeMonth, 2017, 1, 29, "AE529G7", false)] // Previous month
[TestCase(Futures.Energy.ArgusPropaneSaudiAramco, 2017, 1, 29, "A9N29G7", false)] // Previous month
[TestCase(Futures.Energy.BrentCrude, 2017, 1, 29, "B29H7", false)] // Second prior month
@@ -287,7 +296,7 @@ public void GenerateFutureSymbolFromTickerExpiringBefore2000(string ticker)
[TestCase("PROPANE_NON_LDH_MONT_BELVIEU", QuantConnect.Securities.Futures.Energy.PropaneNonLDHMontBelvieu)]
[TestCase("ARGUS_PROPANE_FAR_EAST_INDEX_BALMO", QuantConnect.Securities.Futures.Energy.ArgusPropaneFarEastIndexBALMO)]
[TestCase("GASOLINE", QuantConnect.Securities.Futures.Energy.Gasoline)]
- [TestCase("NATURAL_GAS",QuantConnect.Securities.Futures.Energy.NaturalGas)]
+ [TestCase("NATURAL_GAS", QuantConnect.Securities.Futures.Energy.NaturalGas)]
public void FutureEnergySymbolsWorkInPythonWithPEP8(string FutureEnergyName, string expectedFutureEnergyValue)
{
using (Py.GIL())
diff --git a/Tests/RegressionTestMessageHandler.cs b/Tests/RegressionTestMessageHandler.cs
index 0cb7e4dc9c39..83e22a1ccf84 100644
--- a/Tests/RegressionTestMessageHandler.cs
+++ b/Tests/RegressionTestMessageHandler.cs
@@ -28,7 +28,7 @@ namespace QuantConnect.Tests
///
public class RegressionTestMessageHandler : QuantConnect.Messaging.Messaging
{
- private static readonly bool _updateRegressionStatistics = Config.GetBool("regression-update-statistics", true);
+ private static readonly bool _updateRegressionStatistics = Config.GetBool("regression-update-statistics", false);
private AlgorithmNodePacket _job;
private AlgorithmManager _algorithmManager;