/// <summary> /// Creates a security and matching configuration. This applies the default leverage if /// leverage is less than or equal to zero. /// This method also add the new symbol mapping to the <see cref="SymbolCache"/> /// </summary> public static Security CreateSecurity(SecurityPortfolioManager securityPortfolioManager, SubscriptionManager subscriptionManager, MarketHoursDatabase marketHoursDatabase, SymbolPropertiesDatabase symbolPropertiesDatabase, ISecurityInitializer securityInitializer, Symbol symbol, Resolution resolution, bool fillDataForward, decimal leverage, bool extendedMarketHours, bool isInternalFeed, bool isCustomData, bool addToSymbolCache = true) { var marketHoursDbEntry = marketHoursDatabase.GetEntry(symbol.ID.Market, symbol.Value, symbol.ID.SecurityType); var exchangeHours = marketHoursDbEntry.ExchangeHours; var defaultQuoteCurrency = CashBook.AccountCurrency; if (symbol.ID.SecurityType == SecurityType.Forex) { defaultQuoteCurrency = symbol.Value.Substring(3); } var symbolProperties = symbolPropertiesDatabase.GetSymbolProperties(symbol.ID.Market, symbol.Value, symbol.ID.SecurityType, defaultQuoteCurrency); var type = resolution == Resolution.Tick ? typeof(Tick) : typeof(TradeBar); if (symbol.ID.SecurityType == SecurityType.Option && resolution != Resolution.Tick) { type = typeof(QuoteBar); } return(CreateSecurity(type, securityPortfolioManager, subscriptionManager, exchangeHours, marketHoursDbEntry.DataTimeZone, symbolProperties, securityInitializer, symbol, resolution, fillDataForward, leverage, extendedMarketHours, isInternalFeed, isCustomData, addToSymbolCache)); }
public Security EnsureCurrencyDataFeed(SecurityManager securities, SubscriptionManager subscriptions, MarketHoursDatabase marketHoursDatabase, SymbolPropertiesDatabase symbolPropertiesDatabase, IReadOnlyDictionary <SecurityType, string> marketMap, CashBook cashBook) { if (Symbol == CashBook.AccountCurrency) { SecuritySymbol = VigiothCapital.QuantTrader.Symbol.Empty; _isBaseCurrency = true; ConversionRate = 1.0m; return(null); } if (subscriptions.Count == 0) { throw new InvalidOperationException("Unable to add cash when no subscriptions are present. Please add subscriptions in the Initialize() method."); } string normal = Symbol + CashBook.AccountCurrency; string invert = CashBook.AccountCurrency + Symbol; foreach (var config in subscriptions.Subscriptions.Where(config => config.SecurityType == SecurityType.Forex || config.SecurityType == SecurityType.Cfd)) { if (config.Symbol.Value == normal) { SecuritySymbol = config.Symbol; return(null); } if (config.Symbol.Value == invert) { SecuritySymbol = config.Symbol; _invertRealTimePrice = true; return(null); } } var currencyPairs = Currencies.CurrencyPairs.Select(x => { var securityType = Symbol.StartsWith("X") ? SecurityType.Cfd : SecurityType.Forex; var market = marketMap[securityType]; return(VigiothCapital.QuantTrader.Symbol.Create(x, securityType, market)); }); var minimumResolution = subscriptions.Subscriptions.Select(x => x.Resolution).DefaultIfEmpty(Resolution.Minute).Min(); var objectType = minimumResolution == Resolution.Tick ? typeof(Tick) : typeof(TradeBar); foreach (var symbol in currencyPairs) { if (symbol.Value == normal || symbol.Value == invert) { _invertRealTimePrice = symbol.Value == invert; var securityType = symbol.ID.SecurityType; var symbolProperties = symbolPropertiesDatabase.GetSymbolProperties(symbol.ID.Market, symbol.Value, securityType, Symbol); Cash quoteCash; if (!cashBook.TryGetValue(symbolProperties.QuoteCurrency, out quoteCash)) { throw new Exception("Unable to resolve quote cash: " + symbolProperties.QuoteCurrency + ". This is required to add conversion feed: " + symbol.ToString()); } var marketHoursDbEntry = marketHoursDatabase.GetEntry(symbol.ID.Market, symbol.Value, symbol.ID.SecurityType); var exchangeHours = marketHoursDbEntry.ExchangeHours; var config = subscriptions.Add(objectType, symbol, minimumResolution, marketHoursDbEntry.DataTimeZone, exchangeHours.TimeZone, false, true, false, true); SecuritySymbol = config.Symbol; Security security; if (securityType == SecurityType.Cfd) { security = new Cfd.Cfd(exchangeHours, quoteCash, config, symbolProperties); } else { security = new Forex.Forex(exchangeHours, this, config, symbolProperties); } securities.Add(config.Symbol, security); Log.Trace("Cash.EnsureCurrencyDataFeed(): Adding " + symbol.Value + " for cash " + Symbol + " currency feed"); return(security); } } throw new ArgumentException(string.Format("In order to maintain cash in {0} you are required to add a subscription for Forex pair {0}{1} or {1}{0}", Symbol, CashBook.AccountCurrency)); }