public void ToXML_EnsuresUSLocaleForDecimals()
        {
            CultureInfo existingCulture = CultureInfo.CurrentCulture;

            try
            {
#if netcore
                CultureInfo.CurrentCulture = new CultureInfo("it-IT");
#else
                Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("it-IT");
#endif

                TransactionRequest transactionRequest = new TransactionRequest
                {
                    Amount = 100.0M,
                    TaxAmount = 10.0M,
                };

                SubscriptionRequest subscriptionRequest = new SubscriptionRequest
                {
                    Price = 200.0M,
                };

                SubscriptionTransactionRequest subscriptionTransactionRequest = new SubscriptionTransactionRequest
                {
                    Amount = 300.0M
                };

                ModificationRequest modificationRequest = new ModificationRequest
                {
                    Amount = 400.0M
                };

                TestHelper.AssertIncludes("<amount>100.00</amount>", transactionRequest.ToXml());
                TestHelper.AssertIncludes("<tax-amount>10.00</tax-amount>", transactionRequest.ToXml());
                TestHelper.AssertIncludes("<price>200.00</price>", subscriptionRequest.ToXml());
                TestHelper.AssertIncludes("<amount>300.00</amount>", subscriptionTransactionRequest.ToXml());
                TestHelper.AssertIncludes("<amount>400.00</amount>", modificationRequest.ToXml("root"));
            }
            finally
            {
#if netcore
                CultureInfo.CurrentCulture = existingCulture;
#else
                Thread.CurrentThread.CurrentCulture = existingCulture;
#endif
            }
        }
        public void Create_SubscriptionWithoutTrial()
        {
            TestPlan plan = PlanFixture.PLAN_WITHOUT_TRIAL;

            SubscriptionRequest request = new SubscriptionRequest
            {
                PaymentMethodToken = creditCard.Token,
                PlanId = plan.Id
            };

            Result<Subscription> result = gateway.Subscription.Create(request);
            Assert.IsTrue(result.IsSuccess());
            Subscription subscription = result.Target;

            Assert.AreEqual(creditCard.Token, subscription.PaymentMethodToken);
            Assert.AreEqual(plan.Id, subscription.PlanId);
            Assert.AreEqual(MerchantAccountIDs.DEFAULT_MERCHANT_ACCOUNT_ID, subscription.MerchantAccountId);
            Assert.AreEqual(plan.Price, subscription.Price);
            Assert.AreEqual(plan.Price, subscription.NextBillAmount);
            Assert.AreEqual(plan.Price, subscription.NextBillingPeriodAmount);
            Assert.AreEqual(0.00M, subscription.Balance);
            Assert.IsTrue(Regex.IsMatch(subscription.Id, "^\\w{6}$"));
            Assert.AreEqual(SubscriptionStatus.ACTIVE, subscription.Status);
            Assert.AreEqual(0, subscription.FailureCount);
            Assert.IsFalse((bool)subscription.HasTrialPeriod);
            Assert.AreEqual(1, subscription.CurrentBillingCycle);

            Assert.IsTrue(subscription.BillingPeriodEndDate.HasValue);
            Assert.IsTrue(subscription.BillingPeriodStartDate.HasValue);
            Assert.IsTrue(subscription.NextBillingDate.HasValue);
            Assert.IsTrue(subscription.FirstBillingDate.HasValue);
            Assert.IsTrue(subscription.CreatedAt.HasValue);
            Assert.IsTrue(subscription.UpdatedAt.HasValue);
            Assert.IsTrue(subscription.PaidThroughDate.HasValue);

            Assert.AreEqual(SubscriptionStatus.ACTIVE, subscription.StatusHistory[0].Status);
            Assert.AreEqual(SubscriptionSource.API, subscription.StatusHistory[0].Source);
            Assert.AreEqual(plan.Price, subscription.StatusHistory[0].Price);
            Assert.AreEqual(0.00M, subscription.StatusHistory[0].Balance);
            Assert.AreEqual("USD", subscription.StatusHistory[0].CurrencyIsoCode);
            Assert.AreEqual("integration_trialless_plan", subscription.StatusHistory[0].PlanId);
        }
        public void ToXML_EnsuresUSLocaleForDecimals()
        {
            System.Globalization.CultureInfo existingCulture = System.Globalization.CultureInfo.CurrentCulture;

            try
            {
                System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.GetCultureInfo("it-IT");

                TransactionRequest transactionRequest = new TransactionRequest
                {
                    Amount = 100.0M
                };

                SubscriptionRequest subscriptionRequest = new SubscriptionRequest
                {
                    Price = 200.0M,
                };

                SubscriptionTransactionRequest subscriptionTransactionRequest = new SubscriptionTransactionRequest
                {
                    Amount = 300.0M
                };

                ModificationRequest modificationRequest = new ModificationRequest
                {
                    Amount = 400.0M
                };

                TestHelper.AssertIncludes("<amount>100.0</amount>", transactionRequest.ToXml());
                TestHelper.AssertIncludes("<price>200.0</price>", subscriptionRequest.ToXml());
                TestHelper.AssertIncludes("<amount>300.0</amount>", subscriptionTransactionRequest.ToXml());
                TestHelper.AssertIncludes("<amount>400.0</amount>", modificationRequest.ToXml("root"));
            }
            finally
            {
                System.Threading.Thread.CurrentThread.CurrentCulture = existingCulture;
            }
        }
Exemple #4
0
 public Subscription CreateSubscription(SubscriptionRequest request)
 {
     return(null);
 }
        public void Create_HasTransactionOnCreateWithNoTrial()
        {
            TestPlan plan = PlanFixture.PLAN_WITHOUT_TRIAL;
            SubscriptionRequest request = new SubscriptionRequest
            {
                PaymentMethodToken = creditCard.Token,
                PlanId = plan.Id,
                Price = 482.48M
            };

            Result<Subscription> result = gateway.Subscription.Create(request);
            Assert.IsTrue(result.IsSuccess());
            Subscription subscription = result.Target;
            Transaction transaction = subscription.Transactions[0];

            Assert.AreEqual(1, subscription.Transactions.Count);
            Assert.AreEqual(482.48M, transaction.Amount);
            Assert.AreEqual(TransactionType.SALE, transaction.Type);
            Assert.AreEqual(subscription.Id, transaction.SubscriptionId);
        }
Exemple #6
0
        public void RefreshesOptionChainUniverseOnDateChange()
        {
            var startTime    = new DateTime(2018, 10, 19, 10, 0, 0);
            var timeProvider = new ManualTimeProvider(startTime);

            var canonicalSymbol = Symbol.Create("SPY", SecurityType.Option, Market.USA, "?SPY");

            var quoteCurrency = new Cash(Currencies.USD, 0, 1);
            var exchangeHours = MarketHoursDatabase.FromDataFolder().GetExchangeHours(Market.USA, canonicalSymbol, SecurityType.Option);
            var config        = new SubscriptionDataConfig(
                typeof(ZipEntryName),
                canonicalSymbol,
                Resolution.Minute,
                TimeZones.Utc,
                TimeZones.NewYork,
                true,
                false,
                false,
                false,
                TickType.Quote,
                false,
                DataNormalizationMode.Raw
                );

            var option = new Option(
                canonicalSymbol,
                exchangeHours,
                quoteCurrency,
                new OptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null,
                new SecurityCache()
                );

            var fillForwardResolution = Ref.CreateReadOnly(() => Resolution.Minute.ToTimeSpan());
            var symbolUniverse        = new TestDataQueueUniverseProvider(timeProvider);
            TradeBarBuilderEnumerator underlyingEnumerator = null;
            Func <SubscriptionRequest, IEnumerator <BaseData>, IEnumerator <BaseData> > underlyingEnumeratorFunc =
                (req, input) =>
            {
                underlyingEnumerator = (TradeBarBuilderEnumerator)input;
                return(new LiveFillForwardEnumerator(
                           timeProvider,
                           input,
                           option.Exchange,
                           fillForwardResolution,
                           false,
                           Time.EndOfTime,
                           Resolution.Minute.ToTimeSpan(),
                           TimeZones.Utc,
                           Time.BeginningOfTime));
            };
            var factory = new OptionChainUniverseSubscriptionEnumeratorFactory(underlyingEnumeratorFunc, symbolUniverse, timeProvider);

            var universeSettings = new UniverseSettings(Resolution.Minute, 0, true, false, TimeSpan.Zero);
            var universe         = new OptionChainUniverse(option, universeSettings, true);
            var request          = new SubscriptionRequest(true, universe, option, config, startTime, Time.EndOfTime);
            var enumerator       = (DataQueueOptionChainUniverseDataCollectionEnumerator)factory.CreateEnumerator(request, new DefaultDataProvider());

            // 2018-10-19 10:00 AM UTC
            underlyingEnumerator.ProcessData(new Tick {
                Symbol = Symbols.SPY, Value = 280m
            });

            Assert.IsTrue(enumerator.MoveNext());
            // no underlying data available yet
            Assert.IsNull(enumerator.Current);
            Assert.AreEqual(0, symbolUniverse.TotalLookupCalls);

            // 2018-10-19 10:01 AM UTC
            timeProvider.Advance(Time.OneMinute);

            underlyingEnumerator.ProcessData(new Tick {
                Symbol = Symbols.SPY, Value = 280m
            });

            Assert.IsTrue(enumerator.MoveNext());
            Assert.IsNotNull(enumerator.Current);
            Assert.AreEqual(1, symbolUniverse.TotalLookupCalls);
            var data = enumerator.Current;

            Assert.IsNotNull(data);
            Assert.AreEqual(1, data.Data.Count);
            Assert.IsNotNull(data.Underlying);

            // 2018-10-19 10:02 AM UTC
            timeProvider.Advance(Time.OneMinute);

            underlyingEnumerator.ProcessData(new Tick {
                Symbol = Symbols.SPY, Value = 280m
            });

            Assert.IsTrue(enumerator.MoveNext());
            Assert.IsNotNull(enumerator.Current);
            Assert.AreEqual(1, symbolUniverse.TotalLookupCalls);
            data = enumerator.Current;
            Assert.IsNotNull(data);
            Assert.AreEqual(1, data.Data.Count);
            Assert.IsNotNull(data.Underlying);

            // 2018-10-19 10:03 AM UTC
            timeProvider.Advance(Time.OneMinute);

            underlyingEnumerator.ProcessData(new Tick {
                Symbol = Symbols.SPY, Value = 280m
            });

            Assert.IsTrue(enumerator.MoveNext());
            Assert.IsNotNull(enumerator.Current);
            Assert.AreEqual(1, symbolUniverse.TotalLookupCalls);
            data = enumerator.Current;
            Assert.IsNotNull(data);
            Assert.AreEqual(1, data.Data.Count);
            Assert.IsNotNull(data.Underlying);

            // 2018-10-20 10:03 AM UTC
            timeProvider.Advance(Time.OneDay);

            underlyingEnumerator.ProcessData(new Tick {
                Symbol = Symbols.SPY, Value = 280m
            });

            Assert.IsTrue(enumerator.MoveNext());
            Assert.IsNotNull(enumerator.Current);
            Assert.AreEqual(2, symbolUniverse.TotalLookupCalls);
            data = enumerator.Current;
            Assert.IsNotNull(data);
            Assert.AreEqual(2, data.Data.Count);
            Assert.IsNotNull(data.Underlying);

            // 2018-10-20 10:04 AM UTC
            timeProvider.Advance(Time.OneMinute);

            underlyingEnumerator.ProcessData(new Tick {
                Symbol = Symbols.SPY, Value = 280m
            });

            Assert.IsTrue(enumerator.MoveNext());
            Assert.IsNotNull(enumerator.Current);
            Assert.AreEqual(2, symbolUniverse.TotalLookupCalls);
            data = enumerator.Current;
            Assert.IsNotNull(data);
            Assert.AreEqual(2, data.Data.Count);
            Assert.IsNotNull(data.Underlying);

            enumerator.Dispose();
        }
        private Subscription CreateSubscription(Resolution resolution, string symbol = "AAPL", bool isInternalFeed = false,
                                                SecurityType type = SecurityType.Equity, TickType tickType         = TickType.Trade)
        {
            var      start = DateTime.UtcNow;
            var      end   = start.AddSeconds(10);
            Security security;
            Symbol   _symbol;

            if (type == SecurityType.Equity)
            {
                _symbol  = new Symbol(SecurityIdentifier.GenerateEquity(DateTime.Now, symbol, Market.USA), symbol);
                security = new Equity(
                    _symbol,
                    SecurityExchangeHours.AlwaysOpen(DateTimeZone.Utc),
                    new Cash(Currencies.USD, 0, 1),
                    SymbolProperties.GetDefault(Currencies.USD),
                    ErrorCurrencyConverter.Instance,
                    RegisteredSecurityDataTypesProvider.Null,
                    new SecurityCache()
                    );
            }
            else if (type == SecurityType.Option)
            {
                _symbol = new Symbol(SecurityIdentifier.GenerateOption(DateTime.Now,
                                                                       SecurityIdentifier.GenerateEquity(DateTime.Now, symbol, Market.USA),
                                                                       Market.USA, 0.0m, OptionRight.Call, OptionStyle.American), symbol);
                security = new Option(
                    _symbol,
                    SecurityExchangeHours.AlwaysOpen(DateTimeZone.Utc),
                    new Cash(Currencies.USD, 0, 1),
                    new OptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)),
                    ErrorCurrencyConverter.Instance,
                    RegisteredSecurityDataTypesProvider.Null,
                    new SecurityCache()
                    );
            }
            else if (type == SecurityType.Future)
            {
                _symbol  = new Symbol(SecurityIdentifier.GenerateFuture(DateTime.Now, symbol, Market.COMEX), symbol);
                security = new Future(
                    _symbol,
                    SecurityExchangeHours.AlwaysOpen(DateTimeZone.Utc),
                    new Cash(Currencies.USD, 0, 1),
                    SymbolProperties.GetDefault(Currencies.USD),
                    ErrorCurrencyConverter.Instance,
                    RegisteredSecurityDataTypesProvider.Null,
                    new SecurityCache()
                    );
            }
            else
            {
                throw new Exception("SecurityType not implemented");
            }
            var config = new SubscriptionDataConfig(typeof(TradeBar), _symbol, resolution, DateTimeZone.Utc, DateTimeZone.Utc, true, false, isInternalFeed, false, tickType);
            var timeZoneOffsetProvider     = new TimeZoneOffsetProvider(DateTimeZone.Utc, start, end);
            var enumerator                 = new EnqueueableEnumerator <BaseData>();
            var subscriptionDataEnumerator = new SubscriptionDataEnumerator(config, security.Exchange.Hours, timeZoneOffsetProvider, enumerator);
            var subscriptionRequest        = new SubscriptionRequest(false, null, security, config, start, end);

            return(new Subscription(subscriptionRequest, subscriptionDataEnumerator, timeZoneOffsetProvider));
        }
 public override Task <ResponseStatus> Subscribe(SubscriptionRequest request, ServerCallContext context)
 {
     return(lifetimeScopeExecutor.ExecuteInNewScope <ISubscriptionActionsService, ResponseStatus>(service => service.Subscribe(request, context)));
 }
        /// <summary>
        /// Setups a new <see cref="Subscription"/> which will consume a blocking <see cref="EnqueueableEnumerator{T}"/>
        /// that will be feed by a worker task
        /// </summary>
        /// <param name="request">The subscription data request</param>
        /// <param name="enumerator">The data enumerator stack</param>
        /// <param name="factorFileProvider">The factor file provider</param>
        /// <param name="enablePriceScale">Enables price factoring</param>
        /// <returns>A new subscription instance ready to consume</returns>
        public static Subscription CreateAndScheduleWorker(
            SubscriptionRequest request,
            IEnumerator <BaseData> enumerator,
            IFactorFileProvider factorFileProvider,
            bool enablePriceScale)
        {
            var     factorFile             = GetFactorFileToUse(request.Configuration, factorFileProvider);
            var     exchangeHours          = request.Security.Exchange.Hours;
            var     enqueueable            = new EnqueueableEnumerator <SubscriptionData>(true);
            var     timeZoneOffsetProvider = new TimeZoneOffsetProvider(request.Security.Exchange.TimeZone, request.StartTimeUtc, request.EndTimeUtc);
            var     subscription           = new Subscription(request, enqueueable, timeZoneOffsetProvider);
            var     config           = subscription.Configuration;
            var     lastTradableDate = DateTime.MinValue;
            decimal?currentScale     = null;

            Func <int, bool> produce = (workBatchSize) =>
            {
                try
                {
                    var count = 0;
                    while (enumerator.MoveNext())
                    {
                        // subscription has been removed, no need to continue enumerating
                        if (enqueueable.HasFinished)
                        {
                            enumerator.DisposeSafely();
                            return(false);
                        }

                        var data = enumerator.Current;

                        // Use our config filter to see if we should emit this
                        // This currently catches Auxiliary data that we don't want to emit
                        if (data != null && !config.ShouldEmitData(data))
                        {
                            continue;
                        }

                        var requestMode = config.DataNormalizationMode;
                        var mode        = requestMode != DataNormalizationMode.Raw
                            ? requestMode
                            : DataNormalizationMode.Adjusted;
                        // We update our price scale factor when the date changes for non fill forward bars or if we haven't initialized yet.
                        // We don't take into account auxiliary data because we don't scale it and because the underlying price data could be fill forwarded
                        if (enablePriceScale && data?.Time.Date > lastTradableDate && data.DataType != MarketDataType.Auxiliary && (!data.IsFillForward || lastTradableDate == DateTime.MinValue))
                        {
                            lastTradableDate = data.Time.Date;
                            currentScale     = GetScaleFactor(factorFile, mode, data.Time.Date);
                        }

                        SubscriptionData subscriptionData = SubscriptionData.Create(
                            config,
                            exchangeHours,
                            subscription.OffsetProvider,
                            data,
                            mode,
                            enablePriceScale ? currentScale : null);

                        // drop the data into the back of the enqueueable
                        enqueueable.Enqueue(subscriptionData);

                        count++;
                        // stop executing if added more data than the work batch size, we don't want to fill the ram
                        if (count > workBatchSize)
                        {
                            return(true);
                        }
                    }
                }
                catch (Exception exception)
                {
                    Log.Error(exception, $"Subscription worker task exception {request.Configuration}.");
                }

                // we made it here because MoveNext returned false or we exploded, stop the enqueueable
                enqueueable.Stop();
                // we have to dispose of the enumerator
                enumerator.DisposeSafely();
                return(false);
            };

            WeightedWorkScheduler.Instance.QueueWork(produce,
                                                     // if the subscription finished we return 0, so the work is prioritized and gets removed
                                                     () =>
            {
                if (enqueueable.HasFinished)
                {
                    return(0);
                }
                var count = enqueueable.Count;
                return(count > WeightedWorkScheduler.MaxWorkWeight ? WeightedWorkScheduler.MaxWorkWeight : count);
            }
                                                     );

            return(subscription);
        }
Exemple #10
0
        /// <summary>
        /// Creates a new subscription for universe selection
        /// </summary>
        /// <param name="request">The subscription request</param>
        private Subscription CreateUniverseSubscription(SubscriptionRequest request)
        {
            Subscription subscription = null;

            // TODO : Consider moving the creating of universe subscriptions to a separate, testable class

            // grab the relevant exchange hours
            var config           = request.Universe.Configuration;
            var localEndTime     = request.EndTimeUtc.ConvertFromUtc(request.Security.Exchange.TimeZone);
            var tzOffsetProvider = new TimeZoneOffsetProvider(request.Security.Exchange.TimeZone, request.StartTimeUtc, request.EndTimeUtc);

            IEnumerator <BaseData> enumerator;

            var timeTriggered = request.Universe as ITimeTriggeredUniverse;

            if (timeTriggered != null)
            {
                Log.Trace($"LiveTradingDataFeed.CreateUniverseSubscription(): Creating user defined universe: {config.Symbol}");

                // spoof a tick on the requested interval to trigger the universe selection function
                var enumeratorFactory = new TimeTriggeredUniverseSubscriptionEnumeratorFactory(timeTriggered, MarketHoursDatabase.FromDataFolder(), _frontierTimeProvider);
                enumerator = enumeratorFactory.CreateEnumerator(request, _dataProvider);

                enumerator = new FrontierAwareEnumerator(enumerator, _timeProvider, tzOffsetProvider);

                var enqueueable = new EnqueueableEnumerator <BaseData>();
                _customExchange.AddEnumerator(new EnumeratorHandler(config.Symbol, enumerator, enqueueable));
                enumerator = enqueueable;
            }
            else if (config.Type == typeof(CoarseFundamental))
            {
                Log.Trace("LiveTradingDataFeed.CreateUniverseSubscription(): Creating coarse universe: " + config.Symbol.ToString());

                // we subscribe using a normalized symbol, without a random GUID,
                // since the ticker plant will send the coarse data using this symbol
                var normalizedSymbol = CoarseFundamental.CreateUniverseSymbol(config.Symbol.ID.Market, false);

                // since we're binding to the data queue exchange we'll need to let him
                // know that we expect this data
                _dataQueueHandler.Subscribe(_job, new[] { normalizedSymbol });

                var enqueable = new EnqueueableEnumerator <BaseData>();
                // We `AddDataHandler` not `Set` so we can have multiple handlers for the coarse data
                _exchange.AddDataHandler(normalizedSymbol, data =>
                {
                    enqueable.Enqueue(data);

                    subscription.OnNewDataAvailable();
                });

                enumerator = GetConfiguredFrontierAwareEnumerator(enqueable, tzOffsetProvider,
                                                                  // advance time if before 23pm or after 5am and not on Saturdays
                                                                  time => time.Hour < 23 && time.Hour > 5 && time.DayOfWeek != DayOfWeek.Saturday);
            }
            else if (request.Universe is OptionChainUniverse)
            {
                Log.Trace("LiveTradingDataFeed.CreateUniverseSubscription(): Creating option chain universe: " + config.Symbol.ToString());

                Func <SubscriptionRequest, IEnumerator <BaseData>, IEnumerator <BaseData> > configure = (subRequest, input) =>
                {
                    // we check if input enumerator is an underlying enumerator. If yes, we subscribe it to the data.
                    var aggregator = input as TradeBarBuilderEnumerator;

                    if (aggregator != null)
                    {
                        _exchange.SetDataHandler(request.Configuration.Symbol, data =>
                        {
                            aggregator.ProcessData((Tick)data);
                        });
                    }

                    var fillForwardResolution = _subscriptions.UpdateAndGetFillForwardResolution(request.Configuration);

                    return(new LiveFillForwardEnumerator(_frontierTimeProvider, input, request.Security.Exchange, fillForwardResolution, request.Configuration.ExtendedMarketHours, localEndTime, request.Configuration.Increment, request.Configuration.DataTimeZone, request.StartTimeLocal));
                };

                var symbolUniverse = _dataQueueHandler as IDataQueueUniverseProvider;
                if (symbolUniverse == null)
                {
                    throw new NotSupportedException("The DataQueueHandler does not support Options.");
                }

                var enumeratorFactory = new OptionChainUniverseSubscriptionEnumeratorFactory(configure, symbolUniverse, _timeProvider);
                enumerator = enumeratorFactory.CreateEnumerator(request, _dataProvider);

                enumerator = GetConfiguredFrontierAwareEnumerator(enumerator, tzOffsetProvider,
                                                                  time => symbolUniverse.CanAdvanceTime(config.SecurityType));
            }
            else if (request.Universe is FuturesChainUniverse)
            {
                Log.Trace("LiveTradingDataFeed.CreateUniverseSubscription(): Creating futures chain universe: " + config.Symbol.ToString());

                var symbolUniverse = _dataQueueHandler as IDataQueueUniverseProvider;
                if (symbolUniverse == null)
                {
                    throw new NotSupportedException("The DataQueueHandler does not support Futures.");
                }

                var enumeratorFactory = new FuturesChainUniverseSubscriptionEnumeratorFactory(symbolUniverse, _timeProvider);
                enumerator = enumeratorFactory.CreateEnumerator(request, _dataProvider);

                enumerator = GetConfiguredFrontierAwareEnumerator(enumerator, tzOffsetProvider,
                                                                  time => symbolUniverse.CanAdvanceTime(config.SecurityType));
            }
            else
            {
                Log.Trace("LiveTradingDataFeed.CreateUniverseSubscription(): Creating custom universe: " + config.Symbol.ToString());

                var factory         = new LiveCustomDataSubscriptionEnumeratorFactory(_timeProvider);
                var enumeratorStack = factory.CreateEnumerator(request, _dataProvider);
                enumerator = new BaseDataCollectionAggregatorEnumerator(enumeratorStack, config.Symbol, liveMode: true);

                var enqueueable = new EnqueueableEnumerator <BaseData>();
                _customExchange.AddEnumerator(new EnumeratorHandler(config.Symbol, enumerator, enqueueable));
                enumerator = enqueueable;
            }

            // create the subscription
            var subscriptionDataEnumerator = new SubscriptionDataEnumerator(request.Configuration, request.Security.Exchange.Hours, tzOffsetProvider, enumerator);

            subscription = new Subscription(request, subscriptionDataEnumerator, tzOffsetProvider);

            return(subscription);
        }
        public void Create_WithBadAddOnParamsCorrectlyParsesValidationErrors()
        {
            TestPlan plan = PlanFixture.ADD_ON_DISCOUNT_PLAN;
            SubscriptionRequest request = new SubscriptionRequest
            {
                PaymentMethodToken = creditCard.Token,
                PlanId = plan.Id,
                AddOns = new AddOnsRequest
                {
                    Update = new UpdateAddOnRequest[]
                    {
                        new UpdateAddOnRequest
                        {
                            ExistingId = "increase_10",
                            Amount = -200M
                        },
                        new UpdateAddOnRequest
                        {
                            ExistingId = "increase_20",
                            Quantity = -9
                        }
                    }
                }
            };

            Result<Subscription> result = gateway.Subscription.Create(request);
            Assert.IsFalse(result.IsSuccess());

            Assert.AreEqual(ValidationErrorCode.SUBSCRIPTION_MODIFICATION_AMOUNT_IS_INVALID,
                result.Errors.ForObject("Subscription").ForObject("AddOns").ForObject("Update").ForIndex(0).OnField("Amount")[0].Code);

            Assert.AreEqual(ValidationErrorCode.SUBSCRIPTION_MODIFICATION_QUANTITY_IS_INVALID,
                result.Errors.ForObject("Subscription").ForObject("AddOns").ForObject("Update").ForIndex(1).OnField("Quantity")[0].Code);
        }
        public void Create_CanAddAddOnsAndDiscounts()
        {
            TestPlan plan = PlanFixture.ADD_ON_DISCOUNT_PLAN;
            SubscriptionRequest request = new SubscriptionRequest
            {
                PaymentMethodToken = creditCard.Token,
                PlanId = plan.Id,
                AddOns = new AddOnsRequest
                {
                    Add = new AddAddOnRequest[]
                    {
                        new AddAddOnRequest
                        {
                            InheritedFromId = "increase_30",
                            Amount = 35M,
                            NumberOfBillingCycles = 3,
                            Quantity = 8
                        }
                    },
                    Remove = new string[] { "increase_10", "increase_20" }
                },
                Discounts = new DiscountsRequest
                {
                    Add = new AddDiscountRequest[]
                    {
                        new AddDiscountRequest
                        {
                            InheritedFromId = "discount_15",
                            Amount = 17M,
                            NeverExpires = true,
                            Quantity = 9
                        }
                    },
                    Remove = new string[] { "discount_7", "discount_11" }
                }
            };

            Result<Subscription> result = gateway.Subscription.Create(request);
            Assert.IsTrue(result.IsSuccess());
            Subscription subscription = result.Target;

            Assert.AreEqual(1, subscription.AddOns.Count);

            Assert.AreEqual("increase_30", subscription.AddOns[0].Id);
            Assert.AreEqual(35M, subscription.AddOns[0].Amount);
            Assert.AreEqual(8, subscription.AddOns[0].Quantity);
            Assert.IsFalse(subscription.AddOns[0].NeverExpires.Value);
            Assert.AreEqual(3, subscription.AddOns[0].NumberOfBillingCycles);
            Assert.AreEqual(0, subscription.AddOns[0].CurrentBillingCycle);

            Assert.AreEqual(1, subscription.Discounts.Count);

            Assert.AreEqual("discount_15", subscription.Discounts[0].Id);
            Assert.AreEqual(17M, subscription.Discounts[0].Amount);
            Assert.AreEqual(9, subscription.Discounts[0].Quantity);
            Assert.IsTrue(subscription.Discounts[0].NeverExpires.Value);
            Assert.IsNull(subscription.Discounts[0].NumberOfBillingCycles);
            Assert.AreEqual(0, subscription.Discounts[0].CurrentBillingCycle);
        }
        public void Create_CanRemoveInheritedAddOnsAndDiscounts()
        {
            TestPlan plan = PlanFixture.ADD_ON_DISCOUNT_PLAN;
            SubscriptionRequest request = new SubscriptionRequest
            {
                PaymentMethodToken = creditCard.Token,
                PlanId = plan.Id,
                AddOns = new AddOnsRequest
                {
                    Remove = new string[] { "increase_10", "increase_20" }
                },
                Discounts = new DiscountsRequest
                {
                    Remove = new string[] { "discount_11" }
                }
            };

            Result<Subscription> result = gateway.Subscription.Create(request);
            Assert.IsTrue(result.IsSuccess());
            Subscription subscription = result.Target;

            Assert.AreEqual(0, subscription.AddOns.Count);
            Assert.AreEqual(1, subscription.Discounts.Count);

            Assert.AreEqual("discount_7", subscription.Discounts[0].Id);
        }
        public void Create_CanOverrideInheritedAddOnsAndDiscountsFromPlan()
        {
            TestPlan plan = PlanFixture.ADD_ON_DISCOUNT_PLAN;
            SubscriptionRequest request = new SubscriptionRequest
            {
                PaymentMethodToken = creditCard.Token,
                PlanId = plan.Id,
                AddOns = new AddOnsRequest
                {
                    Update = new UpdateAddOnRequest[]
                    {
                        new UpdateAddOnRequest
                        {
                            ExistingId = "increase_10",
                            Amount = 30M,
                            Quantity = 9,
                            NeverExpires = true
                        },
                        new UpdateAddOnRequest
                        {
                            ExistingId = "increase_20",
                            Amount = 40M,
                            NumberOfBillingCycles = 20
                        }
                    }
                },
                Discounts = new DiscountsRequest
                {
                    Update = new UpdateDiscountRequest[]
                    {
                        new UpdateDiscountRequest
                        {
                            ExistingId = "discount_7",
                            Amount = 15M,
                            Quantity = 7,
                            NeverExpires = true
                        },
                        new UpdateDiscountRequest
                        {
                            ExistingId = "discount_11",
                            Amount = 23M,
                            NumberOfBillingCycles = 11
                        }
                    }
                }
            };

            Result<Subscription> result = gateway.Subscription.Create(request);
            Assert.IsTrue(result.IsSuccess());
            Subscription subscription = result.Target;

            List<AddOn> addOns = subscription.AddOns;
            addOns.Sort(TestHelper.CompareModificationsById);

            Assert.AreEqual(2, addOns.Count);

            Assert.AreEqual(30M, addOns[0].Amount);
            Assert.AreEqual(9, addOns[0].Quantity);
            Assert.IsTrue(addOns[0].NeverExpires.Value);
            Assert.IsNull(addOns[0].NumberOfBillingCycles);
            Assert.AreEqual(0, addOns[0].CurrentBillingCycle);

            Assert.AreEqual(40.00M, addOns[1].Amount);
            Assert.AreEqual(1, addOns[1].Quantity);
            Assert.IsFalse(addOns[1].NeverExpires.Value);
            Assert.AreEqual(20, addOns[1].NumberOfBillingCycles);
            Assert.AreEqual(0, addOns[1].CurrentBillingCycle);

            List<Discount> discounts = subscription.Discounts;
            discounts.Sort(TestHelper.CompareModificationsById);

            Assert.AreEqual(2, discounts.Count);

            Assert.AreEqual(23M, discounts[0].Amount);
            Assert.AreEqual(1, discounts[0].Quantity);
            Assert.IsFalse(discounts[0].NeverExpires.Value);
            Assert.AreEqual(11, discounts[0].NumberOfBillingCycles);
            Assert.AreEqual(0, discounts[0].CurrentBillingCycle);

            Assert.AreEqual(15M, discounts[1].Amount);
            Assert.AreEqual(7, discounts[1].Quantity);
            Assert.IsTrue(discounts[1].NeverExpires.Value);
            Assert.IsNull(discounts[1].NumberOfBillingCycles);
            Assert.AreEqual(0, discounts[1].CurrentBillingCycle);
        }
        public void Create_InheritsAddOnsAndDiscountsFromPlan() {
            TestPlan plan = PlanFixture.ADD_ON_DISCOUNT_PLAN;
            SubscriptionRequest request = new SubscriptionRequest
            {
                PaymentMethodToken = creditCard.Token,
                PlanId = plan.Id
            };

            Result<Subscription> result = gateway.Subscription.Create(request);
            Assert.IsTrue(result.IsSuccess());
            Subscription subscription = result.Target;

            List<AddOn> addOns = subscription.AddOns;
            addOns.Sort(TestHelper.CompareModificationsById);

            Assert.AreEqual(2, addOns.Count);

            Assert.AreEqual(10M, addOns[0].Amount);
            Assert.AreEqual(1, addOns[0].Quantity);
            Assert.IsTrue(addOns[0].NeverExpires.Value);
            Assert.IsNull(addOns[0].NumberOfBillingCycles);
            Assert.AreEqual(0, addOns[0].CurrentBillingCycle);

            Assert.AreEqual(20.00M, addOns[1].Amount);
            Assert.AreEqual(1, addOns[1].Quantity);
            Assert.IsTrue(addOns[1].NeverExpires.Value);
            Assert.IsNull(addOns[1].NumberOfBillingCycles);
            Assert.AreEqual(0, addOns[1].CurrentBillingCycle);

            List<Discount> discounts = subscription.Discounts;
            discounts.Sort(TestHelper.CompareModificationsById);

            Assert.AreEqual(2, discounts.Count);

            Assert.AreEqual(11M, discounts[0].Amount);
            Assert.AreEqual(1, discounts[0].Quantity);
            Assert.IsTrue(discounts[0].NeverExpires.Value);
            Assert.IsNull(discounts[0].NumberOfBillingCycles);
            Assert.AreEqual(0, discounts[0].CurrentBillingCycle);

            Assert.AreEqual(7M, discounts[1].Amount);
            Assert.AreEqual(1, discounts[1].Quantity);
            Assert.IsTrue(discounts[1].NeverExpires.Value);
            Assert.IsNull(discounts[1].NumberOfBillingCycles);
            Assert.AreEqual(0, discounts[1].CurrentBillingCycle);
        }
        public void Create_InheritsNoAddOnsAndDiscountsWhenOptionIsPassed()
        {
            TestPlan plan = PlanFixture.ADD_ON_DISCOUNT_PLAN;
            SubscriptionRequest request = new SubscriptionRequest
            {
                PaymentMethodToken = creditCard.Token,
                PlanId = plan.Id,
                Options = new SubscriptionOptionsRequest
                {
                    DoNotInheritAddOnsOrDiscounts = true
                }
            };

            Result<Subscription> result = gateway.Subscription.Create(request);
            Assert.IsTrue(result.IsSuccess());
            Subscription subscription = result.Target;

            Assert.AreEqual(0, subscription.AddOns.Count);
            Assert.AreEqual(0, subscription.Discounts.Count);
        }
        public void Create_HasNoTransactionOnCreateWithATrial()
        {
            TestPlan plan = PlanFixture.PLAN_WITH_TRIAL;

            SubscriptionRequest request = new SubscriptionRequest
            {
                PaymentMethodToken = creditCard.Token,
                PlanId = plan.Id
            };

            Result<Subscription> result = gateway.Subscription.Create(request);
            Assert.IsTrue(result.IsSuccess());
            Subscription subscription = result.Target;

            Assert.AreEqual(0, subscription.Transactions.Count);
        }
Exemple #18
0
        /// <summary>
        /// Creates a subscription to process the request
        /// </summary>
        private Subscription CreateSubscription(HistoryRequest request, DateTime startUtc, DateTime endUtc)
        {
            // data reader expects these values in local times
            var startTimeLocal = startUtc.ConvertFromUtc(request.ExchangeHours.TimeZone);
            var endTimeLocal   = endUtc.ConvertFromUtc(request.ExchangeHours.TimeZone);

            var config = new SubscriptionDataConfig(request.DataType,
                                                    request.Symbol,
                                                    request.Resolution,
                                                    request.DataTimeZone,
                                                    request.ExchangeHours.TimeZone,
                                                    request.FillForwardResolution.HasValue,
                                                    request.IncludeExtendedMarketHours,
                                                    false,
                                                    request.IsCustomData,
                                                    request.TickType,
                                                    true,
                                                    request.DataNormalizationMode
                                                    );

            _dataPermissionManager.AssertConfiguration(config);

            var security = new Security(
                request.ExchangeHours,
                config,
                new Cash(Currencies.NullCurrency, 0, 1m),
                SymbolProperties.GetDefault(Currencies.NullCurrency),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null,
                new SecurityCache()
                );

            var mapFileResolver = MapFileResolver.Empty;

            if (config.TickerShouldBeMapped())
            {
                mapFileResolver = _mapFileProvider.Get(config.Market);
                var mapFile = mapFileResolver.ResolveMapFile(config.Symbol.ID.Symbol, config.Symbol.ID.Date);
                config.MappedSymbol = mapFile.GetMappedSymbol(startTimeLocal, config.MappedSymbol);
            }

            // Tradable dates are defined with the data time zone to access the right source
            var tradableDates = Time.EachTradeableDayInTimeZone(request.ExchangeHours, startTimeLocal, endTimeLocal, request.DataTimeZone, request.IncludeExtendedMarketHours);

            var dataReader = new SubscriptionDataReader(config,
                                                        startTimeLocal,
                                                        endTimeLocal,
                                                        mapFileResolver,
                                                        _factorFileProvider,
                                                        tradableDates,
                                                        false,
                                                        _dataCacheProvider
                                                        );

            dataReader.InvalidConfigurationDetected += (sender, args) => { OnInvalidConfigurationDetected(args); };
            dataReader.NumericalPrecisionLimited    += (sender, args) => { OnNumericalPrecisionLimited(args); };
            dataReader.StartDateLimited             += (sender, args) => { OnStartDateLimited(args); };
            dataReader.DownloadFailed      += (sender, args) => { OnDownloadFailed(args); };
            dataReader.ReaderErrorDetected += (sender, args) => { OnReaderErrorDetected(args); };

            IEnumerator <BaseData> reader = dataReader;
            var intraday = GetIntradayDataEnumerator(dataReader, request);

            if (intraday != null)
            {
                // we optionally concatenate the intraday data enumerator
                reader = new ConcatEnumerator(true, reader, intraday);
            }

            reader = CorporateEventEnumeratorFactory.CreateEnumerators(
                reader,
                config,
                _factorFileProvider,
                dataReader,
                mapFileResolver,
                false,
                startTimeLocal);

            // optionally apply fill forward behavior
            if (request.FillForwardResolution.HasValue)
            {
                // copy forward Bid/Ask bars for QuoteBars
                if (request.DataType == typeof(QuoteBar))
                {
                    reader = new QuoteBarFillForwardEnumerator(reader);
                }

                var readOnlyRef = Ref.CreateReadOnly(() => request.FillForwardResolution.Value.ToTimeSpan());
                reader = new FillForwardEnumerator(reader, security.Exchange, readOnlyRef, request.IncludeExtendedMarketHours, endTimeLocal, config.Increment, config.DataTimeZone);
            }

            // since the SubscriptionDataReader performs an any overlap condition on the trade bar's entire
            // range (time->end time) we can end up passing the incorrect data (too far past, possibly future),
            // so to combat this we deliberately filter the results from the data reader to fix these cases
            // which only apply to non-tick data

            reader = new SubscriptionFilterEnumerator(reader, security, endTimeLocal, config.ExtendedMarketHours, false, request.ExchangeHours);
            reader = new FilterEnumerator <BaseData>(reader, data =>
            {
                // allow all ticks
                if (config.Resolution == Resolution.Tick)
                {
                    return(true);
                }
                // filter out future data
                if (data.EndTime > endTimeLocal)
                {
                    return(false);
                }
                // filter out data before the start
                return(data.EndTime > startTimeLocal);
            });
            var subscriptionRequest = new SubscriptionRequest(false, null, security, config, request.StartTimeUtc, request.EndTimeUtc);

            if (_parallelHistoryRequestsEnabled)
            {
                return(SubscriptionUtils.CreateAndScheduleWorker(subscriptionRequest, reader, _factorFileProvider, false));
            }
            return(SubscriptionUtils.Create(subscriptionRequest, reader));
        }
Exemple #19
0
        /// <summary>
        /// Creates a new subscription for the specified security
        /// </summary>
        /// <param name="request">The subscription request</param>
        /// <returns>A new subscription instance of the specified security</returns>
        protected Subscription CreateSubscription(SubscriptionRequest request)
        {
            Subscription subscription = null;

            try
            {
                var localEndTime           = request.EndTimeUtc.ConvertFromUtc(request.Security.Exchange.TimeZone);
                var timeZoneOffsetProvider = new TimeZoneOffsetProvider(request.Security.Exchange.TimeZone, request.StartTimeUtc, request.EndTimeUtc);

                IEnumerator <BaseData> enumerator;
                if (request.Configuration.IsCustomData)
                {
                    if (!Quandl.IsAuthCodeSet)
                    {
                        // we're not using the SubscriptionDataReader, so be sure to set the auth token here
                        Quandl.SetAuthCode(Config.Get("quandl-auth-token"));
                    }

                    // each time we exhaust we'll new up this enumerator stack
                    var refresher = new RefreshEnumerator <BaseData>(() =>
                    {
                        var dateInDataTimeZone    = DateTime.UtcNow.ConvertFromUtc(request.Configuration.DataTimeZone).Date;
                        var enumeratorFactory     = new BaseDataSubscriptionEnumeratorFactory(r => new[] { dateInDataTimeZone });
                        var factoryReadEnumerator = enumeratorFactory.CreateEnumerator(request);
                        var maximumDataAge        = TimeSpan.FromTicks(Math.Max(request.Configuration.Increment.Ticks, TimeSpan.FromSeconds(5).Ticks));
                        var fastForward           = new FastForwardEnumerator(factoryReadEnumerator, _timeProvider, request.Security.Exchange.TimeZone, maximumDataAge);
                        return(new FrontierAwareEnumerator(fastForward, _frontierTimeProvider, timeZoneOffsetProvider));
                    });

                    // rate limit the refreshing of the stack to the requested interval
                    // At Tick resolution, it will refresh at full speed
                    // At Second and Minute resolution, it will refresh every second and minute respectively
                    // At Hour and Daily resolutions, it will refresh every 30 minutes
                    var minimumTimeBetweenCalls = Math.Min(request.Configuration.Increment.Ticks, TimeSpan.FromMinutes(30).Ticks);
                    var rateLimit = new RateLimitEnumerator(refresher, _timeProvider, TimeSpan.FromTicks(minimumTimeBetweenCalls));
                    _customExchange.AddEnumerator(request.Configuration.Symbol, rateLimit);

                    var enqueable = new EnqueueableEnumerator <BaseData>();
                    _customExchange.SetDataHandler(request.Configuration.Symbol, data =>
                    {
                        enqueable.Enqueue(data);
                        if (subscription != null)
                        {
                            subscription.RealtimePrice = data.Value;
                        }
                    });
                    enumerator = enqueable;
                }
                else if (request.Configuration.Resolution != Resolution.Tick)
                {
                    // this enumerator allows the exchange to pump ticks into the 'back' of the enumerator,
                    // and the time sync loop can pull aggregated trade bars off the front
                    var aggregator = new TradeBarBuilderEnumerator(request.Configuration.Increment, request.Security.Exchange.TimeZone, _timeProvider);
                    _exchange.SetDataHandler(request.Configuration.Symbol, data =>
                    {
                        aggregator.ProcessData((Tick)data);
                        if (subscription != null)
                        {
                            subscription.RealtimePrice = data.Value;
                        }
                    });
                    enumerator = aggregator;
                }
                else
                {
                    // tick subscriptions can pass right through
                    var tickEnumerator = new EnqueueableEnumerator <BaseData>();
                    _exchange.SetDataHandler(request.Configuration.Symbol, data =>
                    {
                        tickEnumerator.Enqueue(data);
                        if (subscription != null)
                        {
                            subscription.RealtimePrice = data.Value;
                        }
                    });
                    enumerator = tickEnumerator;
                }

                if (request.Configuration.FillDataForward)
                {
                    enumerator = new LiveFillForwardEnumerator(_frontierTimeProvider, enumerator, request.Security.Exchange, _fillForwardResolution, request.Configuration.ExtendedMarketHours, localEndTime, request.Configuration.Increment);
                }

                // define market hours and user filters to incoming data
                if (request.Configuration.IsFilteredSubscription)
                {
                    enumerator = new SubscriptionFilterEnumerator(enumerator, request.Security, localEndTime);
                }

                // finally, make our subscriptions aware of the frontier of the data feed, prevents future data from spewing into the feed
                enumerator = new FrontierAwareEnumerator(enumerator, _frontierTimeProvider, timeZoneOffsetProvider);

                subscription = new Subscription(request.Universe, request.Security, request.Configuration, enumerator, timeZoneOffsetProvider, request.StartTimeUtc, request.EndTimeUtc, false);
            }
            catch (Exception err)
            {
                Log.Error(err);
            }

            return(subscription);
        }
        public void Find()
        {
            TestPlan plan = PlanFixture.PLAN_WITH_TRIAL;
            SubscriptionRequest request = new SubscriptionRequest
            {
                PaymentMethodToken = creditCard.Token,
                PlanId = plan.Id
            };

            Subscription subscription = gateway.Subscription.Create(request).Target;

            Subscription foundSubscription = gateway.Subscription.Find(subscription.Id);
            Assert.AreEqual(subscription.Id, foundSubscription.Id);
            Assert.AreEqual(subscription.PaymentMethodToken, creditCard.Token);
            Assert.AreEqual(subscription.PlanId, plan.Id);
        }
Exemple #21
0
 /// <summary>
 /// Creates a new subscription to provide data for the specified security.
 /// </summary>
 /// <param name="request">Defines the subscription to be added, including start/end times the universe and security</param>
 /// <returns>The created <see cref="Subscription"/> if successful, null otherwise</returns>
 public Subscription CreateSubscription(SubscriptionRequest request)
 {
     return(request.IsUniverseSubscription
         ? CreateUniverseSubscription(request)
         : CreateDataSubscription(request));
 }
        public void Search_OnBillingCyclesRemainingIs()
        {
            SubscriptionRequest request1 = new SubscriptionRequest
            {
                NumberOfBillingCycles = 5,
                PaymentMethodToken = creditCard.Token,
                PlanId = PlanFixture.PLAN_WITH_TRIAL.Id,
                Price = 4M
            };

            SubscriptionRequest request2 = new SubscriptionRequest
            {
                NumberOfBillingCycles = 10,
                PaymentMethodToken = creditCard.Token,
                PlanId = PlanFixture.PLAN_WITH_TRIAL.Id,
                Price = 4M
            };

            Subscription subscription1 = gateway.Subscription.Create(request1).Target;
            Subscription subscription2 = gateway.Subscription.Create(request2).Target;

            SubscriptionSearchRequest request = new SubscriptionSearchRequest().
                BillingCyclesRemaining.Is(5).
                Price.Is(4M);

            ResourceCollection<Subscription> collection = gateway.Subscription.Search(request);

            Assert.IsTrue(TestHelper.IncludesSubscription(collection, subscription1));
            Assert.IsFalse(TestHelper.IncludesSubscription(collection, subscription2));
        }
Exemple #23
0
        /// <summary>
        /// Applies universe selection the the data feed and algorithm
        /// </summary>
        /// <param name="universe">The universe to perform selection on</param>
        /// <param name="dateTimeUtc">The current date time in utc</param>
        /// <param name="universeData">The data provided to perform selection with</param>
        public SecurityChanges ApplyUniverseSelection(Universe universe, DateTime dateTimeUtc, BaseDataCollection universeData)
        {
            var algorithmEndDateUtc = _algorithm.EndDate.ConvertToUtc(_algorithm.TimeZone);

            if (dateTimeUtc > algorithmEndDateUtc)
            {
                return(SecurityChanges.None);
            }

            IEnumerable <Symbol> selectSymbolsResult;

            // check if this universe must be filtered with fine fundamental data
            var fineFiltered = universe as FineFundamentalFilteredUniverse;

            if (fineFiltered != null)
            {
                // perform initial filtering and limit the result
                selectSymbolsResult = universe.SelectSymbols(dateTimeUtc, universeData);

                // prepare a BaseDataCollection of FineFundamental instances
                var fineCollection = new BaseDataCollection();
                var dataProvider   = new DefaultDataProvider();

                foreach (var symbol in selectSymbolsResult)
                {
                    var factory = new FineFundamentalSubscriptionEnumeratorFactory(_algorithm.LiveMode, x => new[] { dateTimeUtc });
                    var config  = FineFundamentalUniverse.CreateConfiguration(symbol);

                    var exchangeHours    = _marketHoursDatabase.GetEntry(symbol.ID.Market, symbol, symbol.ID.SecurityType).ExchangeHours;
                    var symbolProperties = _symbolPropertiesDatabase.GetSymbolProperties(symbol.ID.Market, symbol, symbol.ID.SecurityType, CashBook.AccountCurrency);
                    var quoteCash        = _algorithm.Portfolio.CashBook[symbolProperties.QuoteCurrency];

                    var security = new Equity(symbol, exchangeHours, quoteCash, symbolProperties);

                    var request = new SubscriptionRequest(true, universe, security, new SubscriptionDataConfig(config), dateTimeUtc, dateTimeUtc);
                    using (var enumerator = factory.CreateEnumerator(request, dataProvider))
                    {
                        if (enumerator.MoveNext())
                        {
                            fineCollection.Data.Add(enumerator.Current);
                        }
                    }
                }

                // perform the fine fundamental universe selection
                selectSymbolsResult = fineFiltered.FineFundamentalUniverse.PerformSelection(dateTimeUtc, fineCollection);
            }
            else
            {
                // perform initial filtering and limit the result
                selectSymbolsResult = universe.PerformSelection(dateTimeUtc, universeData);
            }

            // check for no changes first
            if (ReferenceEquals(selectSymbolsResult, Universe.Unchanged))
            {
                return(SecurityChanges.None);
            }

            // materialize the enumerable into a set for processing
            var selections = selectSymbolsResult.ToHashSet();

            var additions = new List <Security>();
            var removals  = new List <Security>();

            // remove previously deselected members which were kept in the universe because of holdings or open orders
            foreach (var member in _pendingRemovals.ToList())
            {
                var openOrders = _algorithm.Transactions.GetOrders(x => x.Status.IsOpen() && x.Symbol == member.Symbol);
                if (!member.HoldStock && !openOrders.Any())
                {
                    RemoveSecurityFromUniverse(universe, member, removals, dateTimeUtc, algorithmEndDateUtc);

                    _pendingRemovals.Remove(member);
                }
            }

            // determine which data subscriptions need to be removed from this universe
            foreach (var member in universe.Members.Values)
            {
                // if we've selected this subscription again, keep it
                if (selections.Contains(member.Symbol))
                {
                    continue;
                }

                // don't remove if the universe wants to keep him in
                if (!universe.CanRemoveMember(dateTimeUtc, member))
                {
                    continue;
                }

                // remove the member - this marks this member as not being
                // selected by the universe, but it may remain in the universe
                // until open orders are closed and the security is liquidated
                removals.Add(member);

                // but don't physically remove it from the algorithm if we hold stock or have open orders against it
                var openOrders = _algorithm.Transactions.GetOrders(x => x.Status.IsOpen() && x.Symbol == member.Symbol);
                if (!member.HoldStock && !openOrders.Any())
                {
                    RemoveSecurityFromUniverse(universe, member, removals, dateTimeUtc, algorithmEndDateUtc);
                }
                else
                {
                    _pendingRemovals.Add(member);
                }
            }

            var keys = _pendingSecurityAdditions.Keys;

            if (keys.Any() && keys.Single() != dateTimeUtc)
            {
                // if the frontier moved forward then we've added these securities to the algorithm
                _pendingSecurityAdditions.Clear();
            }

            Dictionary <Symbol, Security> pendingAdditions;

            if (!_pendingSecurityAdditions.TryGetValue(dateTimeUtc, out pendingAdditions))
            {
                // keep track of created securities so we don't create the same security twice, leads to bad things :)
                pendingAdditions = new Dictionary <Symbol, Security>();
                _pendingSecurityAdditions[dateTimeUtc] = pendingAdditions;
            }

            // find new selections and add them to the algorithm
            foreach (var symbol in selections)
            {
                // create the new security, the algorithm thread will add this at the appropriate time
                Security security;
                if (!pendingAdditions.TryGetValue(symbol, out security) && !_algorithm.Securities.TryGetValue(symbol, out security))
                {
                    security = universe.CreateSecurity(symbol, _algorithm, _marketHoursDatabase, _symbolPropertiesDatabase);
                    pendingAdditions.Add(symbol, security);
                }

                var addedSubscription = false;

                foreach (var request in universe.GetSubscriptionRequests(security, dateTimeUtc, algorithmEndDateUtc))
                {
                    // add the new subscriptions to the data feed
                    _dataFeed.AddSubscription(request);

                    // only update our security changes if we actually added data
                    if (!request.IsUniverseSubscription)
                    {
                        addedSubscription = true;
                    }
                }

                if (addedSubscription)
                {
                    var addedMember = universe.AddMember(dateTimeUtc, security);

                    if (addedMember)
                    {
                        additions.Add(security);
                    }
                }
            }

            // return None if there's no changes, otherwise return what we've modified
            var securityChanges = additions.Count + removals.Count != 0
                ? new SecurityChanges(additions, removals)
                : SecurityChanges.None;

            // Add currency data feeds that weren't explicitly added in Initialize
            if (additions.Count > 0)
            {
                var addedSecurities = _algorithm.Portfolio.CashBook.EnsureCurrencyDataFeeds(_algorithm.Securities, _algorithm.SubscriptionManager, _marketHoursDatabase, _symbolPropertiesDatabase, _algorithm.BrokerageModel.DefaultMarkets, securityChanges);
                foreach (var security in addedSecurities)
                {
                    // assume currency feeds are always one subscription per, these are typically quote subscriptions
                    _dataFeed.AddSubscription(new SubscriptionRequest(false, universe, security, new SubscriptionDataConfig(security.Subscriptions.First()), dateTimeUtc, algorithmEndDateUtc));
                }
            }

            if (securityChanges != SecurityChanges.None)
            {
                Log.Debug("UniverseSelection.ApplyUniverseSelection(): " + dateTimeUtc + ": " + securityChanges);
            }

            return(securityChanges);
        }
        public void Search_OnDaysPastDueBetween()
        {
            SubscriptionRequest subscriptionRequest = new SubscriptionRequest
            {
                PaymentMethodToken = creditCard.Token,
                PlanId = PlanFixture.PLAN_WITH_TRIAL.Id,
            };

            Subscription subscription = gateway.Subscription.Create(subscriptionRequest).Target;
            MakePastDue(subscription, 3);

            SubscriptionSearchRequest request = new SubscriptionSearchRequest().
                DaysPastDue.Between(2, 10);

            ResourceCollection<Subscription> collection = gateway.Subscription.Search(request);
            Assert.IsTrue(collection.MaximumCount > 0);

            foreach (Subscription foundSubscription in collection) {
                Assert.IsTrue(foundSubscription.DaysPastDue >= 2 && foundSubscription.DaysPastDue <= 10);
            }
        }
Exemple #25
0
        /// <summary>
        /// Creates a new subscription for universe selection
        /// </summary>
        /// <param name="request">The subscription request</param>
        private Subscription CreateUniverseSubscription(SubscriptionRequest request)
        {
            // TODO : Consider moving the creating of universe subscriptions to a separate, testable class

            // grab the relevant exchange hours
            var config           = request.Universe.Configuration;
            var localEndTime     = request.EndTimeUtc.ConvertFromUtc(request.Security.Exchange.TimeZone);
            var tzOffsetProvider = new TimeZoneOffsetProvider(request.Security.Exchange.TimeZone, request.StartTimeUtc, request.EndTimeUtc);

            IEnumerator <BaseData> enumerator;

            var timeTriggered = request.Universe as ITimeTriggeredUniverse;

            if (timeTriggered != null)
            {
                Log.Trace("LiveTradingDataFeed.CreateUniverseSubscription(): Creating user defined universe: " + config.Symbol.ToString());

                // spoof a tick on the requested interval to trigger the universe selection function
                var enumeratorFactory = new TimeTriggeredUniverseSubscriptionEnumeratorFactory(timeTriggered, MarketHoursDatabase.FromDataFolder());
                enumerator = enumeratorFactory.CreateEnumerator(request, _dataProvider);

                enumerator = new FrontierAwareEnumerator(enumerator, _timeProvider, tzOffsetProvider);

                var enqueueable = new EnqueueableEnumerator <BaseData>();
                _customExchange.AddEnumerator(new EnumeratorHandler(config.Symbol, enumerator, enqueueable));
                enumerator = enqueueable;

                // Trigger universe selection when security added/removed after Initialize
                if (timeTriggered is UserDefinedUniverse)
                {
                    var userDefined = (UserDefinedUniverse)timeTriggered;
                    userDefined.CollectionChanged += (sender, args) =>
                    {
                        var items =
                            args.Action == NotifyCollectionChangedAction.Add ? args.NewItems :
                            args.Action == NotifyCollectionChangedAction.Remove ? args.OldItems : null;

                        var currentFrontierUtcTime = _frontierTimeProvider.GetUtcNow();
                        if (items == null || currentFrontierUtcTime == DateTime.MinValue)
                        {
                            return;
                        }

                        var symbol = items.OfType <Symbol>().FirstOrDefault();
                        if (symbol == null)
                        {
                            return;
                        }

                        var collection = new BaseDataCollection(currentFrontierUtcTime, symbol);
                        var changes    = _universeSelection.ApplyUniverseSelection(userDefined, currentFrontierUtcTime, collection);
                        _algorithm.OnSecuritiesChanged(changes);
                    };
                }
            }
            else if (config.Type == typeof(CoarseFundamental))
            {
                Log.Trace("LiveTradingDataFeed.CreateUniverseSubscription(): Creating coarse universe: " + config.Symbol.ToString());

                // we subscribe using a normalized symbol, without a random GUID,
                // since the ticker plant will send the coarse data using this symbol
                var normalizedSymbol = CoarseFundamental.CreateUniverseSymbol(config.Symbol.ID.Market, false);

                // since we're binding to the data queue exchange we'll need to let him
                // know that we expect this data
                _dataQueueHandler.Subscribe(_job, new[] { normalizedSymbol });

                var enqueable = new EnqueueableEnumerator <BaseData>();
                // We `AddDataHandler` not `Set` so we can have multiple handlers for the coarse data
                _exchange.AddDataHandler(normalizedSymbol, data =>
                {
                    enqueable.Enqueue(data);
                });
                enumerator = enqueable;
            }
            else if (request.Universe is OptionChainUniverse)
            {
                Log.Trace("LiveTradingDataFeed.CreateUniverseSubscription(): Creating option chain universe: " + config.Symbol.ToString());

                Func <SubscriptionRequest, IEnumerator <BaseData>, IEnumerator <BaseData> > configure = (subRequest, input) =>
                {
                    // we check if input enumerator is an underlying enumerator. If yes, we subscribe it to the data.
                    var aggregator = input as TradeBarBuilderEnumerator;

                    if (aggregator != null)
                    {
                        _exchange.SetDataHandler(request.Configuration.Symbol, data =>
                        {
                            aggregator.ProcessData((Tick)data);
                        });
                    }

                    var fillForwardResolution = _subscriptions.UpdateAndGetFillForwardResolution(request.Configuration);

                    return(new LiveFillForwardEnumerator(_frontierTimeProvider, input, request.Security.Exchange, fillForwardResolution, request.Configuration.ExtendedMarketHours, localEndTime, request.Configuration.Increment, request.Configuration.DataTimeZone));
                };

                var symbolUniverse = _dataQueueHandler as IDataQueueUniverseProvider;
                if (symbolUniverse == null)
                {
                    throw new NotSupportedException("The DataQueueHandler does not support Options.");
                }

                var enumeratorFactory = new OptionChainUniverseSubscriptionEnumeratorFactory(configure, symbolUniverse, _timeProvider);
                enumerator = enumeratorFactory.CreateEnumerator(request, _dataProvider);

                enumerator = new FrontierAwareEnumerator(enumerator, _frontierTimeProvider, tzOffsetProvider);
            }
            else if (request.Universe is FuturesChainUniverse)
            {
                Log.Trace("LiveTradingDataFeed.CreateUniverseSubscription(): Creating futures chain universe: " + config.Symbol.ToString());

                var symbolUniverse = _dataQueueHandler as IDataQueueUniverseProvider;
                if (symbolUniverse == null)
                {
                    throw new NotSupportedException("The DataQueueHandler does not support Futures.");
                }

                var enumeratorFactory = new FuturesChainUniverseSubscriptionEnumeratorFactory(symbolUniverse, _timeProvider);
                enumerator = enumeratorFactory.CreateEnumerator(request, _dataProvider);

                enumerator = new FrontierAwareEnumerator(enumerator, _frontierTimeProvider, tzOffsetProvider);
            }
            else
            {
                Log.Trace("LiveTradingDataFeed.CreateUniverseSubscription(): Creating custom universe: " + config.Symbol.ToString());

                var factory         = new LiveCustomDataSubscriptionEnumeratorFactory(_timeProvider);
                var enumeratorStack = factory.CreateEnumerator(request, _dataProvider);
                enumerator = new BaseDataCollectionAggregatorEnumerator(enumeratorStack, config.Symbol);

                var enqueueable = new EnqueueableEnumerator <BaseData>();
                _customExchange.AddEnumerator(new EnumeratorHandler(config.Symbol, enumerator, enqueueable));
                enumerator = enqueueable;
            }

            // create the subscription
            var subscriptionDataEnumerator = SubscriptionData.Enumerator(request.Configuration, request.Security, tzOffsetProvider, enumerator);
            var subscription = new Subscription(request, subscriptionDataEnumerator, tzOffsetProvider);

            return(subscription);
        }
        public void Search_OnIdIs()
        {
            SubscriptionRequest request1 = new SubscriptionRequest
            {
                Id = string.Format("find_me{0}", new Random().Next(1000000)),
                PaymentMethodToken = creditCard.Token,
                PlanId = PlanFixture.PLAN_WITH_TRIAL.Id,
                Price = 3M
            };

            SubscriptionRequest request2 = new SubscriptionRequest
            {
                Id = string.Format("do_not_find_me{0}", new Random().Next(1000000)),
                PaymentMethodToken = creditCard.Token,
                PlanId = PlanFixture.PLAN_WITH_TRIAL.Id,
                Price = 3M
            };

            Subscription subscription1 = gateway.Subscription.Create(request1).Target;
            Subscription subscription2 = gateway.Subscription.Create(request2).Target;

            SubscriptionSearchRequest request = new SubscriptionSearchRequest().
                Id.StartsWith("find_me").
                Price.Is(3M);

            ResourceCollection<Subscription> collection = gateway.Subscription.Search(request);

            Assert.IsTrue(TestHelper.IncludesSubscription(collection, subscription1));
            Assert.IsFalse(TestHelper.IncludesSubscription(collection, subscription2));
        }
Exemple #27
0
        /// <summary>
        /// Creates a new subscription for the specified security
        /// </summary>
        /// <param name="request">The subscription request</param>
        /// <returns>A new subscription instance of the specified security</returns>
        protected Subscription CreateDataSubscription(SubscriptionRequest request)
        {
            Subscription subscription = null;

            try
            {
                var localEndTime           = request.EndTimeUtc.ConvertFromUtc(request.Security.Exchange.TimeZone);
                var timeZoneOffsetProvider = new TimeZoneOffsetProvider(request.Security.Exchange.TimeZone, request.StartTimeUtc, request.EndTimeUtc);

                IEnumerator <BaseData> enumerator;
                if (!_channelProvider.ShouldStreamSubscription(_job, request.Configuration))
                {
                    if (!Quandl.IsAuthCodeSet)
                    {
                        // we're not using the SubscriptionDataReader, so be sure to set the auth token here
                        Quandl.SetAuthCode(Config.Get("quandl-auth-token"));
                    }

                    if (!Tiingo.IsAuthCodeSet)
                    {
                        // we're not using the SubscriptionDataReader, so be sure to set the auth token here
                        Tiingo.SetAuthCode(Config.Get("tiingo-auth-token"));
                    }

                    if (!USEnergyAPI.IsAuthCodeSet)
                    {
                        // we're not using the SubscriptionDataReader, so be sure to set the auth token here
                        USEnergyAPI.SetAuthCode(Config.Get("us-energy-information-auth-token"));
                    }

                    if (!FredApi.IsAuthCodeSet)
                    {
                        // we're not using the SubscriptionDataReader, so be sure to set the auth token here
                        FredApi.SetAuthCode(Config.Get("fred-auth-token"));
                    }

                    if (!TradingEconomicsCalendar.IsAuthCodeSet)
                    {
                        // we're not using the SubscriptionDataReader, so be sure to set the auth token here
                        TradingEconomicsCalendar.SetAuthCode(Config.Get("trading-economics-auth-token"));
                    }

                    var factory         = new LiveCustomDataSubscriptionEnumeratorFactory(_timeProvider);
                    var enumeratorStack = factory.CreateEnumerator(request, _dataProvider);

                    _customExchange.AddEnumerator(request.Configuration.Symbol, enumeratorStack);

                    var enqueable = new EnqueueableEnumerator <BaseData>();
                    _customExchange.SetDataHandler(request.Configuration.Symbol, data =>
                    {
                        enqueable.Enqueue(data);

                        subscription.OnNewDataAvailable();
                    });
                    enumerator = enqueable;
                }
                else
                {
                    EventHandler handler = (sender, args) => subscription?.OnNewDataAvailable();
                    enumerator = _dataQueueHandler.Subscribe(request.Configuration, handler);

                    if (request.Configuration.Symbol.SecurityType == SecurityType.Equity && !request.Configuration.IsInternalFeed)
                    {
                        var dividends = _dataQueueHandler.Subscribe(new SubscriptionDataConfig(request.Configuration, typeof(Dividend)), handler);
                        var splits    = _dataQueueHandler.Subscribe(new SubscriptionDataConfig(request.Configuration, typeof(Split)), handler);

                        enumerator = new LiveEquityDataSynchronizingEnumerator(_timeProvider, request.Configuration.ExchangeTimeZone, enumerator, dividends, splits);
                    }
                }

                if (request.Configuration.FillDataForward)
                {
                    var fillForwardResolution = _subscriptions.UpdateAndGetFillForwardResolution(request.Configuration);

                    enumerator = new LiveFillForwardEnumerator(_frontierTimeProvider, enumerator, request.Security.Exchange, fillForwardResolution, request.Configuration.ExtendedMarketHours, localEndTime, request.Configuration.Increment, request.Configuration.DataTimeZone, request.StartTimeLocal);
                }

                // define market hours and user filters to incoming data
                if (request.Configuration.IsFilteredSubscription)
                {
                    enumerator = new SubscriptionFilterEnumerator(enumerator, request.Security, localEndTime, request.Configuration.ExtendedMarketHours, true);
                }

                // finally, make our subscriptions aware of the frontier of the data feed, prevents future data from spewing into the feed
                enumerator = new FrontierAwareEnumerator(enumerator, _frontierTimeProvider, timeZoneOffsetProvider);

                var subscriptionDataEnumerator = new SubscriptionDataEnumerator(request.Configuration, request.Security.Exchange.Hours, timeZoneOffsetProvider, enumerator);
                subscription = new Subscription(request, subscriptionDataEnumerator, timeZoneOffsetProvider);
            }
            catch (Exception err)
            {
                Log.Error(err);
            }

            return(subscription);
        }
        public void Create_SubscriptionWithPaymentMethodNonce()
        {
            TestPlan plan = PlanFixture.PLAN_WITHOUT_TRIAL;
            string nonce = TestHelper.GenerateUnlockedNonce(gateway, "4242424242424242", creditCard.CustomerId);
            SubscriptionRequest request = new SubscriptionRequest
            {
                PaymentMethodNonce = nonce,
                PlanId = plan.Id
            };

            Result<Subscription> result = gateway.Subscription.Create(request);
            Assert.IsTrue(result.IsSuccess());
            Subscription subscription = result.Target;
            Transaction transaction = subscription.Transactions[0];
            Assert.AreEqual("424242", transaction.CreditCard.Bin);
        }
Exemple #29
0
        // reproduces GH issue 3877
        public void ConfigurationForAddedSubscriptionIsAlwaysPresent()
        {
            var dataPermissionManager = new DataPermissionManager();
            var dataFeed    = new TestDataFeed();
            var dataManager = new DataManager(dataFeed,
                                              new UniverseSelection(_algorithm,
                                                                    _securityService,
                                                                    dataPermissionManager,
                                                                    new DefaultDataProvider()),
                                              _algorithm,
                                              _algorithm.TimeKeeper,
                                              MarketHoursDatabase.AlwaysOpen,
                                              false,
                                              new RegisteredSecurityDataTypesProvider(),
                                              dataPermissionManager);

            var config = new SubscriptionDataConfig(typeof(TradeBar),
                                                    Symbols.SPY,
                                                    Resolution.Daily,
                                                    TimeZones.NewYork,
                                                    TimeZones.NewYork,
                                                    false,
                                                    false,
                                                    false);

            // Universe A: adds the config
            dataManager.SubscriptionManagerGetOrAdd(config);

            var request = new SubscriptionRequest(false,
                                                  null,
                                                  new Security(Symbols.SPY,
                                                               SecurityExchangeHours.AlwaysOpen(DateTimeZone.Utc),
                                                               new Cash(Currencies.USD, 1, 1),
                                                               SymbolProperties.GetDefault(Currencies.USD),
                                                               new IdentityCurrencyConverter(Currencies.USD),
                                                               new RegisteredSecurityDataTypesProvider(),
                                                               new SecurityCache()),
                                                  config,
                                                  new DateTime(2019, 1, 1),
                                                  new DateTime(2019, 1, 1));

            dataFeed.Subscription = new Subscription(request,
                                                     new EnqueueableEnumerator <SubscriptionData>(),
                                                     null);

            // Universe A: adds the subscription
            dataManager.AddSubscription(request);

            // Universe B: adds the config
            dataManager.SubscriptionManagerGetOrAdd(config);

            // Universe A: removes the subscription
            Assert.IsTrue(dataManager.RemoveSubscription(config));
            Assert.AreEqual(0, dataManager.GetSubscriptionDataConfigs(config.Symbol).Count);

            // Universe B: adds the subscription
            Assert.IsTrue(dataManager.AddSubscription(request));

            // the config should be present
            Assert.AreEqual(1, dataManager.GetSubscriptionDataConfigs(config.Symbol).Count);

            dataManager.RemoveAllSubscriptions();
        }
        public void Search_OnInTrialPeriodIs()
        {
            SubscriptionRequest request1 = new SubscriptionRequest
            {
                PaymentMethodToken = creditCard.Token,
                PlanId = PlanFixture.PLAN_WITH_TRIAL.Id
            };

            SubscriptionRequest request2 = new SubscriptionRequest
            {
                PaymentMethodToken = creditCard.Token,
                PlanId = PlanFixture.PLAN_WITHOUT_TRIAL.Id
            };

            Subscription trial = gateway.Subscription.Create(request1).Target;
            Subscription noTrial = gateway.Subscription.Create(request2).Target;

            SubscriptionSearchRequest request = new SubscriptionSearchRequest().
                InTrialPeriod.Is(true);

            ResourceCollection<Subscription> trialResults = gateway.Subscription.Search(request);

            Assert.IsTrue(TestHelper.IncludesSubscription(trialResults, trial));
            Assert.IsFalse(TestHelper.IncludesSubscription(trialResults, noTrial));

            request = new SubscriptionSearchRequest().
            InTrialPeriod.Is(false);

            ResourceCollection<Subscription> noTrialResults = gateway.Subscription.Search(request);

            Assert.IsTrue(TestHelper.IncludesSubscription(noTrialResults, noTrial));
            Assert.IsFalse(TestHelper.IncludesSubscription(noTrialResults, trial));
        }
Exemple #31
0
 CreateSubscriptionAsync(string customerId, SubscriptionRequest request)
 {
     return(await this.PostAsync <SubscriptionResponse>($"customers/{customerId}/subscriptions", request)
            .ConfigureAwait(false));
 }
        public void Search_OnMerchantAccountIdIs()
        {
            SubscriptionRequest request1 = new SubscriptionRequest
            {
                MerchantAccountId = MerchantAccountIDs.DEFAULT_MERCHANT_ACCOUNT_ID,
                PaymentMethodToken = creditCard.Token,
                PlanId = PlanFixture.PLAN_WITH_TRIAL.Id,
                Price = 2M
            };

            SubscriptionRequest request2 = new SubscriptionRequest
            {
                MerchantAccountId = MerchantAccountIDs.NON_DEFAULT_MERCHANT_ACCOUNT_ID,
                PaymentMethodToken = creditCard.Token,
                PlanId = PlanFixture.PLAN_WITH_TRIAL.Id,
                Price = 2M
            };

            Subscription defaultMerchantAccountSubscription = gateway.Subscription.Create(request1).Target;
            Subscription nonDefaultMerchantAccountSubscription = gateway.Subscription.Create(request2).Target;

            SubscriptionSearchRequest request = new SubscriptionSearchRequest().
                MerchantAccountId.Is(MerchantAccountIDs.NON_DEFAULT_MERCHANT_ACCOUNT_ID).
                Price.Is(2M);

            ResourceCollection<Subscription> collection = gateway.Subscription.Search(request);

            Assert.IsTrue(TestHelper.IncludesSubscription(collection, nonDefaultMerchantAccountSubscription));
            Assert.IsFalse(TestHelper.IncludesSubscription(collection, defaultMerchantAccountSubscription));
        }
Exemple #33
0
 /// <summary>
 /// Creates a file based data enumerator for the given subscription request
 /// </summary>
 /// <remarks>Protected so it can be used by the <see cref="LiveTradingDataFeed"/> to warmup requests</remarks>
 protected IEnumerator <BaseData> CreateEnumerator(SubscriptionRequest request)
 {
     return(request.IsUniverseSubscription ? CreateUniverseEnumerator(request, CreateDataEnumerator) : CreateDataEnumerator(request));
 }
        public void Search_OnMerchantAccountIdWithBogusMerchantId()
        {
            Random random = new Random();
            string subscriptionId = random.Next(0, 100000).ToString();
            var subscriptionRequest = new SubscriptionRequest
            {
                MerchantAccountId = MerchantAccountIDs.NON_DEFAULT_MERCHANT_ACCOUNT_ID,
                PaymentMethodToken = creditCard.Token,
                PlanId = PlanFixture.PLAN_WITH_TRIAL.Id,
                Price = 2M,
                Id = subscriptionId
            };

            gateway.Subscription.Create(subscriptionRequest);

            var searchRequest = new SubscriptionSearchRequest().
                MerchantAccountId.Is(MerchantAccountIDs.NON_DEFAULT_MERCHANT_ACCOUNT_ID).
                Id.Is(subscriptionId).
                Price.Is(2M);

            var collection = gateway.Subscription.Search(searchRequest);

            Assert.AreEqual(1, collection.MaximumCount);

            searchRequest = new SubscriptionSearchRequest().
                MerchantAccountId.IncludedIn(MerchantAccountIDs.NON_DEFAULT_MERCHANT_ACCOUNT_ID, "bogus_merchant_account_id").
                Id.Is(subscriptionId).
                Price.Is(2M);

            collection = gateway.Subscription.Search(searchRequest);

            Assert.AreEqual(1, collection.MaximumCount);

            searchRequest = new SubscriptionSearchRequest().
                MerchantAccountId.Is("bogus_merchant_account_id").
                Id.Is(subscriptionId).
                Price.Is(2M);

            collection = gateway.Subscription.Search(searchRequest);

            Assert.AreEqual(0, collection.MaximumCount);
        }
Exemple #35
0
        /// <summary>
        /// Creates a new subscription for the specified security
        /// </summary>
        /// <param name="request">The subscription request</param>
        /// <returns>A new subscription instance of the specified security</returns>
        protected Subscription CreateDataSubscription(SubscriptionRequest request)
        {
            Subscription subscription = null;

            try
            {
                var localEndTime           = request.EndTimeUtc.ConvertFromUtc(request.Security.Exchange.TimeZone);
                var timeZoneOffsetProvider = new TimeZoneOffsetProvider(request.Security.Exchange.TimeZone, request.StartTimeUtc, request.EndTimeUtc);

                IEnumerator <BaseData> enumerator;
                if (!_channelProvider.ShouldStreamSubscription(request.Configuration))
                {
                    if (!Quandl.IsAuthCodeSet)
                    {
                        // we're not using the SubscriptionDataReader, so be sure to set the auth token here
                        Quandl.SetAuthCode(Config.Get("quandl-auth-token"));
                    }

                    if (!Tiingo.IsAuthCodeSet)
                    {
                        // we're not using the SubscriptionDataReader, so be sure to set the auth token here
                        Tiingo.SetAuthCode(Config.Get("tiingo-auth-token"));
                    }

                    var factory         = new LiveCustomDataSubscriptionEnumeratorFactory(_timeProvider);
                    var enumeratorStack = factory.CreateEnumerator(request, _dataProvider);

                    _customExchange.AddEnumerator(request.Configuration.Symbol, enumeratorStack);

                    var enqueable = new EnqueueableEnumerator <BaseData>();
                    _customExchange.SetDataHandler(request.Configuration.Symbol, data =>
                    {
                        enqueable.Enqueue(data);

                        subscription.OnNewDataAvailable();
                    });
                    enumerator = enqueable;
                }
                else
                {
                    var auxEnumerators = new List <IEnumerator <BaseData> >();

                    if (LiveAuxiliaryDataEnumerator.TryCreate(request.Configuration, _timeProvider, _dataQueueHandler,
                                                              request.Security.Cache, _mapFileProvider, _factorFileProvider, request.StartTimeLocal, out var auxDataEnumator))
                    {
                        auxEnumerators.Add(auxDataEnumator);
                    }

                    EventHandler handler = (_, _) => subscription?.OnNewDataAvailable();
                    enumerator = _dataQueueHandler.Subscribe(request.Configuration, handler);

                    if (request.Configuration.EmitSplitsAndDividends())
                    {
                        auxEnumerators.Add(_dataQueueHandler.Subscribe(new SubscriptionDataConfig(request.Configuration, typeof(Dividend)), handler));
                        auxEnumerators.Add(_dataQueueHandler.Subscribe(new SubscriptionDataConfig(request.Configuration, typeof(Split)), handler));
                    }

                    if (auxEnumerators.Count > 0)
                    {
                        enumerator = new LiveAuxiliaryDataSynchronizingEnumerator(_timeProvider, request.Configuration.ExchangeTimeZone, enumerator, auxEnumerators);
                    }
                }

                if (request.Configuration.FillDataForward)
                {
                    var fillForwardResolution = _subscriptions.UpdateAndGetFillForwardResolution(request.Configuration);

                    enumerator = new LiveFillForwardEnumerator(_frontierTimeProvider, enumerator, request.Security.Exchange, fillForwardResolution, request.Configuration.ExtendedMarketHours, localEndTime, request.Configuration.Increment, request.Configuration.DataTimeZone);
                }

                // define market hours and user filters to incoming data
                if (request.Configuration.IsFilteredSubscription)
                {
                    enumerator = new SubscriptionFilterEnumerator(enumerator, request.Security, localEndTime, request.Configuration.ExtendedMarketHours, true, request.ExchangeHours);
                }

                // finally, make our subscriptions aware of the frontier of the data feed, prevents future data from spewing into the feed
                enumerator = new FrontierAwareEnumerator(enumerator, _frontierTimeProvider, timeZoneOffsetProvider);

                var subscriptionDataEnumerator = new SubscriptionDataEnumerator(request.Configuration, request.Security.Exchange.Hours, timeZoneOffsetProvider, enumerator, request.IsUniverseSubscription);
                subscription = new Subscription(request, subscriptionDataEnumerator, timeZoneOffsetProvider);
            }
            catch (Exception err)
            {
                Log.Error(err);
            }

            return(subscription);
        }
        public void Search_OnNextBillingDate()
        {
            TestPlan triallessPlan = PlanFixture.PLAN_WITHOUT_TRIAL;
            TestPlan trialPlan = PlanFixture.PLAN_WITH_TRIAL;
            SubscriptionRequest request1 = new SubscriptionRequest
            {
                PaymentMethodToken = creditCard.Token,
                PlanId = triallessPlan.Id,
                Price = 7M
            };

            SubscriptionRequest request2 = new SubscriptionRequest
            {
                PaymentMethodToken = creditCard.Token,
                PlanId = trialPlan.Id,
                Price = 7M
            };

            Subscription triallessSubscription = gateway.Subscription.Create(request1).Target;
            Subscription trialSubscription = gateway.Subscription.Create(request2).Target;

            SubscriptionSearchRequest request = new SubscriptionSearchRequest().
                NextBillingDate.GreaterThanOrEqualTo(DateTime.Now.AddDays(5));

            ResourceCollection<Subscription> collection = gateway.Subscription.Search(request);

            Assert.IsTrue(TestHelper.IncludesSubscription(collection, triallessSubscription));
            Assert.IsFalse(TestHelper.IncludesSubscription(collection, trialSubscription));
        }
Exemple #37
0
        /// <summary>
        /// Creates a new subscription for universe selection
        /// </summary>
        /// <param name="request">The subscription request</param>
        private Subscription CreateUniverseSubscription(SubscriptionRequest request)
        {
            // TODO : Consider moving the creating of universe subscriptions to a separate, testable class

            // grab the relevant exchange hours
            var config = request.Universe.Configuration;

            var tzOffsetProvider = new TimeZoneOffsetProvider(request.Security.Exchange.TimeZone, request.StartTimeUtc, request.EndTimeUtc);

            IEnumerator <BaseData> enumerator;

            var userDefined = request.Universe as UserDefinedUniverse;

            if (userDefined != null)
            {
                Log.Trace("LiveTradingDataFeed.CreateUniverseSubscription(): Creating user defined universe: " + config.Symbol.ToString());

                // spoof a tick on the requested interval to trigger the universe selection function
                var enumeratorFactory = new UserDefinedUniverseSubscriptionEnumeratorFactory(userDefined, MarketHoursDatabase.FromDataFolder());
                enumerator = enumeratorFactory.CreateEnumerator(request);

                enumerator = new FrontierAwareEnumerator(enumerator, _timeProvider, tzOffsetProvider);

                var enqueueable = new EnqueueableEnumerator <BaseData>();
                _customExchange.AddEnumerator(new EnumeratorHandler(config.Symbol, enumerator, enqueueable));
                enumerator = enqueueable;

                // Trigger universe selection when security added/removed after Initialize
                userDefined.CollectionChanged += (sender, args) =>
                {
                    var items =
                        args.Action == NotifyCollectionChangedAction.Add ? args.NewItems :
                        args.Action == NotifyCollectionChangedAction.Remove ? args.OldItems : null;

                    if (items == null || _frontierUtc == DateTime.MinValue)
                    {
                        return;
                    }

                    var symbol = items.OfType <Symbol>().FirstOrDefault();
                    if (symbol == null)
                    {
                        return;
                    }

                    var collection = new BaseDataCollection(_frontierUtc, symbol);
                    var changes    = _universeSelection.ApplyUniverseSelection(userDefined, _frontierUtc, collection);
                    _algorithm.OnSecuritiesChanged(changes);
                };
            }
            else if (config.Type == typeof(CoarseFundamental))
            {
                Log.Trace("LiveTradingDataFeed.CreateUniverseSubscription(): Creating coarse universe: " + config.Symbol.ToString());

                // since we're binding to the data queue exchange we'll need to let him
                // know that we expect this data
                _dataQueueHandler.Subscribe(_job, new[] { request.Security.Symbol });

                var enqueable = new EnqueueableEnumerator <BaseData>();
                _exchange.SetDataHandler(config.Symbol, data =>
                {
                    enqueable.Enqueue(data);
                });
                enumerator = enqueable;
            }
            else
            {
                Log.Trace("LiveTradingDataFeed.CreateUniverseSubscription(): Creating custom universe: " + config.Symbol.ToString());

                // each time we exhaust we'll new up this enumerator stack
                var refresher = new RefreshEnumerator <BaseDataCollection>(() =>
                {
                    var sourceProvider     = (BaseData)Activator.CreateInstance(config.Type);
                    var dateInDataTimeZone = DateTime.UtcNow.ConvertFromUtc(config.DataTimeZone).Date;
                    var source             = sourceProvider.GetSource(config, dateInDataTimeZone, true);
                    var factory            = SubscriptionDataSourceReader.ForSource(source, config, dateInDataTimeZone, false);
                    var factorEnumerator   = factory.Read(source).GetEnumerator();
                    var fastForward        = new FastForwardEnumerator(factorEnumerator, _timeProvider, request.Security.Exchange.TimeZone, config.Increment);
                    var frontierAware      = new FrontierAwareEnumerator(fastForward, _frontierTimeProvider, tzOffsetProvider);
                    return(new BaseDataCollectionAggregatorEnumerator(frontierAware, config.Symbol));
                });

                // rate limit the refreshing of the stack to the requested interval
                var minimumTimeBetweenCalls = Math.Min(config.Increment.Ticks, TimeSpan.FromMinutes(30).Ticks);
                var rateLimit   = new RateLimitEnumerator(refresher, _timeProvider, TimeSpan.FromTicks(minimumTimeBetweenCalls));
                var enqueueable = new EnqueueableEnumerator <BaseData>();
                _customExchange.AddEnumerator(new EnumeratorHandler(config.Symbol, rateLimit, enqueueable));
                enumerator = enqueueable;
            }

            // create the subscription
            var subscription = new Subscription(request.Universe, request.Security, config, enumerator, tzOffsetProvider, request.StartTimeUtc, request.EndTimeUtc, true);

            return(subscription);
        }
        public void Search_OnPlanIdIs()
        {
            TestPlan triallessPlan = PlanFixture.PLAN_WITHOUT_TRIAL;
            TestPlan trialPlan = PlanFixture.PLAN_WITH_TRIAL;
            SubscriptionRequest request1 = new SubscriptionRequest
            {
                PaymentMethodToken = creditCard.Token,
                PlanId = trialPlan.Id,
                Price = 5M
            };

            SubscriptionRequest request2 = new SubscriptionRequest
            {
                PaymentMethodToken = creditCard.Token,
                PlanId = triallessPlan.Id,
                Price = 5M
            };

            Subscription trialSubscription = gateway.Subscription.Create(request1).Target;
            Subscription triallessSubscription = gateway.Subscription.Create(request2).Target;

            SubscriptionSearchRequest request = new SubscriptionSearchRequest().
                PlanId.Is(trialPlan.Id).
                Price.Is(5M);

            ResourceCollection<Subscription> collection = gateway.Subscription.Search(request);

            Assert.IsTrue(TestHelper.IncludesSubscription(collection, trialSubscription));
            Assert.IsFalse(TestHelper.IncludesSubscription(collection, triallessSubscription));
        }
        public void Find_FindsAssociatedSubscriptions()
        {
            Customer customer = gateway.Customer.Create(new CustomerRequest()).Target;

            var creditCardRequest = new CreditCardRequest
            {
                CustomerId = customer.Id,
                Number = "5105105105105100",
                ExpirationDate = "05/12",
                CVV = "123"
            };

            CreditCard originalCreditCard = gateway.CreditCard.Create(creditCardRequest).Target;
            string id = Guid.NewGuid().ToString();
            var subscriptionRequest = new SubscriptionRequest
            {
                Id = id,
                PlanId = "integration_trialless_plan",
                PaymentMethodToken = originalCreditCard.Token,
                Price = 1.00M
            };
            gateway.Subscription.Create(subscriptionRequest);

            CreditCard creditCard = gateway.CreditCard.Find(originalCreditCard.Token);
            Subscription subscription = creditCard.Subscriptions[0];
            Assert.AreEqual(id, subscription.Id);
            Assert.AreEqual("integration_trialless_plan", subscription.PlanId);
            Assert.AreEqual(1.00M, subscription.Price);
        }
        public void Find_FindsAssociatedSubscriptions()
        {
            Customer customer = gateway.Customer.Create(new CustomerRequest()).Target;

            var creditCardRequest = new CreditCardRequest
            {
                CustomerId = customer.Id,
                Number = "5555555555554444",
                ExpirationDate = EXP_MONTH_YEAR,
                CVV = "123"
            };

            CreditCard originalCreditCard = gateway.CreditCard.Create(creditCardRequest).Target;
            string id = Guid.NewGuid().ToString();
            var subscriptionRequest = new SubscriptionRequest
            {
                Id = id,
                PlanId = "integration_trialless_plan",
                PaymentMethodToken = originalCreditCard.Token,
                Price = 1.00M
            };
            var resp = gateway.Subscription.Create(subscriptionRequest);
            Assert.IsNotNull(resp);
            if (!resp.IsSuccess())
                Assert.Inconclusive(resp.Message);
            else
            {
                CreditCard creditCard = gateway.CreditCard.Find(originalCreditCard.Token);
                Assert.IsNotNull(creditCard);
                Assert.IsNotEmpty(creditCard.Subscriptions);
                Subscription subscription = creditCard.Subscriptions[0];
                Assert.IsNotNull(subscription);
                Assert.AreEqual(id, subscription.Id);
                Assert.AreEqual("integration_trialless_plan", subscription.PlanId);
                Assert.AreEqual(1.00M, subscription.Price);
            }
        }
 public Task Update([FromBody] SubscriptionRequest request)
 {
     return(_eventBusSubscriptionsManager.SaveSubscriptionAsync(request));
 }
        /// <summary>
        /// Updates an existing subscription
        /// </summary>
        /// <param name="request">
        /// The request.
        /// </param>
        /// <returns>
        /// The <see cref="Attempt"/>.
        /// </returns>
        public Attempt<Subscription> Update(SubscriptionRequest request)
        {
            Updating.RaiseEvent(new SaveEventArgs<SubscriptionRequest>(request), this);

            var attempt = TryGetApiResult(() => BraintreeGateway.Subscription.Update(request.Id, request));

            if (!attempt.Success) return Attempt<Subscription>.Fail(attempt.Exception);

            var result = attempt.Result;

            if (result.IsSuccess())
            {
                Updated.RaiseEvent(new SaveEventArgs<Subscription>(result.Target), this);

                return Attempt<Subscription>.Succeed(result.Target);
            }

            var error = new BraintreeApiException(result.Errors, result.Message);

            LogHelper.Error<BraintreeSubscriptionApiService>("Failed to create a subscription", error);

            return Attempt<Subscription>.Fail(error);
        }
Exemple #43
0
 /// <summary>
 /// Invokes the configuration following enumerator creation
 /// </summary>
 /// <param name="request">The subscription request to be read</param>
 /// <returns>An enumerator reading the subscription request</returns>
 public IEnumerator <BaseData> CreateEnumerator(SubscriptionRequest request)
 {
     return(_configurator(_factory.CreateEnumerator(request)));
 }
Exemple #44
0
 /// <inheritdoc />
 public bool AddSubscription(SubscriptionRequest request)
 {
     throw new NotImplementedException("Unexpected usage of null data feed implementation.");
 }
        /// <summary>
        /// Applies universe selection the the data feed and algorithm
        /// </summary>
        /// <param name="universe">The universe to perform selection on</param>
        /// <param name="dateTimeUtc">The current date time in utc</param>
        /// <param name="universeData">The data provided to perform selection with</param>
        public SecurityChanges ApplyUniverseSelection(Universe universe, DateTime dateTimeUtc, BaseDataCollection universeData)
        {
            var algorithmEndDateUtc = _algorithm.EndDate.ConvertToUtc(_algorithm.TimeZone);

            if (dateTimeUtc > algorithmEndDateUtc)
            {
                return(SecurityChanges.None);
            }

            IEnumerable <Symbol> selectSymbolsResult;

            // check if this universe must be filtered with fine fundamental data
            var fineFiltered = universe as FineFundamentalFilteredUniverse;

            if (fineFiltered != null)
            {
                // perform initial filtering and limit the result
                selectSymbolsResult = universe.SelectSymbols(dateTimeUtc, universeData);

                if (!ReferenceEquals(selectSymbolsResult, Universe.Unchanged))
                {
                    // prepare a BaseDataCollection of FineFundamental instances
                    var fineCollection = new BaseDataCollection();
                    var dataProvider   = new DefaultDataProvider();

                    // Create a dictionary of CoarseFundamental keyed by Symbol that also has FineFundamental
                    // Coarse raw data has SID collision on: CRHCY R735QTJ8XC9X
                    var allCoarse  = universeData.Data.OfType <CoarseFundamental>();
                    var coarseData = allCoarse.Where(c => c.HasFundamentalData)
                                     .DistinctBy(c => c.Symbol)
                                     .ToDictionary(c => c.Symbol);

                    // Remove selected symbols that does not have fine fundamental data
                    var anyDoesNotHaveFundamentalData = false;
                    // only pre filter selected symbols if there actually is any coarse data. This way we can support custom universe filtered by fine fundamental data
                    // which do not use coarse data as underlying, in which case it could happen that we try to load fine fundamental data that is missing, but no problem,
                    // 'FineFundamentalSubscriptionEnumeratorFactory' won't emit it
                    if (allCoarse.Any())
                    {
                        selectSymbolsResult = selectSymbolsResult
                                              .Where(
                            symbol =>
                        {
                            var result = coarseData.ContainsKey(symbol);
                            anyDoesNotHaveFundamentalData |= !result;
                            return(result);
                        }
                            );
                    }

                    if (!_anyDoesNotHaveFundamentalDataWarningLogged && anyDoesNotHaveFundamentalData)
                    {
                        _algorithm.Debug("Note: Your coarse selection filter was updated to exclude symbols without fine fundamental data. Make sure your coarse filter excludes symbols where HasFundamental is false.");
                        _anyDoesNotHaveFundamentalDataWarningLogged = true;
                    }

                    // use all available threads, the entire system is waiting for this to complete
                    var options = new ParallelOptions {
                        MaxDegreeOfParallelism = Environment.ProcessorCount
                    };
                    Parallel.ForEach(selectSymbolsResult, options, symbol =>
                    {
                        var config   = FineFundamentalUniverse.CreateConfiguration(symbol);
                        var security = _securityService.CreateSecurity(symbol,
                                                                       config,
                                                                       addToSymbolCache: false);

                        var localStartTime = dateTimeUtc.ConvertFromUtc(config.ExchangeTimeZone).AddDays(-1);
                        var factory        = new FineFundamentalSubscriptionEnumeratorFactory(_algorithm.LiveMode, x => new[] { localStartTime });
                        var request        = new SubscriptionRequest(true, universe, security, new SubscriptionDataConfig(config), localStartTime, localStartTime);
                        using (var enumerator = factory.CreateEnumerator(request, dataProvider))
                        {
                            if (enumerator.MoveNext())
                            {
                                lock (fineCollection.Data)
                                {
                                    fineCollection.Data.Add(enumerator.Current);
                                }
                            }
                        }
                    });

                    // WARNING -- HACK ATTACK -- WARNING
                    // Fine universes are considered special due to their chaining behavior.
                    // As such, we need a means of piping the fine data read in here back to the data feed
                    // so that it can be properly emitted via a TimeSlice.Create call. There isn't a mechanism
                    // in place for this function to return such data. The following lines are tightly coupled
                    // to the universeData dictionaries in SubscriptionSynchronizer and LiveTradingDataFeed and
                    // rely on reference semantics to work.

                    universeData.Data = new List <BaseData>();
                    foreach (var fine in fineCollection.Data.OfType <FineFundamental>())
                    {
                        var fundamentals = new Fundamentals
                        {
                            Symbol              = fine.Symbol,
                            Time                = fine.Time,
                            EndTime             = fine.EndTime,
                            DataType            = fine.DataType,
                            AssetClassification = fine.AssetClassification,
                            CompanyProfile      = fine.CompanyProfile,
                            CompanyReference    = fine.CompanyReference,
                            EarningReports      = fine.EarningReports,
                            EarningRatios       = fine.EarningRatios,
                            FinancialStatements = fine.FinancialStatements,
                            OperationRatios     = fine.OperationRatios,
                            SecurityReference   = fine.SecurityReference,
                            ValuationRatios     = fine.ValuationRatios,
                            Market              = fine.Symbol.ID.Market
                        };

                        CoarseFundamental coarse;
                        if (coarseData.TryGetValue(fine.Symbol, out coarse))
                        {
                            // the only time the coarse data won't exist is if the selection function
                            // doesn't use the data provided, and instead returns a constant list of
                            // symbols -- coupled with a potential hole in the data
                            fundamentals.Value              = coarse.Value;
                            fundamentals.Volume             = coarse.Volume;
                            fundamentals.DollarVolume       = coarse.DollarVolume;
                            fundamentals.HasFundamentalData = coarse.HasFundamentalData;

                            // set the fine fundamental price property to yesterday's closing price
                            fine.Value = coarse.Value;
                        }

                        universeData.Data.Add(fundamentals);
                    }

                    // END -- HACK ATTACK -- END

                    // perform the fine fundamental universe selection
                    selectSymbolsResult = fineFiltered.FineFundamentalUniverse.PerformSelection(dateTimeUtc, fineCollection);
                }
            }
            else
            {
                // perform initial filtering and limit the result
                selectSymbolsResult = universe.PerformSelection(dateTimeUtc, universeData);
            }

            // materialize the enumerable into a set for processing
            var selections = selectSymbolsResult.ToHashSet();

            var additions = new List <Security>();
            var removals  = new List <Security>();

            // first check for no pending removals, even if the universe selection
            // didn't change we might need to remove a security because a position was closed
            RemoveSecurityFromUniverse(
                _pendingRemovalsManager.CheckPendingRemovals(selections, universe),
                removals,
                dateTimeUtc,
                algorithmEndDateUtc);

            // check for no changes second
            if (ReferenceEquals(selectSymbolsResult, Universe.Unchanged))
            {
                return(SecurityChanges.None);
            }

            // determine which data subscriptions need to be removed from this universe
            foreach (var member in universe.Members.Values)
            {
                // if we've selected this subscription again, keep it
                if (selections.Contains(member.Symbol))
                {
                    continue;
                }

                // don't remove if the universe wants to keep him in
                if (!universe.CanRemoveMember(dateTimeUtc, member))
                {
                    continue;
                }

                // remove the member - this marks this member as not being
                // selected by the universe, but it may remain in the universe
                // until open orders are closed and the security is liquidated
                removals.Add(member);

                RemoveSecurityFromUniverse(_pendingRemovalsManager.TryRemoveMember(member, universe),
                                           removals,
                                           dateTimeUtc,
                                           algorithmEndDateUtc);
            }

            var keys = _pendingSecurityAdditions.Keys;

            if (keys.Any() && keys.Single() != dateTimeUtc)
            {
                // if the frontier moved forward then we've added these securities to the algorithm
                _pendingSecurityAdditions.Clear();
            }

            Dictionary <Symbol, Security> pendingAdditions;

            if (!_pendingSecurityAdditions.TryGetValue(dateTimeUtc, out pendingAdditions))
            {
                // keep track of created securities so we don't create the same security twice, leads to bad things :)
                pendingAdditions = new Dictionary <Symbol, Security>();
                _pendingSecurityAdditions[dateTimeUtc] = pendingAdditions;
            }

            // find new selections and add them to the algorithm
            foreach (var symbol in selections)
            {
                if (universe.Securities.ContainsKey(symbol))
                {
                    // if its already part of the universe no need to re add it
                    continue;
                }

                // create the new security, the algorithm thread will add this at the appropriate time
                Security security;
                if (!pendingAdditions.TryGetValue(symbol, out security) && !_algorithm.Securities.TryGetValue(symbol, out security))
                {
                    // For now this is required for retro compatibility with usages of security.Subscriptions
                    var configs = _algorithm.SubscriptionManager.SubscriptionDataConfigService.Add(symbol,
                                                                                                   universe.UniverseSettings.Resolution,
                                                                                                   universe.UniverseSettings.FillForward,
                                                                                                   universe.UniverseSettings.ExtendedMarketHours,
                                                                                                   dataNormalizationMode: universe.UniverseSettings.DataNormalizationMode);

                    security = _securityService.CreateSecurity(symbol, configs, universe.UniverseSettings.Leverage, symbol.ID.SecurityType == SecurityType.Option);

                    pendingAdditions.Add(symbol, security);

                    SetUnderlyingSecurity(universe, security);
                }

                var addedSubscription = false;

                foreach (var request in universe.GetSubscriptionRequests(security, dateTimeUtc, algorithmEndDateUtc,
                                                                         _algorithm.SubscriptionManager.SubscriptionDataConfigService))
                {
                    if (security.Symbol == request.Configuration.Symbol && // Just in case check its the same symbol, else AddData will throw.
                        !security.Subscriptions.Contains(request.Configuration))
                    {
                        // For now this is required for retro compatibility with usages of security.Subscriptions
                        security.AddData(request.Configuration);
                    }

                    var toRemove = _currencySubscriptionDataConfigManager.GetSubscriptionDataConfigToRemove(request.Configuration.Symbol);
                    if (toRemove != null)
                    {
                        Log.Trace($"UniverseSelection.ApplyUniverseSelection(): Removing internal currency data feed {toRemove}");
                        _dataManager.RemoveSubscription(toRemove);
                    }

                    _dataManager.AddSubscription(request);

                    // only update our security changes if we actually added data
                    if (!request.IsUniverseSubscription)
                    {
                        addedSubscription = true;
                    }
                }

                if (addedSubscription)
                {
                    var addedMember = universe.AddMember(dateTimeUtc, security);

                    if (addedMember)
                    {
                        additions.Add(security);
                    }
                }
            }

            // return None if there's no changes, otherwise return what we've modified
            var securityChanges = additions.Count + removals.Count != 0
                ? new SecurityChanges(additions, removals)
                : SecurityChanges.None;

            // Add currency data feeds that weren't explicitly added in Initialize
            if (additions.Count > 0)
            {
                EnsureCurrencyDataFeeds(securityChanges);
            }

            if (securityChanges != SecurityChanges.None && Log.DebuggingEnabled)
            {
                // for performance lets not create the message string if debugging is not enabled
                // this can be executed many times and its in the algorithm thread
                Log.Debug("UniverseSelection.ApplyUniverseSelection(): " + dateTimeUtc + ": " + securityChanges);
            }

            return(securityChanges);
        }
        public async Task <Subscription> CreateSubscription(SubscriptionRequest createSubscriptionRequest)
        {
            var url = string.Format(SUBSCRIPTIONS_PATH, createSubscriptionRequest.CustomerId);

            return(await SendRequest <Subscription>(HttpMethod.Post, url, createSubscriptionRequest));
        }
Exemple #47
0
        /// <summary>
        /// Creates a new subscription for the specified security
        /// </summary>
        /// <param name="request">The subscription request</param>
        /// <returns>A new subscription instance of the specified security</returns>
        protected Subscription CreateDataSubscription(SubscriptionRequest request)
        {
            Subscription subscription = null;

            try
            {
                var localEndTime           = request.EndTimeUtc.ConvertFromUtc(request.Security.Exchange.TimeZone);
                var timeZoneOffsetProvider = new TimeZoneOffsetProvider(request.Security.Exchange.TimeZone, request.StartTimeUtc, request.EndTimeUtc);

                IEnumerator <BaseData> enumerator;
                if (request.Configuration.IsCustomData)
                {
                    if (!Quandl.IsAuthCodeSet)
                    {
                        // we're not using the SubscriptionDataReader, so be sure to set the auth token here
                        Quandl.SetAuthCode(Config.Get("quandl-auth-token"));
                    }

                    if (!Tiingo.IsAuthCodeSet)
                    {
                        // we're not using the SubscriptionDataReader, so be sure to set the auth token here
                        Tiingo.SetAuthCode(Config.Get("tiingo-auth-token"));
                    }

                    var factory         = new LiveCustomDataSubscriptionEnumeratorFactory(_timeProvider);
                    var enumeratorStack = factory.CreateEnumerator(request, _dataProvider);

                    _customExchange.AddEnumerator(request.Configuration.Symbol, enumeratorStack);

                    var enqueable = new EnqueueableEnumerator <BaseData>();
                    _customExchange.SetDataHandler(request.Configuration.Symbol, data =>
                    {
                        enqueable.Enqueue(data);

                        UpdateSubscriptionRealTimePrice(
                            subscription,
                            timeZoneOffsetProvider,
                            request.Security.Exchange.Hours,
                            data);
                    });
                    enumerator = enqueable;
                }
                else if (request.Configuration.Resolution != Resolution.Tick)
                {
                    // this enumerator allows the exchange to pump ticks into the 'back' of the enumerator,
                    // and the time sync loop can pull aggregated trade bars off the front
                    switch (request.Configuration.TickType)
                    {
                    case TickType.Quote:
                        var quoteBarAggregator = new QuoteBarBuilderEnumerator(request.Configuration.Increment, request.Security.Exchange.TimeZone, _timeProvider);
                        _exchange.AddDataHandler(request.Configuration.Symbol, data =>
                        {
                            var tick = data as Tick;

                            if (tick.TickType == TickType.Quote)
                            {
                                quoteBarAggregator.ProcessData(tick);

                                UpdateSubscriptionRealTimePrice(
                                    subscription,
                                    timeZoneOffsetProvider,
                                    request.Security.Exchange.Hours,
                                    data);
                            }
                        });
                        enumerator = quoteBarAggregator;
                        break;

                    case TickType.Trade:
                    default:
                        var tradeBarAggregator = new TradeBarBuilderEnumerator(request.Configuration.Increment, request.Security.Exchange.TimeZone, _timeProvider);
                        var auxDataEnumerator  = new LiveAuxiliaryDataEnumerator(request.Security.Exchange.TimeZone, _timeProvider);

                        _exchange.AddDataHandler(request.Configuration.Symbol, data =>
                        {
                            if (data.DataType == MarketDataType.Auxiliary)
                            {
                                auxDataEnumerator.Enqueue(data);
                            }
                            else
                            {
                                var tick = data as Tick;
                                if (tick.TickType == TickType.Trade)
                                {
                                    tradeBarAggregator.ProcessData(tick);

                                    UpdateSubscriptionRealTimePrice(
                                        subscription,
                                        timeZoneOffsetProvider,
                                        request.Security.Exchange.Hours,
                                        data);
                                }
                            }
                        });

                        enumerator = request.Configuration.SecurityType == SecurityType.Equity
                                ? (IEnumerator <BaseData>) new LiveEquityDataSynchronizingEnumerator(_frontierTimeProvider, request.Security.Exchange.TimeZone, auxDataEnumerator, tradeBarAggregator)
                                : tradeBarAggregator;
                        break;

                    case TickType.OpenInterest:
                        var oiAggregator = new OpenInterestEnumerator(request.Configuration.Increment, request.Security.Exchange.TimeZone, _timeProvider);
                        _exchange.AddDataHandler(request.Configuration.Symbol, data =>
                        {
                            var tick = data as Tick;

                            if (tick.TickType == TickType.OpenInterest)
                            {
                                oiAggregator.ProcessData(tick);
                            }
                        });
                        enumerator = oiAggregator;
                        break;
                    }
                }
                else
                {
                    // tick subscriptions can pass right through
                    var tickEnumerator = new EnqueueableEnumerator <BaseData>();
                    _exchange.SetDataHandler(request.Configuration.Symbol, data =>
                    {
                        tickEnumerator.Enqueue(data);

                        if (data.DataType != MarketDataType.Auxiliary)
                        {
                            UpdateSubscriptionRealTimePrice(
                                subscription,
                                timeZoneOffsetProvider,
                                request.Security.Exchange.Hours,
                                data);
                        }
                    });
                    enumerator = tickEnumerator;
                }

                if (request.Configuration.FillDataForward)
                {
                    var fillForwardResolution = _subscriptions.UpdateAndGetFillForwardResolution(request.Configuration);

                    enumerator = new LiveFillForwardEnumerator(_frontierTimeProvider, enumerator, request.Security.Exchange, fillForwardResolution, request.Configuration.ExtendedMarketHours, localEndTime, request.Configuration.Increment, request.Configuration.DataTimeZone);
                }

                // define market hours and user filters to incoming data
                if (request.Configuration.IsFilteredSubscription)
                {
                    enumerator = new SubscriptionFilterEnumerator(enumerator, request.Security, localEndTime);
                }

                // finally, make our subscriptions aware of the frontier of the data feed, prevents future data from spewing into the feed
                enumerator = new FrontierAwareEnumerator(enumerator, _frontierTimeProvider, timeZoneOffsetProvider);

                var subscriptionDataEnumerator = SubscriptionData.Enumerator(request.Configuration, request.Security, timeZoneOffsetProvider, enumerator);
                subscription = new Subscription(request, subscriptionDataEnumerator, timeZoneOffsetProvider);
            }
            catch (Exception err)
            {
                Log.Error(err);
            }

            return(subscription);
        }
 internal SubscriptionStream(SubscriptionRequest request)
 {
     this.Request = request;
 }
        public void RefreshesFutureChainUniverseOnDateChange()
        {
            var startTime    = new DateTime(2018, 10, 17, 10, 0, 0);
            var timeProvider = new ManualTimeProvider(startTime);

            var symbolUniverse = new TestDataQueueUniverseProvider(timeProvider);
            var factory        = new FuturesChainUniverseSubscriptionEnumeratorFactory(symbolUniverse, timeProvider);

            var canonicalSymbol = Symbol.Create("VX", SecurityType.Future, Market.USA, "/VX");

            var quoteCurrency = new Cash(Currencies.USD, 0, 1);
            var exchangeHours = MarketHoursDatabase.FromDataFolder().GetExchangeHours(Market.USA, canonicalSymbol, SecurityType.Future);
            var config        = new SubscriptionDataConfig(
                typeof(ZipEntryName),
                canonicalSymbol,
                Resolution.Minute,
                TimeZones.Utc,
                TimeZones.Chicago,
                true,
                false,
                false,
                false,
                TickType.Quote,
                false,
                DataNormalizationMode.Raw
                );

            var future = new Future(
                canonicalSymbol,
                exchangeHours,
                quoteCurrency,
                SymbolProperties.GetDefault(Currencies.USD),
                ErrorCurrencyConverter.Instance
                );

            var universeSettings = new UniverseSettings(Resolution.Minute, 0, true, false, TimeSpan.Zero);
            var universe         = new FuturesChainUniverse(future, universeSettings);
            var request          = new SubscriptionRequest(true, universe, future, config, startTime, Time.EndOfTime);
            var enumerator       = factory.CreateEnumerator(request, new DefaultDataProvider());

            Assert.IsTrue(enumerator.MoveNext());
            Assert.IsNotNull(enumerator.Current);
            Assert.AreEqual(1, symbolUniverse.TotalLookupCalls);
            var data = enumerator.Current as FuturesChainUniverseDataCollection;

            Assert.IsNotNull(data);
            Assert.AreEqual(1, data.Data.Count);

            timeProvider.Advance(Time.OneSecond);

            Assert.IsTrue(enumerator.MoveNext());
            Assert.IsNull(enumerator.Current);
            Assert.AreEqual(1, symbolUniverse.TotalLookupCalls);

            timeProvider.Advance(Time.OneMinute);

            Assert.IsTrue(enumerator.MoveNext());
            Assert.IsNull(enumerator.Current);
            Assert.AreEqual(1, symbolUniverse.TotalLookupCalls);

            timeProvider.Advance(Time.OneDay);

            Assert.IsTrue(enumerator.MoveNext());
            Assert.IsNotNull(enumerator.Current);
            Assert.AreEqual(2, symbolUniverse.TotalLookupCalls);
            data = enumerator.Current as FuturesChainUniverseDataCollection;
            Assert.IsNotNull(data);
            Assert.AreEqual(2, data.Data.Count);

            timeProvider.Advance(Time.OneMinute);

            Assert.IsTrue(enumerator.MoveNext());
            Assert.IsNull(enumerator.Current);
            Assert.AreEqual(2, symbolUniverse.TotalLookupCalls);

            enumerator.Dispose();
        }
        /// <summary>
        /// Creates a <see cref="Subscription"/>.
        /// </summary>
        /// <param name="request">
        /// The request.
        /// </param>
        /// <returns>
        /// The <see cref="Attempt{Subscription}"/>.
        /// </returns>
        public Attempt<Subscription> Create(SubscriptionRequest request)
        {
            Creating.RaiseEvent(new Core.Events.NewEventArgs<SubscriptionRequest>(request), this);

            LogHelper.Info<BraintreeTransactionApiService>(string.Format("Braintree create subscription attempt PlanID: {0}, Price: {1}", request.PlanId, request.Price));
            var attempt = this.TryGetApiResult(() => this.BraintreeGateway.Subscription.Create(request));

            if (!attempt.Success) return Attempt<Subscription>.Fail(attempt.Exception);

            var result = attempt.Result;

            if (result.IsSuccess())
            {
                Created.RaiseEvent(new Core.Events.NewEventArgs<Subscription>(result.Target), this);

                return Attempt<Subscription>.Succeed(result.Target);
            }

            var error = new BraintreeApiException(result.Errors, result.Message);

            LogHelper.Error<BraintreeSubscriptionApiService>("Failed to create a subscription", error);

            return Attempt<Subscription>.Fail(error);
        }
        public void EnumerationWhileUpdatingDoesNotThrow()
        {
            var cts           = new CancellationTokenSource();
            var subscriptions = new SubscriptionCollection();
            var start         = DateTime.UtcNow;
            var end           = start.AddSeconds(10);
            var config        = new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY, Resolution.Minute, DateTimeZone.Utc, DateTimeZone.Utc, true, false, false);
            var security      = new Equity(
                Symbols.SPY,
                SecurityExchangeHours.AlwaysOpen(DateTimeZone.Utc),
                new Cash(Currencies.USD, 0, 1),
                SymbolProperties.GetDefault(Currencies.USD),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null,
                new SecurityCache()
                );
            var timeZoneOffsetProvider     = new TimeZoneOffsetProvider(DateTimeZone.Utc, start, end);
            var enumerator                 = new EnqueueableEnumerator <BaseData>();
            var subscriptionDataEnumerator = new SubscriptionDataEnumerator(config, security.Exchange.Hours, timeZoneOffsetProvider, enumerator);
            var subscriptionRequest        = new SubscriptionRequest(false, null, security, config, start, end);
            var subscription               = new Subscription(subscriptionRequest, subscriptionDataEnumerator, timeZoneOffsetProvider);

            var addTask = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("Add task started");

                while (DateTime.UtcNow < end)
                {
                    if (!subscriptions.Contains(config))
                    {
                        subscriptions.TryAdd(subscription);
                    }

                    Thread.Sleep(1);
                }

                Console.WriteLine("Add task ended");
            }, cts.Token);

            var removeTask = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("Remove task started");

                while (DateTime.UtcNow < end)
                {
                    Subscription removed;
                    subscriptions.TryRemove(config, out removed);

                    Thread.Sleep(1);
                }

                Console.WriteLine("Remove task ended");
            }, cts.Token);

            var readTask = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("Read task started");

                while (DateTime.UtcNow < end)
                {
                    foreach (var sub in subscriptions)
                    {
                    }

                    Thread.Sleep(1);
                }

                Console.WriteLine("Read task ended");
            }, cts.Token);

            Task.WaitAll(addTask, removeTask, readTask);
            subscription.Dispose();
        }
        /// <summary>
        /// Updates an existing subscription
        /// </summary>
        /// <param name="request">
        /// The request.
        /// </param>
        /// <returns>
        /// The <see cref="Attempt"/>.
        /// </returns>
        public Attempt<Subscription> Update(SubscriptionRequest request)
        {
            Updating.RaiseEvent(new SaveEventArgs<SubscriptionRequest>(request), this);

            LogHelper.Info<BraintreeTransactionApiService>(string.Format("Braintree Update subscription attempt PlanId: {0}", request.PlanId));
            var attempt = this.TryGetApiResult(() => this.BraintreeGateway.Subscription.Update(request.Id, request));

            if (!attempt.Success) return Attempt<Subscription>.Fail(attempt.Exception);

            var result = attempt.Result;

            if (result.IsSuccess())
            {
                Updated.RaiseEvent(new SaveEventArgs<Subscription>(result.Target), this);

                var cacheKey = this.MakeSubscriptionCacheKey(request.Id);
                this.RuntimeCache.ClearCacheItem(cacheKey);

                return Attempt<Subscription>.Succeed(result.Target);
            }

            var error = new BraintreeApiException(result.Errors, result.Message);

            LogHelper.Error<BraintreeSubscriptionApiService>("Failed to create a subscription", error);

            return Attempt<Subscription>.Fail(error);
        }
Exemple #53
0
        /// <summary>
        /// Creates a new subscription for universe selection
        /// </summary>
        /// <param name="request">The subscription request</param>
        private Subscription CreateUniverseSubscription(SubscriptionRequest request)
        {
            Subscription subscription = null;

            // TODO : Consider moving the creating of universe subscriptions to a separate, testable class

            // grab the relevant exchange hours
            var config           = request.Universe.Configuration;
            var localEndTime     = request.EndTimeUtc.ConvertFromUtc(request.Security.Exchange.TimeZone);
            var tzOffsetProvider = new TimeZoneOffsetProvider(request.Security.Exchange.TimeZone, request.StartTimeUtc, request.EndTimeUtc);

            IEnumerator <BaseData> enumerator = null;

            var timeTriggered = request.Universe as ITimeTriggeredUniverse;

            if (timeTriggered != null)
            {
                Log.Trace($"LiveTradingDataFeed.CreateUniverseSubscription(): Creating user defined universe: {config.Symbol.ID}");

                // spoof a tick on the requested interval to trigger the universe selection function
                var enumeratorFactory = new TimeTriggeredUniverseSubscriptionEnumeratorFactory(timeTriggered, MarketHoursDatabase.FromDataFolder(), _frontierTimeProvider);
                enumerator = enumeratorFactory.CreateEnumerator(request, _dataProvider);

                enumerator = new FrontierAwareEnumerator(enumerator, _timeProvider, tzOffsetProvider);

                var enqueueable = new EnqueueableEnumerator <BaseData>();
                _customExchange.AddEnumerator(new EnumeratorHandler(config.Symbol, enumerator, enqueueable));
                enumerator = enqueueable;
            }
            else if (config.Type == typeof(CoarseFundamental))
            {
                Log.Trace($"LiveTradingDataFeed.CreateUniverseSubscription(): Creating coarse universe: {config.Symbol.ID}");

                // we subscribe using a normalized symbol, without a random GUID,
                // since the ticker plant will send the coarse data using this symbol
                var normalizedSymbol = CoarseFundamental.CreateUniverseSymbol(config.Symbol.ID.Market, false);

                // Will try to pull coarse data from the data folder every 30min, file with today's date.
                // If lean is started today it will trigger initial coarse universe selection
                var factory = new LiveCustomDataSubscriptionEnumeratorFactory(_timeProvider,
                                                                              // we adjust time to the previous tradable date
                                                                              time => Time.GetStartTimeForTradeBars(request.Security.Exchange.Hours, time, Time.OneDay, 1, false, config.DataTimeZone)
                                                                              );
                var enumeratorStack = factory.CreateEnumerator(request, _dataProvider);

                // aggregates each coarse data point into a single BaseDataCollection
                var aggregator = new BaseDataCollectionAggregatorEnumerator(enumeratorStack, normalizedSymbol, true);
                _customExchange.AddEnumerator(normalizedSymbol, aggregator);

                var enqueable = new EnqueueableEnumerator <BaseData>();
                _customExchange.SetDataHandler(normalizedSymbol, data =>
                {
                    var coarseData = data as BaseDataCollection;
                    enqueable.Enqueue(new BaseDataCollection(coarseData.Time, config.Symbol, coarseData.Data));
                    subscription.OnNewDataAvailable();
                });
                enumerator = GetConfiguredFrontierAwareEnumerator(enqueable, tzOffsetProvider,
                                                                  // advance time if before 23pm or after 5am and not on Saturdays
                                                                  time => time.Hour < 23 && time.Hour > 5 && time.DayOfWeek != DayOfWeek.Saturday);
            }
            else if (request.Universe is OptionChainUniverse)
            {
                Log.Trace("LiveTradingDataFeed.CreateUniverseSubscription(): Creating option chain universe: " + config.Symbol.ID);

                Func <SubscriptionRequest, IEnumerator <BaseData> > configure = (subRequest) =>
                {
                    var fillForwardResolution = _subscriptions.UpdateAndGetFillForwardResolution(subRequest.Configuration);
                    var input = _dataQueueHandler.Subscribe(subRequest.Configuration, (sender, args) => subscription.OnNewDataAvailable());
                    return(new LiveFillForwardEnumerator(_frontierTimeProvider, input, subRequest.Security.Exchange, fillForwardResolution, subRequest.Configuration.ExtendedMarketHours, localEndTime, subRequest.Configuration.Increment, subRequest.Configuration.DataTimeZone, subRequest.StartTimeLocal));
                };

                var symbolUniverse = _dataQueueHandler as IDataQueueUniverseProvider;
                if (symbolUniverse == null)
                {
                    throw new NotSupportedException("The DataQueueHandler does not support Options.");
                }

                var timeProvider = new PredicateTimeProvider(_timeProvider,
                                                             time => symbolUniverse.CanAdvanceTime(config.SecurityType));

                var enumeratorFactory = new OptionChainUniverseSubscriptionEnumeratorFactory(configure, symbolUniverse, timeProvider);
                enumerator = enumeratorFactory.CreateEnumerator(request, _dataProvider);

                enumerator = new FrontierAwareEnumerator(enumerator, _frontierTimeProvider, tzOffsetProvider);
            }
            else if (request.Universe is FuturesChainUniverse)
            {
                Log.Trace("LiveTradingDataFeed.CreateUniverseSubscription(): Creating futures chain universe: " + config.Symbol.ID);

                var symbolUniverse = _dataQueueHandler as IDataQueueUniverseProvider;
                if (symbolUniverse == null)
                {
                    throw new NotSupportedException("The DataQueueHandler does not support Futures.");
                }

                var timeProvider = new PredicateTimeProvider(_timeProvider,
                                                             time => symbolUniverse.CanAdvanceTime(config.SecurityType));

                var enumeratorFactory = new FuturesChainUniverseSubscriptionEnumeratorFactory(symbolUniverse, timeProvider);
                enumerator = enumeratorFactory.CreateEnumerator(request, _dataProvider);

                enumerator = new FrontierAwareEnumerator(enumerator, _frontierTimeProvider, tzOffsetProvider);
            }
            else
            {
                Log.Trace("LiveTradingDataFeed.CreateUniverseSubscription(): Creating custom universe: " + config.Symbol.ID);

                var factory         = new LiveCustomDataSubscriptionEnumeratorFactory(_timeProvider);
                var enumeratorStack = factory.CreateEnumerator(request, _dataProvider);
                enumerator = new BaseDataCollectionAggregatorEnumerator(enumeratorStack, config.Symbol, liveMode: true);

                var enqueueable = new EnqueueableEnumerator <BaseData>();
                _customExchange.AddEnumerator(new EnumeratorHandler(config.Symbol, enumerator, enqueueable));
                enumerator = enqueueable;
            }

            // create the subscription
            var subscriptionDataEnumerator = new SubscriptionDataEnumerator(request.Configuration, request.Security.Exchange.Hours, tzOffsetProvider, enumerator);

            subscription = new Subscription(request, subscriptionDataEnumerator, tzOffsetProvider);

            // send the subscription for the new symbol through to the data queuehandler
            if (_channelProvider.ShouldStreamSubscription(_job, subscription.Configuration))
            {
                _dataQueueHandler.Subscribe(request.Configuration, (sender, args) => subscription.OnNewDataAvailable());
            }

            return(subscription);
        }
        /// <summary>
        /// Creates a <see cref="SubscriptionRequest"/>.
        /// </summary>
        /// <param name="paymentMethodToken">
        /// The payment method token.
        /// </param>
        /// <param name="planId">
        /// The plan id.
        /// </param>
        /// <param name="price">
        /// An optional price used to override the plan price.
        /// </param>
        /// <returns>
        /// The <see cref="SubscriptionRequest"/>.
        /// </returns>
        public SubscriptionRequest CreateSubscriptionRequest(string paymentMethodToken, string planId, decimal? price = null)
        {
            Mandate.ParameterNotNullOrEmpty(paymentMethodToken, "paymentMethodToken");
            Mandate.ParameterNotNullOrEmpty(planId, "planId");

            var request = new SubscriptionRequest()
                       {
                           PaymentMethodToken = paymentMethodToken,
                           PlanId = planId,
                       };

            // TODO figure out the descriptor for nicer Credit Card statements
            // TODO https://www.braintreepayments.com/docs/dotnet/transactions/dynamic_descriptors
            //if (_settings.MerchantDescriptor.HasValues())
            //{
            //    request.Descriptor = _settings.MerchantDescriptor.AsDescriptorRequest();
            //}

            if (price != null) request.Price = price.Value;

            return request;
        }
Exemple #55
0
        public void DoesNotEmitInvalidData()
        {
            var startTime = new DateTime(2014, 06, 06, 0, 0, 0);
            var endTime   = new DateTime(2014, 06, 09, 20, 0, 0);

            var canonicalSymbol = Symbol.Create("AAPL", SecurityType.Option, Market.USA, "?AAPL");

            var quoteCurrency = new Cash(Currencies.USD, 0, 1);
            var exchangeHours = MarketHoursDatabase.FromDataFolder().GetExchangeHours(Market.USA, canonicalSymbol, SecurityType.Option);
            var config        = new SubscriptionDataConfig(
                typeof(ZipEntryName),
                canonicalSymbol,
                Resolution.Minute,
                TimeZones.Utc,
                TimeZones.NewYork,
                true,
                false,
                false,
                false,
                TickType.Quote,
                false,
                DataNormalizationMode.Raw
                );

            var option = new Option(
                canonicalSymbol,
                exchangeHours,
                quoteCurrency,
                new OptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null,
                new SecurityCache()
                );

            var fillForwardResolution = Ref.CreateReadOnly(() => Resolution.Minute.ToTimeSpan());
            Func <SubscriptionRequest, IEnumerator <BaseData>, IEnumerator <BaseData> > underlyingEnumeratorFunc =
                (req, input) =>
            {
                input = new BaseDataCollectionAggregatorEnumerator(input, req.Configuration.Symbol);
                return(new FillForwardEnumerator(
                           input,
                           option.Exchange,
                           fillForwardResolution,
                           false,
                           endTime,
                           Resolution.Minute.ToTimeSpan(),
                           TimeZones.Utc,
                           startTime));
            };
            var factory = new OptionChainUniverseSubscriptionEnumeratorFactory(underlyingEnumeratorFunc,
                                                                               MapFileResolver.Create(Globals.DataFolder, Market.USA),
                                                                               new LocalDiskFactorFileProvider(new LocalDiskMapFileProvider()));

            var request    = new SubscriptionRequest(true, null, option, config, startTime, endTime);
            var enumerator = factory.CreateEnumerator(request, new DefaultDataProvider());

            var emittedCount = 0;

            foreach (var data in enumerator.AsEnumerable())
            {
                emittedCount++;
                var optionData = data as OptionChainUniverseDataCollection;

                Assert.IsNotNull(optionData);
                Assert.IsNotNull(optionData.Underlying);
                Assert.AreNotEqual(0, optionData.Data.Count);
            }

            // 9:30 to 15:59 -> 6.5 hours * 60 => 390 minutes * 2 days = 780
            Assert.AreEqual(780, emittedCount);
        }
        public void Create_SetId()
        {
            TestPlan plan = PlanFixture.PLAN_WITH_TRIAL;
            string newId = "new-id-" + new Random().Next(1000000);
            SubscriptionRequest request = new SubscriptionRequest
            {
                PaymentMethodToken = creditCard.Token,
                PlanId = plan.Id,
                Price = 482.48M,
                Id = newId
            };

            Result<Subscription> result = gateway.Subscription.Create(request);
            Assert.IsTrue(result.IsSuccess());
            Subscription subscription = result.Target;

            Assert.AreEqual(newId, subscription.Id);
        }
        /// <summary>
        /// Creates an enumerator to read the specified request.
        /// </summary>
        /// <param name="request">The subscription request to be read</param>
        /// <param name="dataProvider">Provider used to get data when it is not present on disk</param>
        /// <returns>An enumerator reading the subscription request</returns>
        public IEnumerator <BaseData> CreateEnumerator(SubscriptionRequest request, IDataProvider dataProvider)
        {
            var config = request.Configuration;

            // frontier value used to prevent emitting duplicate time stamps between refreshed enumerators
            // also provides some immediate fast-forward to handle spooling through remote files quickly
            var frontier = Ref.Create(_dateAdjustment?.Invoke(request.StartTimeLocal) ?? request.StartTimeLocal);
            var lastSourceRefreshTime = DateTime.MinValue;
            var sourceFactory         = config.GetBaseDataInstance();

            // this is refreshing the enumerator stack for each new source
            var refresher = new RefreshEnumerator <BaseData>(() =>
            {
                // rate limit the refresh of this enumerator stack
                var utcNow = _timeProvider.GetUtcNow();
                var minimumTimeBetweenCalls = GetMinimumTimeBetweenCalls(config.Increment, _minimumIntervalCheck);
                if (utcNow - lastSourceRefreshTime < minimumTimeBetweenCalls)
                {
                    return(Enumerable.Empty <BaseData>().GetEnumerator());
                }

                lastSourceRefreshTime = utcNow;
                var localDate         = _dateAdjustment?.Invoke(utcNow.ConvertFromUtc(config.ExchangeTimeZone).Date) ?? utcNow.ConvertFromUtc(config.ExchangeTimeZone).Date;
                var source            = sourceFactory.GetSource(config, localDate, true);

                // fetch the new source and enumerate the data source reader
                var enumerator = EnumerateDataSourceReader(config, dataProvider, frontier, source, localDate, sourceFactory);

                if (SourceRequiresFastForward(source))
                {
                    // The FastForwardEnumerator implements these two features:
                    // (1) make sure we never emit past data
                    // (2) data filtering based on a maximum data age
                    // For custom data we don't want feature (2) because we would reject data points emitted later
                    // (e.g. Quandl daily data after a weekend), so we disable it using a huge maximum data age.

                    // apply fast forward logic for file transport mediums
                    var maximumDataAge = GetMaximumDataAge(Time.MaxTimeSpan);
                    enumerator         = new FastForwardEnumerator(enumerator, _timeProvider, config.ExchangeTimeZone, maximumDataAge);
                }
                else
                {
                    // rate limit calls to this enumerator stack
                    enumerator = new RateLimitEnumerator <BaseData>(enumerator, _timeProvider, minimumTimeBetweenCalls);
                }

                if (source.Format == FileFormat.UnfoldingCollection)
                {
                    // unroll collections into individual data points after fast forward/rate limiting applied
                    enumerator = enumerator.SelectMany(data =>
                    {
                        var collection = data as BaseDataCollection;
                        IEnumerator <BaseData> collectionEnumerator;
                        if (collection != null)
                        {
                            if (source.TransportMedium == SubscriptionTransportMedium.Rest)
                            {
                                // we want to make sure the data points we *unroll* are not past
                                collectionEnumerator = collection.Data
                                                       .Where(baseData => baseData.EndTime > frontier.Value)
                                                       .GetEnumerator();
                            }
                            else
                            {
                                collectionEnumerator = collection.Data.GetEnumerator();
                            }
                        }
                        else
                        {
                            collectionEnumerator = new List <BaseData> {
                                data
                            }.GetEnumerator();
                        }
                        return(collectionEnumerator);
                    });
                }

                return(enumerator);
            });

            return(refresher);
        }
        public void Create_SetMerchantAccountId()
        {
            TestPlan plan = PlanFixture.PLAN_WITH_TRIAL;
            SubscriptionRequest request = new SubscriptionRequest
            {
                PaymentMethodToken = creditCard.Token,
                PlanId = plan.Id,
                MerchantAccountId = MerchantAccountIDs.NON_DEFAULT_MERCHANT_ACCOUNT_ID
            };

            Result<Subscription> result = gateway.Subscription.Create(request);
            Assert.IsTrue(result.IsSuccess());
            Subscription subscription = result.Target;

            Assert.AreEqual(MerchantAccountIDs.NON_DEFAULT_MERCHANT_ACCOUNT_ID, subscription.MerchantAccountId);
        }
        public void Can_Create_A_Subscription_For_A_Customer_With_Discount()
        {
            //// Arrange
            // Step 1 - Plan selection

            var plan = this.BraintreeApiService.Subscription.GetAllPlans().FirstOrDefault();
            Assert.NotNull(plan, "The plan was null");

            var discount = this.BraintreeApiService.Subscription.GetAllDiscounts().FirstOrDefault();
            Assert.NotNull(discount, "The discount was null");

            // Step 2 - establish the customer
            var customer = this.BraintreeApiService.Customer.GetBraintreeCustomer(this.TestCustomer);

            // Step 3 - select the paymentmethod
            PaymentMethod paymentMethod;

            if (customer.PaymentMethods.Any())
            {
                // use the default payment method
                paymentMethod = customer.DefaultPaymentMethod;
            }
            else
            {
                // or create a new payment method
                var billingAddress = new Core.Models.Address()
                {
                    Address1 = "114 W. Magnolia St. Suite 300",
                    Locality = "Bellingham",
                    Region = "WA",
                    PostalCode = "98225",
                    CountryCode = "US",
                    AddressType = AddressType.Billing
                };

                // The 'true' value sets this to the default payment method.  This is true by default
                var attemptPaymentMethod = this.BraintreeApiService.PaymentMethod.Create(this.TestCustomer, "nonce-from-the-client", billingAddress, true);

                if (!attemptPaymentMethod.Success) Assert.Fail("Failed to create the payment method");

                paymentMethod = attemptPaymentMethod.Result;
            }

            //// Act

            // note there are additional paremeters to fill out here
            var subscriptionRequest = new SubscriptionRequest()
                                          {
                                              PaymentMethodToken = paymentMethod.Token,
                                              PlanId = plan.Id,
                                              Discounts = new DiscountsRequest()
                                                              {
                                                                  Add = new[]
                                                                    {
                                                                        new AddDiscountRequest()
                                                                            {
                                                                                InheritedFromId = discount.Id
                                                                            }
                                                                    }
                                                              }
                                          };

            var subscriptionAttempt = this.BraintreeApiService.Subscription.Create(subscriptionRequest);

            //// Assert
            Assert.IsTrue(subscriptionAttempt.Success, "Failed to create the subscription ");

            var subscription = subscriptionAttempt.Result;

            if (subscription.Status == SubscriptionStatus.ACTIVE)
            {
                var trans = subscription.Transactions.FirstOrDefault();

                var cs = trans.Customer;

                Assert.NotNull(cs);
            }
        }
 public void Subscribe(SubscriptionRequest request)
 {
 }