private Security GetSecurity(Symbol symbol, DataNormalizationMode mode)
        {
            var symbolProperties = SymbolPropertiesDatabase.FromDataFolder()
                .GetSymbolProperties(symbol.ID.Market, symbol.Value, symbol.ID.SecurityType, CashBook.AccountCurrency);

            Security security;
            if (symbol.ID.SecurityType == SecurityType.Equity)
            {
                security = new QuantConnect.Securities.Equity.Equity(
                    SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork),
                    new SubscriptionDataConfig(typeof(TradeBar), symbol, Resolution.Minute, TimeZones.NewYork, TimeZones.NewYork, true, true, false),
                    new Cash(CashBook.AccountCurrency, 0, 1m),
                    symbolProperties);
            }
            else
            {
                security = new QuantConnect.Securities.Forex.Forex(
                   SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork),
                   new Cash(CashBook.AccountCurrency, 0, 1m),
                   new SubscriptionDataConfig(typeof(TradeBar), symbol, Resolution.Minute, TimeZones.NewYork, TimeZones.NewYork, true, true, false),
                   symbolProperties);
            }

            var TimeKeeper = new TimeKeeper(DateTime.Now.ConvertToUtc(TimeZones.NewYork), new[] { TimeZones.NewYork });
            security.SetLocalTimeKeeper(TimeKeeper.GetLocalTimeKeeper(TimeZones.NewYork));
            security.SetDataNormalizationMode(mode);

            return security;
        }
示例#2
0
        /// <summary>
        /// Sets the data normalization mode to be used by this security
        /// </summary>
        public override void SetDataNormalizationMode(DataNormalizationMode mode)
        {
            base.SetDataNormalizationMode(mode);

            if (mode == DataNormalizationMode.Adjusted)
            {
                PriceVariationModel = new AdjustedPriceVariationModel();
            }
            else
            {
                PriceVariationModel = new EquityPriceVariationModel();
            }
        }
示例#3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="HistoryRequest"/> class from the specified config and exchange hours
 /// </summary>
 /// <param name="config">The subscription data config used to initalize this request</param>
 /// <param name="hours">The exchange hours used for fill forward processing</param>
 /// <param name="startTimeUtc">The start time for this request,</param>
 /// <param name="endTimeUtc">The start time for this request</param>
 public HistoryRequest(SubscriptionDataConfig config, SecurityExchangeHours hours, DateTime startTimeUtc, DateTime endTimeUtc)
 {
     StartTimeUtc               = startTimeUtc;
     EndTimeUtc                 = endTimeUtc;
     Symbol                     = config.Symbol;
     ExchangeHours              = hours;
     Resolution                 = config.Resolution;
     FillForwardResolution      = config.FillDataForward ? config.Resolution : (Resolution?)null;
     IncludeExtendedMarketHours = config.ExtendedMarketHours;
     DataType                   = config.Type;
     IsCustomData               = config.IsCustomData;
     DataNormalizationMode      = config.DataNormalizationMode;
     TimeZone                   = config.DataTimeZone;
 }
示例#4
0
        public void HistoryDoesNotThrowForSupportedDataNormalizationMode_Equity(DataNormalizationMode dataNormalizationMode)
        {
            _algorithm = GetAlgorithmWithEquity(new DateTime(2014, 6, 6));
            Assert.AreEqual(2, _algorithm.SubscriptionManager.Subscriptions.ToList().Count);
            var equity = _algorithm.SubscriptionManager.Subscriptions.First();

            Assert.AreEqual(SecurityType.Equity, equity.SecurityType);

            Assert.DoesNotThrow(() =>
            {
                _algorithm.History(new [] { equity.Symbol }, _algorithm.Time.AddDays(-1), _algorithm.Time, equity.Resolution,
                                   dataNormalizationMode: dataNormalizationMode).ToList();
            });
        }
示例#5
0
        public void HistoryDoesNotThrowForSupportedDataNormalizationMode_Future(DataNormalizationMode dataNormalizationMode)
        {
            _algorithm = GetAlgorithmWithFuture(new DateTime(2014, 1, 1));
            Assert.IsNotEmpty(_algorithm.SubscriptionManager.Subscriptions);
            var future = _algorithm.SubscriptionManager.Subscriptions.First();

            Assert.AreEqual(SecurityType.Future, future.SecurityType);

            Assert.DoesNotThrow(() =>
            {
                _algorithm.History(new [] { future.Symbol }, _algorithm.StartDate, _algorithm.Time, future.Resolution,
                                   dataNormalizationMode: dataNormalizationMode).ToList();
            });
        }
示例#6
0
        public void SubscriptionHistoryRequestWithDifferentDataNormalizationModes_Equity()
        {
            var dataNormalizationModes = new DataNormalizationMode[] {
                DataNormalizationMode.Raw,
                DataNormalizationMode.Adjusted,
                DataNormalizationMode.SplitAdjusted
            };

            _algorithm = GetAlgorithmWithEquity(new DateTime(2014, 6, 6));
            var equity = _algorithm.SubscriptionManager.Subscriptions.First();

            CheckHistoryResultsForDataNormalizationModes(_algorithm, equity.Symbol, _algorithm.Time.AddDays(-1), _algorithm.Time, equity.Resolution,
                                                         dataNormalizationModes);
        }
示例#7
0
        public void SubscriptionHistoryRequestWithDifferentDataNormalizationModes_Future()
        {
            var dataNormalizationModes = new DataNormalizationMode[] {
                DataNormalizationMode.Raw,
                DataNormalizationMode.BackwardsRatio,
                DataNormalizationMode.BackwardsPanamaCanal,
                DataNormalizationMode.ForwardPanamaCanal
            };

            _algorithm = GetAlgorithmWithFuture(new DateTime(2014, 1, 1));
            var future = _algorithm.SubscriptionManager.Subscriptions.First();

            CheckHistoryResultsForDataNormalizationModes(_algorithm, future.Symbol, new DateTime(2013, 10, 6), _algorithm.Time, future.Resolution,
                                                         dataNormalizationModes);
        }
示例#8
0
 /// <summary>
 /// Initializes a new default instance of the <see cref="HistoryRequest"/> class
 /// </summary>
 public HistoryRequest()
 {
     StartTimeUtc               = EndTimeUtc = DateTime.UtcNow;
     Symbol                     = Symbol.Empty;
     ExchangeHours              = SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork);
     Resolution                 = Resolution.Minute;
     FillForwardResolution      = Resolution.Minute;
     IncludeExtendedMarketHours = false;
     DataType                   = typeof(TradeBar);
     SecurityType               = SecurityType.Equity;
     TimeZone                   = TimeZones.NewYork;
     Market                     = QuantConnect.Market.USA;
     IsCustomData               = false;
     DataNormalizationMode      = DataNormalizationMode.Adjusted;
 }
示例#9
0
 /// <summary>
 /// Creates and adds a list of <see cref="SubscriptionDataConfig" /> for a given symbol and configuration.
 /// Can optionally pass in desired subscription data type to use.
 /// If the config already existed will return existing instance instead
 /// </summary>
 public SubscriptionDataConfig Add(
     Type dataType,
     Symbol symbol,
     Resolution?resolution       = null,
     bool fillForward            = true,
     bool extendedMarketHours    = false,
     bool isFilteredSubscription = true,
     bool isInternalFeed         = false,
     bool isCustomData           = false,
     DataNormalizationMode dataNormalizationMode = DataNormalizationMode.Adjusted
     )
 {
     return(Add(symbol, resolution, fillForward, extendedMarketHours, isFilteredSubscription, isInternalFeed, isCustomData,
                new List <Tuple <Type, TickType> > {
         new Tuple <Type, TickType>(dataType, LeanData.GetCommonTickTypeForCommonDataTypes(dataType, symbol.SecurityType))
     }, dataNormalizationMode)
            .First());
 }
示例#10
0
        private static decimal GetScaleFactor(FactorFile factorFile, DataNormalizationMode mode, DateTime date)
        {
            switch (mode)
            {
            case DataNormalizationMode.Raw:
                return(1);

            case DataNormalizationMode.TotalReturn:
            case DataNormalizationMode.SplitAdjusted:
                return(factorFile.GetSplitFactor(date));

            case DataNormalizationMode.Adjusted:
                return(factorFile.GetPriceScaleFactor(date));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
示例#11
0
        /// <summary>
        /// Resolves the price scale for a date given a factor file and required settings
        /// </summary>
        /// <param name="factorFile">The factor file to use</param>
        /// <param name="dateTime">The date for the price scale lookup</param>
        /// <param name="normalizationMode">The price normalization mode requested</param>
        /// <param name="contractOffset">The contract offset, useful for continuous contracts</param>
        /// <param name="dataMappingMode">The data mapping mode used, useful for continuous contracts</param>
        /// <returns>The price scale to use</returns>
        public static decimal GetPriceScale(
            this IFactorProvider factorFile,
            DateTime dateTime,
            DataNormalizationMode normalizationMode,
            uint contractOffset             = 0,
            DataMappingMode?dataMappingMode = null
            )
        {
            if (factorFile == null)
            {
                if (normalizationMode is DataNormalizationMode.BackwardsPanamaCanal or DataNormalizationMode.ForwardPanamaCanal)
                {
                    return(0);
                }
                return(1);
            }

            return(factorFile.GetPriceFactor(dateTime, normalizationMode, dataMappingMode, contractOffset));
        }
示例#12
0
        public override void OnEndOfAlgorithm()
        {
            var equityDataNormalizationModes = new DataNormalizationMode[] {
                DataNormalizationMode.Raw,
                DataNormalizationMode.Adjusted,
                DataNormalizationMode.SplitAdjusted
            };

            CheckHistoryResultsForDataNormalizationModes(_aaplEquitySymbol, StartDate, EndDate, Resolution.Daily, equityDataNormalizationModes);

            var futureDataNormalizationModes = new DataNormalizationMode[] {
                DataNormalizationMode.Raw,
                DataNormalizationMode.BackwardsRatio,
                DataNormalizationMode.BackwardsPanamaCanal,
                DataNormalizationMode.ForwardPanamaCanal
            };

            CheckHistoryResultsForDataNormalizationModes(_esFutureSymbol, StartDate, EndDate, Resolution.Daily, futureDataNormalizationModes);
        }
示例#13
0
        /// <summary>
        /// Sets the data normalization mode to be used by this security
        /// </summary>
        public void SetDataNormalizationMode(DataNormalizationMode mode)
        {
            foreach (var subscription in SubscriptionsBag)
            {
                subscription.DataNormalizationMode = mode;
            }

            if (Type == SecurityType.Equity)
            {
                if (mode == DataNormalizationMode.Adjusted)
                {
                    PriceVariationModel = new AdjustedPriceVariationModel();
                }
                else
                {
                    PriceVariationModel = new EquityPriceVariationModel();
                }
            }
        }
        /// <summary>
        /// Applies a dividend to the portfolio
        /// </summary>
        /// <param name="dividend">The dividend to be applied</param>
        /// <param name="liveMode">True if live mode, false for backtest</param>
        /// <param name="mode">The <see cref="DataNormalizationMode"/> for this security</param>
        public void ApplyDividend(Dividend dividend, bool liveMode, DataNormalizationMode mode)
        {
            // we currently don't properly model dividend payable dates, so in
            // live mode it's more accurate to rely on the brokerage cash sync
            if (liveMode)
            {
                return;
            }

            var security = Securities[dividend.Symbol];

            // only apply dividends when we're in raw mode or split adjusted mode
            if (mode == DataNormalizationMode.Raw || mode == DataNormalizationMode.SplitAdjusted)
            {
                // longs get benefits, shorts get clubbed on dividends
                var total = security.Holdings.Quantity * dividend.Distribution;

                // assuming USD, we still need to add Currency to the security object
                _baseCurrencyCash.AddAmount(total);
            }
        }
        public void CheckSecurityMinimumPriceVariation(string ticker, SecurityType securityType, string market, DataNormalizationMode mode)
        {
            var symbol = Symbol.Create(ticker, securityType, market);
            var security = GetSecurity(symbol, mode);
            var expected = security.SymbolProperties.MinimumPriceVariation;
            var adjutedEquity = mode == DataNormalizationMode.Adjusted && securityType == SecurityType.Equity;

            security.SetMarketPrice(new IndicatorDataPoint(symbol, DateTime.Now, 10m));
            var actual = security.PriceVariationModel.GetMinimumPriceVariation(security);
            Assert.AreEqual(adjutedEquity ? 0 : expected, actual);

            security.SetMarketPrice(new IndicatorDataPoint(symbol, DateTime.Now, 1m));
            actual = security.PriceVariationModel.GetMinimumPriceVariation(security);
            Assert.AreEqual(adjutedEquity ? 0 : expected, actual);

            // Special case, if stock price less than $1, minimum price variation is $0.0001
            if (securityType == SecurityType.Equity) expected = 0.0001m;

            security.SetMarketPrice(new IndicatorDataPoint(symbol, DateTime.Now, .99m));
            actual = security.PriceVariationModel.GetMinimumPriceVariation(security);
            Assert.AreEqual(adjutedEquity ? 0 : expected, actual);
        }
 /// <summary>
 ///     Add Market Data Required - generic data typing support as long as Type implements BaseData.
 /// </summary>
 /// <param name="dataType">Set the type of the data we're subscribing to.</param>
 /// <param name="tickType">Tick type for the subscription.</param>
 /// <param name="symbol">Symbol of the asset we're like</param>
 /// <param name="resolution">Resolution of Asset Required</param>
 /// <param name="dataTimeZone">The time zone the subscription's data is time stamped in</param>
 /// <param name="exchangeTimeZone">
 ///     Specifies the time zone of the exchange for the security this subscription is for. This
 ///     is this output time zone, that is, the time zone that will be used on BaseData instances
 /// </param>
 /// <param name="isCustomData">True if this is custom user supplied data, false for normal QC data</param>
 /// <param name="fillDataForward">when there is no data pass the last tradebar forward</param>
 /// <param name="extendedMarketHours">Request premarket data as well when true </param>
 /// <param name="isInternalFeed">
 ///     Set to true to prevent data from this subscription from being sent into the algorithm's
 ///     OnData events
 /// </param>
 /// <param name="isFilteredSubscription">
 ///     True if this subscription should have filters applied to it (market hours/user
 ///     filters from security), false otherwise
 /// </param>
 /// <param name="dataNormalizationMode">Define how data is normalized</param>
 /// <returns>
 ///     The newly created <see cref="SubscriptionDataConfig" /> or existing instance if it already existed
 /// </returns>
 public SubscriptionDataConfig Add(
     Type dataType,
     TickType tickType,
     Symbol symbol,
     Resolution resolution,
     DateTimeZone dataTimeZone,
     DateTimeZone exchangeTimeZone,
     bool isCustomData,
     bool fillDataForward        = true,
     bool extendedMarketHours    = false,
     bool isInternalFeed         = false,
     bool isFilteredSubscription = true,
     DataNormalizationMode dataNormalizationMode = DataNormalizationMode.Adjusted
     )
 {
     return(SubscriptionDataConfigService.Add(symbol, resolution, fillDataForward,
                                              extendedMarketHours, isFilteredSubscription, isInternalFeed, isCustomData,
                                              new List <Tuple <Type, TickType> > {
         new Tuple <Type, TickType>(dataType, tickType)
     },
                                              dataNormalizationMode).First());
 }
示例#17
0
 /// <summary>
 /// Initializes a new instance of the <see cref="HistoryRequest"/> class from the specified parameters
 /// </summary>
 /// <param name="startTimeUtc">The start time for this request,</param>
 /// <param name="endTimeUtc">The start time for this request</param>
 /// <param name="dataType">The data type of the output data</param>
 /// <param name="symbol">The symbol to request data for</param>
 /// <param name="resolution">The requested data resolution</param>
 /// <param name="exchangeHours">The exchange hours used in fill forward processing</param>
 /// <param name="fillForwardResolution">The requested fill forward resolution for this request</param>
 /// <param name="includeExtendedMarketHours">True to include data from pre/post market hours</param>
 /// <param name="isCustomData">True for custom user data, false for normal QC data</param>
 /// <param name="dataNormalizationMode">Specifies normalization mode used for this subscription</param>
 public HistoryRequest(DateTime startTimeUtc,
                       DateTime endTimeUtc,
                       Type dataType,
                       Symbol symbol,
                       Resolution resolution,
                       SecurityExchangeHours exchangeHours,
                       Resolution?fillForwardResolution,
                       bool includeExtendedMarketHours,
                       bool isCustomData,
                       DataNormalizationMode dataNormalizationMode
                       )
 {
     StartTimeUtc               = startTimeUtc;
     EndTimeUtc                 = endTimeUtc;
     Symbol                     = symbol;
     ExchangeHours              = exchangeHours;
     Resolution                 = resolution;
     FillForwardResolution      = fillForwardResolution;
     IncludeExtendedMarketHours = includeExtendedMarketHours;
     DataType                   = dataType;
     IsCustomData               = isCustomData;
     DataNormalizationMode      = dataNormalizationMode;
     TimeZone                   = exchangeHours.TimeZone;
 }
示例#18
0
        public void CheckUniverseSelectionSecurityDataNormalizationMode(DataNormalizationMode dataNormalizationMode)
        {
            var tuple       = GetAlgorithmAndDataManager();
            var algorithm   = tuple.Item1;
            var dataManager = tuple.Item2;

            var symbol = Symbols.SPY;

            algorithm.UniverseSettings.DataNormalizationMode = dataNormalizationMode;
            algorithm.AddUniverse(coarse => new[] { symbol });

            var changes = dataManager.UniverseSelection
                          .ApplyUniverseSelection(
                algorithm.UniverseManager.First().Value,
                algorithm.UtcTime,
                new BaseDataCollection(algorithm.UtcTime, null, Enumerable.Empty <CoarseFundamental>()));

            Assert.AreEqual(1, changes.AddedSecurities.Count());

            var security = changes.AddedSecurities.First();

            Assert.AreEqual(symbol, security.Symbol);
            Assert.AreEqual(dataNormalizationMode, security.DataNormalizationMode);
        }
示例#19
0
        /// <summary>
        /// Gets the price scale factor that includes dividend and split adjustments for the specified search date
        /// </summary>
        public override decimal GetPriceFactor(DateTime searchDate, DataNormalizationMode dataNormalizationMode, DataMappingMode?dataMappingMode = null, uint contractOffset = 0)
        {
            if (dataNormalizationMode == DataNormalizationMode.Raw)
            {
                return(0);
            }

            var factor = 1m;

            for (var i = 0; i < _reversedFactorFileDates.Count; i++)
            {
                var factorDate = _reversedFactorFileDates[i];
                if (factorDate.Date < searchDate.Date)
                {
                    break;
                }

                var factorFileRow = SortedFactorFileData[factorDate];
                switch (dataNormalizationMode)
                {
                case DataNormalizationMode.TotalReturn:
                case DataNormalizationMode.SplitAdjusted:
                    factor = factorFileRow.First().SplitFactor;
                    break;

                case DataNormalizationMode.Adjusted:
                    factor = factorFileRow.First().PriceScaleFactor;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            return(factor);
        }
示例#20
0
 /// <summary>
 /// Initializes a new instance of the <see cref="HistoryRequest"/> class from the specified parameters
 /// </summary>
 /// <param name="startTimeUtc">The start time for this request,</param>
 /// <param name="endTimeUtc">The start time for this request</param>
 /// <param name="dataType">The data type of the output data</param>
 /// <param name="symbol">The symbol to request data for</param>
 /// <param name="resolution">The requested data resolution</param>
 /// <param name="exchangeHours">The exchange hours used in fill forward processing</param>
 /// <param name="dataTimeZone">The time zone of the data</param>
 /// <param name="fillForwardResolution">The requested fill forward resolution for this request</param>
 /// <param name="includeExtendedMarketHours">True to include data from pre/post market hours</param>
 /// <param name="isCustomData">True for custom user data, false for normal QC data</param>
 /// <param name="dataNormalizationMode">Specifies normalization mode used for this subscription</param>
 /// <param name="tickType">The tick type used to created the <see cref="SubscriptionDataConfig"/> for the retrieval of history data</param>
 public HistoryRequest(DateTime startTimeUtc,
                       DateTime endTimeUtc,
                       Type dataType,
                       Symbol symbol,
                       Resolution resolution,
                       SecurityExchangeHours exchangeHours,
                       DateTimeZone dataTimeZone,
                       Resolution?fillForwardResolution,
                       bool includeExtendedMarketHours,
                       bool isCustomData,
                       DataNormalizationMode dataNormalizationMode,
                       TickType tickType)
     : base(startTimeUtc, endTimeUtc, exchangeHours, tickType)
 {
     Symbol                     = symbol;
     DataTimeZone               = dataTimeZone;
     Resolution                 = resolution;
     FillForwardResolution      = fillForwardResolution;
     IncludeExtendedMarketHours = includeExtendedMarketHours;
     DataType                   = dataType;
     IsCustomData               = isCustomData;
     DataNormalizationMode      = dataNormalizationMode;
     TickType                   = tickType;
 }
示例#21
0
        /// <summary>
        /// Creates and adds a list of <see cref="SubscriptionDataConfig" /> for a given symbol and configuration.
        /// Can optionally pass in desired subscription data types to use.
        ///  If the config already existed will return existing instance instead
        /// </summary>
        public List <SubscriptionDataConfig> Add(
            Symbol symbol,
            Resolution?resolution       = null,
            bool fillForward            = true,
            bool extendedMarketHours    = false,
            bool isFilteredSubscription = true,
            bool isInternalFeed         = false,
            bool isCustomData           = false,
            List <Tuple <Type, TickType> > subscriptionDataTypes = null,
            DataNormalizationMode dataNormalizationMode          = DataNormalizationMode.Adjusted
            )
        {
            var dataTypes = subscriptionDataTypes ??
                            LookupSubscriptionConfigDataTypes(symbol.SecurityType, resolution ?? Resolution.Minute, symbol.IsCanonical());

            if (!dataTypes.Any())
            {
                throw new ArgumentNullException(nameof(dataTypes), "At least one type needed to create new subscriptions");
            }

            var resolutionWasProvided = resolution.HasValue;

            foreach (var typeTuple in dataTypes)
            {
                var baseInstance = typeTuple.Item1.GetBaseDataInstance();
                baseInstance.Symbol = symbol;
                if (!resolutionWasProvided)
                {
                    var defaultResolution = baseInstance.DefaultResolution();
                    if (resolution.HasValue && resolution != defaultResolution)
                    {
                        // we are here because there are multiple 'dataTypes'.
                        // if we get different default resolutions lets throw, this shouldn't happen
                        throw new InvalidOperationException(
                                  $"Different data types ({string.Join(",", dataTypes.Select(tuple => tuple.Item1))})" +
                                  $" provided different default resolutions {defaultResolution} and {resolution}, this is an unexpected invalid operation.");
                    }
                    resolution = defaultResolution;
                }
                else
                {
                    // only assert resolution in backtesting, live can use other data source
                    // for example daily data for options
                    if (!_liveMode)
                    {
                        var supportedResolutions = baseInstance.SupportedResolutions();
                        if (supportedResolutions.Contains(resolution.Value))
                        {
                            continue;
                        }

                        throw new ArgumentException($"Sorry {resolution.ToStringInvariant()} is not a supported resolution for {typeTuple.Item1.Name}" +
                                                    $" and SecurityType.{symbol.SecurityType.ToStringInvariant()}." +
                                                    $" Please change your AddData to use one of the supported resolutions ({string.Join(",", supportedResolutions)}).");
                    }
                }
            }

            MarketHoursDatabase.Entry marketHoursDbEntry;
            if (!_marketHoursDatabase.TryGetEntry(symbol.ID.Market, symbol, symbol.ID.SecurityType, out marketHoursDbEntry))
            {
                if (symbol.SecurityType == SecurityType.Base)
                {
                    var baseInstance = dataTypes.Single().Item1.GetBaseDataInstance();
                    baseInstance.Symbol = symbol;
                    _marketHoursDatabase.SetEntryAlwaysOpen(symbol.ID.Market, null, SecurityType.Base, baseInstance.DataTimeZone());
                }

                marketHoursDbEntry = _marketHoursDatabase.GetEntry(symbol.ID.Market, symbol, symbol.ID.SecurityType);
            }

            var exchangeHours = marketHoursDbEntry.ExchangeHours;

            if (symbol.ID.SecurityType.IsOption() ||
                symbol.ID.SecurityType == SecurityType.Future ||
                symbol.ID.SecurityType == SecurityType.Index)
            {
                dataNormalizationMode = DataNormalizationMode.Raw;
            }

            if (marketHoursDbEntry.DataTimeZone == null)
            {
                throw new ArgumentNullException(nameof(marketHoursDbEntry.DataTimeZone),
                                                "DataTimeZone is a required parameter for new subscriptions. Set to the time zone the raw data is time stamped in.");
            }

            if (exchangeHours.TimeZone == null)
            {
                throw new ArgumentNullException(nameof(exchangeHours.TimeZone),
                                                "ExchangeTimeZone is a required parameter for new subscriptions. Set to the time zone the security exchange resides in.");
            }

            var result = (from subscriptionDataType in dataTypes
                          let dataType = subscriptionDataType.Item1
                                         let tickType = subscriptionDataType.Item2
                                                        select new SubscriptionDataConfig(
                              dataType,
                              symbol,
                              resolution.Value,
                              marketHoursDbEntry.DataTimeZone,
                              exchangeHours.TimeZone,
                              fillForward,
                              extendedMarketHours,
                              // if the subscription data types were not provided and the tick type is OpenInterest we make it internal
                              subscriptionDataTypes == null && tickType == TickType.OpenInterest || isInternalFeed,
                              isCustomData,
                              isFilteredSubscription: isFilteredSubscription,
                              tickType: tickType,
                              dataNormalizationMode: dataNormalizationMode)).ToList();

            for (int i = 0; i < result.Count; i++)
            {
                result[i] = SubscriptionManagerGetOrAdd(result[i]);

                // track all registered data types
                _registeredTypesProvider.RegisterType(result[i].Type);
            }
            return(result);
        }
示例#22
0
        /// <summary>
        /// Sets the data normalization mode to be used by this security
        /// </summary>
        public void SetDataNormalizationMode(DataNormalizationMode mode)
        {
            foreach (var subscription in SubscriptionsBag)
            {
                subscription.DataNormalizationMode = mode;
            }

            if (Type == SecurityType.Equity)
            {
                if (mode == DataNormalizationMode.Adjusted)
                {
                    PriceVariationModel = new AdjustedPriceVariationModel();
                }
                else
                {
                    PriceVariationModel = new EquityPriceVariationModel();
                }
            }
        }
        /// <summary>
        /// Applies a split to the portfolio
        /// </summary>
        /// <param name="split">The split to be applied</param>
        /// <param name="liveMode">True if live mode, false for backtest</param>
        /// <param name="mode">The <see cref="DataNormalizationMode"/> for this security</param>
        public void ApplySplit(Split split, bool liveMode, DataNormalizationMode mode)
        {
            var security = Securities[split.Symbol];

            // only apply splits to equities
            if (security.Type != SecurityType.Equity)
            {
                return;
            }

            // only apply splits in live or raw data mode
            if (!liveMode && mode != DataNormalizationMode.Raw)
            {
                return;
            }

            // we need to modify our holdings in lght of the split factor
            var quantity = security.Holdings.Quantity / split.SplitFactor;
            var avgPrice = security.Holdings.AveragePrice * split.SplitFactor;

            // we'll model this as a cash adjustment
            var leftOver  = quantity - (int)quantity;
            var extraCash = leftOver * split.ReferencePrice;

            _baseCurrencyCash.AddAmount(extraCash);

            security.Holdings.SetHoldings(avgPrice, (int)quantity);

            // build a 'next' value to update the market prices in light of the split factor
            var next = security.GetLastData();

            if (next == null)
            {
                // sometimes we can get splits before we receive data which
                // will cause this to return null, in this case we can't possibly
                // have any holdings or price to set since we haven't received
                // data yet, so just do nothing
                return;
            }
            next.Value *= split.SplitFactor;

            // make sure to modify open/high/low as well for tradebar data types
            var tradeBar = next as TradeBar;

            if (tradeBar != null)
            {
                tradeBar.Open *= split.SplitFactor;
                tradeBar.High *= split.SplitFactor;
                tradeBar.Low  *= split.SplitFactor;
            }

            // make sure to modify bid/ask as well for tradebar data types
            var tick = next as Tick;

            if (tick != null)
            {
                tick.AskPrice *= split.SplitFactor;
                tick.BidPrice *= split.SplitFactor;
            }

            security.SetMarketPrice(next);
            // security price updated
            InvalidateTotalPortfolioValue();
        }
示例#24
0
文件: Security.cs 项目: aajtodd/Lean
 /// <summary>
 /// Sets the data normalization mode to be used by this security
 /// </summary>
 public void SetDataNormalizationMode(DataNormalizationMode mode)
 {
     foreach (var subscription in SubscriptionsBag)
     {
         subscription.DataNormalizationMode = mode;
     }
 }
示例#25
0
文件: Security.cs 项目: neosb/Lean
 /// <summary>
 /// Sets the data normalization mode to be used by this security
 /// </summary>
 public void SetDataNormalizationMode(DataNormalizationMode mode)
 {
     _config.DataNormalizationMode = mode;
 }
示例#26
0
        public void CheckSecurityMinimumPriceVariation(string ticker, SecurityType securityType, string market, DataNormalizationMode mode)
        {
            var symbol        = Symbol.Create(ticker, securityType, market);
            var security      = GetSecurity(symbol, mode);
            var expected      = security.SymbolProperties.MinimumPriceVariation;
            var adjutedEquity = mode == DataNormalizationMode.Adjusted && securityType == SecurityType.Equity;

            security.SetMarketPrice(new IndicatorDataPoint(symbol, DateTime.Now, 10m));
            var actual = security.PriceVariationModel.GetMinimumPriceVariation(
                new GetMinimumPriceVariationParameters(security, security.Price));

            Assert.AreEqual(adjutedEquity ? 0 : expected, actual);

            security.SetMarketPrice(new IndicatorDataPoint(symbol, DateTime.Now, 1m));
            actual = security.PriceVariationModel.GetMinimumPriceVariation(
                new GetMinimumPriceVariationParameters(security, security.Price));
            Assert.AreEqual(adjutedEquity ? 0 : expected, actual);

            // Special case, if stock price less than $1, minimum price variation is $0.0001
            if (securityType == SecurityType.Equity)
            {
                expected = 0.0001m;
            }

            security.SetMarketPrice(new IndicatorDataPoint(symbol, DateTime.Now, .99m));
            actual = security.PriceVariationModel.GetMinimumPriceVariation(
                new GetMinimumPriceVariationParameters(security, security.Price));
            Assert.AreEqual(adjutedEquity ? 0 : expected, actual);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="CustomSecurityInitializer"/> class
 /// with the specified normalization mode
 /// </summary>
 /// <param name="brokerageModel">The brokerage model used to get fill/fee/slippage/settlement models</param>
 /// <param name="dataNormalizationMode">The desired data normalization mode</param>
 public CustomSecurityInitializer(IBrokerageModel brokerageModel, DataNormalizationMode dataNormalizationMode)
     : base(brokerageModel)
 {
     _dataNormalizationMode = dataNormalizationMode;
 }
示例#28
0
        /// <summary>
        /// Creates and adds a list of <see cref="SubscriptionDataConfig" /> for a given symbol and configuration.
        /// Can optionally pass in desired subscription data types to use.
        ///  If the config already existed will return existing instance instead
        /// </summary>
        public List <SubscriptionDataConfig> Add(
            Symbol symbol,
            Resolution resolution,
            bool fillForward,
            bool extendedMarketHours,
            bool isFilteredSubscription = true,
            bool isInternalFeed         = false,
            bool isCustomData           = false,
            List <Tuple <Type, TickType> > subscriptionDataTypes = null,
            DataNormalizationMode dataNormalizationMode          = DataNormalizationMode.Adjusted
            )
        {
            var dataTypes = subscriptionDataTypes ??
                            LookupSubscriptionConfigDataTypes(symbol.SecurityType, resolution, symbol.IsCanonical());

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

            if (symbol.ID.SecurityType == SecurityType.Option || symbol.ID.SecurityType == SecurityType.Future)
            {
                dataNormalizationMode = DataNormalizationMode.Raw;
            }

            if (marketHoursDbEntry.DataTimeZone == null)
            {
                throw new ArgumentNullException(nameof(marketHoursDbEntry.DataTimeZone),
                                                "DataTimeZone is a required parameter for new subscriptions. Set to the time zone the raw data is time stamped in.");
            }

            if (exchangeHours.TimeZone == null)
            {
                throw new ArgumentNullException(nameof(exchangeHours.TimeZone),
                                                "ExchangeTimeZone is a required parameter for new subscriptions. Set to the time zone the security exchange resides in.");
            }

            if (!dataTypes.Any())
            {
                throw new ArgumentNullException(nameof(dataTypes), "At least one type needed to create new subscriptions");
            }

            var result = (from subscriptionDataType in dataTypes
                          let dataType = subscriptionDataType.Item1
                                         let tickType = subscriptionDataType.Item2
                                                        select new SubscriptionDataConfig(
                              dataType,
                              symbol,
                              resolution,
                              marketHoursDbEntry.DataTimeZone,
                              exchangeHours.TimeZone,
                              fillForward,
                              extendedMarketHours,
                              isInternalFeed,
                              isCustomData,
                              isFilteredSubscription: isFilteredSubscription,
                              tickType: tickType,
                              dataNormalizationMode: dataNormalizationMode)).ToList();

            for (int i = 0; i < result.Count; i++)
            {
                result[i] = SubscriptionManagerGetOrAdd(result[i]);

                // track all registered data types
                _registeredTypesProvider.RegisterType(result[i].Type);
            }
            return(result);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="CustomSecurityInitializer"/> class
 /// with the specified normalization mode
 /// </summary>
 /// <param name="brokerageModel">The brokerage model used to get fill/fee/slippage/settlement models</param>
 /// <param name="dataNormalizationMode">The desired data normalization mode</param>
 public CustomSecurityInitializer(IBrokerageModel brokerageModel, DataNormalizationMode dataNormalizationMode)
     : base(brokerageModel)
 {
     _dataNormalizationMode = dataNormalizationMode;
 }
示例#30
0
 /// <summary>
 /// Sets the data normalization mode to be used by this security
 /// </summary>
 public void SetDataNormalizationMode(DataNormalizationMode mode)
 {
     _config.DataNormalizationMode = mode;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="UniverseSettings"/> class
 /// </summary>
 /// <param name="resolution">The resolution</param>
 /// <param name="leverage">The leverage to be used</param>
 /// <param name="fillForward">True to fill data forward, false otherwise</param>
 /// <param name="extendedMarketHours">True to allow extended market hours data, false otherwise</param>
 /// <param name="minimumTimeInUniverse">Defines the minimum amount of time a security must remain in the universe before being removed</param>
 /// <param name="dataNormalizationMode">Defines how universe data is normalized before being send into the algorithm</param>
 public UniverseSettings(Resolution resolution, decimal leverage, bool fillForward, bool extendedMarketHours, TimeSpan minimumTimeInUniverse, DataNormalizationMode dataNormalizationMode = DataNormalizationMode.Adjusted)
 {
     Resolution            = resolution;
     Leverage              = leverage;
     FillForward           = fillForward;
     ExtendedMarketHours   = extendedMarketHours;
     MinimumTimeInUniverse = minimumTimeInUniverse;
     DataNormalizationMode = dataNormalizationMode;
 }
示例#32
0
        /// <summary>
        /// Clones the data, computes the utc emit time and performs exchange round down behavior, storing the result in a new <see cref="SubscriptionData"/> instance
        /// </summary>
        /// <param name="configuration">The subscription's configuration</param>
        /// <param name="exchangeHours">The exchange hours of the security</param>
        /// <param name="offsetProvider">The subscription's offset provider</param>
        /// <param name="data">The data being emitted</param>
        /// <param name="normalizationMode">Specifies how data is normalized</param>
        /// <param name="factor">price scale factor</param>
        /// <returns>A new <see cref="SubscriptionData"/> containing the specified data</returns>
        public static SubscriptionData Create(SubscriptionDataConfig configuration, SecurityExchangeHours exchangeHours, TimeZoneOffsetProvider offsetProvider, BaseData data, DataNormalizationMode normalizationMode, decimal?factor = null)
        {
            if (data == null)
            {
                return(null);
            }

            data = data.Clone(data.IsFillForward);
            var emitTimeUtc = offsetProvider.ConvertToUtc(data.EndTime);

            // Let's round down for any data source that implements a time delta between
            // the start of the data and end of the data (usually used with Bars).
            // The time delta ensures that the time collected from `EndTime` has
            // no look-ahead bias, and is point-in-time.
            if (data.Time != data.EndTime)
            {
                data.Time = data.Time.ExchangeRoundDownInTimeZone(configuration.Increment, exchangeHours, configuration.DataTimeZone, configuration.ExtendedMarketHours);
            }

            if (factor.HasValue && (factor.Value != 1 || configuration.SumOfDividends != 0))
            {
                var sumOfDividends = configuration.SumOfDividends;

                var normalizedData = data.Clone(data.IsFillForward);

                if (normalizationMode == DataNormalizationMode.Adjusted || normalizationMode == DataNormalizationMode.SplitAdjusted)
                {
                    normalizedData.Adjust(factor.Value);
                }
                else if (normalizationMode == DataNormalizationMode.TotalReturn)
                {
                    normalizedData.Scale(p => p * factor.Value + sumOfDividends, 1 / factor.Value);
                }

                return(new PrecalculatedSubscriptionData(configuration, data, normalizedData, normalizationMode, emitTimeUtc));
            }

            return(new SubscriptionData(data, emitTimeUtc));
        }
示例#33
0
        /// <summary>
        /// Gets the historical data for the specified symbols between the specified dates. The symbols must exist in the Securities collection.
        /// </summary>
        /// <param name="pyObject">The symbols to retrieve historical data for</param>
        /// <param name="start">The start time in the algorithm's time zone</param>
        /// <param name="end">The end time in the algorithm's time zone</param>
        /// <param name="resolution">The resolution to request</param>
        /// <param name="selector">Selects a value from the BaseData to filter the request output, if null retuns all OHLCV</param>
        /// <param name="dataNormalizationMode">The data normalization mode. Default is Adjusted</param>
        /// <param name="extendedMarket">True to include extended market hours data, false otherwise</param>
        /// <returns>A pandas.DataFrame containing the requested historical data</returns>
        public PyObject History(PyObject pyObject, DateTime?start = null, DateTime?end = null, Resolution resolution = Resolution.Daily, Func <IBaseData, decimal> selector = null, DataNormalizationMode dataNormalizationMode = DataNormalizationMode.Adjusted, bool extendedMarket = false)
        {
            var symbols = GetSymbolsFromPyObject(pyObject);

            if (symbols == null)
            {
                return("Invalid ticker(s). Please use get_symbol to add symbols.".ToPython());
            }

            var requests = symbols.Select(symbol =>
            {
                if (symbol.SecurityType == SecurityType.Forex || symbol.SecurityType == SecurityType.Cfd)
                {
                    start = start ?? new DateTime(2005, 1, 1);
                }

                return(new HistoryRequest()
                {
                    Symbol = symbol,
                    StartTimeUtc = start ?? symbol.ID.Date,
                    EndTimeUtc = end ?? DateTime.Now,
                    Resolution = resolution,
                    FillForwardResolution = null,
                    DataNormalizationMode = dataNormalizationMode,
                    IncludeExtendedMarketHours = extendedMarket,
                    DataType = symbol.ID.SecurityType == SecurityType.Equity ? typeof(TradeBar) : typeof(QuoteBar)
                });
            });

            return(CreateDataFrame(requests, _historyProvider.GetHistory(requests, TimeZones.NewYork), selector));
        }
示例#34
0
        /// <summary>
        /// Gets the historical data for the specified symbols between the specified dates. The symbols must exist in the Securities collection.
        /// </summary>
        /// <param name="symbols">The symbols to retrieve historical data for</param>
        /// <param name="span">The span over which to retrieve recent historical data</param>
        /// <param name="resolution">The resolution to request</param>
        /// <param name="selector">Selects a value from the BaseData to filter the request output, if null retuns all OHLCV</param>
        /// <param name="dataNormalizationMode">The data normalization mode. Default is Adjusted</param>
        /// <param name="extendedMarket">True to include extended market hours data, false otherwise</param>
        /// <returns>A pandas.DataFrame containing the requested historical data</returns>
        public PyObject History(PyObject symbols, TimeSpan span, Resolution resolution = Resolution.Daily, Func <IBaseData, decimal> selector = null, DataNormalizationMode dataNormalizationMode = DataNormalizationMode.Adjusted, bool extendedMarket = false)
        {
            var endTimeUtc   = DateTime.Now;
            var startTimeUtc = endTimeUtc - span;

            return(History(symbols, startTimeUtc, endTimeUtc, resolution, selector, dataNormalizationMode, extendedMarket));
        }
示例#35
0
        /// <summary>
        /// Constructor for Data Subscriptions
        /// </summary>
        /// <param name="objectType">Type of the data objects.</param>
        /// <param name="symbol">Symbol of the asset we're requesting</param>
        /// <param name="resolution">Resolution of the asset we're requesting</param>
        /// <param name="dataTimeZone">The time zone the raw data is time stamped in</param>
        /// <param name="exchangeTimeZone">Specifies the time zone of the exchange for the security this subscription is for. This
        /// is this output time zone, that is, the time zone that will be used on BaseData instances</param>
        /// <param name="fillForward">Fill in gaps with historical data</param>
        /// <param name="extendedHours">Equities only - send in data from 4am - 8pm</param>
        /// <param name="isInternalFeed">Set to true if this subscription is added for the sole purpose of providing currency conversion rates,
        /// setting this flag to true will prevent the data from being sent into the algorithm's OnData methods</param>
        /// <param name="isCustom">True if this is user supplied custom data, false for normal QC data</param>
        /// <param name="tickType">Specifies if trade or quote data is subscribed</param>
        /// <param name="isFilteredSubscription">True if this subscription should have filters applied to it (market hours/user filters from security), false otherwise</param>
        /// <param name="dataNormalizationMode">Specifies normalization mode used for this subscription</param>
        public SubscriptionDataConfig(Type objectType,
                                      Symbol symbol,
                                      Resolution resolution,
                                      DateTimeZone dataTimeZone,
                                      DateTimeZone exchangeTimeZone,
                                      bool fillForward,
                                      bool extendedHours,
                                      bool isInternalFeed,
                                      bool isCustom               = false,
                                      TickType?tickType           = null,
                                      bool isFilteredSubscription = true,
                                      DataNormalizationMode dataNormalizationMode = DataNormalizationMode.Adjusted)
        {
            if (objectType == null)
            {
                throw new ArgumentNullException("objectType");
            }
            if (symbol == null)
            {
                throw new ArgumentNullException("symbol");
            }
            if (dataTimeZone == null)
            {
                throw new ArgumentNullException("dataTimeZone");
            }
            if (exchangeTimeZone == null)
            {
                throw new ArgumentNullException("exchangeTimeZone");
            }

            Type                   = objectType;
            SecurityType           = symbol.ID.SecurityType;
            Resolution             = resolution;
            _sid                   = symbol.ID;
            Symbol                 = symbol;
            FillDataForward        = fillForward;
            ExtendedMarketHours    = extendedHours;
            PriceScaleFactor       = 1;
            IsInternalFeed         = isInternalFeed;
            IsCustomData           = isCustom;
            Market                 = symbol.ID.Market;
            DataTimeZone           = dataTimeZone;
            ExchangeTimeZone       = exchangeTimeZone;
            IsFilteredSubscription = isFilteredSubscription;
            Consolidators          = new HashSet <IDataConsolidator>();
            DataNormalizationMode  = dataNormalizationMode;

            TickType = tickType ?? LeanData.GetCommonTickTypeForCommonDataTypes(objectType, SecurityType);

            switch (resolution)
            {
            case Resolution.Tick:
                //Ticks are individual sales and fillforward doesn't apply.
                Increment       = TimeSpan.FromSeconds(0);
                FillDataForward = false;
                break;

            case Resolution.Second:
                Increment = TimeSpan.FromSeconds(1);
                break;

            case Resolution.Minute:
                Increment = TimeSpan.FromMinutes(1);
                break;

            case Resolution.Hour:
                Increment = TimeSpan.FromHours(1);
                break;

            case Resolution.Daily:
                Increment = TimeSpan.FromDays(1);
                break;

            default:
                throw new InvalidEnumArgumentException("Unexpected Resolution: " + resolution);
            }
        }
示例#36
0
        /// <summary>
        /// Gets the historical data for the specified symbols between the specified dates. The symbols must exist in the Securities collection.
        /// </summary>
        /// <param name="symbols">The symbols to retrieve historical data for</param>
        /// <param name="periods">The number of bars to request</param>
        /// <param name="resolution">The resolution to request</param>
        /// <param name="selector">Selects a value from the BaseData to filter the request output, if null retuns all OHLCV</param>
        /// <param name="dataNormalizationMode">The data normalization mode. Default is Adjusted</param>
        /// <param name="extendedMarket">True to include extended market hours data, false otherwise</param>
        /// <returns>A pandas.DataFrame containing the requested historical data</returns>
        public PyObject History(PyObject symbols, int periods, Resolution resolution = Resolution.Daily, Func <IBaseData, decimal> selector = null, DataNormalizationMode dataNormalizationMode = DataNormalizationMode.Adjusted, bool extendedMarket = false)
        {
            var span = TimeSpan.FromDays(periods);

            switch (resolution)
            {
            case Resolution.Second:
                span = TimeSpan.FromSeconds(periods);
                break;

            case Resolution.Minute:
                span = TimeSpan.FromMinutes(periods);
                break;

            case Resolution.Hour:
                span = TimeSpan.FromHours(periods);
                break;

            default:
                break;
            }

            return(History(symbols, span, resolution, selector, dataNormalizationMode, extendedMarket));
        }