示例#1
0
        public void AddDataSecurityTickerWithUnderlying(string ticker, Type customDataType, SecurityType securityType, bool securityShouldBeMapped, bool customDataShouldBeMapped)
        {
            SymbolCache.Clear();
            var qcAlgorithm = new QCAlgorithm();

            qcAlgorithm.SubscriptionManager.SetDataManager(new DataManagerStub(qcAlgorithm));

            Security asset;

            switch (securityType)
            {
            case SecurityType.Cfd:
                asset = qcAlgorithm.AddCfd(ticker, Resolution.Daily);
                break;

            case SecurityType.Crypto:
                asset = qcAlgorithm.AddCrypto(ticker, Resolution.Daily);
                break;

            case SecurityType.Equity:
                asset = qcAlgorithm.AddEquity(ticker, Resolution.Daily);
                break;

            case SecurityType.Forex:
                asset = qcAlgorithm.AddForex(ticker, Resolution.Daily);
                break;

            case SecurityType.Future:
                asset = qcAlgorithm.AddFuture(ticker, Resolution.Daily);
                break;

            default:
                throw new Exception($"SecurityType {securityType} is not valid for this test");
            }

            // Aliased value for Futures contains a forward-slash, which causes the
            // lookup in the SymbolCache to fail
            if (securityType == SecurityType.Future)
            {
                ticker = asset.Symbol.Value;
            }

            // Dummy here is meant to try to corrupt the SymbolCache. Ideally, SymbolCache should return non-custom data types with higher priority
            // in case we want to add two custom data types, but still have them associated with the equity from the cache if we're using it.
            // This covers the case where two idential data subscriptions are created.
            var dummy      = qcAlgorithm.AddData(customDataType, ticker, Resolution.Daily, qcAlgorithm.SubscriptionManager.Subscriptions.Where(x => x.SecurityType == securityType).First().DataTimeZone);
            var customData = qcAlgorithm.AddData(customDataType, ticker, Resolution.Daily, qcAlgorithm.SubscriptionManager.Subscriptions.Where(x => x.SecurityType == securityType).First().DataTimeZone);

            Assert.IsTrue(customData.Symbol.HasUnderlying, $"Custom data added as {ticker} Symbol with SecurityType {securityType} does not have underlying");
            Assert.AreEqual(customData.Symbol.Underlying, asset.Symbol, $"Custom data underlying does not match {securityType} Symbol for {ticker}");

            var assetSubscription      = qcAlgorithm.SubscriptionManager.Subscriptions.Where(x => x.SecurityType == securityType).First();
            var customDataSubscription = qcAlgorithm.SubscriptionManager.Subscriptions.Where(x => x.SecurityType == SecurityType.Base).Single();

            var assetShouldBeMapped  = assetSubscription.TickerShouldBeMapped();
            var customShouldBeMapped = customDataSubscription.TickerShouldBeMapped();

            if (securityType == SecurityType.Equity)
            {
                Assert.AreEqual(securityShouldBeMapped, assetShouldBeMapped);
                Assert.AreEqual(customDataShouldBeMapped, customShouldBeMapped);

                Assert.AreNotEqual(assetSubscription, customDataSubscription);

                if (assetShouldBeMapped == customShouldBeMapped)
                {
                    Assert.AreEqual(assetSubscription.MappedSymbol, customDataSubscription.MappedSymbol);
                    Assert.AreEqual(asset.Symbol.Value, customData.Symbol.Value.Split('.').First());
                }
            }
        }
示例#2
0
        public void AddDataSecurityTickerNoUnderlying(string ticker, Type customDataType, SecurityType securityType, bool securityShouldBeMapped, bool customDataShouldBeMapped)
        {
            SymbolCache.Clear();
            var qcAlgorithm = new QCAlgorithm();

            qcAlgorithm.SubscriptionManager.SetDataManager(new DataManagerStub(qcAlgorithm));

            Security asset;

            switch (securityType)
            {
            case SecurityType.Cfd:
                asset = qcAlgorithm.AddCfd(ticker, Resolution.Daily);
                break;

            case SecurityType.Crypto:
                asset = qcAlgorithm.AddCrypto(ticker, Resolution.Daily);
                break;

            case SecurityType.Equity:
                asset = qcAlgorithm.AddEquity(ticker, Resolution.Daily);
                break;

            case SecurityType.Forex:
                asset = qcAlgorithm.AddForex(ticker, Resolution.Daily);
                break;

            case SecurityType.Future:
                asset = qcAlgorithm.AddFuture(ticker, Resolution.Daily);
                break;

            default:
                throw new Exception($"SecurityType {securityType} is not valid for this test");
            }

            // Dummy here is meant to try to corrupt the SymbolCache. Ideally, SymbolCache should return non-custom data types with higher priority
            // in case we want to add two custom data types, but still have them associated with the equity from the cache if we're using it.
            // This covers the case where two idential data subscriptions are created.
            var dummy      = qcAlgorithm.AddData(customDataType, ticker, Resolution.Daily, qcAlgorithm.SubscriptionManager.Subscriptions.Where(x => x.SecurityType == securityType).First().DataTimeZone);
            var customData = qcAlgorithm.AddData(customDataType, ticker, Resolution.Daily, qcAlgorithm.SubscriptionManager.Subscriptions.Where(x => x.SecurityType == securityType).First().DataTimeZone);

            // Check to see if we have an underlying symbol when we shouldn't
            Assert.IsFalse(customData.Symbol.HasUnderlying, $"{customDataType.Name} has underlying symbol for SecurityType {securityType} with ticker {ticker}");
            Assert.AreEqual(customData.Symbol.Underlying, null, $"{customDataType.Name} - Custom data underlying Symbol for SecurityType {securityType} is not null");

            var assetSubscription      = qcAlgorithm.SubscriptionManager.Subscriptions.Where(x => x.SecurityType == securityType).First();
            var customDataSubscription = qcAlgorithm.SubscriptionManager.Subscriptions.Where(x => x.SecurityType == SecurityType.Base).Single();

            var assetShouldBeMapped  = assetSubscription.TickerShouldBeMapped();
            var customShouldBeMapped = customDataSubscription.TickerShouldBeMapped();

            Assert.AreEqual(securityShouldBeMapped, assetShouldBeMapped);
            Assert.AreEqual(customDataShouldBeMapped, customShouldBeMapped);

            Assert.AreNotEqual(assetSubscription, customDataSubscription);

            if (assetShouldBeMapped == customShouldBeMapped)
            {
                // Would fail with CL future without this check because MappedSymbol returns "/CL" for the Future symbol
                if (assetSubscription.SecurityType == SecurityType.Future)
                {
                    Assert.AreNotEqual(assetSubscription.MappedSymbol, customDataSubscription.MappedSymbol);
                    Assert.AreNotEqual(asset.Symbol.Value, customData.Symbol.Value.Split('.').First());
                }
                else
                {
                    Assert.AreEqual(assetSubscription.MappedSymbol, customDataSubscription.MappedSymbol);
                    Assert.AreEqual(asset.Symbol.Value, customData.Symbol.Value.Split('.').First());
                }
            }
        }
示例#3
0
文件: QuantBook.cs 项目: yuzhucu/Lean
 /// <summary>
 /// Creates and adds a new <see cref="Cfd"/> security to the algorithm
 /// </summary>
 /// <param name="ticker">The currency pair</param>
 /// <param name="resolution">The <see cref="Resolution"/> of market data, Tick, Second, Minute, Hour, or Daily. Default is <see cref="Resolution.Minute"/></param>
 /// <param name="market">The cfd trading market, <seealso cref="Market"/>. Default value is null and looked up using BrokerageModel.DefaultMarkets in <see cref="AddSecurity{T}"/></param>
 /// <param name="fillDataForward">If true, returns the last available data even if none in that timeslice. Default is <value>true</value></param>
 /// <param name="leverage">The requested leverage for this equity. Default is set by <see cref="SecurityInitializer"/></param>
 /// <returns>The new <see cref="Cfd"/> security</returns>
 public Cfd AddCfd(string ticker, Resolution resolution = Resolution.Minute, string market = null, bool fillDataForward = true, decimal leverage = 0m)
 {
     return(_algorithm.AddCfd(ticker, resolution, market, fillDataForward, leverage));
 }