Esempio n. 1
0
        public void BlackScholesPortfolioTest()
        {
            const decimal price           = 20.00m;
            const decimal underlyingPrice = 200m;
            const decimal underlyingVol   = 0.15m;
            const decimal riskFreeRate    = 0.01m;
            var           tz                    = TimeZones.NewYork;
            var           evaluationDate        = new DateTime(2015, 2, 19);
            var           SPY_C_192_Feb19_2016E = Symbol.CreateOption("SPY", Market.USA, OptionStyle.European, OptionRight.Call, 192m, new DateTime(2016, 02, 19));

            // setting up underlying
            var equity = new Equity(
                SecurityExchangeHours.AlwaysOpen(tz),
                new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY, Resolution.Minute, tz, tz, true, false, false),
                new Cash(Currencies.USD, 0, 1m),
                SymbolProperties.GetDefault(Currencies.USD),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null
                );

            equity.SetMarketPrice(new Tick {
                Value = underlyingPrice
            });
            equity.VolatilityModel = new DummyVolatilityModel(underlyingVol);

            // setting up European style option
            var contract = new OptionContract(SPY_C_192_Feb19_2016E, Symbols.SPY)
            {
                Time = evaluationDate
            };
            var optionCall = new Option(
                SecurityExchangeHours.AlwaysOpen(tz),
                new SubscriptionDataConfig(typeof(TradeBar), SPY_C_192_Feb19_2016E, Resolution.Minute, tz, tz, true, false, false),
                new Cash(Currencies.USD, 0, 1m),
                new OptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null
                );

            optionCall.SetMarketPrice(new Tick {
                Value = price
            });
            optionCall.Underlying = equity;

            // running evaluation
            var priceModel = OptionPriceModels.BlackScholes();
            var results    = priceModel.Evaluate(optionCall, null, contract);
            var callPrice  = results.TheoreticalPrice;
            var greeks     = results.Greeks;

            // BS equation
            var rightPart = greeks.Theta + riskFreeRate * underlyingPrice * greeks.Delta + 0.5m * underlyingVol * underlyingVol * underlyingPrice * underlyingPrice * greeks.Gamma;
            var leftPart  = riskFreeRate * callPrice;

            Assert.AreEqual((double)leftPart, (double)rightPart, 0.0001);
        }
Esempio n. 2
0
        public Option GetOption(Symbol symbol, Equity underlying, NodaTime.DateTimeZone tz)
        {
            var option = new Option(
                SecurityExchangeHours.AlwaysOpen(tz),
                new SubscriptionDataConfig(typeof(TradeBar), symbol, Resolution.Minute, tz, tz, true, false, false),
                new Cash(Currencies.USD, 0, 1m),
                new OptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null
                );

            option.Underlying = underlying;

            return(option);
        }
        public void FreeBuyingPowerPercentDefault_Option()
        {
            const decimal price           = 25m;
            const decimal underlyingPrice = 25m;

            var tz     = TimeZones.NewYork;
            var equity = new QuantConnect.Securities.Equity.Equity(
                SecurityExchangeHours.AlwaysOpen(tz),
                new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY, Resolution.Minute, tz, tz, true, false, false),
                new Cash(Currencies.USD, 0, 1m),
                SymbolProperties.GetDefault(Currencies.USD),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null
                );

            equity.SetMarketPrice(new Tick {
                Value = underlyingPrice
            });

            var optionPutSymbol = Symbol.CreateOption(Symbols.SPY, Market.USA, OptionStyle.American, OptionRight.Put, 207m, new DateTime(2015, 02, 27));
            var security        = new Option(
                SecurityExchangeHours.AlwaysOpen(tz),
                new SubscriptionDataConfig(typeof(TradeBar), optionPutSymbol, Resolution.Minute, tz, tz, true, false, false),
                new Cash(Currencies.USD, 0, 1m),
                new OptionSymbolProperties("", Currencies.USD, 100, 0.01m, 1),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null
                );

            security.SetMarketPrice(new Tick {
                Value = price
            });
            security.Underlying = equity;

            var algo = GetAlgorithm();

            security.SetLocalTimeKeeper(algo.TimeKeeper.GetLocalTimeKeeper(tz));
            var actual = security.BuyingPowerModel.GetMaximumOrderQuantityForTargetBuyingPower(
                new GetMaximumOrderQuantityForTargetBuyingPowerParameters(algo.Portfolio, security, 1, 0)).Quantity;

            // (100000 * 1) / (25 * 100 contract multiplier) - 1 order due to fees
            Assert.AreEqual(39m, actual);
            Assert.IsTrue(HasSufficientBuyingPowerForOrder(actual, security, algo));
            Assert.AreEqual(algo.Portfolio.Cash, security.BuyingPowerModel.GetBuyingPower(algo.Portfolio, security, OrderDirection.Buy));
        }
        public OptionPriceModelPriceGeneratorTests()
        {
            _underlying = new Security(
                SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork),
                new SubscriptionDataConfig(
                    typeof(TradeBar),
                    Symbols.SPY,
                    Resolution.Minute,
                    TimeZones.NewYork,
                    TimeZones.NewYork,
                    false,
                    false,
                    false
                    ),
                new Cash("USD", 0, 1m),
                SymbolProperties.GetDefault("USD"),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null,
                new SecurityCache()
                );

            var optionSymbol = Symbol.CreateOption(
                _underlying.Symbol,
                _underlying.Symbol.ID.Market,
                _underlying.Symbol.SecurityType.DefaultOptionStyle(),
                OptionRight.Call,
                20,
                new DateTime(2022, 1, 1));

            _option = new Option(
                optionSymbol,
                SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork),
                new Cash("USD", 0, 1m),
                new OptionSymbolProperties(_underlying.SymbolProperties),
                new CashBook(),
                new RegisteredSecurityDataTypesProvider(),
                new OptionCache(),
                _underlying);
        }
Esempio n. 5
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);
        }
Esempio n. 6
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)
            {
                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);
        }
Esempio n. 7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="OptionChainUniverse"/> class
 /// </summary>
 /// <param name="option">The canonical option chain security</param>
 /// <param name="universeSettings">The universe settings to be used for new subscriptions</param>
 /// <param name="securityInitializer">The security initializer to use on newly created securities</param>
 public OptionChainUniverse(Option option, UniverseSettings universeSettings, ISecurityInitializer securityInitializer = null)
     : base(option.SubscriptionDataConfig, securityInitializer)
 {
     _option = option;
     _universeSettings = universeSettings;
 }
Esempio n. 8
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);
        }
Esempio n. 9
0
        public void ReturnsNoneIfNotWarmedUp()
        {
            const decimal underlyingPrice = 200m;
            const decimal underlyingVol   = 0.15m;
            const decimal riskFreeRate    = 0.01m;
            var           tz                    = TimeZones.NewYork;
            var           evaluationDate        = new DateTime(2015, 2, 19);
            var           SPY_C_192_Feb19_2016E = Symbol.CreateOption("SPY", Market.USA, OptionStyle.European, OptionRight.Call, 192m, new DateTime(2016, 02, 19));
            var           SPY_P_192_Feb19_2016E = Symbol.CreateOption("SPY", Market.USA, OptionStyle.European, OptionRight.Put, 192m, new DateTime(2016, 02, 19));

            // setting up underlying
            var equity = new Equity(
                SecurityExchangeHours.AlwaysOpen(tz),
                new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY, Resolution.Minute, tz, tz, true, false, false),
                new Cash(Currencies.USD, 0, 1m),
                SymbolProperties.GetDefault(Currencies.USD),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null
                );

            equity.SetMarketPrice(new Tick {
                Value = underlyingPrice
            });
            equity.VolatilityModel = new DummyVolatilityModel(underlyingVol);

            // setting up European style call option
            var contractCall = new OptionContract(SPY_C_192_Feb19_2016E, Symbols.SPY)
            {
                Time = evaluationDate
            };
            var optionCall = new Option(
                SecurityExchangeHours.AlwaysOpen(tz),
                new SubscriptionDataConfig(typeof(TradeBar), SPY_C_192_Feb19_2016E, Resolution.Minute, tz, tz, true, false, false),
                new Cash(Currencies.USD, 0, 1m),
                new OptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null
                );

            optionCall.Underlying = equity;

            // setting up European style put option
            var contractPut = new OptionContract(SPY_P_192_Feb19_2016E, Symbols.SPY)
            {
                Time = evaluationDate
            };
            var optionPut = new Option(
                SecurityExchangeHours.AlwaysOpen(tz),
                new SubscriptionDataConfig(typeof(TradeBar), SPY_P_192_Feb19_2016E, Resolution.Minute, tz, tz, true, false, false),
                new Cash(Currencies.USD, 0, 1m),
                new OptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null
                );

            optionPut.Underlying = equity;

            // running evaluation
            var volatilityModel = new Mock <IQLUnderlyingVolatilityEstimator>();

            volatilityModel.SetupGet(s => s.IsReady).Returns(false);
            var priceModel = new QLOptionPriceModel(process => new AnalyticEuropeanEngine(process),
                                                    volatilityModel.Object,
                                                    null,
                                                    null);
            var resultsCall = priceModel.Evaluate(optionCall, null, contractCall);
            var resultsPut  = priceModel.Evaluate(optionPut, null, contractPut);

            Assert.AreEqual(OptionPriceModelResult.None, resultsCall);
            Assert.AreEqual(OptionPriceModelResult.None, resultsCall);
        }
Esempio n. 10
0
        public void PutCallParityTest()
        {
            const decimal underlyingPrice = 200m;
            const decimal underlyingVol   = 0.15m;
            const decimal riskFreeRate    = 0.01m;
            var           tz                    = TimeZones.NewYork;
            var           evaluationDate        = new DateTime(2015, 2, 19);
            var           SPY_C_192_Feb19_2016E = Symbol.CreateOption("SPY", Market.USA, OptionStyle.European, OptionRight.Call, 192m, new DateTime(2016, 02, 19));
            var           SPY_P_192_Feb19_2016E = Symbol.CreateOption("SPY", Market.USA, OptionStyle.European, OptionRight.Put, 192m, new DateTime(2016, 02, 19));

            // setting up underlying
            var equity = new Equity(
                SecurityExchangeHours.AlwaysOpen(tz),
                new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY, Resolution.Minute, tz, tz, true, false, false),
                new Cash(Currencies.USD, 0, 1m),
                SymbolProperties.GetDefault(Currencies.USD),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null
                );

            equity.SetMarketPrice(new Tick {
                Value = underlyingPrice
            });
            equity.VolatilityModel = new DummyVolatilityModel(underlyingVol);

            // setting up European style call option
            var contractCall = new OptionContract(SPY_C_192_Feb19_2016E, Symbols.SPY)
            {
                Time = evaluationDate
            };
            var optionCall = new Option(
                SecurityExchangeHours.AlwaysOpen(tz),
                new SubscriptionDataConfig(typeof(TradeBar), SPY_C_192_Feb19_2016E, Resolution.Minute, tz, tz, true, false, false),
                new Cash(Currencies.USD, 0, 1m),
                new OptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null
                );

            optionCall.Underlying = equity;

            // setting up European style put option
            var contractPut = new OptionContract(SPY_P_192_Feb19_2016E, Symbols.SPY)
            {
                Time = evaluationDate
            };
            var optionPut = new Option(
                SecurityExchangeHours.AlwaysOpen(tz),
                new SubscriptionDataConfig(typeof(TradeBar), SPY_P_192_Feb19_2016E, Resolution.Minute, tz, tz, true, false, false),
                new Cash(Currencies.USD, 0, 1m),
                new OptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null
                );

            optionPut.Underlying = equity;

            // running evaluation
            var priceModel  = OptionPriceModels.BlackScholes();
            var resultsCall = priceModel.Evaluate(optionCall, null, contractCall);
            var resultsPut  = priceModel.Evaluate(optionPut, null, contractPut);
            var callPrice   = resultsCall.TheoreticalPrice;
            var putPrice    = resultsPut.TheoreticalPrice;

            // Put-call parity equation
            var rightPart = putPrice + underlyingPrice; // no yield
            var leftPart  = callPrice + contractCall.Strike * (decimal)Math.Exp((double)-riskFreeRate);

            Assert.AreEqual((double)leftPart, (double)rightPart, 0.0001);
        }
Esempio n. 11
0
        public void GreekApproximationTest()
        {
            const decimal price           = 20.00m;
            const decimal underlyingPrice = 190m;
            const decimal underlyingVol   = 0.15m;
            var           tz             = TimeZones.NewYork;
            var           evaluationDate = new DateTime(2016, 1, 19);

            var equity = new Equity(
                SecurityExchangeHours.AlwaysOpen(tz),
                new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY, Resolution.Minute, tz, tz, true, false, false),
                new Cash(Currencies.USD, 0, 1m),
                SymbolProperties.GetDefault(Currencies.USD),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null
                );

            equity.SetMarketPrice(new Tick {
                Value = underlyingPrice
            });
            equity.VolatilityModel = new DummyVolatilityModel(underlyingVol);

            var contract = new OptionContract(Symbols.SPY_P_192_Feb19_2016, Symbols.SPY)
            {
                Time = evaluationDate
            };
            var optionPut = new Option(
                SecurityExchangeHours.AlwaysOpen(tz),
                new SubscriptionDataConfig(
                    typeof(TradeBar),
                    Symbols.SPY_P_192_Feb19_2016,
                    Resolution.Minute,
                    tz,
                    tz,
                    true,
                    false,
                    false
                    ),
                new Cash(Currencies.USD, 0, 1m),
                new OptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null
                );

            optionPut.SetMarketPrice(new Tick {
                Value = price
            });
            optionPut.Underlying = equity;

            var priceModel = (QLOptionPriceModel)OptionPriceModels.CrankNicolsonFD();

            priceModel.EnableGreekApproximation = false;

            var results = priceModel.Evaluate(optionPut, null, contract);
            var greeks  = results.Greeks;

            Assert.AreEqual(greeks.Theta, 0);
            Assert.AreEqual(greeks.Rho, 0);
            Assert.AreEqual(greeks.Vega, 0);

            priceModel = (QLOptionPriceModel)OptionPriceModels.CrankNicolsonFD();
            priceModel.EnableGreekApproximation = true;

            results = priceModel.Evaluate(optionPut, null, contract);
            greeks  = results.Greeks;

            Assert.LessOrEqual(greeks.Theta, 0);
            Assert.AreNotEqual(greeks.Rho, 0);
            Assert.Greater(greeks.Vega, 0);
        }
Esempio n. 12
0
        public void EvaluationDateWorksInPortfolioTest()
        {
            const decimal price           = 30.00m;
            const decimal underlyingPrice = 200m;
            const decimal underlyingVol   = 0.25m;
            var           tz = TimeZones.NewYork;
            var           evaluationDate1 = new DateTime(2015, 2, 19);
            var           evaluationDate2 = new DateTime(2015, 2, 20);

            var equity = new Equity(
                SecurityExchangeHours.AlwaysOpen(tz),
                new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY, Resolution.Minute, tz, tz, true, false, false),
                new Cash(Currencies.USD, 0, 1m),
                SymbolProperties.GetDefault(Currencies.USD),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null
                );

            equity.SetMarketPrice(new Tick {
                Value = underlyingPrice
            });
            equity.VolatilityModel = new DummyVolatilityModel(underlyingVol);

            var contract = new OptionContract(Symbols.SPY_C_192_Feb19_2016, Symbols.SPY)
            {
                Time = evaluationDate1
            };
            var optionCall = new Option(
                SecurityExchangeHours.AlwaysOpen(tz),
                new SubscriptionDataConfig(
                    typeof(TradeBar),
                    Symbols.SPY_C_192_Feb19_2016,
                    Resolution.Minute,
                    tz,
                    tz,
                    true,
                    false,
                    false
                    ),
                new Cash(Currencies.USD, 0, 1m),
                new OptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null
                );

            optionCall.SetMarketPrice(new Tick {
                Value = price
            });
            optionCall.Underlying = equity;

            var priceModel = OptionPriceModels.BaroneAdesiWhaley();
            var results    = priceModel.Evaluate(optionCall, null, contract);

            var callPrice1 = results.TheoreticalPrice;

            contract.Time = evaluationDate2;
            results       = priceModel.Evaluate(optionCall, null, contract);

            var callPrice2 = results.TheoreticalPrice;

            Assert.Greater(callPrice1, callPrice2);
        }
Esempio n. 13
0
        public void BaroneAdesiWhaleyPortfolioTest()
        {
            const decimal price           = 30.00m;
            const decimal underlyingPrice = 200m;
            const decimal underlyingVol   = 0.25m;
            const decimal riskFreeRate    = 0.01m;
            var           tz             = TimeZones.NewYork;
            var           evaluationDate = new DateTime(2015, 2, 19);

            var equity = new Equity(
                SecurityExchangeHours.AlwaysOpen(tz),
                new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY, Resolution.Minute, tz, tz, true, false, false),
                new Cash(Currencies.USD, 0, 1m),
                SymbolProperties.GetDefault(Currencies.USD),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null
                );

            equity.SetMarketPrice(new Tick {
                Value = underlyingPrice
            });
            equity.VolatilityModel = new DummyVolatilityModel(underlyingVol);

            var contract = new OptionContract(Symbols.SPY_C_192_Feb19_2016, Symbols.SPY)
            {
                Time = evaluationDate
            };
            var optionCall = new Option(
                SecurityExchangeHours.AlwaysOpen(tz),
                new SubscriptionDataConfig(
                    typeof(TradeBar),
                    Symbols.SPY_C_192_Feb19_2016,
                    Resolution.Minute,
                    tz,
                    tz,
                    true,
                    false,
                    false
                    ),
                new Cash(Currencies.USD, 0, 1m),
                new OptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null
                );

            optionCall.SetMarketPrice(new Tick {
                Value = price
            });
            optionCall.Underlying = equity;

            var priceModel = OptionPriceModels.BaroneAdesiWhaley();
            var results    = priceModel.Evaluate(optionCall, null, contract);

            var callPrice         = results.TheoreticalPrice;
            var impliedVolatility = results.ImpliedVolatility;
            var greeks            = results.Greeks;

            Assert.Greater(price, callPrice);
            Assert.Greater(impliedVolatility, underlyingVol);

            // BS equation (inequality)
            var rightPart = greeks.Theta + riskFreeRate * underlyingPrice * greeks.Delta + 0.5m * underlyingVol * underlyingVol * underlyingPrice * underlyingPrice * greeks.Gamma;
            var leftPart  = riskFreeRate * callPrice;

            Assert.GreaterOrEqual(Math.Round(leftPart, 4), Math.Round(rightPart, 4));
        }
Esempio n. 14
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,
                                              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);
        }