Exemplo n.º 1
0
        public void SetHoldings_Short_RoundOff()
        {
            var algo = new QCAlgorithm();

            algo.AddSecurity(SecurityType.Forex, "EURUSD");
            algo.SetCash(100000);
            algo.SetBrokerageModel(BrokerageName.FxcmBrokerage);
            algo.Securities[Symbols.EURUSD].TransactionModel = new ConstantFeeTransactionModel(0);
            Security eurusd = algo.Securities[Symbols.EURUSD];

            // Set Price to $26
            Update(eurusd, 26);
            // So -100000/26 = -3846, After Rounding off becomes -3000
            var actual = algo.CalculateOrderQuantity(Symbols.EURUSD, -1m);

            Assert.AreEqual(-3000m, actual);

            var btcusd = algo.AddCrypto("BTCUSD", market: Market.GDAX);

            btcusd.TransactionModel = new ConstantFeeTransactionModel(0);
            // Set Price to $26
            Update(btcusd, 26);
            // So -100000/26 = 3846.153846153846, After Rounding off becomes -3846.15384615, since lot size is 0.00000001
            actual = algo.CalculateOrderQuantity(Symbols.BTCUSD, -1m);
            Assert.AreEqual(-3846.15384615m, actual);
        }
Exemplo n.º 2
0
        public void LimitBuyOrderChecksOpenOrders()
        {
            _portfolio.SetCash(5000);

            _btcusd = _algorithm.AddCrypto("BTCUSD");
            _btcusd.SetMarketPrice(new Tick {
                Value = 15000m
            });

            _ethusd = _algorithm.AddCrypto("ETHUSD");
            _ethusd.SetMarketPrice(new Tick {
                Value = 1000m
            });
            _algorithm.SetFinishedWarmingUp();

            // BTCUSD buy order decreases available USD (5000 - 1500 = 3500 USD)
            SubmitLimitOrder(_btcusd.Symbol, 0.1m, 15000m);

            // ETHUSD buy order decreases available USD (3500 - 3000 = 500 USD)
            SubmitLimitOrder(_ethusd.Symbol, 3m, 1000m);

            // 500 USD available, can buy 0.05 BTC at 10000
            var order = new LimitOrder(_btcusd.Symbol, 0.05m, 10000m, DateTime.UtcNow);

            Assert.IsTrue(_buyingPowerModel.HasSufficientBuyingPowerForOrder(_portfolio, _btcusd, order));

            // 500 USD available, cannot buy 0.06 BTC at 10000
            order = new LimitOrder(_btcusd.Symbol, 0.06m, 10000m, DateTime.UtcNow);
            Assert.IsFalse(_buyingPowerModel.HasSufficientBuyingPowerForOrder(_portfolio, _btcusd, order));
        }
Exemplo n.º 3
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());
                }
            }
        }
Exemplo n.º 4
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());
                }
            }
        }
Exemplo n.º 5
0
 /// <summary>
 /// Creates and adds a new <see cref="Crypto"/> 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="Crypto"/> security</returns>
 public Crypto AddCrypto(string ticker, Resolution resolution = Resolution.Minute, string market = null, bool fillDataForward = true, decimal leverage = 0m)
 {
     return(_algorithm.AddCrypto(ticker, resolution, market, fillDataForward, leverage));
 }