Example #1
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();
            }
        }
        /// <summary>
        /// For backwards adjusted data the price is adjusted by a scale factor which is a combination of splits and dividends.
        /// This backwards adjusted price is used by default and fed as the current price.
        /// </summary>
        /// <param name="date">Current date of the backtest.</param>
        private void UpdateScaleFactors(DateTime date)
        {
            switch (_config.DataNormalizationMode)
            {
            case DataNormalizationMode.Raw:
                return;

            case DataNormalizationMode.TotalReturn:
            case DataNormalizationMode.SplitAdjusted:
                _config.PriceScaleFactor = _factorFile.GetSplitFactor(date);
                break;

            case DataNormalizationMode.Adjusted:
                _config.PriceScaleFactor = _factorFile.GetPriceScaleFactor(date);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
        /// <summary>
        /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
        /// </summary>
        /// <param name="data">Slice object keyed by symbol containing the stock data</param>
        public override void OnData(Slice data)
        {
            if (!Portfolio.Invested)
            {
                SetHoldings(_aapl, 1);
            }

            if (data.Splits.ContainsKey(_aapl))
            {
                Log(data.Splits[_aapl].ToString());
            }

            if (data.Bars.ContainsKey(_aapl))
            {
                var aaplData = data.Bars[_aapl];

                // Assert our volume matches what we expect
                if (_expectedAdjustedVolume.MoveNext() && _expectedAdjustedVolume.Current != aaplData.Volume)
                {
                    // Our values don't match lets try and give a reason why
                    var dayFactor = _factorFile.GetSplitFactor(aaplData.Time);
                    var probableAdjustedVolume = aaplData.Volume / dayFactor;

                    if (_expectedAdjustedVolume.Current == probableAdjustedVolume)
                    {
                        throw new ArgumentException($"Volume was incorrect; but manually adjusted value is correct." +
                                                    $" Adjustment by multiplying volume by {1 / dayFactor} is not occurring.");
                    }
                    else
                    {
                        throw new ArgumentException($"Volume was incorrect; even when adjusted manually by" +
                                                    $" multiplying volume by {1 / dayFactor}. Data may have changed.");
                    }
                }
            }

            if (data.QuoteBars.ContainsKey(_aapl))
            {
                var aaplQuoteData = data.QuoteBars[_aapl];

                // Assert our askSize matches what we expect
                if (_expectedAdjustedAskSize.MoveNext() && _expectedAdjustedAskSize.Current != aaplQuoteData.LastAskSize)
                {
                    // Our values don't match lets try and give a reason why
                    var dayFactor = _factorFile.GetSplitFactor(aaplQuoteData.Time);
                    var probableAdjustedAskSize = aaplQuoteData.LastAskSize / dayFactor;

                    if (_expectedAdjustedAskSize.Current == probableAdjustedAskSize)
                    {
                        throw new ArgumentException($"Ask size was incorrect; but manually adjusted value is correct." +
                                                    $" Adjustment by multiplying size by {1 / dayFactor} is not occurring.");
                    }
                    else
                    {
                        throw new ArgumentException($"Ask size was incorrect; even when adjusted manually by" +
                                                    $" multiplying size by {1 / dayFactor}. Data may have changed.");
                    }
                }

                // Assert our bidSize matches what we expect
                if (_expectedAdjustedBidSize.MoveNext() && _expectedAdjustedBidSize.Current != aaplQuoteData.LastBidSize)
                {
                    // Our values don't match lets try and give a reason why
                    var dayFactor = _factorFile.GetSplitFactor(aaplQuoteData.Time);
                    var probableAdjustedBidSize = aaplQuoteData.LastBidSize / dayFactor;

                    if (_expectedAdjustedBidSize.Current == probableAdjustedBidSize)
                    {
                        throw new ArgumentException($"Bid size was incorrect; but manually adjusted value is correct." +
                                                    $" Adjustment by multiplying size by {1 / dayFactor} is not occurring.");
                    }
                    else
                    {
                        throw new ArgumentException($"Bid size was incorrect; even when adjusted manually by" +
                                                    $" multiplying size by {1 / dayFactor}. Data may have changed.");
                    }
                }
            }
        }