diff --git a/Common/Algorithm/Framework/Portfolio/SignalExports/Collective2SignalExport.cs b/Common/Algorithm/Framework/Portfolio/SignalExports/Collective2SignalExport.cs
index b86f5946c351..c922eeeb0600 100644
--- a/Common/Algorithm/Framework/Portfolio/SignalExports/Collective2SignalExport.cs
+++ b/Common/Algorithm/Framework/Portfolio/SignalExports/Collective2SignalExport.cs
@@ -31,6 +31,12 @@ namespace QuantConnect.Algorithm.Framework.Portfolio.SignalExports
///
public class Collective2SignalExport : BaseSignalExport
{
+ ///
+ /// Hashset of symbols whose market is unknown but have already been seen by
+ /// this signal export manager
+ ///
+ private HashSet _unknownMarketSymbols;
+
///
/// API key provided by Collective2
///
@@ -86,6 +92,7 @@ public class Collective2SignalExport : BaseSignalExport
/// Whether to use the white-label API instead of the general one
public Collective2SignalExport(string apiKey, int systemId, bool useWhiteLabelApi = false)
{
+ _unknownMarketSymbols = new HashSet();
_apiKey = apiKey;
_systemId = systemId;
Destination = new Uri(useWhiteLabelApi
@@ -131,7 +138,7 @@ protected bool ConvertHoldingsToCollective2(SignalExportTargetParameters paramet
{
_algorithm = parameters.Algorithm;
var targets = parameters.Targets;
- positions = new List();
+ positions = [];
foreach (var target in targets)
{
if (target == null)
@@ -140,27 +147,29 @@ protected bool ConvertHoldingsToCollective2(SignalExportTargetParameters paramet
return false;
}
- if (!ConvertTypeOfSymbol(target.Symbol, out string typeOfSymbol))
+ var securityType = GetSecurityTypeAcronym(target.Symbol.SecurityType);
+ if (securityType == null)
{
- return false;
+ continue;
}
- var symbol = _algorithm.Ticker(target.Symbol);
- if (target.Symbol.SecurityType == SecurityType.Future)
+ var maturityMonthYear = GetMaturityMonthYear(target.Symbol);
+ if (maturityMonthYear?.Length == 0)
{
- symbol = $"@{SymbolRepresentation.GenerateFutureTicker(target.Symbol.ID.Symbol, target.Symbol.ID.Date, doubleDigitsYear: false, includeExpirationDate: false)}";
- }
- else if (target.Symbol.SecurityType.IsOption())
- {
- symbol = SymbolRepresentation.GenerateOptionTicker(target.Symbol);
+ continue;
}
positions.Add(new Collective2Position
{
- C2Symbol = new C2Symbol
+ ExchangeSymbol = new C2ExchangeSymbol
{
- FullSymbol = symbol,
- SymbolType = typeOfSymbol,
+ Symbol = GetSymbol(target.Symbol),
+ Currency = parameters.Algorithm.AccountCurrency,
+ SecurityExchange = GetMICExchangeCode(target.Symbol),
+ SecurityType = securityType,
+ MaturityMonthYear = maturityMonthYear,
+ PutOrCall = GetPutOrCallValue(target.Symbol),
+ StrikePrice = GetStrikePrice(target.Symbol)
},
Quantity = ConvertPercentageToQuantity(_algorithm, target),
});
@@ -169,46 +178,6 @@ protected bool ConvertHoldingsToCollective2(SignalExportTargetParameters paramet
return true;
}
- ///
- /// Classifies a symbol type into the possible symbol types values defined
- /// by Collective2 API.
- ///
- /// Symbol of the desired position
- /// The type of the symbol according to Collective2 API
- /// True if the symbol's type is supported by Collective2, false otherwise
- private bool ConvertTypeOfSymbol(Symbol targetSymbol, out string typeOfSymbol)
- {
- switch (targetSymbol.SecurityType)
- {
- case SecurityType.Equity:
- typeOfSymbol = "stock";
- break;
- case SecurityType.Option:
- typeOfSymbol = "option";
- break;
- case SecurityType.Future:
- typeOfSymbol = "future";
- break;
- case SecurityType.Forex:
- typeOfSymbol = "forex";
- break;
- case SecurityType.IndexOption:
- typeOfSymbol = "option";
- break;
- default:
- typeOfSymbol = "NotImplemented";
- break;
- }
-
- if (typeOfSymbol == "NotImplemented")
- {
- _algorithm.Error($"{targetSymbol.SecurityType} security type is not supported by Collective2.");
- return false;
- }
-
- return true;
- }
-
///
/// Converts a given percentage of a position into the number of shares of it
///
@@ -332,6 +301,138 @@ private class DesiredPositionResponse
public List CanceledSignals { get; set; } = new List();
}
+ ///
+ /// Returns the given symbol in the expected C2 format
+ ///
+ private string GetSymbol(Symbol symbol)
+ {
+ if (CurrencyPairUtil.TryDecomposeCurrencyPair(symbol, out var baseCurrency, out var quoteCurrency))
+ {
+ return $"{baseCurrency}/{quoteCurrency}";
+ }
+ else if (symbol.SecurityType.IsOption())
+ {
+ return symbol.Underlying.Value;
+ }
+ else
+ {
+ return symbol.ID.Symbol;
+ }
+ }
+
+ private string GetMICExchangeCode(Symbol symbol)
+ {
+ if (_unknownMarketSymbols.Contains(symbol.Value) || symbol.SecurityType == SecurityType.Equity || symbol.SecurityType.IsOption())
+ {
+ return "DEFAULT";
+ }
+
+ switch (symbol.ID.Market)
+ {
+ case "india":
+ return "XNSE";
+ case "hkfe":
+ return "XHKF";
+ case "nyseliffe":
+ return "XNLI";
+ case "eurex":
+ return "XEUR";
+ case "ice":
+ return "IEPA";
+ case "cboe":
+ return "XCBO";
+ case "cfe":
+ return "XCBF";
+ case "cbot":
+ return "XCBT";
+ case "comex":
+ return "XCEC";
+ case "nymex":
+ return "XNYM";
+ case "sgx":
+ return "XSES";
+ case "fxcm":
+ return symbol.ID.Market.ToUpper();
+ case "ose":
+ case "cme":
+ return "X" + symbol.ID.Market.ToUpper();
+ default:
+ _unknownMarketSymbols.Add(symbol.Value);
+ _algorithm.Debug($"The market of the symbol {symbol.Value} was unexpected: {symbol.ID.Market}. Using 'DEFAULT' as market");
+ return "DEFAULT";
+ }
+ }
+
+ ///
+ /// Returns the given security type in the format C2 expects
+ ///
+ private string GetSecurityTypeAcronym(SecurityType securityType)
+ {
+ switch (securityType)
+ {
+ case SecurityType.Equity:
+ return "CS";
+ case SecurityType.Future:
+ return "FUT";
+ case SecurityType.Option:
+ case SecurityType.IndexOption:
+ return "OPT";
+ case SecurityType.Forex:
+ return "FOR";
+ default:
+ _algorithm.Error($"Unexpected security type found: {securityType}. Collective2 just accepts: Equity, Future, Option, Index Option and Stock");
+ return null;
+ }
+ }
+
+ ///
+ /// Returns the expiration date in the format C2 expects
+ ///
+ private string GetMaturityMonthYear(Symbol symbol)
+ {
+ var delistingDate = symbol.GetDelistingDate();
+ if (delistingDate == Time.EndOfTime) // The given symbol is equity or forex
+ {
+ return null;
+ }
+
+ if (delistingDate < _algorithm.Securities[symbol].LocalTime) // The given symbol has already expired
+ {
+ _algorithm.Error($"Instrument {symbol} has already expired. Its delisting date was: {delistingDate}. This signal won't be sent to Collective2.");
+ return string.Empty;
+ }
+
+ return $"{delistingDate:yyyyMMdd}";
+ }
+
+ private int? GetPutOrCallValue(Symbol symbol)
+ {
+ if (symbol.SecurityType.IsOption())
+ {
+ switch (symbol.ID.OptionRight)
+ {
+ case OptionRight.Put:
+ return 0;
+ case OptionRight.Call:
+ return 1;
+ }
+ }
+
+ return null;
+ }
+
+ private decimal? GetStrikePrice(Symbol symbol)
+ {
+ if (symbol.SecurityType.IsOption())
+ {
+ return symbol.ID.StrikePrice;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
///
/// The C2 ResponseStatus object
///
@@ -393,34 +494,72 @@ protected class Collective2Position
///
/// Position symbol
///
- [JsonProperty(PropertyName = "C2Symbol")]
- public C2Symbol C2Symbol { get; set; }
+ [JsonProperty(PropertyName = "exchangeSymbol")]
+ public C2ExchangeSymbol ExchangeSymbol { get; set; }
///
/// Number of shares/contracts of the given symbol. Positive quantites are long positions
/// and negative short positions.
///
- [JsonProperty(PropertyName = "Quantity")]
+ [JsonProperty(PropertyName = "quantity")]
public decimal Quantity { get; set; } // number of shares, not % of the portfolio
}
///
/// The Collective2 symbol
///
- protected class C2Symbol
+ protected class C2ExchangeSymbol
{
///
- /// The The full native C2 symbol e.g. BSRR2121Q22.5
+ /// The exchange root symbol e.g. AAPL
+ ///
+ [JsonProperty(PropertyName = "symbol")]
+ public string Symbol { get; set; }
+
+ ///
+ /// The 3-character ISO instrument currency. E.g. 'USD'
+ ///
+ [JsonProperty(PropertyName = "currency")]
+ public string Currency { get; set; }
+
+ ///
+ /// The MIC Exchange code e.g. DEFAULT (for stocks & options),
+ /// XCME, XEUR, XICE, XLIF, XNYB, XNYM, XASX, XCBF, XCBT, XCEC,
+ /// XKBT, XSES. See details at http://www.iso15022.org/MIC/homepageMIC.htm
///
- [JsonProperty(PropertyName = "FullSymbol")]
- public string FullSymbol { get; set; }
+ [JsonProperty(PropertyName = "securityExchange")]
+ public string SecurityExchange { get; set; }
///
- /// The type of instrument. e.g. 'stock', 'option', 'future', 'forex'
+ /// The SecurityType e.g. 'CS'(Common Stock), 'FUT' (Future), 'OPT' (Option), 'FOR' (Forex)
+ ///
+ [JsonProperty(PropertyName = "securityType")]
+ public string SecurityType { get; set; }
+
+ ///
+ /// The MaturityMonthYear e.g. '202103' (March 2021), or if the contract requires a day: '20210521' (May 21, 2021)
+ ///
+ [JsonProperty(PropertyName = "maturityMonthYear")]
+ public string MaturityMonthYear { get; set; }
+
+ ///
+ /// The Option PutOrCall e.g. 0 = Put, 1 = Call
+ ///
+ [JsonProperty(PropertyName = "putOrCall")]
+ public int? PutOrCall { get; set; }
+
+ ///
+ /// The ISO Option Strike Price. Zero means none
+ ///
+ [JsonProperty(PropertyName = "strikePrice")]
+ public decimal? StrikePrice { get; set; }
+
+ ///
+ /// The multiplier to apply to the Exchange price to get the C2-formatted price. Default is 1
///
- [JsonProperty(PropertyName = "SymbolType")]
- public string SymbolType { get; set; }
+ [JsonProperty(PropertyName = "priceMultiplier")]
+ public decimal PriceMultiplier { get; set; } = 1;
}
}
}
diff --git a/Tests/Algorithm/Framework/Portfolio/SignalExportTargetTests.cs b/Tests/Algorithm/Framework/Portfolio/SignalExportTargetTests.cs
index d6ba4f6c181a..8d6d65e744c9 100644
--- a/Tests/Algorithm/Framework/Portfolio/SignalExportTargetTests.cs
+++ b/Tests/Algorithm/Framework/Portfolio/SignalExportTargetTests.cs
@@ -30,38 +30,49 @@ namespace QuantConnect.Tests.Algorithm.Framework.Portfolio
[TestFixture]
public class SignalExportTargetTests
{
- [Test]
- public void SendsTargetsToCollective2Appropiately()
+ [TestCaseSource(nameof(SendsTargetsToCollective2AppropiatelyTestCases))]
+ public void SendsTargetsToCollective2Appropiately(string currency, Symbol symbol, decimal quantity, string expectedMessage)
{
- var symbols = new List()
- {
- Symbols.SPY,
- Symbols.EURUSD,
- Symbols.Future_ESZ18_Dec2018,
- Symbols.SPY_C_192_Feb19_2016
- };
-
- var targetList = new List()
- {
- new PortfolioTarget(Symbols.SPY, (decimal)0.2),
- new PortfolioTarget(Symbols.EURUSD, (decimal)0.3),
- new PortfolioTarget(Symbols.Future_ESZ18_Dec2018, (decimal)0.2),
- new PortfolioTarget(Symbols.SPY_C_192_Feb19_2016, (decimal)0.3)
- };
+ var targetList = new List() { new(symbol, quantity) };
var algorithm = new AlgorithmStub();
- AddSymbols(symbols, algorithm);
+ algorithm.SetDateTime(new DateTime(2016, 02, 16, 11, 53, 30));
+ algorithm.Portfolio.SetAccountCurrency(currency);
+ var security = algorithm.AddSecurity(symbol);
+ security.SetMarketPrice(new Tick { Value = 100 });
+
algorithm.Portfolio.SetCash(50000);
using var manager = new Collective2SignalExportHandler("", 0);
var message = manager.GetMessageSent(new SignalExportTargetParameters { Targets = targetList, Algorithm = algorithm });
- var expectedMessage = @"{""StrategyId"":0,""Positions"":[{""C2Symbol"":{""FullSymbol"":""SPY"",""SymbolType"":""stock""},""Quantity"":99.0},{""C2Symbol"":{""FullSymbol"":""EURUSD"",""SymbolType"":""forex""},""Quantity"":149.0},{""C2Symbol"":{""FullSymbol"":""@ESZ8"",""SymbolType"":""future""},""Quantity"":2.0},{""C2Symbol"":{""FullSymbol"":""SPY1619B192"",""SymbolType"":""option""},""Quantity"":1.0}]}";
-
Assert.AreEqual(expectedMessage, message);
}
+ [Test]
+ public void Collective2SignalExportManagerDoesNotLogMoreThanOnceWhenUnknownMarket()
+ {
+ var targetList = new List() { new(Symbols.EURUSD, 1) };
+
+ var algorithm = new AlgorithmStub();
+ algorithm.SetDateTime(new DateTime(2016, 02, 16, 11, 53, 30));
+ algorithm.Portfolio.SetAccountCurrency("USD");
+ var security = algorithm.AddSecurity(Symbols.EURUSD);
+ security.SetMarketPrice(new Tick { Value = 100 });
+
+ algorithm.Portfolio.SetCash(50000);
+
+ using var manager = new Collective2SignalExportHandler("", 0);
+
+ for (int count = 0; count < 100; count++)
+ {
+ manager.GetMessageSent(new SignalExportTargetParameters { Targets = targetList, Algorithm = algorithm });
+ }
+
+ Assert.AreEqual(1, algorithm.DebugMessages.Count);
+ }
+
[Test]
public void Collective2ConvertsPercentageToQuantityAppropiately()
{
@@ -388,6 +399,51 @@ public void SignalExportManagerReturnsFalseWhenNegativeTotalPortfolioValue()
Assert.IsFalse(signalExportManagerHandler.GetPortfolioTargets(out _));
}
+ private static object[] SendsTargetsToCollective2AppropiatelyTestCases =
+ {
+ new object[] { "USD", Symbols.SPY, 0.2m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""SPY"",""currency"":""USD"",""securityExchange"":""DEFAULT"",""securityType"":""CS"",""maturityMonthYear"":null,""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":99.0}]}" },
+ new object[] { "USD", Symbols.EURUSD, 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""EUR/USD"",""currency"":""USD"",""securityExchange"":""DEFAULT"",""securityType"":""FOR"",""maturityMonthYear"":null,""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "USD", Symbols.EURGBP, 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""EUR/GBP"",""currency"":""USD"",""securityExchange"":""DEFAULT"",""securityType"":""FOR"",""maturityMonthYear"":null,""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "USD", Symbols.GBPJPY, 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""GBP/JPY"",""currency"":""USD"",""securityExchange"":""DEFAULT"",""securityType"":""FOR"",""maturityMonthYear"":null,""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "USD", Symbols.GBPUSD, 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""GBP/USD"",""currency"":""USD"",""securityExchange"":""DEFAULT"",""securityType"":""FOR"",""maturityMonthYear"":null,""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "USD", Symbols.USDJPY, 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""USD/JPY"",""currency"":""USD"",""securityExchange"":""DEFAULT"",""securityType"":""FOR"",""maturityMonthYear"":null,""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "USD", Symbols.CreateOptionSymbol("SPY", OptionRight.Call, 192m, new DateTime(2016, 02, 15)), 0.2m, @"{""StrategyId"":0,""Positions"":[]}" },
+ new object[] { "USD", Symbols.CreateOptionSymbol("SPY", OptionRight.Call, 192m, new DateTime(2056, 02, 19)), 0.2m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""SPY"",""currency"":""USD"",""securityExchange"":""DEFAULT"",""securityType"":""OPT"",""maturityMonthYear"":""20560218"",""putOrCall"":1,""strikePrice"":192.0,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "USD", Symbols.CreateOptionSymbol("SPY", OptionRight.Put, 192m, new DateTime(2056, 02, 19)), 0.2m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""SPY"",""currency"":""USD"",""securityExchange"":""DEFAULT"",""securityType"":""OPT"",""maturityMonthYear"":""20560218"",""putOrCall"":0,""strikePrice"":192.0,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "USD", Symbol.Create("EURUSD", SecurityType.Forex, Market.FXCM), 0.2m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""EUR/USD"",""currency"":""USD"",""securityExchange"":""FXCM"",""securityType"":""FOR"",""maturityMonthYear"":null,""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "USD", Symbol.Create("NQX", SecurityType.IndexOption, Market.USA), 0.2m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""NQX"",""currency"":""USD"",""securityExchange"":""DEFAULT"",""securityType"":""OPT"",""maturityMonthYear"":null,""putOrCall"":1,""strikePrice"":0.0,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "USD", Symbol.CreateFuture("NIFTY", Market.India, new DateTime(2056, 02, 19)), 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""NIFTY"",""currency"":""USD"",""securityExchange"":""XNSE"",""securityType"":""FUT"",""maturityMonthYear"":""20560219"",""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "USD", Symbol.CreateFuture("HSI", Market.HKFE, new DateTime(2056, 02, 19)), 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""HSI"",""currency"":""USD"",""securityExchange"":""XHKF"",""securityType"":""FUT"",""maturityMonthYear"":""20560219"",""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "USD", Symbol.CreateFuture("ZG", Market.NYSELIFFE, new DateTime(2056, 02, 19)), 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""ZG"",""currency"":""USD"",""securityExchange"":""XNLI"",""securityType"":""FUT"",""maturityMonthYear"":""20560219"",""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "USD", Symbol.CreateFuture("FESX", Market.EUREX, new DateTime(2056, 02, 19)), 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""FESX"",""currency"":""USD"",""securityExchange"":""XEUR"",""securityType"":""FUT"",""maturityMonthYear"":""20560219"",""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "USD", Symbol.CreateFuture("KC", Market.ICE, new DateTime(2056, 02, 19)), 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""KC"",""currency"":""USD"",""securityExchange"":""IEPA"",""securityType"":""FUT"",""maturityMonthYear"":""20560219"",""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "USD", Symbol.CreateFuture("VIX", Market.CFE, new DateTime(2056, 02, 19)), 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""VIX"",""currency"":""USD"",""securityExchange"":""XCBF"",""securityType"":""FUT"",""maturityMonthYear"":""20560219"",""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "USD", Symbol.CreateFuture("ZC", Market.CBOT, new DateTime(2056, 02, 19)), 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""ZC"",""currency"":""USD"",""securityExchange"":""XCBT"",""securityType"":""FUT"",""maturityMonthYear"":""20560219"",""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "USD", Symbol.CreateFuture("GC", Market.COMEX, new DateTime(2056, 02, 19)), 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""GC"",""currency"":""USD"",""securityExchange"":""XCEC"",""securityType"":""FUT"",""maturityMonthYear"":""20560219"",""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "USD", Symbol.CreateFuture("CL", Market.NYMEX, new DateTime(2056, 02, 19)), 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""CL"",""currency"":""USD"",""securityExchange"":""XNYM"",""securityType"":""FUT"",""maturityMonthYear"":""20560219"",""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "USD", Symbol.CreateFuture("NK", Market.SGX, new DateTime(2056, 02, 19)), 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""NK"",""currency"":""USD"",""securityExchange"":""XSES"",""securityType"":""FUT"",""maturityMonthYear"":""20560219"",""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "EUR", Symbols.SPY, 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""SPY"",""currency"":""EUR"",""securityExchange"":""DEFAULT"",""securityType"":""CS"",""maturityMonthYear"":null,""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "EUR", Symbols.EURUSD, 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""EUR/USD"",""currency"":""EUR"",""securityExchange"":""DEFAULT"",""securityType"":""FOR"",""maturityMonthYear"":null,""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "EUR", Symbols.EURGBP, 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""EUR/GBP"",""currency"":""EUR"",""securityExchange"":""DEFAULT"",""securityType"":""FOR"",""maturityMonthYear"":null,""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "EUR", Symbols.GBPJPY, 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""GBP/JPY"",""currency"":""EUR"",""securityExchange"":""DEFAULT"",""securityType"":""FOR"",""maturityMonthYear"":null,""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "EUR", Symbols.GBPUSD, 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""GBP/USD"",""currency"":""EUR"",""securityExchange"":""DEFAULT"",""securityType"":""FOR"",""maturityMonthYear"":null,""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "EUR", Symbols.USDJPY, 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""USD/JPY"",""currency"":""EUR"",""securityExchange"":""DEFAULT"",""securityType"":""FOR"",""maturityMonthYear"":null,""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "EUR", Symbols.CreateOptionSymbol("SPY", OptionRight.Call, 192m, new DateTime(2056, 02, 19)), 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""SPY"",""currency"":""EUR"",""securityExchange"":""DEFAULT"",""securityType"":""OPT"",""maturityMonthYear"":""20560218"",""putOrCall"":1,""strikePrice"":192.0,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "EUR", Symbols.CreateOptionSymbol("SPY", OptionRight.Put, 192m, new DateTime(2056, 02, 19)), 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""SPY"",""currency"":""EUR"",""securityExchange"":""DEFAULT"",""securityType"":""OPT"",""maturityMonthYear"":""20560218"",""putOrCall"":0,""strikePrice"":192.0,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "EUR", Symbols.CreateOptionSymbol("SPY", OptionRight.Call, 192m, new DateTime(2016, 02, 15)), 0.2m, @"{""StrategyId"":0,""Positions"":[]}" },
+ new object[] { "EUR", Symbol.Create("EURUSD", SecurityType.Forex, Market.FXCM), 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""EUR/USD"",""currency"":""EUR"",""securityExchange"":""FXCM"",""securityType"":""FOR"",""maturityMonthYear"":null,""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "EUR", Symbol.CreateFuture("NIFTY", Market.India, new DateTime(2056, 02, 19)), 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""NIFTY"",""currency"":""EUR"",""securityExchange"":""XNSE"",""securityType"":""FUT"",""maturityMonthYear"":""20560219"",""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "EUR", Symbol.CreateFuture("HSI", Market.HKFE, new DateTime(2056, 02, 19)), 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""HSI"",""currency"":""EUR"",""securityExchange"":""XHKF"",""securityType"":""FUT"",""maturityMonthYear"":""20560219"",""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "EUR", Symbol.CreateFuture("ZG", Market.NYSELIFFE, new DateTime(2056, 02, 19)), 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""ZG"",""currency"":""EUR"",""securityExchange"":""XNLI"",""securityType"":""FUT"",""maturityMonthYear"":""20560219"",""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "EUR", Symbol.CreateFuture("FESX", Market.EUREX, new DateTime(2056, 02, 19)), 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""FESX"",""currency"":""EUR"",""securityExchange"":""XEUR"",""securityType"":""FUT"",""maturityMonthYear"":""20560219"",""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "EUR", Symbol.CreateFuture("KC", Market.ICE, new DateTime(2056, 02, 19)), 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""KC"",""currency"":""EUR"",""securityExchange"":""IEPA"",""securityType"":""FUT"",""maturityMonthYear"":""20560219"",""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "EUR", Symbol.CreateFuture("VIX", Market.CFE, new DateTime(2056, 02, 19)), 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""VIX"",""currency"":""EUR"",""securityExchange"":""XCBF"",""securityType"":""FUT"",""maturityMonthYear"":""20560219"",""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "EUR", Symbol.CreateFuture("ZC", Market.CBOT, new DateTime(2056, 02, 19)), 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""ZC"",""currency"":""EUR"",""securityExchange"":""XCBT"",""securityType"":""FUT"",""maturityMonthYear"":""20560219"",""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "EUR", Symbol.CreateFuture("GC", Market.COMEX, new DateTime(2056, 02, 19)), 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""GC"",""currency"":""EUR"",""securityExchange"":""XCEC"",""securityType"":""FUT"",""maturityMonthYear"":""20560219"",""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "EUR", Symbol.CreateFuture("CL", Market.NYMEX, new DateTime(2056, 02, 19)), 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""CL"",""currency"":""EUR"",""securityExchange"":""XNYM"",""securityType"":""FUT"",""maturityMonthYear"":""20560219"",""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ new object[] { "EUR", Symbol.CreateFuture("NK", Market.SGX, new DateTime(2056, 02, 19)), 0m, @"{""StrategyId"":0,""Positions"":[{""exchangeSymbol"":{""symbol"":""NK"",""currency"":""EUR"",""securityExchange"":""XSES"",""securityType"":""FUT"",""maturityMonthYear"":""20560219"",""putOrCall"":null,""strikePrice"":null,""priceMultiplier"":1.0},""quantity"":0.0}]}" },
+ };
+
private static void AddSymbols(List symbols, QCAlgorithm algorithm)
{
algorithm.SetDateTime(new DateTime(2016, 02, 16, 11, 53, 30));