コード例 #1
0
        private Security CreateSecurity()
        {
            var config   = CreateTradeBarDataConfig(SecurityType.Forex);
            var security = new QuantConnect.Securities.Forex.Forex(SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork), new Cash("abc", 0, 0), config);

            return(security);
        }
コード例 #2
0
        /// <summary>
        /// Ensures that we have a data feed to conver 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>
        public void EnsureCurrencyDataFeed(SecurityManager securities, SubscriptionManager subscriptions)
        {
            if (Symbol == CashBook.AccountCurrency)
            {
                _isBaseCurrency = true;
                ConversionRate  = 1.0m;
                return;
            }

            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;

            for (int i = 0; i < subscriptions.Subscriptions.Count; i++)
            {
                var config = subscriptions.Subscriptions[i];
                if (config.SecurityType != SecurityType.Forex)
                {
                    continue;
                }
                if (config.Symbol == normal)
                {
                    _config = config;
                    return;
                }
                if (config.Symbol == invert)
                {
                    _config = config;
                    _invertRealTimePrice = true;
                    return;
                }
            }

            // if we've made it here we didn't find a subscription, so we'll need to add one
            var currencyPairs     = Forex.Forex.CurrencyPairs;
            var minimumResolution = subscriptions.Subscriptions.Min(x => x.Resolution);
            var objectType        = minimumResolution == Resolution.Tick ? typeof(Tick) : typeof(TradeBar);
            var isTradeBar        = objectType == typeof(TradeBar);

            foreach (var symbol in currencyPairs)
            {
                if (symbol == normal || symbol == invert)
                {
                    _invertRealTimePrice = symbol == invert;
                    // set this as an internal feed so that the data doesn't get sent into the algorithm's OnData events
                    _config = subscriptions.Add(objectType, SecurityType.Forex, symbol, minimumResolution, true, false, isTradeBar, isTradeBar, true);
                    var security = new Forex.Forex(this, _config, 1m, false);
                    securities.Add(symbol, security);
                    return;
                }
            }

            // 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));
        }
コード例 #3
0
        /// <summary>
        /// Add a new security by all of its properties.
        /// </summary>
        /// <param name="symbol">Symbol of the security</param>
        /// <param name="config">The SubscriptionDataConfig for this symbol</param>
        /// <param name="leverage">Leverage for this security, default = 1</param>
        /// <param name="isDynamicallyLoadedData">Use dynamic data</param>
        public void Add(string symbol, SubscriptionDataConfig config, decimal leverage = 1m, bool isDynamicallyLoadedData = false)
        {
            //Upper case sybol:
            symbol = symbol.ToUpper();
            if (symbol != config.Symbol)
            {
                throw new ArgumentException("Expected SubscriptionDataConfig for " + symbol + " but received " + config.Symbol);
            }

            CheckResolutionCounts(config.Resolution);

            //If we don't already have this asset, add it to the securities list.
            if (_securityManager.ContainsKey(symbol))
            {
                //Otherwise, we already have it, just change its resolution:
                Log.Trace("Algorithm.Securities.Add(): Changing security information will overwrite portfolio");
            }

            switch (config.Security)
            {
            case SecurityType.Equity:
                _securityManager[symbol] = new Equity.Equity(symbol, config, leverage, isDynamicallyLoadedData);
                break;

            case SecurityType.Forex:
                _securityManager[symbol] = new Forex.Forex(symbol, config, leverage, isDynamicallyLoadedData);
                break;

            case SecurityType.Base:
                _securityManager[symbol] = new Security(symbol, config, leverage, isDynamicallyLoadedData);
                break;
            }
        }
コード例 #4
0
ファイル: ForexHoldingTest.cs プロジェクト: zhenpingfeng/Lean
        public void TotalProfitIsCorrectlyEstimated(string ticker, decimal conversionRate,
                                                    decimal minimumPriceVariation,
                                                    int lotSize, decimal entryPrice, decimal pips, int entryQuantity)
        {
            // Arrange
            var timeKeeper = new TimeKeeper(DateTime.Now, TimeZones.NewYork);

            var symbol            = Symbol.Create(ticker, SecurityType.Forex, Market.FXCM);
            var pairQuoteCurrency = symbol.Value.Substring(startIndex: 3);
            var cash         = new Cash(pairQuoteCurrency, amount: 100000, conversionRate: conversionRate);
            var subscription = new SubscriptionDataConfig(typeof(QuoteBar), symbol, Resolution.Daily,
                                                          TimeZones.NewYork, TimeZones.NewYork, fillForward: true,
                                                          extendedHours: true, isInternalFeed: true);

            var pair = new QuantConnect.Securities.Forex.Forex(SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork),
                                                               cash, subscription,
                                                               new SymbolProperties("", pairQuoteCurrency, 1,
                                                                                    minimumPriceVariation, lotSize));

            pair.SetLocalTimeKeeper(timeKeeper.GetLocalTimeKeeper(TimeZones.NewYork));
            pair.SetFeeModel(new ConstantFeeModel(decimal.Zero));
            var forexHolding = new ForexHolding(pair);

            // Act
            forexHolding.SetHoldings(entryPrice, entryQuantity);
            var priceVariation = pips * 10 * minimumPriceVariation;

            forexHolding.UpdateMarketPrice(entryPrice + priceVariation);
            pair.SetMarketPrice(new Tick(DateTime.Now, pair.Symbol, forexHolding.Price, forexHolding.Price));
            var actualPips = forexHolding.TotalCloseProfitPips();

            // Assert
            Assert.AreEqual(pips, actualPips);
        }
コード例 #5
0
        /// <summary>
        /// Add a new security by all of its properties.
        /// </summary>
        /// <param name="symbol">Symbol of the security</param>
        /// <param name="type">Type of security: Equity, Forex or Future</param>
        /// <param name="resolution">Resolution of data required: currently only tick, second and minute for QuantConnect sources.</param>
        /// <param name="fillDataForward">Return previous bar's data when there is no trading in this bar</param>
        /// <param name="leverage">Leverage for this security, default = 1</param>
        /// <param name="extendedMarketHours">Request all the data available, including the extended market hours from 4am - 8pm.</param>
        /// <param name="isDynamicallyLoadedData">Use dynamic data</param>
        public void Add(string symbol, SecurityType type = SecurityType.Equity, Resolution resolution = Resolution.Minute, bool fillDataForward = true, decimal leverage = 1, bool extendedMarketHours = false, bool isDynamicallyLoadedData = false)
        {
            //Upper case sybol:
            symbol = symbol.ToUpper();

            //Maximum Data Usage: mainly RAM constraints but this has never been fully tested.
            if (GetResolutionCount(Resolution.Tick) == 30 && resolution == Resolution.Tick)
            {
                throw new Exception("We currently only support 30 tick assets at a time.");
            }
            if (GetResolutionCount(Resolution.Second) == 100 && resolution == Resolution.Second)
            {
                throw new Exception("We currently only support 100 second resolution securities at a time.");
            }
            if (GetResolutionCount(Resolution.Minute) == 1000 && resolution == Resolution.Minute)
            {
                throw new Exception("We currently only support 1000 minute assets at a time.");
            }

            //If we don't already have this asset, add it to the securities list.
            if (!_securityManager.ContainsKey(symbol))
            {
                switch (type)
                {
                case SecurityType.Equity:
                    Add(symbol, new Equity.Equity(symbol, resolution, fillDataForward, leverage, extendedMarketHours, isDynamicallyLoadedData));
                    break;

                case SecurityType.Forex:
                    Add(symbol, new Forex.Forex(symbol, resolution, fillDataForward, leverage, extendedMarketHours, isDynamicallyLoadedData));
                    break;

                case SecurityType.Base:
                    Add(symbol, new Security(symbol, SecurityType.Base, resolution, fillDataForward, leverage, extendedMarketHours));
                    break;
                }
            }
            else
            {
                //Otherwise, we already have it, just change its resolution:
                Log.Trace("Algorithm.Securities.Add(): Changing security information will overwrite portfolio");
                switch (type)
                {
                case SecurityType.Equity:
                    _securityManager[symbol] = new Equity.Equity(symbol, resolution, fillDataForward, leverage, extendedMarketHours);
                    break;

                case SecurityType.Forex:
                    _securityManager[symbol] = new Forex.Forex(symbol, resolution, fillDataForward, leverage, extendedMarketHours);
                    break;

                case SecurityType.Base:
                    _securityManager[symbol] = new Security(symbol, SecurityType.Base, resolution, fillDataForward, leverage, extendedMarketHours);
                    break;
                }
            }
        }
コード例 #6
0
        private Security CreateSecurity()
        {
            var config   = CreateTradeBarDataConfig(SecurityType.Forex);
            var security = new QuantConnect.Securities.Forex.Forex(
                SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork),
                new Cash("abc", 0, 0),
                config,
                SymbolProperties.GetDefault("abc"),
                ErrorCurrencyConverter.Instance
                );

            return(security);
        }
コード例 #7
0
ファイル: Cash.cs プロジェクト: andrewfry/Lean
        /// <summary>
        /// Ensures that we have a data feed to conver 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>
        public void EnsureCurrencyDataFeed(SecurityManager securities, SubscriptionManager subscriptions, MarketHoursDatabase marketHoursDatabase)
        {
            if (Symbol == CashBook.AccountCurrency)
            {
                SecuritySymbol  = QuantConnect.Symbol.Empty;
                _isBaseCurrency = true;
                ConversionRate  = 1.0m;
                return;
            }

            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))
            {
                if (config.Symbol.Value == normal)
                {
                    SecuritySymbol = config.Symbol;
                    return;
                }
                if (config.Symbol.Value == invert)
                {
                    SecuritySymbol       = config.Symbol;
                    _invertRealTimePrice = true;
                    return;
                }
            }

            // get the market from the first Forex subscription
            string market = (from config in subscriptions.Subscriptions
                             where config.SecurityType == SecurityType.Forex
                             select config.Market).FirstOrDefault() ?? Market.FXCM;

            // if we've made it here we didn't find a subscription, so we'll need to add one
            var currencyPairs     = Forex.Forex.CurrencyPairs.Select(x => new Symbol(SecurityIdentifier.GenerateForex(x, market), x));
            var minimumResolution = subscriptions.Subscriptions.Min(x => x.Resolution);
            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 marketHoursDbEntry = marketHoursDatabase.GetEntry(market, symbol, SecurityType.Forex);
                    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);
                    var security = new Forex.Forex(exchangeHours, this, config, 1m);
                    SecuritySymbol = config.Symbol;
                    securities.Add(config.Symbol, security);
                    Log.Trace("Cash.EnsureCurrencyDataFeed(): Adding " + symbol.ToString() + " for cash " + Symbol + " currency feed");
                    return;
                }
            }

            // 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));
        }
コード例 #8
0
ファイル: ForexHolding.cs プロジェクト: sopnic/Lean
 /********************************************************
 * CONSTRUCTOR/DELEGATE DEFINITIONS
 *********************************************************/
 /// <summary>
 /// Forex Holding Class
 /// </summary>
 /// <param name="security">The forex security being held</param>
 /// <param name="transactionModel">The transaction model used for the security</param>
 /// <param name="marginModel">The margin model used for the security</param>
 public ForexHolding(Forex security, ISecurityTransactionModel transactionModel, ISecurityMarginModel marginModel)
     : base(security)
 {
     _forex = security;
 }
コード例 #9
0
ファイル: SecurityService.cs プロジェクト: yinzhema/Lean
        /// <summary>
        /// Creates a new security
        /// </summary>
        /// <remarks>Following the obsoletion of Security.Subscriptions,
        /// both overloads will be merged removing <see cref="SubscriptionDataConfig"/> arguments</remarks>
        public Security CreateSecurity(Symbol symbol,
                                       List <SubscriptionDataConfig> subscriptionDataConfigList,
                                       decimal leverage      = 0,
                                       bool addToSymbolCache = true)
        {
            var configList = new SubscriptionDataConfigList(symbol);

            configList.AddRange(subscriptionDataConfigList);

            var exchangeHours = _marketHoursDatabase.GetEntry(symbol.ID.Market, symbol, symbol.ID.SecurityType).ExchangeHours;

            var defaultQuoteCurrency = _cashBook.AccountCurrency;

            if (symbol.ID.SecurityType == SecurityType.Forex)
            {
                defaultQuoteCurrency = symbol.Value.Substring(3);
            }

            if (symbol.ID.SecurityType == SecurityType.Crypto && !_symbolPropertiesDatabase.ContainsKey(symbol.ID.Market, symbol, symbol.ID.SecurityType))
            {
                throw new ArgumentException($"Symbol can't be found in the Symbol Properties Database: {symbol.Value}");
            }

            // For Futures Options that don't have a SPDB entry, the futures entry will be used instead.
            var symbolProperties = _symbolPropertiesDatabase.GetSymbolProperties(
                symbol.ID.Market,
                symbol,
                symbol.SecurityType,
                defaultQuoteCurrency);

            // add the symbol to our cache
            if (addToSymbolCache)
            {
                SymbolCache.Set(symbol.Value, symbol);
            }

            // verify the cash book is in a ready state
            var quoteCurrency = symbolProperties.QuoteCurrency;

            if (!_cashBook.ContainsKey(quoteCurrency))
            {
                // since we have none it's safe to say the conversion is zero
                _cashBook.Add(quoteCurrency, 0, 0);
            }
            if (symbol.ID.SecurityType == SecurityType.Forex || symbol.ID.SecurityType == SecurityType.Crypto)
            {
                // decompose the symbol into each currency pair
                string baseCurrency;
                if (symbol.ID.SecurityType == SecurityType.Forex)
                {
                    Forex.Forex.DecomposeCurrencyPair(symbol.Value, out baseCurrency, out quoteCurrency);
                }
                else
                {
                    Crypto.Crypto.DecomposeCurrencyPair(symbol, symbolProperties, out baseCurrency, out quoteCurrency);
                }

                if (!_cashBook.ContainsKey(baseCurrency))
                {
                    // since we have none it's safe to say the conversion is zero
                    _cashBook.Add(baseCurrency, 0, 0);
                }
                if (!_cashBook.ContainsKey(quoteCurrency))
                {
                    // since we have none it's safe to say the conversion is zero
                    _cashBook.Add(quoteCurrency, 0, 0);
                }
            }

            var quoteCash = _cashBook[symbolProperties.QuoteCurrency];
            var cache     = _cacheProvider.GetSecurityCache(symbol);

            Security security;

            switch (symbol.ID.SecurityType)
            {
            case SecurityType.Equity:
                security = new Equity.Equity(symbol, exchangeHours, quoteCash, symbolProperties, _cashBook, _registeredTypes, cache);
                break;

            case SecurityType.Option:
                if (addToSymbolCache)
                {
                    SymbolCache.Set(symbol.Underlying.Value, symbol.Underlying);
                }
                security = new Option.Option(symbol, exchangeHours, quoteCash, new Option.OptionSymbolProperties(symbolProperties), _cashBook, _registeredTypes, cache);
                break;

            case SecurityType.FutureOption:
                if (addToSymbolCache)
                {
                    SymbolCache.Set(symbol.Underlying.Value, symbol.Underlying);
                }
                var optionSymbolProperties = new Option.OptionSymbolProperties(symbolProperties);

                // Future options exercised only gives us one contract back, rather than the
                // 100x seen in equities.
                optionSymbolProperties.SetContractUnitOfTrade(1);

                security = new FutureOption.FutureOption(symbol, exchangeHours, quoteCash, optionSymbolProperties, _cashBook, _registeredTypes, cache);
                break;

            case SecurityType.Future:
                security = new Future.Future(symbol, exchangeHours, quoteCash, symbolProperties, _cashBook, _registeredTypes, cache);
                break;

            case SecurityType.Forex:
                security = new Forex.Forex(symbol, exchangeHours, quoteCash, symbolProperties, _cashBook, _registeredTypes, cache);
                break;

            case SecurityType.Cfd:
                security = new Cfd.Cfd(symbol, exchangeHours, quoteCash, symbolProperties, _cashBook, _registeredTypes, cache);
                break;

            case SecurityType.Crypto:
                security = new Crypto.Crypto(symbol, exchangeHours, quoteCash, symbolProperties, _cashBook, _registeredTypes, cache);
                break;

            default:
            case SecurityType.Base:
                security = new Security(symbol, exchangeHours, quoteCash, symbolProperties, _cashBook, _registeredTypes, cache);
                break;
            }

            // if we're just creating this security and it only has an internal
            // feed, mark it as non-tradable since the user didn't request this data
            if (!configList.IsInternalFeed)
            {
                security.IsTradable = true;
            }

            security.AddData(configList);

            // invoke the security initializer
            _securityInitializerProvider.SecurityInitializer.Initialize(security);

            // if leverage was specified then apply to security after the initializer has run, parameters of this
            // method take precedence over the intializer
            if (leverage != Security.NullLeverage)
            {
                security.SetLeverage(leverage);
            }

            var isNotNormalized = configList.DataNormalizationMode() == DataNormalizationMode.Raw;

            // In live mode and non normalized data, equity assumes specific price variation model
            if ((_isLiveMode || isNotNormalized) && security.Type == SecurityType.Equity)
            {
                security.PriceVariationModel = new EquityPriceVariationModel();
            }

            return(security);
        }
コード例 #10
0
        /// <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(Type factoryType,
                                              SecurityPortfolioManager securityPortfolioManager,
                                              SubscriptionManager subscriptionManager,
                                              SecurityExchangeHours exchangeHours,
                                              DateTimeZone dataTimeZone,
                                              ISecurityInitializer securityInitializer,
                                              Symbol symbol,
                                              Resolution resolution,
                                              bool fillDataForward,
                                              decimal leverage,
                                              bool extendedMarketHours,
                                              bool isInternalFeed,
                                              bool isCustomData,
                                              bool addToSymbolCache = true)
        {
            var sid = symbol.ID;

            // add the symbol to our cache
            if (addToSymbolCache)
            {
                SymbolCache.Set(symbol.Value, symbol);
            }

            //Add the symbol to Data Manager -- generate unified data streams for algorithm events
            var config = subscriptionManager.Add(factoryType, symbol, resolution, dataTimeZone, exchangeHours.TimeZone, isCustomData, fillDataForward,
                                                 extendedMarketHours, isInternalFeed);

            Security security;

            switch (config.SecurityType)
            {
            case SecurityType.Equity:
                security = new Equity.Equity(exchangeHours, config);
                break;

            case SecurityType.Forex:
                // decompose the symbol into each currency pair
                string baseCurrency, quoteCurrency;
                Forex.Forex.DecomposeCurrencyPair(symbol.Value, out baseCurrency, out quoteCurrency);

                if (!securityPortfolioManager.CashBook.ContainsKey(baseCurrency))
                {
                    // since we have none it's safe to say the conversion is zero
                    securityPortfolioManager.CashBook.Add(baseCurrency, 0, 0);
                }
                if (!securityPortfolioManager.CashBook.ContainsKey(quoteCurrency))
                {
                    // since we have none it's safe to say the conversion is zero
                    securityPortfolioManager.CashBook.Add(quoteCurrency, 0, 0);
                }
                security = new Forex.Forex(exchangeHours, securityPortfolioManager.CashBook[quoteCurrency], config);
                break;

            default:
            case SecurityType.Base:
                security = new Security(exchangeHours, config);
                break;
            }

            // invoke the security initializer
            securityInitializer.Initialize(security);

            // if leverage was specified then apply to security after the initializer has run, parameters of this
            // method take precedence over the intializer
            if (leverage > 0)
            {
                security.SetLeverage(leverage);
            }

            return(security);
        }
コード例 #11
0
 private Security CreateSecurity()
 {
     var config = CreateTradeBarDataConfig(SecurityType.Forex, Symbol);
     var security = new QuantConnect.Securities.Forex.Forex(SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork), new Cash("abc", 0, 0), config, 1);
     return security;
 }
コード例 #12
0
ファイル: ForexHolding.cs プロジェクト: skyfyl/Lean
 /// <summary>
 /// Forex Holding Class
 /// </summary>
 /// <param name="security">The forex security being held</param>
 public ForexHolding(Forex security)
     : base(security)
 {
     _forex = security;
 }
コード例 #13
0
        /// <summary>
        /// Creates a new security
        /// </summary>
        /// <remarks>Following the obsoletion of Security.Subscriptions,
        /// both overloads will be merged removing <see cref="SubscriptionDataConfig"/> arguments</remarks>
        public Security CreateSecurity(Symbol symbol,
                                       List <SubscriptionDataConfig> subscriptionDataConfigList,
                                       decimal leverage      = 0,
                                       bool addToSymbolCache = true)
        {
            var configList = new SubscriptionDataConfigList(symbol);

            configList.AddRange(subscriptionDataConfigList);

            var exchangeHours = _marketHoursDatabase.GetEntry(symbol.ID.Market, symbol, symbol.ID.SecurityType).ExchangeHours;

            var defaultQuoteCurrency = _cashBook.AccountCurrency;

            if (symbol.ID.SecurityType == SecurityType.Forex || symbol.ID.SecurityType == SecurityType.Crypto)
            {
                defaultQuoteCurrency = symbol.Value.Substring(3);
            }

            var symbolProperties = _symbolPropertiesDatabase.GetSymbolProperties(symbol.ID.Market, symbol, symbol.ID.SecurityType, defaultQuoteCurrency);

            // add the symbol to our cache
            if (addToSymbolCache)
            {
                SymbolCache.Set(symbol.Value, symbol);
            }

            // verify the cash book is in a ready state
            var quoteCurrency = symbolProperties.QuoteCurrency;

            if (!_cashBook.ContainsKey(quoteCurrency))
            {
                // since we have none it's safe to say the conversion is zero
                _cashBook.Add(quoteCurrency, 0, 0);
            }
            if (symbol.ID.SecurityType == SecurityType.Forex || symbol.ID.SecurityType == SecurityType.Crypto)
            {
                // decompose the symbol into each currency pair
                string baseCurrency;
                Forex.Forex.DecomposeCurrencyPair(symbol.Value, out baseCurrency, out quoteCurrency);

                if (!_cashBook.ContainsKey(baseCurrency))
                {
                    // since we have none it's safe to say the conversion is zero
                    _cashBook.Add(baseCurrency, 0, 0);
                }
                if (!_cashBook.ContainsKey(quoteCurrency))
                {
                    // since we have none it's safe to say the conversion is zero
                    _cashBook.Add(quoteCurrency, 0, 0);
                }
            }

            var quoteCash = _cashBook[symbolProperties.QuoteCurrency];

            Security security;

            switch (symbol.ID.SecurityType)
            {
            case SecurityType.Equity:
                security = new Equity.Equity(symbol, exchangeHours, quoteCash, symbolProperties, _cashBook);
                break;

            case SecurityType.Option:
                if (addToSymbolCache)
                {
                    SymbolCache.Set(symbol.Underlying.Value, symbol.Underlying);
                }
                security = new Option.Option(symbol, exchangeHours, _cashBook[_cashBook.AccountCurrency], new Option.OptionSymbolProperties(symbolProperties), _cashBook);
                break;

            case SecurityType.Future:
                security = new Future.Future(symbol, exchangeHours, _cashBook[_cashBook.AccountCurrency], symbolProperties, _cashBook);
                break;

            case SecurityType.Forex:
                security = new Forex.Forex(symbol, exchangeHours, quoteCash, symbolProperties, _cashBook);
                break;

            case SecurityType.Cfd:
                security = new Cfd.Cfd(symbol, exchangeHours, quoteCash, symbolProperties, _cashBook);
                break;

            case SecurityType.Crypto:
                security = new Crypto.Crypto(symbol, exchangeHours, quoteCash, symbolProperties, _cashBook);
                break;

            default:
            case SecurityType.Base:
                security = new Security(symbol, exchangeHours, quoteCash, symbolProperties, _cashBook);
                break;
            }

            // if we're just creating this security and it only has an internal
            // feed, mark it as non-tradable since the user didn't request this data
            if (!configList.IsInternalFeed)
            {
                security.IsTradable = true;
            }

            security.AddData(configList);

            // invoke the security initializer
            _securityInitializerProvider.SecurityInitializer.Initialize(security);

            // if leverage was specified then apply to security after the initializer has run, parameters of this
            // method take precedence over the intializer
            if (leverage > 0)
            {
                security.SetLeverage(leverage);
            }

            // In live mode, equity assumes specific price variation model
            if (_isLiveMode && security.Type == SecurityType.Equity)
            {
                security.PriceVariationModel = new EquityPriceVariationModel();
            }

            return(security);
        }
コード例 #14
0
ファイル: Cash.cs プロジェクト: pmerrill/Lean
        /// <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 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;

                    var securityType = symbol.ID.SecurityType;
                    Security security;
                    if (securityType == SecurityType.Cfd)
                    {
                        var symbolProperties = symbolPropertiesDatabase.GetSymbolProperties(symbol.ID.Market, symbol.Value, securityType);
                        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());
                        }
                        security = new Cfd.Cfd(exchangeHours, quoteCash, config, symbolProperties);
                    }
                    else
                    {
                        security = new Forex.Forex(exchangeHours, this, config);
                    }
                    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));
        }
コード例 #15
0
ファイル: Cash.cs プロジェクト: dalebrubaker/Lean
        /// <summary>
        /// Ensures that we have a data feed to conver 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="exchangeHoursProvider">A security exchange hours provider instance used to resolve exchange hours for new subscriptions</param>
        public void EnsureCurrencyDataFeed(SecurityManager securities, SubscriptionManager subscriptions, SecurityExchangeHoursProvider exchangeHoursProvider)
        {
            if (Symbol == CashBook.AccountCurrency)
            {
                SecuritySymbol = string.Empty;
                _isBaseCurrency = true;
                ConversionRate = 1.0m;
                return;
            }

            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))
            {
                if (config.Symbol == normal)
                {
                    SecuritySymbol = config.Symbol;
                    return;
                }
                if (config.Symbol == invert)
                {
                    SecuritySymbol = config.Symbol;
                    _invertRealTimePrice = true;
                    return;
                }
            }

            // get the market from the first Forex subscription
            string market = (from config in subscriptions.Subscriptions
                             where config.SecurityType == SecurityType.Forex
                             select config.Market).FirstOrDefault() ?? "fxcm";

            // if we've made it here we didn't find a subscription, so we'll need to add one
            var currencyPairs = Forex.Forex.CurrencyPairs;
            var minimumResolution = subscriptions.Subscriptions.Min(x => x.Resolution);
            var objectType = minimumResolution == Resolution.Tick ? typeof (Tick) : typeof (TradeBar);
            foreach (var symbol in currencyPairs)
            {
                if (symbol == normal || symbol == invert)
                {
                    _invertRealTimePrice = symbol == invert;
                    var exchangeHours = exchangeHoursProvider.GetExchangeHours(market, symbol, SecurityType.Forex);
                    // 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, SecurityType.Forex, symbol, minimumResolution, market, exchangeHours.TimeZone, true, false, true);
                    var security = new Forex.Forex(this, config, 1m);
                    SecuritySymbol = config.Symbol;
                    securities.Add(symbol, security);
                    Log.Trace("Cash.EnsureCurrencyDataFeed(): Adding " + symbol + " for cash " + Symbol + " currency feed");
                    return;
                }
            }

            // 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));
        }
コード例 #16
0
ファイル: Cash.cs プロジェクト: reddream/Lean
        /// <summary>
        /// Ensures that we have a data feed to conver 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>
        public void EnsureCurrencyDataFeed(SecurityManager securities, SubscriptionManager subscriptions)
        {
            if (Symbol == CashBook.AccountCurrency)
            {
                _isBaseCurrency = true;
                ConversionRate = 1.0m;
                return;
            }

            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;
            for (int i = 0; i < subscriptions.Subscriptions.Count; i++)
            {
                var config = subscriptions.Subscriptions[i];
                if (config.SecurityType != SecurityType.Forex)
                {
                    continue;
                }
                if (config.Symbol == normal)
                {
                    _config = config;
                    return;
                }
                if (config.Symbol == invert)
                {
                    _config = config;
                    _invertRealTimePrice = true;
                    return;
                }
            }

            // if we've made it here we didn't find a subscription, so we'll need to add one
            var currencyPairs = Forex.Forex.CurrencyPairs;
            var minimumResolution = subscriptions.Subscriptions.Min(x => x.Resolution);
            var objectType = minimumResolution == Resolution.Tick ? typeof (Tick) : typeof (TradeBar);
            var isTradeBar = objectType == typeof (TradeBar);
            foreach (var symbol in currencyPairs)
            {
                if (symbol == normal || symbol == invert)
                {
                    _invertRealTimePrice = symbol == invert;
                    // set this as an internal feed so that the data doesn't get sent into the algorithm's OnData events
                    _config = subscriptions.Add(objectType, SecurityType.Forex, symbol, minimumResolution, true, false, isTradeBar, isTradeBar, true);
                    var security = new Forex.Forex(this, _config, 1m, false);
                    securities.Add(symbol, security);
                    Log.Trace("Cash.EnsureCurrencyDataFeed(): Adding " + symbol + " for cash " + this.Symbol + " currency feed");
                    return;
                }
            }

            // 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));
        }
コード例 #17
0
ファイル: ForexHolding.cs プロジェクト: AcePilot10/InsiderBot
 /// <summary>
 /// Forex Holding Class
 /// </summary>
 /// <param name="security">The forex security being held</param>
 /// <param name="currencyConverter">A currency converter instance</param>
 public ForexHolding(Forex security, ICurrencyConverter currencyConverter)
     : base(security, currencyConverter)
 {
 }
コード例 #18
0
ファイル: Cash.cs プロジェクト: beezy3601/lean2
        /// <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));
        }
コード例 #19
0
ファイル: ForexHolding.cs プロジェクト: leinsister/Lean
 /// <summary>
 /// Forex Holding Class
 /// </summary>
 /// <param name="security">The forex security being held</param>
 public ForexHolding(Forex security)
     : base(security)
 {
     _forex = security;
 }
コード例 #20
0
ファイル: SecurityManager.cs プロジェクト: zhangxia85/Lean
        /// <summary>
        /// Creates a security and matching configuration. This applies the default leverage if
        /// leverage is less than or equal to zero
        /// </summary>
        public static Security CreateSecurity(SecurityPortfolioManager securityPortfolioManager,
                                              SubscriptionManager subscriptionManager,
                                              SecurityExchangeHoursProvider securityExchangeHoursProvider,
                                              SecurityType securityType,
                                              Symbol symbol,
                                              Resolution resolution,
                                              string market,
                                              bool fillDataForward,
                                              decimal leverage,
                                              bool extendedMarketHours,
                                              bool isInternalFeed,
                                              bool isCustomData)
        {
            //If it hasn't been set, use some defaults based on the portfolio type:
            if (leverage <= 0)
            {
                switch (securityType)
                {
                case SecurityType.Equity:
                    leverage = 2;     //Cash Ac. = 1, RegT Std = 2 or PDT = 4.
                    break;

                case SecurityType.Forex:
                    leverage = 50;
                    break;
                }
            }

            if (market == null)
            {
                // set default values
                if (securityType == SecurityType.Forex)
                {
                    market = "fxcm";
                }
                else if (securityType == SecurityType.Equity)
                {
                    market = "usa";
                }
                else
                {
                    market = "usa";
                }
            }

            //Add the symbol to Data Manager -- generate unified data streams for algorithm events
            var exchangeHours = securityExchangeHoursProvider.GetExchangeHours(market, symbol, securityType);
            var tradeBarType  = typeof(TradeBar);
            var type          = resolution == Resolution.Tick ? typeof(Tick) : tradeBarType;
            var config        = subscriptionManager.Add(type, securityType, symbol, resolution, market, exchangeHours.TimeZone, isCustomData, fillDataForward, extendedMarketHours, isInternalFeed);

            Security security;

            switch (config.SecurityType)
            {
            case SecurityType.Equity:
                security = new Equity.Equity(exchangeHours, config, leverage);
                break;

            case SecurityType.Forex:
                // decompose the symbol into each currency pair
                string baseCurrency, quoteCurrency;
                Forex.Forex.DecomposeCurrencyPair(symbol.Value, out baseCurrency, out quoteCurrency);

                if (!securityPortfolioManager.CashBook.ContainsKey(baseCurrency))
                {
                    // since we have none it's safe to say the conversion is zero
                    securityPortfolioManager.CashBook.Add(baseCurrency, 0, 0);
                }
                if (!securityPortfolioManager.CashBook.ContainsKey(quoteCurrency))
                {
                    // since we have none it's safe to say the conversion is zero
                    securityPortfolioManager.CashBook.Add(quoteCurrency, 0, 0);
                }
                security = new Forex.Forex(exchangeHours, securityPortfolioManager.CashBook[quoteCurrency], config, leverage);
                break;

            default:
            case SecurityType.Base:
                security = new Security(exchangeHours, config, leverage);
                break;
            }
            return(security);
        }
コード例 #21
0
        /// <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(List <Tuple <Type, TickType> > subscriptionDataTypes,
                                              SecurityPortfolioManager securityPortfolioManager,
                                              SubscriptionManager subscriptionManager,
                                              SecurityExchangeHours exchangeHours,
                                              DateTimeZone dataTimeZone,
                                              SymbolProperties symbolProperties,
                                              ISecurityInitializer securityInitializer,
                                              Symbol symbol,
                                              Resolution resolution,
                                              bool fillDataForward,
                                              decimal leverage,
                                              bool extendedMarketHours,
                                              bool isInternalFeed,
                                              bool isCustomData,
                                              bool isLiveMode,
                                              bool addToSymbolCache       = true,
                                              bool isFilteredSubscription = true)
        {
            if (!subscriptionDataTypes.Any())
            {
                throw new ArgumentNullException(nameof(subscriptionDataTypes), "At least one type needed to create security");
            }

            // add the symbol to our cache
            if (addToSymbolCache)
            {
                SymbolCache.Set(symbol.Value, symbol);
            }

            // Add the symbol to Data Manager -- generate unified data streams for algorithm events
            var configList = new SubscriptionDataConfigList(symbol);

            configList.AddRange(from subscriptionDataType
                                in subscriptionDataTypes
                                let dataType = subscriptionDataType.Item1
                                               let tickType = subscriptionDataType.Item2
                                                              select subscriptionManager.Add(dataType, tickType,
                                                                                             symbol, resolution, dataTimeZone,
                                                                                             exchangeHours.TimeZone, isCustomData,
                                                                                             fillDataForward, extendedMarketHours,
                                                                                             isInternalFeed, isFilteredSubscription));

            // verify the cash book is in a ready state
            var quoteCurrency = symbolProperties.QuoteCurrency;

            if (!securityPortfolioManager.CashBook.ContainsKey(quoteCurrency))
            {
                // since we have none it's safe to say the conversion is zero
                securityPortfolioManager.CashBook.Add(quoteCurrency, 0, 0);
            }
            if (symbol.ID.SecurityType == SecurityType.Forex || symbol.ID.SecurityType == SecurityType.Crypto)
            {
                // decompose the symbol into each currency pair
                string baseCurrency;
                Forex.Forex.DecomposeCurrencyPair(symbol.Value, out baseCurrency, out quoteCurrency);

                if (!securityPortfolioManager.CashBook.ContainsKey(baseCurrency))
                {
                    // since we have none it's safe to say the conversion is zero
                    securityPortfolioManager.CashBook.Add(baseCurrency, 0, 0);
                }
                if (!securityPortfolioManager.CashBook.ContainsKey(quoteCurrency))
                {
                    // since we have none it's safe to say the conversion is zero
                    securityPortfolioManager.CashBook.Add(quoteCurrency, 0, 0);
                }
            }

            var quoteCash = securityPortfolioManager.CashBook[symbolProperties.QuoteCurrency];

            Security security;

            switch (configList.Symbol.ID.SecurityType)
            {
            case SecurityType.Equity:
                security = new Equity.Equity(symbol, exchangeHours, quoteCash, symbolProperties);
                break;

            case SecurityType.Option:
                if (addToSymbolCache)
                {
                    SymbolCache.Set(symbol.Underlying.Value, symbol.Underlying);
                }
                configList.SetDataNormalizationMode(DataNormalizationMode.Raw);
                security = new Option.Option(symbol, exchangeHours, securityPortfolioManager.CashBook[CashBook.AccountCurrency], new Option.OptionSymbolProperties(symbolProperties));
                break;

            case SecurityType.Future:
                configList.SetDataNormalizationMode(DataNormalizationMode.Raw);
                security = new Future.Future(symbol, exchangeHours, securityPortfolioManager.CashBook[CashBook.AccountCurrency], symbolProperties);
                break;

            case SecurityType.Forex:
                security = new Forex.Forex(symbol, exchangeHours, quoteCash, symbolProperties);
                break;

            case SecurityType.Cfd:
                security = new Cfd.Cfd(symbol, exchangeHours, quoteCash, symbolProperties);
                break;

            case SecurityType.Crypto:
                security = new Crypto.Crypto(symbol, exchangeHours, quoteCash, symbolProperties);
                break;

            default:
            case SecurityType.Base:
                security = new Security(symbol, exchangeHours, quoteCash, symbolProperties);
                break;
            }

            // if we're just creating this security and it only has an internal
            // feed, mark it as non-tradable since the user didn't request this data
            if (!configList.IsInternalFeed)
            {
                security.IsTradable = true;
            }

            security.AddData(configList);

            // invoke the security initializer
            securityInitializer.Initialize(security, true);

            // if leverage was specified then apply to security after the initializer has run, parameters of this
            // method take precedence over the intializer
            if (leverage > 0)
            {
                security.SetLeverage(leverage);
            }

            // In live mode, equity assumes specific price variation model
            if (isLiveMode && security.Type == SecurityType.Equity)
            {
                security.PriceVariationModel = new EquityPriceVariationModel();
            }

            return(security);
        }
コード例 #22
0
ファイル: SecurityManager.cs プロジェクト: andrewfry/Lean
        /// <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,
                                              Symbol symbol,
                                              Resolution resolution,
                                              bool fillDataForward,
                                              decimal leverage,
                                              bool extendedMarketHours,
                                              bool isInternalFeed,
                                              bool isCustomData)
        {
            var sid = symbol.ID;

            //If it hasn't been set, use some defaults based on the security type
            if (leverage <= 0)
            {
                if (sid.SecurityType == SecurityType.Equity)
                {
                    leverage = 2;
                }
                else if (sid.SecurityType == SecurityType.Forex)
                {
                    leverage = 50;
                }
                // default to 1 for everything else
                else
                {
                    leverage = 1m;
                }
            }

            // add the symbol to our cache
            SymbolCache.Set(symbol.Value, symbol);

            var market       = sid.Market;
            var securityType = sid.SecurityType;

            //Add the symbol to Data Manager -- generate unified data streams for algorithm events
            var marketHoursDbEntry = marketHoursDatabase.GetEntry(market, symbol, securityType);
            var exchangeHours      = marketHoursDbEntry.ExchangeHours;
            var tradeBarType       = typeof(TradeBar);
            var type   = resolution == Resolution.Tick ? typeof(Tick) : tradeBarType;
            var config = subscriptionManager.Add(type, symbol, resolution, marketHoursDbEntry.DataTimeZone, exchangeHours.TimeZone, isCustomData, fillDataForward: fillDataForward, extendedMarketHours: extendedMarketHours, isInternalFeed: isInternalFeed);

            Security security;

            switch (config.SecurityType)
            {
            case SecurityType.Equity:
                security = new Equity.Equity(exchangeHours, config, leverage);
                break;

            case SecurityType.Forex:
                // decompose the symbol into each currency pair
                string baseCurrency, quoteCurrency;
                Forex.Forex.DecomposeCurrencyPair(symbol.Value, out baseCurrency, out quoteCurrency);

                if (!securityPortfolioManager.CashBook.ContainsKey(baseCurrency))
                {
                    // since we have none it's safe to say the conversion is zero
                    securityPortfolioManager.CashBook.Add(baseCurrency, 0, 0);
                }
                if (!securityPortfolioManager.CashBook.ContainsKey(quoteCurrency))
                {
                    // since we have none it's safe to say the conversion is zero
                    securityPortfolioManager.CashBook.Add(quoteCurrency, 0, 0);
                }
                security = new Forex.Forex(exchangeHours, securityPortfolioManager.CashBook[quoteCurrency], config, leverage);
                break;

            default:
            case SecurityType.Base:
                security = new Security(exchangeHours, config, leverage);
                break;
            }
            return(security);
        }
コード例 #23
0
ファイル: Cash.cs プロジェクト: won21kr/Lean
        /// <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));
        }
コード例 #24
0
        /// <summary>
        /// Add a new security by all of its properties.
        /// </summary>
        /// <param name="symbol">Symbol of the security</param>
        /// <param name="type">Type of security: Equity, Forex or Future</param>
        /// <param name="resolution">Resolution of data required: currently only tick, second and minute for QuantConnect sources.</param>
        /// <param name="fillDataForward">Return previous bar's data when there is no trading in this bar</param>
        /// <param name="leverage">Leverage for this security, default = 1</param>
        /// <param name="extendedMarketHours">Request all the data available, including the extended market hours from 4am - 8pm.</param>
        /// <param name="isDynamicallyLoadedData">Use dynamic data</param>
        public void Add(string symbol, SecurityType type = SecurityType.Equity, Resolution resolution = Resolution.Minute, bool fillDataForward = true, decimal leverage = 1, bool extendedMarketHours = false, bool isDynamicallyLoadedData = false)
        {
            //Upper case sybol:
            symbol = symbol.ToUpper();

            //Maximum Data Usage: mainly RAM constraints but this has never been fully tested.
            if (GetResolutionCount(Resolution.Tick) >= _tickLimit && resolution == Resolution.Tick)
            {
                throw new Exception("We currently only support " + _tickLimit + " tick assets at a time due to physical memory limitations.");
            }
            if (GetResolutionCount(Resolution.Second) >= _secondLimit && resolution == Resolution.Second)
            {
                throw new Exception("We currently only support  " + _secondLimit + "  second resolution securities at a time due to physical memory limitations.");
            }
            if (GetResolutionCount(Resolution.Minute) >= _minuteLimit && resolution == Resolution.Minute)
            {
                throw new Exception("We currently only support  " + _minuteLimit + "  minute assets at a time due to physical memory limitations.");
            }

            //Current ram usage: this especially applies during live trading where micro servers have limited resources:
            var currentEstimatedRam = GetRamEstimate(GetResolutionCount(Resolution.Minute), GetResolutionCount(Resolution.Second), GetResolutionCount(Resolution.Tick));

            if (currentEstimatedRam > _maxRamEstimate)
            {
                throw new Exception("We estimate you will run out of memory (" + currentEstimatedRam + "mb of " + _maxRamEstimate + "mb physically available). Please reduce the number of symbols you're analysing or if in live trading upgrade your server to allow more memory.");
            }

            //If we don't already have this asset, add it to the securities list.
            if (!_securityManager.ContainsKey(symbol))
            {
                switch (type)
                {
                case SecurityType.Equity:
                    Add(symbol, new Equity.Equity(symbol, resolution, fillDataForward, leverage, extendedMarketHours, isDynamicallyLoadedData));
                    break;

                case SecurityType.Forex:
                    Add(symbol, new Forex.Forex(symbol, resolution, fillDataForward, leverage, extendedMarketHours, isDynamicallyLoadedData));
                    break;

                case SecurityType.Base:
                    Add(symbol, new Security(symbol, SecurityType.Base, resolution, fillDataForward, leverage, extendedMarketHours, isDynamicallyLoadedData));
                    break;
                }
            }
            else
            {
                //Otherwise, we already have it, just change its resolution:
                Log.Trace("Algorithm.Securities.Add(): Changing security information will overwrite portfolio");
                switch (type)
                {
                case SecurityType.Equity:
                    _securityManager[symbol] = new Equity.Equity(symbol, resolution, fillDataForward, leverage, extendedMarketHours);
                    break;

                case SecurityType.Forex:
                    _securityManager[symbol] = new Forex.Forex(symbol, resolution, fillDataForward, leverage, extendedMarketHours);
                    break;

                case SecurityType.Base:
                    _securityManager[symbol] = new Security(symbol, SecurityType.Base, resolution, fillDataForward, leverage, extendedMarketHours, isDynamicallyLoadedData);
                    break;
                }
            }
        }
コード例 #25
0
ファイル: SecurityManager.cs プロジェクト: xhxuciedu/Lean
        /// <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(Type factoryType,
                                              SecurityPortfolioManager securityPortfolioManager,
                                              SubscriptionManager subscriptionManager,
                                              SecurityExchangeHours exchangeHours,
                                              DateTimeZone dataTimeZone,
                                              SymbolProperties symbolProperties,
                                              ISecurityInitializer securityInitializer,
                                              Symbol symbol,
                                              Resolution resolution,
                                              bool fillDataForward,
                                              decimal leverage,
                                              bool extendedMarketHours,
                                              bool isInternalFeed,
                                              bool isCustomData,
                                              bool isLiveMode,
                                              bool addToSymbolCache       = true,
                                              bool isFilteredSubscription = true)
        {
            // add the symbol to our cache
            if (addToSymbolCache)
            {
                SymbolCache.Set(symbol.Value, symbol);
            }

            //Add the symbol to Data Manager -- generate unified data streams for algorithm events
            var config = subscriptionManager.Add(factoryType, symbol, resolution, dataTimeZone, exchangeHours.TimeZone, isCustomData, fillDataForward,
                                                 extendedMarketHours, isInternalFeed, isFilteredSubscription);

            // verify the cash book is in a ready state
            var quoteCurrency = symbolProperties.QuoteCurrency;

            if (!securityPortfolioManager.CashBook.ContainsKey(quoteCurrency))
            {
                // since we have none it's safe to say the conversion is zero
                securityPortfolioManager.CashBook.Add(quoteCurrency, 0, 0);
            }
            if (symbol.ID.SecurityType == SecurityType.Forex)
            {
                // decompose the symbol into each currency pair
                string baseCurrency;
                Forex.Forex.DecomposeCurrencyPair(symbol.Value, out baseCurrency, out quoteCurrency);

                if (!securityPortfolioManager.CashBook.ContainsKey(baseCurrency))
                {
                    // since we have none it's safe to say the conversion is zero
                    securityPortfolioManager.CashBook.Add(baseCurrency, 0, 0);
                }
                if (!securityPortfolioManager.CashBook.ContainsKey(quoteCurrency))
                {
                    // since we have none it's safe to say the conversion is zero
                    securityPortfolioManager.CashBook.Add(quoteCurrency, 0, 0);
                }
            }

            var quoteCash = securityPortfolioManager.CashBook[symbolProperties.QuoteCurrency];

            Security security;

            switch (config.SecurityType)
            {
            case SecurityType.Equity:
                security = new Equity.Equity(symbol, exchangeHours, quoteCash, symbolProperties);
                break;

            case SecurityType.Option:
                security = new Option.Option(exchangeHours, config, securityPortfolioManager.CashBook[CashBook.AccountCurrency], symbolProperties);
                break;

            case SecurityType.Forex:
                security = new Forex.Forex(symbol, exchangeHours, quoteCash, symbolProperties);
                break;

            case SecurityType.Cfd:
                security = new Cfd.Cfd(symbol, exchangeHours, quoteCash, symbolProperties);
                break;

            default:
            case SecurityType.Base:
                security = new Security(symbol, exchangeHours, quoteCash, symbolProperties);
                break;
            }

            // if we're just creating this security and it only has an internal
            // feed, mark it as non-tradable since the user didn't request this data
            if (!config.IsInternalFeed)
            {
                security.IsTradable = true;
            }

            security.AddData(config);

            // invoke the security initializer
            securityInitializer.Initialize(security);

            // if leverage was specified then apply to security after the initializer has run, parameters of this
            // method take precedence over the intializer
            if (leverage > 0)
            {
                security.SetLeverage(leverage);
            }

            // In live mode, equity assumes specific price variation model
            if (isLiveMode && security.Type == SecurityType.Equity)
            {
                security.PriceVariationModel = new EquityPriceVariationModel();
            }

            return(security);
        }
コード例 #26
0
 /// <summary>
 /// Forex Holding Class
 /// </summary>
 /// <param name="security">The forex security being held</param>
 /// <param name="transactionModel">The transaction model used for the security</param>
 /// <param name="marginModel">The margin model used for the security</param>
 public ForexHolding(Forex security, ISecurityTransactionModel transactionModel, ISecurityMarginModel marginModel)
     : base(security)
 {
     _forex = security;
 }
コード例 #27
0
        public override void ProcessFill(SecurityPortfolioManager portfolio, Security security, OrderEvent fill)
        {
            // split the symbol into base and quote currencies

            string baseCurrency;
            string quoteCurrency;

            Forex.DecomposeCurrencyPair(security.Symbol, out baseCurrency, out quoteCurrency);

            // e.g. EUR GBP

            // EUR
            var baseCash = portfolio.CashBook[baseCurrency];
            // GBP
            var quoteCash = portfolio.CashBook[quoteCurrency];

            //Get the required information from the vehicle this order will affect
            var closedPosition = false;
            var isLong         = security.Holdings.IsLong;
            var isShort        = security.Holdings.IsShort;

            //Make local decimals to avoid any rounding errors from int multiplication
            var averageHoldingsPrice     = security.Holdings.AveragePrice;
            var quantityHoldings         = (decimal)security.Holdings.Quantity;
            var absoluteHoldingsQuantity = security.Holdings.AbsoluteQuantity;

            var lastTradeProfit = 0m;

            try
            {
                //Update the Vehicle approximate total sales volume.
                var saleValueInQuoteCurrency = fill.FillPrice * Convert.ToDecimal(fill.AbsoluteFillQuantity);
                var saleValue = saleValueInQuoteCurrency * quoteCash.ConversionRate;
                security.Holdings.AddNewSale(saleValue);

                //Get the Fee for this Order - Update the Portfolio Cash Balance: Remove Transaction Fees.
                var order = new MarketOrder(security.Symbol, fill.FillQuantity, security.Time, type: security.Type)
                {
                    Price = fill.FillPrice
                };
                var feeThisOrder = Math.Abs(security.TransactionModel.GetOrderFee(security, order));
                security.Holdings.AddNewFee(feeThisOrder);
                portfolio.CashBook[CashBook.AccountCurrency].Quantity -= feeThisOrder;

                baseCash.Quantity  += fill.FillQuantity;
                quoteCash.Quantity -= fill.FillQuantity * fill.FillPrice;

                //Calculate & Update the Last Trade Profit;
                if (isLong && fill.Direction == OrderDirection.Sell)
                {
                    //Closing up a long position
                    if (quantityHoldings >= fill.AbsoluteFillQuantity)
                    {
                        //Closing up towards Zero -- this is in the quote currency
                        lastTradeProfit = (fill.FillPrice - averageHoldingsPrice) * fill.AbsoluteFillQuantity;
                    }
                    else
                    {
                        //Closing up to Neg/Short Position (selling more than we have) - Only calc profit on the stock we have to sell.
                        lastTradeProfit = (fill.FillPrice - averageHoldingsPrice) * quantityHoldings;
                    }
                    closedPosition = true;
                }
                else if (isShort && fill.Direction == OrderDirection.Buy)
                {
                    //Closing up a short position.
                    if (absoluteHoldingsQuantity >= fill.FillQuantity)
                    {
                        //Reducing the stock we have, and enough stock on hand to process order.
                        lastTradeProfit = (averageHoldingsPrice - fill.FillPrice) * fill.AbsoluteFillQuantity;
                    }
                    else
                    {
                        //Increasing stock holdings, short to positive through zero, but only calc profit on stock we Buy.
                        lastTradeProfit = (averageHoldingsPrice - fill.FillPrice) * absoluteHoldingsQuantity;
                    }
                    closedPosition = true;
                }


                if (closedPosition)
                {
                    // convert the compute profit into the account currency
                    lastTradeProfit *= quoteCash.ConversionRate;

                    //Update Vehicle Profit Tracking:
                    security.Holdings.AddNewProfit(lastTradeProfit);
                    security.Holdings.SetLastTradeProfit(lastTradeProfit);
                    portfolio.AddTransactionRecord(security.Time, lastTradeProfit - 2 * feeThisOrder);
                }


                //UPDATE HOLDINGS QUANTITY, AVG PRICE:
                //Currently NO holdings. The order is ALL our holdings.
                if (quantityHoldings == 0)
                {
                    //First transaction just subtract order from cash and set our holdings:
                    averageHoldingsPrice = fill.FillPrice;
                    quantityHoldings     = fill.FillQuantity;
                }
                else if (isLong)
                {
                    //If we're currently LONG on the stock.
                    switch (fill.Direction)
                    {
                    case OrderDirection.Buy:
                        //Update the Holding Average Price: Total Value / Total Quantity:
                        averageHoldingsPrice = ((averageHoldingsPrice * quantityHoldings) + (fill.FillQuantity * fill.FillPrice)) / (quantityHoldings + fill.FillQuantity);
                        //Add the new quantity:
                        quantityHoldings += fill.FillQuantity;
                        break;

                    case OrderDirection.Sell:
                        quantityHoldings += fill.FillQuantity;     //+ a short = a subtraction
                        if (quantityHoldings < 0)
                        {
                            //If we've now passed through zero from selling stock: new avg price:
                            averageHoldingsPrice = fill.FillPrice;
                        }
                        else if (quantityHoldings == 0)
                        {
                            averageHoldingsPrice = 0;
                        }
                        break;
                    }
                }
                else if (isShort)
                {
                    //We're currently SHORTING the stock: What is the new position now?
                    switch (fill.Direction)
                    {
                    case OrderDirection.Buy:
                        //Buying when we're shorting moves to close position:
                        quantityHoldings += fill.FillQuantity;
                        if (quantityHoldings > 0)
                        {
                            //If we were short but passed through zero, new average price is what we paid. The short position was closed.
                            averageHoldingsPrice = fill.FillPrice;
                        }
                        else if (quantityHoldings == 0)
                        {
                            averageHoldingsPrice = 0;
                        }
                        break;

                    case OrderDirection.Sell:
                        //We are increasing a Short position:
                        //E.g.  -100 @ $5, adding -100 @ $10: Avg: $7.5
                        //      dAvg = (-500 + -1000) / -200 = 7.5
                        averageHoldingsPrice = ((averageHoldingsPrice * quantityHoldings) + (fill.FillQuantity * fill.FillPrice)) / (quantityHoldings + fill.FillQuantity);
                        quantityHoldings    += fill.FillQuantity;
                        break;
                    }
                }
            }
            catch (Exception err)
            {
                Log.Error("ForexPortfolioManager.ProcessFill(orderEvent): " + err.Message);
            }

            //Set the results back to the vehicle.
            security.Holdings.SetHoldings(averageHoldingsPrice, Convert.ToInt32(quantityHoldings));
        }
コード例 #28
0
ファイル: ForexHolding.cs プロジェクト: aihua/quant-lean
 /// <summary>
 /// Forex Holding Class
 /// </summary>
 /// <param name="security">The forex security being held</param>
 public ForexHolding(Forex security)
     : base(security)
 {
 }