Beispiel #1
0
 /********************************************************
  * CLASS CONSTRUCTOR
  *********************************************************/
 /// <summary>
 /// Initialise security portfolio manager.
 /// </summary>
 public SecurityPortfolioManager(SecurityManager securityManager, SecurityTransactionManager transactions)
 {
     Securities        = securityManager;
     Transactions      = transactions;
     CashBook          = new CashBook();
     _baseCurrencyCash = CashBook[CashBook.BaseCurrency];
 }
        /********************************************************
         * CLASS CONSTRUCTOR
         *********************************************************/
        /// <summary>
        /// Initialise security portfolio manager.
        /// </summary>
        public SecurityPortfolioManager(SecurityManager securityManager, SecurityTransactionManager transactions)
        {
            Securities      = securityManager;
            Transactions    = transactions;
            MarginCallModel = new MarginCallModel(this);

            CashBook          = new CashBook();
            _baseCurrencyCash = CashBook[CashBook.AccountCurrency];
        }
Beispiel #3
0
 /// <summary>
 /// Creates a new instance of the SecurityService class
 /// </summary>
 public SecurityService(CashBook cashBook,
                        MarketHoursDatabase marketHoursDatabase,
                        SymbolPropertiesDatabase symbolPropertiesDatabase,
                        ISecurityInitializerProvider securityInitializerProvider)
 {
     _cashBook                    = cashBook;
     _marketHoursDatabase         = marketHoursDatabase;
     _symbolPropertiesDatabase    = symbolPropertiesDatabase;
     _securityInitializerProvider = securityInitializerProvider;
 }
        /// <summary>
        /// Initialise security portfolio manager.
        /// </summary>
        public SecurityPortfolioManager(SecurityManager securityManager, SecurityTransactionManager transactions)
        {
            Securities      = securityManager;
            Transactions    = transactions;
            MarginCallModel = new MarginCallModel(this);

            CashBook          = new CashBook();
            _baseCurrencyCash = CashBook[CashBook.AccountCurrency];

            // default to $100,000.00
            _baseCurrencyCash.Quantity = 100000;
        }
Beispiel #5
0
 /// <summary>
 /// Creates a new instance of the SecurityService class
 /// </summary>
 public SecurityService(CashBook cashBook,
                        MarketHoursDatabase marketHoursDatabase,
                        SymbolPropertiesDatabase symbolPropertiesDatabase,
                        ISecurityInitializerProvider securityInitializerProvider,
                        IRegisteredSecurityDataTypesProvider registeredTypes)
 {
     _cashBook                    = cashBook;
     _registeredTypes             = registeredTypes;
     _marketHoursDatabase         = marketHoursDatabase;
     _symbolPropertiesDatabase    = symbolPropertiesDatabase;
     _securityInitializerProvider = securityInitializerProvider;
 }
        /// <summary>
        /// Set the cash for the specified symbol
        /// </summary>
        /// <param name="symbol">The cash symbol to set</param>
        /// <param name="cash">Decimal cash value of portfolio</param>
        /// <param name="conversionRate">The current conversion rate for the</param>
        public void SetCash(string symbol, decimal cash, decimal conversionRate)
        {
            Cash item;

            if (CashBook.TryGetValue(symbol, out item))
            {
                item.Quantity       = cash;
                item.ConversionRate = conversionRate;
            }
            else
            {
                CashBook.Add(symbol, cash, conversionRate);
            }
        }
        /// <summary>
        /// Set the cash for the specified symbol
        /// </summary>
        /// <param name="symbol">The cash symbol to set</param>
        /// <param name="cash">Decimal cash value of portfolio</param>
        /// <param name="conversionRate">The current conversion rate for the</param>
        public void SetCash(string symbol, decimal cash, decimal conversionRate)
        {
            _setCashWasCalled = true;
            Cash item;

            if (CashBook.TryGetValue(symbol, out item))
            {
                item.SetAmount(cash);
                item.ConversionRate = conversionRate;
            }
            else
            {
                CashBook.Add(symbol, cash, conversionRate);
            }
        }
        /// <summary>
        /// Initialise security portfolio manager.
        /// </summary>
        public SecurityPortfolioManager(SecurityManager securityManager, SecurityTransactionManager transactions, IOrderProperties defaultOrderProperties = null)
        {
            Securities      = securityManager;
            Transactions    = transactions;
            MarginCallModel = new DefaultMarginCallModel(this, defaultOrderProperties);

            CashBook              = new CashBook();
            UnsettledCashBook     = new CashBook();
            _unsettledCashAmounts = new List <UnsettledCashAmount>();

            _baseCurrencyCash          = CashBook[CashBook.AccountCurrency];
            _baseCurrencyUnsettledCash = UnsettledCashBook[CashBook.AccountCurrency];

            // default to $100,000.00
            _baseCurrencyCash.SetAmount(100000);
        }
 /// <summary>
 /// Creates a new instance of the SecurityService class
 /// </summary>
 public SecurityService(CashBook cashBook,
                        MarketHoursDatabase marketHoursDatabase,
                        SymbolPropertiesDatabase symbolPropertiesDatabase,
                        ISecurityInitializerProvider securityInitializerProvider,
                        IRegisteredSecurityDataTypesProvider registeredTypes,
                        SecurityCacheProvider cacheProvider,
                        IPrimaryExchangeProvider primaryExchangeProvider = null)
 {
     _cashBook                    = cashBook;
     _registeredTypes             = registeredTypes;
     _marketHoursDatabase         = marketHoursDatabase;
     _symbolPropertiesDatabase    = symbolPropertiesDatabase;
     _securityInitializerProvider = securityInitializerProvider;
     _cacheProvider               = cacheProvider;
     _primaryExchangeProvider     = primaryExchangeProvider;
 }
Beispiel #10
0
        /// <summary>
        /// Ensures that we have a data feed to convert this currency into the base currency.
        /// This will add a subscription at the lowest resolution if one is not found.
        /// </summary>
        /// <param name="securities">The security manager</param>
        /// <param name="subscriptions">The subscription manager used for searching and adding subscriptions</param>
        /// <param name="marketHoursDatabase">A security exchange hours provider instance used to resolve exchange hours for new subscriptions</param>
        /// <param name="symbolPropertiesDatabase">A symbol properties database instance</param>
        /// <param name="marketMap">The market map that decides which market the new security should be in</param>
        /// <param name="cashBook">The cash book - used for resolving quote currencies for created conversion securities</param>
        /// <returns>Returns the added currency security if needed, otherwise null</returns>
        public Security EnsureCurrencyDataFeed(SecurityManager securities, SubscriptionManager subscriptions, MarketHoursDatabase marketHoursDatabase, SymbolPropertiesDatabase symbolPropertiesDatabase, IReadOnlyDictionary <SecurityType, string> marketMap, CashBook cashBook)
        {
            if (Symbol == CashBook.AccountCurrency)
            {
                SecuritySymbol  = QuantConnect.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.");
            }

            // we require a subscription that converts this into the base currency
            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);
                }
            }
            // if we've made it here we didn't find a subscription, so we'll need to add one
            var currencyPairs = Currencies.CurrencyPairs.Select(x =>
            {
                // allow XAU or XAG to be used as quote currencies, but pairs including them are CFDs
                var securityType = Symbol.StartsWith("X") ? SecurityType.Cfd : SecurityType.Forex;
                var market       = marketMap[securityType];
                return(QuantConnect.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;
                    // set this as an internal feed so that the data doesn't get sent into the algorithm's OnData events
                    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, quoteCash, config, symbolProperties);
                    }
                    securities.Add(config.Symbol, security);
                    Log.Trace("Cash.EnsureCurrencyDataFeed(): Adding " + symbol.Value + " for cash " + Symbol + " currency feed");
                    return(security);
                }
            }

            // if this still hasn't been set then it's an error condition
            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));
        }
Beispiel #11
0
        /// <summary>
        /// Ensures that we have a data feed to convert this currency into the base currency.
        /// This will add a subscription at the lowest resolution if one is not found.
        /// </summary>
        /// <param name="securities">The security manager</param>
        /// <param name="subscriptions">The subscription manager used for searching and adding subscriptions</param>
        /// <param name="marketHoursDatabase">A security exchange hours provider instance used to resolve exchange hours for new subscriptions</param>
        /// <param name="symbolPropertiesDatabase">A symbol properties database instance</param>
        /// <param name="marketMap">The market map that decides which market the new security should be in</param>
        /// <param name="cashBook">The cash book - used for resolving quote currencies for created conversion securities</param>
        /// <param name="changes"></param>
        /// <returns>Returns the added currency security if needed, otherwise null</returns>
        public Security EnsureCurrencyDataFeed(SecurityManager securities,
                                               SubscriptionManager subscriptions,
                                               MarketHoursDatabase marketHoursDatabase,
                                               SymbolPropertiesDatabase symbolPropertiesDatabase,
                                               IReadOnlyDictionary <SecurityType, string> marketMap,
                                               CashBook cashBook,
                                               SecurityChanges changes
                                               )
        {
            // this gets called every time we add securities using universe selection,
            // so must of the time we've already resolved the value and don't need to again
            if (ConversionRateSecurity != null)
            {
                return(null);
            }

            if (Symbol == CashBook.AccountCurrency)
            {
                ConversionRateSecurity = null;
                _isBaseCurrency        = true;
                ConversionRate         = 1.0m;
                return(null);
            }

            // we require a security that converts this into the base currency
            string normal             = Symbol + CashBook.AccountCurrency;
            string invert             = CashBook.AccountCurrency + Symbol;
            var    securitiesToSearch = securities.Select(kvp => kvp.Value)
                                        .Concat(changes.AddedSecurities)
                                        .Where(s => s.Type == SecurityType.Forex || s.Type == SecurityType.Cfd || s.Type == SecurityType.Crypto);

            foreach (var security in securitiesToSearch)
            {
                if (security.Symbol.Value == normal)
                {
                    ConversionRateSecurity = security;
                    return(null);
                }
                if (security.Symbol.Value == invert)
                {
                    ConversionRateSecurity = security;
                    _invertRealTimePrice   = true;
                    return(null);
                }
            }
            // if we've made it here we didn't find a security, so we'll need to add one

            // Create a SecurityType to Market mapping with the markets from SecurityManager members
            var markets = securities.Select(x => x.Key).GroupBy(x => x.SecurityType).ToDictionary(x => x.Key, y => y.First().ID.Market);

            if (markets.ContainsKey(SecurityType.Cfd) && !markets.ContainsKey(SecurityType.Forex))
            {
                markets.Add(SecurityType.Forex, markets[SecurityType.Cfd]);
            }
            if (markets.ContainsKey(SecurityType.Forex) && !markets.ContainsKey(SecurityType.Cfd))
            {
                markets.Add(SecurityType.Cfd, markets[SecurityType.Forex]);
            }

            var potentials = Currencies.CurrencyPairs.Select(fx => CreateSymbol(marketMap, fx, markets, SecurityType.Forex))
                             .Concat(Currencies.CfdCurrencyPairs.Select(cfd => CreateSymbol(marketMap, cfd, markets, SecurityType.Cfd)))
                             .Concat(Currencies.CryptoCurrencyPairs.Select(crypto => CreateSymbol(marketMap, crypto, markets, SecurityType.Crypto)));

            var minimumResolution = subscriptions.Subscriptions.Select(x => x.Resolution).DefaultIfEmpty(Resolution.Minute).Min();
            var objectType        = minimumResolution == Resolution.Tick ? typeof(Tick) : typeof(QuoteBar);

            foreach (var symbol in potentials)
            {
                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.Value);
                    }
                    var marketHoursDbEntry = marketHoursDatabase.GetEntry(symbol.ID.Market, symbol.Value, symbol.ID.SecurityType);
                    var exchangeHours      = marketHoursDbEntry.ExchangeHours;
                    // set this as an internal feed so that the data doesn't get sent into the algorithm's OnData events
                    var config = subscriptions.Add(objectType, TickType.Quote, symbol, minimumResolution, marketHoursDbEntry.DataTimeZone, exchangeHours.TimeZone, false, true, false, true);

                    Security security;
                    if (securityType == SecurityType.Cfd)
                    {
                        security = new Cfd.Cfd(exchangeHours, quoteCash, config, symbolProperties);
                    }
                    else if (securityType == SecurityType.Crypto)
                    {
                        security = new Crypto.Crypto(exchangeHours, quoteCash, config, symbolProperties);
                    }
                    else
                    {
                        security = new Forex.Forex(exchangeHours, quoteCash, config, symbolProperties);
                    }

                    ConversionRateSecurity = security;
                    securities.Add(config.Symbol, security);
                    Log.Trace("Cash.EnsureCurrencyDataFeed(): Adding " + symbol.Value + " for cash " + Symbol + " currency feed");
                    return(security);
                }
            }

            // if this still hasn't been set then it's an error condition
            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));
        }