22 using System.Collections.Generic;
39 private bool _isLiveMode;
40 private bool _modelsMismatchWarningSent;
55 _registeredTypes = registeredTypes;
56 _marketHoursDatabase = marketHoursDatabase;
57 _symbolPropertiesDatabase = symbolPropertiesDatabase;
58 _securityInitializerProvider = securityInitializerProvider;
59 _cacheProvider = cacheProvider;
60 _primaryExchangeProvider = primaryExchangeProvider;
61 _algorithm = algorithm;
70 List<SubscriptionDataConfig> subscriptionDataConfigList,
72 bool addToSymbolCache,
74 bool initializeSecurity)
77 configList.AddRange(subscriptionDataConfigList);
79 var dataTypes = Enumerable.Empty<Type>();
82 dataTypes =
new[] { type };
84 var exchangeHours = _marketHoursDatabase.GetEntry(symbol, dataTypes).ExchangeHours;
86 var defaultQuoteCurrency = _cashBook.AccountCurrency;
89 defaultQuoteCurrency = symbol.
Value.Substring(3);
94 throw new ArgumentException(Messages.SecurityService.SymbolNotFoundInSymbolPropertiesDatabase(symbol));
98 var symbolProperties = _symbolPropertiesDatabase.GetSymbolProperties(
102 defaultQuoteCurrency);
105 if (addToSymbolCache)
107 SymbolCache.Set(symbol.
Value, symbol);
111 var quoteCurrency = symbolProperties.QuoteCurrency;
112 if (!_cashBook.TryGetValue(quoteCurrency, out var quoteCash))
115 quoteCash = _cashBook.Add(quoteCurrency, 0, 0);
118 Cash baseCash =
null;
124 if (!_cashBook.TryGetValue(baseCurrencySymbol, out baseCash))
127 baseCash = _cashBook.Add(baseCurrencySymbol, 0, 0);
132 throw new ArgumentException($
"Failed to resolve base currency for '{symbol.ID.Symbol}', it might be missing from the Symbol database or market '{symbol.ID.Market}' could be wrong");
136 var cache = _cacheProvider.GetSecurityCache(symbol);
142 var primaryExchange =
143 _primaryExchangeProvider?.GetPrimaryExchange(symbol.
ID) ??
145 security =
new Equity.Equity(symbol, exchangeHours, quoteCash, symbolProperties, _cashBook, _registeredTypes, cache, primaryExchange);
150 security =
new Option.Option(symbol, exchangeHours, quoteCash,
new Option.OptionSymbolProperties(symbolProperties), _cashBook, _registeredTypes, cache, underlying);
155 security =
new IndexOption.IndexOption(symbol, exchangeHours, quoteCash,
new IndexOption.IndexOptionSymbolProperties(symbolProperties), _cashBook, _registeredTypes, cache, underlying);
160 var optionSymbolProperties =
new Option.OptionSymbolProperties(symbolProperties);
164 optionSymbolProperties.SetContractUnitOfTrade(1);
166 security =
new FutureOption.FutureOption(symbol, exchangeHours, quoteCash, optionSymbolProperties, _cashBook, _registeredTypes, cache, underlying);
170 security =
new Future.Future(symbol, exchangeHours, quoteCash, symbolProperties, _cashBook, _registeredTypes, cache, underlying);
174 security =
new Forex.Forex(symbol, exchangeHours, quoteCash, baseCash, symbolProperties, _cashBook, _registeredTypes, cache);
178 security =
new Cfd.Cfd(symbol, exchangeHours, quoteCash, symbolProperties, _cashBook, _registeredTypes, cache);
182 security =
new Index.Index(symbol, exchangeHours, quoteCash, symbolProperties, _cashBook, _registeredTypes, cache);
186 security =
new Crypto.Crypto(symbol, exchangeHours, quoteCash, baseCash, symbolProperties, _cashBook, _registeredTypes, cache);
190 security =
new CryptoFuture.CryptoFuture(symbol, exchangeHours, quoteCash, baseCash, symbolProperties, _cashBook, _registeredTypes, cache);
195 security =
new Security(symbol, exchangeHours, quoteCash, symbolProperties, _cashBook, _registeredTypes, cache);
201 if (security.IsTradable)
203 security.IsTradable = !configList.IsInternalFeed;
206 security.AddData(configList);
209 if (initializeSecurity)
211 _securityInitializerProvider.SecurityInitializer.Initialize(security);
214 CheckCanonicalSecurityModels(security);
218 if (leverage != Security.NullLeverage)
220 security.SetLeverage(leverage);
226 if ((_isLiveMode || isNotNormalized) && security.Type ==
SecurityType.Equity)
228 security.PriceVariationModel =
new EquityPriceVariationModel();
240 List<SubscriptionDataConfig> subscriptionDataConfigList,
241 decimal leverage = 0,
242 bool addToSymbolCache =
true,
245 return CreateSecurity(symbol, subscriptionDataConfigList, leverage, addToSymbolCache, underlying, initializeSecurity:
true);
255 return CreateSecurity(symbol,
new List<SubscriptionDataConfig> { subscriptionDataConfig }, leverage, addToSymbolCache, underlying);
265 return CreateSecurity(symbol,
266 new List<SubscriptionDataConfig>(),
268 addToSymbolCache:
false,
270 initializeSecurity:
false);
279 _isLiveMode = isLiveMode;
286 private void CheckCanonicalSecurityModels(
Security security)
288 if (!_modelsMismatchWarningSent &&
289 _algorithm !=
null &&
291 _algorithm.Securities.TryGetValue(security.
Symbol.
Canonical, out var canonicalSecurity))
293 if (security.
FillModel.GetType() != canonicalSecurity.FillModel.GetType() ||
294 security.
FeeModel.GetType() != canonicalSecurity.FeeModel.GetType() ||
295 security.
BuyingPowerModel.GetType() != canonicalSecurity.BuyingPowerModel.GetType() ||
297 security.
SlippageModel.GetType() != canonicalSecurity.SlippageModel.GetType() ||
298 security.
VolatilityModel.GetType() != canonicalSecurity.VolatilityModel.GetType() ||
299 security.
SettlementModel.GetType() != canonicalSecurity.SettlementModel.GetType())
301 _modelsMismatchWarningSent =
true;
302 _algorithm.Debug($
"Warning: Security {security.Symbol} its canonical security {security.Symbol.Canonical} have at least one model of different types (fill, fee, buying power, margin interest rate, slippage, volatility, settlement). To avoid this, consider using a security initializer to set the right models to each security type according to your algorithm's requirements.");