Beispiel #1
0
        private void UpdateOptimalTrackingFilter(DateTime time, decimal high, decimal low)
        {
            if (barcount > 1)
            {
                decimal v1 = staticAlpha2 * (Price[0].Value - Price[1].Value) + (1 - staticAlpha2) * OptimalValue1[0].Value;
                OptimalValue1.Add(idp(time, v1));
                decimal v2 = .1m * (high - low) + (1 - staticAlpha2) * OmtimalValue2[0].Value;
                OmtimalValue2.Add(idp(time, v2));
            }
            else
            {
                OptimalValue1.Add(idp(time, Price[0].Value));
                OmtimalValue2.Add(idp(time, Price[0].Value));
            }
            lambda.Add(OmtimalValue2[0].Value != 0 ? idp(time, Math.Abs(OptimalValue1[0].Value / OmtimalValue2[0].Value)) : idp(time, 0m));
            double la       = System.Convert.ToDouble(lambda[0].Value);
            double alphaval = (la * -1 * la + Math.Sqrt(la * la * la * la + 16 * la * la)) / 8;

            alpha.Add(idp(time, System.Convert.ToDecimal(alphaval)));
            if (barcount > 4)
            {
                decimal v3 = alpha[0].Value * Price[0].Value + (1 - alpha[0].Value) * OptimalTrackingFilter[0].Value;
                OptimalTrackingFilter.Add(idp(time, v3));
            }
            else
            {
                OptimalTrackingFilter.Add(idp(time, Price[0].Value));
            }
        }
        private void Strategy(TradeBars data)
        {
            if (barcount < 2)
            {
                fishDirectionHistory.Add(idp(this.Time, 0));
                fishDirectionChanged = false;
            }
            else
            {
                fishDirectionHistory.Add(idp(this.Time, Math.Sign(fishHistory[0].Value - fishHistory[1].Value)));
                fishDirectionChanged = fishDirectionHistory[0].Value != fishDirectionHistory[1].Value;
            }

            // liquidate at 3:50 to avoid the 4:00 rush.
            if (this.Time.Hour == 15 && this.Time.Minute > 49)
            {
                openForTrading = false;
                if (Portfolio.Invested)
                {
                    Liquidate();
                }
            }
            if (openForTrading)
            {
                if (cycle.IsReady)
                {
                    Invested();
                    NotInvested();
                }
            }
            sharesOwned = Portfolio[symbol].Quantity;
        }
Beispiel #3
0
        public void IndexingBasedOnReverseInsertedOrder()
        {
            var window = new RollingWindow <int>(3);

            Assert.AreEqual(3, window.Size);

            window.Add(0);
            Assert.AreEqual(1, window.Count);
            Assert.AreEqual(0, window[0]);

            window.Add(1);
            Assert.AreEqual(2, window.Count);
            Assert.AreEqual(0, window[1]);
            Assert.AreEqual(1, window[0]);

            window.Add(2);
            Assert.AreEqual(3, window.Count);
            Assert.AreEqual(0, window[2]);
            Assert.AreEqual(1, window[1]);
            Assert.AreEqual(2, window[0]);

            window.Add(3);
            Assert.AreEqual(3, window.Count);
            Assert.AreEqual(1, window[2]);
            Assert.AreEqual(2, window[1]);
            Assert.AreEqual(3, window[0]);
        }
Beispiel #4
0
        /// <summary>
        /// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.
        /// </summary>
        /// <seealso cref="QCAlgorithm.SetStartDate(System.DateTime)"/>
        /// <seealso cref="QCAlgorithm.SetEndDate(System.DateTime)"/>
        /// <seealso cref="QCAlgorithm.SetCash(decimal)"/>
        public override void Initialize()
        {
            //mylog.Debug(transheader);
            mylog.Debug(ondataheader);

            //Initialize dates
            SetStartDate(2013, 10, 07);
            SetEndDate(2013, 10, 07);
            SetCash(25000);

            //Add as many securities as you like. All the data will be passed into the event handler:
            AddSecurity(SecurityType.Equity, _symbol, Resolution.Minute);


            maxHigh = new Maximum("MaxHigh", _period);
            minLow  = new Minimum("MinLow", _period);
            value1  = new RollingWindow <IndicatorDataPoint>(_period);
            fish    = new RollingWindow <IndicatorDataPoint>(_period);
            //wma = new LinearWeightedMovingAverage(5);       // induces 2 bar lag
            //wwma = new RollingWindow<IndicatorDataPoint>(_period);
            //fishHigh = new Maximum("FishHigh", 400);
            //fishLow = new Minimum("FishLow", 400);
            fx = new FisherTransform(_symbol, _period);
            //fx = FT(_symbol, _period, Resolution.Minute);

            // Add a bars to initialize the RollingWindow
            value1.Add(new IndicatorDataPoint(DateTime.MinValue, .0001m));
            value1.Add(new IndicatorDataPoint(DateTime.MinValue, .0001m));
            fish.Add(new IndicatorDataPoint(DateTime.MinValue, 0m));
            fish.Add(new IndicatorDataPoint(DateTime.MinValue, 0m));
            //wwma.Add(new IndicatorDataPoint(DateTime.MinValue, .0001m));
            //wwma.Add(new IndicatorDataPoint(DateTime.MinValue, .0001m));
        }
Beispiel #5
0
        public void IndexingBasedOnReverseInsertedOrder()
        {
            var window = new RollingWindow<int>(3);
            Assert.AreEqual(3, window.Size);

            window.Add(0);
            Assert.AreEqual(1, window.Count);
            Assert.AreEqual(0, window[0]);

            window.Add(1);
            Assert.AreEqual(2, window.Count);
            Assert.AreEqual(0, window[1]);
            Assert.AreEqual(1, window[0]);

            window.Add(2);
            Assert.AreEqual(3, window.Count);
            Assert.AreEqual(0, window[2]);
            Assert.AreEqual(1, window[1]);
            Assert.AreEqual(2, window[0]);

            window.Add(3);
            Assert.AreEqual(3, window.Count);
            Assert.AreEqual(1, window[2]);
            Assert.AreEqual(2, window[1]);
            Assert.AreEqual(3, window[0]);
        }
Beispiel #6
0
        /// <summary>
        /// Updates the CenterGravity
        /// </summary>
        /// <param name="time"></param>
        private void UpdateCenterGravity(DateTime time)
        {
            decimal num   = 0;
            decimal den   = 0;
            int     count = samplesize / 2;

            if (barcount > count)
            {
                for (int i = 0; i < count; i++)
                {
                    try
                    {
                        num += (1 + i) * (Price[i].Value);
                        den += Price[i].Value;
                    }
                    catch (Exception e)
                    {
                        throw new Exception(e.Message);
                    }
                }
                if (den != 0)
                {
                    decimal c = count + 1;
                    decimal u = System.Convert.ToDecimal(-num / den);
                    centerGravity.Add(idp(time, u + c / 2));
                }
            }
            else
            {
                centerGravity.Add(idp(time, 0));
            }
        }
Beispiel #7
0
        /// <summary>
        /// Adds an item to this window and shifts all other elements
        /// </summary>
        /// <param name="time">The time associated with the value</param>
        /// <param name="value">The value to use to update this window</param>
        public void Add(DateTime time, decimal value)
        {
            if (_window.Samples > 0 && _window[0].EndTime == time)
            {
                return;
            }

            var item = new IndicatorDataPoint(_symbol, time, value);

            _window.Add(item);
        }
Beispiel #8
0
 private void UpdateEma(DateTime time)
 {
     if (barcount > 1)
     {
         decimal emaval = staticAlpha * Price[0].Value + (1 - staticAlpha) * ema[0].Value;
         ema.Add(idp(time, emaval));
     }
     else
     {
         ema.Add(idp(time, Price[0].Value));
     }
 }
        /// <summary>
        /// Computes the next value of this indicator from the given state
        /// </summary>
        /// <param name="input">The input given to the indicator</param>
        /// <returns>A new value for this indicator</returns>
        protected override decimal ComputeNextValue(IndicatorDataPoint input)
        {
            if (IsReady)
            {
                var output = (input.Value + 2 * (_rollingRvi[0] + _rollingRvi[1]) + _rollingRvi[2]) / 6;
                _rollingRvi.Add(input);
                return(output);
            }

            _rollingRvi.Add(input);
            return(0m);
        }
Beispiel #10
0
        public void OldDataFallsOffBackOfWindow()
        {
            var window = new RollingWindow<int>(1);
            window.Add(0);
            Assert.IsFalse(window.IsReady);

            // add one more and the window is ready

            window.Add(1);
            Assert.AreEqual(0, window.MostRecentlyRemoved);
            Assert.AreEqual(1, window.Count);
            Assert.IsTrue(window.IsReady);
        }
Beispiel #11
0
 private void UpdateZema(DateTime time)
 {
     if (barcount > 4)
     {
         decimal zemaval = staticAlpha * (Price[0].Value + estimatedVelocity * (Price[0].Value - Price[4].Value)) +
                           (1 - staticAlpha) * zema[0].Value;
         zema.Add(idp(time, zemaval));
     }
     else
     {
         zema.Add(idp(time, ema[0].Value));
     }
 }
Beispiel #12
0
        public void OldDataFallsOffBackOfWindow()
        {
            var window = new RollingWindow <int>(1);

            window.Add(0);
            Assert.IsFalse(window.IsReady);

            // add one more and the window is ready

            window.Add(1);
            Assert.AreEqual(0, window.MostRecentlyRemoved);
            Assert.AreEqual(1, window.Count);
            Assert.IsTrue(window.IsReady);
        }
Beispiel #13
0
        /// <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)
        {
            // Add SPY TradeBar in rollling window
            _window.Add(data["SPY"]);

            // Wait for windows to be ready.
            if (!_window.IsReady || !_smaWin.IsReady)
            {
                return;
            }

            var currBar = _window[0];                   // Current bar had index zero.
            var pastBar = _window[1];                   // Past bar has index one.

            Log($"Price: {pastBar.Time} -> {pastBar.Close} ... {currBar.Time} -> {currBar.Close}");

            var currSma = _smaWin[0];                   // Current SMA had index zero.
            var pastSma = _smaWin[_smaWin.Count - 1];   // Oldest SMA has index of window count minus 1.

            Log($"SMA: {pastSma.Time} -> {pastSma.Value} ... {currSma.Time} -> {currSma.Value}");

            if (!Portfolio.Invested && currSma > pastSma)
            {
                SetHoldings("SPY", 1);
            }
        }
        public DIFStrategy(Indicator Price, int DecyclePeriod = 20, int InvFisherPeriod = 40, decimal Threshold = 0.9m, decimal Tolerance = 0.001m)
        {
            // Initialize the fields.
            _decyclePeriod = DecyclePeriod;
            _invFisherPeriod = InvFisherPeriod;
            _threshold = Threshold;
            _tolerance = Tolerance;

            // Initialize the indicators used by the Strategy.
            _price = Price;
            DecycleTrend = new Decycle(_decyclePeriod).Of(Price);
            InverseFisher = new InverseFisherTransform(_invFisherPeriod).Of(DecycleTrend);
            InvFisherRW = new RollingWindow<decimal>(2);

            LightSmoothPrice = new Decycle(10).Of(Price);
            Momersion = new MomersionIndicator(10, 30).Of(LightSmoothPrice, false);

            // Fill the Inverse Fisher rolling windows at every new InverseFisher observation.
            // Once the Inverse Fisher rolling windows is ready, at every InverseFisher update, the Check signal method will be called.
            InverseFisher.Updated += (object sender, IndicatorDataPoint updated) =>
            {
                if (InverseFisher.IsReady) InvFisherRW.Add(updated);
                if (InvFisherRW.IsReady) CheckSignal();
            };

            Position = StockState.noInvested;
            EntryPrice = null;
            ActualSignal = OrderSignal.doNothing;
        }
Beispiel #15
0
            /// <summary>
            /// Main constructor for the class
            /// </summary>
            /// <param name="rangePeriod">Range period</param>
            /// <param name="consolidatorResolution">Time length of consolidator</param>
            public SymbolData(int rangePeriod, TimeSpan consolidatorResolution)
            {
                _rangeWindow  = new RollingWindow <TradeBar>(rangePeriod);
                _consolidator = new TradeBarConsolidator(consolidatorResolution);

                // event fired at new consolidated trade bar
                _consolidator.DataConsolidated += (sender, consolidated) =>
                {
                    // add new tradebar to
                    _rangeWindow.Add(consolidated);

                    if (IsReady)
                    {
                        var hh = _rangeWindow.Select(x => x.High).Max();
                        var hc = _rangeWindow.Select(x => x.Close).Max();
                        var lc = _rangeWindow.Select(x => x.Close).Min();
                        var ll = _rangeWindow.Select(x => x.Low).Min();

                        Range = Math.Max(hh - lc, hc - ll);

                        UpperLine = consolidated.Close + K1 * Range;
                        LowerLine = consolidated.Close - K2 * Range;
                    }
                };
            }
        /// <summary>
        /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
        /// </summary>
        /// <param name="data">TradeBars IDictionary object with your stock data</param>
        public void OnData(TradeBars data)
        {
            barcount++;
            var time = this.Time;

            hma7.Update(time, data[symbol].Close);
            hma14.Update(time, data[symbol].Close);
            hma28.Update(time, data[symbol].Close);
            Price.Add(idp(time, data[symbol].Close));
            UpdateInstantTrend(time);
            if (hma28.IsReady)
            {
                string logmsg = string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10}",
                                              this.Time,
                                              barcount,
                                              data[symbol].Open,
                                              data[symbol].High,
                                              data[symbol].Low,
                                              data[symbol].Close,
                                              hma7.Current.Value,
                                              hma14.Current.Value,
                                              hma28.Current.Value,
                                              instantTrend[0].Value,
                                              "");
                mylog.Debug(logmsg);
            }
        }
Beispiel #17
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CrossEMAStrategy"/> class.
        /// </summary>
        /// <param name="Price">The injected price indicator.</param>
        /// <param name="SlowEMAPeriod">The slow EMA period.</param>
        /// <param name="FastEMAPeriod">The fast EMA period.</param>
        public RSIStrategy(Indicator Price, int RSIPeriod = 40, decimal Threshold = 20)
        {
            // Initialize fields.
            _threshold   = Threshold;
            _price       = Price;
            ActualSignal = OrderSignal.doNothing;
            Position     = StockState.noInvested;
            EntryPrice   = null;

            rsi = new RelativeStrengthIndex(RSIPeriod).Of(_price);

            // Fill the RSI rolling windows at every new RSI update. Once the
            // rolling windows is ready, at every indicator update the CheckSignal method will be called.
            rsi.Updated += (object sender, IndicatorDataPoint updated) =>
            {
                if (rsi.IsReady)
                {
                    rsiRW.Add(rsi);
                }
                if (rsiRW.IsReady)
                {
                    CheckSignal();
                }
            };
        }
Beispiel #18
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CrossEMAStrategy"/> class.
        /// </summary>
        /// <param name="Price">The injected price indicator.</param>
        /// <param name="SlowEMAPeriod">The slow EMA period.</param>
        /// <param name="FastEMAPeriod">The fast EMA period.</param>
        public CrossEMAStrategy(Indicator Price, int SlowEMAPeriod = 10, int FastEMAPeriod = 50)
        {
            // Initialize fields.
            _price  = Price;
            fastEMA = new ExponentialMovingAverage(FastEMAPeriod).Of(_price);
            slowEMA = new ExponentialMovingAverage(SlowEMAPeriod).Of(_price);

            ActualSignal = OrderSignal.doNothing;
            Position     = StockState.noInvested;
            EntryPrice   = null;

            // Fill the EMA difference rolling windows at every new slowEMA observation. Once the
            // rolling windows is ready, at every indicator update the CheckSignal method will be called.
            slowEMA.Updated += (object sender, IndicatorDataPoint updated) =>
            {
                if (slowEMA.IsReady)
                {
                    EMADiffRW.Add(fastEMA - slowEMA);
                }
                if (EMADiffRW.IsReady)
                {
                    CheckSignal();
                }
            };
        }
Beispiel #19
0
        public override void OnData(Slice data)
        {
            _ama.Update(data[Symbol] as IndicatorDataPoint);

            if (!_ama.IsReady)
            {
                return;
            }

            var holdings = Portfolio[Symbol].Quantity;

            if (holdings <= 0 && _ama > _previous[0])
            {
                Log("Buy >> " + Securities[Symbol].Price);
                SetHoldings(Symbol, 1.0);
            }

            if (holdings >= 0 && _ama < _previous[0])
            {
                Log("Sell >> " + Securities[Symbol].Price);
                SetHoldings(Symbol, -1.0);
            }

            _previous.Add(_ama);
        }
        public DIFStrategy(Indicator Price, int DecyclePeriod = 20, int InvFisherPeriod = 40, decimal Threshold = 0.9m, decimal Tolerance = 0.001m)
        {
            // Initialize the fields.
            _decyclePeriod   = DecyclePeriod;
            _invFisherPeriod = InvFisherPeriod;
            _threshold       = Threshold;
            _tolerance       = Tolerance;

            // Initialize the indicators used by the Strategy.
            _price        = Price;
            DecycleTrend  = new Decycle(_decyclePeriod).Of(Price);
            InverseFisher = new InverseFisherTransform(_invFisherPeriod).Of(DecycleTrend);
            InvFisherRW   = new RollingWindow <decimal>(2);

            LightSmoothPrice = new Decycle(10).Of(Price);
            Momersion        = new MomersionIndicator(10, 30).Of(LightSmoothPrice, false);

            // Fill the Inverse Fisher rolling windows at every new InverseFisher observation.
            // Once the Inverse Fisher rolling windows is ready, at every InverseFisher update, the Check signal method will be called.
            InverseFisher.Updated += (object sender, IndicatorDataPoint updated) =>
            {
                if (InverseFisher.IsReady)
                {
                    InvFisherRW.Add(updated);
                }
                if (InvFisherRW.IsReady)
                {
                    CheckSignal();
                }
            };

            Position     = StockState.noInvested;
            EntryPrice   = null;
            ActualSignal = OrderSignal.doNothing;
        }
Beispiel #21
0
        public override void Initialize()
        {
            SetStartDate(2016, 01, 01);  //Set Start Date
            SetEndDate(2016, 10, 14);    //Set End Date
            SetCash(10000);              //Set Strategy Cash

            // Find more symbols here: http://quantconnect.com/data
            // Forex, CFD, Equities Resolutions: Tick, Second, Minute, Hour, Daily.
            // Futures Resolution: Tick, Second, Minute
            // Options Resolution: Minute Only.
            // Add each equity so we receive data
            AddEquity(_spy, Resolution.Daily);
            AddEquity(_qqq, Resolution.Daily);
            AddEquity(_tlt, Resolution.Daily);
            AddEquity(_agg, Resolution.Daily);

            //Build window
            _close_window = new RollingWindow <decimal>(84);
            IEnumerable <TradeBar> slices = History(_benchmark, 84);

            foreach (TradeBar bar in slices)
            {
                _close_window.Add(bar.Close);
            }

            // Schedule EveryDayOnMarketOpen function to be called
            // each day 10 minutes after market open
            Schedule.On(DateRules.EveryDay(_benchmark),
                        TimeRules.AfterMarketOpen(_benchmark, 10),
                        EveryDayOnMarketOpen);
        }
        // Updates this model using the new price information in the specified security instance
        // Update is a mandatory method
        public void Update(Security security, BaseData data)
        {
            var timeSinceLastUpdate = data.EndTime - _lastUpdate;

            if (timeSinceLastUpdate >= _periodSpan && data.Price > 0m)
            {
                if (_lastPrice > 0)
                {
                    _window.Add(data.Price / _lastPrice - 1.0m);
                    _needsUpdate = _window.IsReady;
                }

                _lastUpdate = data.EndTime;
                _lastPrice  = data.Price;
            }

            if (_window.Count() < 2)
            {
                Volatility = 0;
                return;
            }

            if (_needsUpdate)
            {
                _needsUpdate = false;
                var mean = _window.Average();
                var std  = Math.Sqrt((double)_window.Sum(x => (x - mean) * (x - mean)) / _window.Count());
                Volatility = Convert.ToDecimal(std * Math.Sqrt(252d));
            }
        }
Beispiel #23
0
        public void AddsData()
        {
            var window = new RollingWindow<int>(1);
            window.Add(1);
            Assert.AreEqual(1, window.Count);
            Assert.AreEqual(1, window.Samples);
            Assert.AreEqual(1, window.Size);
            Assert.IsFalse(window.IsReady);

            // add one more and the window is ready
            window.Add(2);
            Assert.AreEqual(1, window.Count);
            Assert.AreEqual(2, window.Samples);
            Assert.AreEqual(1, window.Size);
            Assert.IsTrue(window.IsReady);
        }
Beispiel #24
0
        /// <summary>
        /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
        /// </summary>
        /// <param name="data">TradeBars IDictionary object with your stock data</param>
        public void OnData(TradeBars data)
        {
            barcount++;

            // Add the history for the bar
            var time = this.Time;

            Price.Add(idp(time, (data[symbol].Close + data[symbol].Open) / 2));

            // Update the indicators
            trend.Update(idp(time, Price[0].Value));
            trendHistory.Add(CalculateNewTrendHistoryValue(barcount, time, Price, trend));
            GetOrderSignals(data);

            // Execute only the selected strategy with it's orderSignal
            foreach (SignalInfo signal in signalInfos)
            {
                if (signal.Value != OrderSignal.doNothing)
                {
                    if (signal.IsActive)
                    {
                        ExecuteStrategy(symbol, signal, data);
                    }
                }
            }
        }
Beispiel #25
0
        /// <summary>
        ///      Computes the next value of this indicator from the given state
        /// </summary>
        /// <param name="time"></param>
        /// <param name="input">The input given to the indicator</param>
        /// <returns>A new value for this indicator</returns>
        protected override DoubleArray Forward(long time, DoubleArray input)
        {
            _price.Add(input.Value);

            if (_price.Samples == 1)
            {
                _price.Add(_price[0]);
                _price.Add(_price[0]);
            }

            var signal = _a0 * _c0 * (_b0 * _price[0] + _b1 * _price[1] + _b2 * _price[2]) + _a0 * (_a1 * _filt[0] + _a2 * _filt[1]);

            _filt.Add(signal);

            return(signal);
        }
Beispiel #26
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ITrendStrategy"/> class.
        /// </summary>
        /// <param name="period">The period of the Instantaneous trend.</param>
        public MultiSymbolStrategy(Indicator price, int period, decimal tolerance = 0.001m, decimal revetPct = 1.0015m,
                                   RevertPositionCheck checkRevertPosition        = RevertPositionCheck.vsTrigger)
        {
            _price         = price;
            sma            = new SimpleMovingAverage(period).Of(price);
            SMAMomentum    = new Momentum(2).Of(sma);
            MomentumWindow = new RollingWindow <decimal>(2);

            Position     = StockState.noInvested;
            EntryPrice   = null;
            ActualSignal = OrderSignal.doNothing;

            _tolerance           = tolerance;
            _revertPCT           = revetPct;
            _checkRevertPosition = checkRevertPosition;



            SMAMomentum.Updated += (object sender, IndicatorDataPoint updated) =>
            {
                if (SMAMomentum.IsReady)
                {
                    MomentumWindow.Add(SMAMomentum.Current.Value);
                }
                if (MomentumWindow.IsReady)
                {
                    CheckSignal();
                }
            };
        }
Beispiel #27
0
        public static RollingWindow <T> Track <T>(IDataConsolidator consolidator, int historyLength = 8) where T : class
        {
            var window = new RollingWindow <T>(historyLength);

            consolidator.DataConsolidated += (sendar, args) => window.Add(args as T);
            return(window);
        }
Beispiel #28
0
        private void UpdateDailyReturn()
        {
            var spyReturn = Securities[spy].Close - _previousTradeBar.Item1.Close / _previousTradeBar.Item1.Close;
            var tltReturn = Securities[tlt].Close - _previousTradeBar.Item2.Close / _previousTradeBar.Item2.Close;

            _dailyReturns.Add(new Tuple <decimal, decimal>(spyReturn, tltReturn));
        }
Beispiel #29
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ITrendStrategy"/> class.
        /// </summary>
        /// <param name="period">The period of the Instantaneous trend.</param>
        public ITrendStrategy(Indicator price, int period, decimal tolerance = 0.001m, decimal revetPct = 1.0015m,
                              RevertPositionCheck checkRevertPosition        = RevertPositionCheck.vsTrigger)
        {
            _price         = price;
            ITrend         = new InstantaneousTrend(period).Of(price);
            ITrendMomentum = new Momentum(2).Of(ITrend);
            MomentumWindow = new RollingWindow <decimal>(2);

            Position     = StockState.noInvested;
            EntryPrice   = null;
            ActualSignal = OrderSignal.doNothing;

            _tolerance           = tolerance;
            _revertPCT           = revetPct;
            _checkRevertPosition = checkRevertPosition;

            //Sig9 sig9 = new Sig9();

            ITrendMomentum.Updated += (object sender, IndicatorDataPoint updated) =>
            {
                if (ITrendMomentum.IsReady)
                {
                    MomentumWindow.Add(ITrendMomentum.Current.Value);
                }
                if (MomentumWindow.IsReady)
                {
                    CheckSignal();
                }
            };
        }
        public override void Initialize()
        {
            SetStartDate(2013, 10, 07);
            SetEndDate(2013, 10, 11);

            SPY = AddEquity("SPY", Resolution.Minute).Symbol;

            // define indicators on SPY daily closing prices
            SPY_Close       = Identity(SPY, Resolution.Daily);
            SPY_Close_EMA10 = SPY_Close.EMA(10);
            SPY_Close_EMA50 = SPY_Close.EMA(50);

            // each time an indicator is updated, push the value into our history rolling windows
            SPY_Close.Updated += (sender, args) =>
            {
                // each time we receive new closing price data, push our window to the object store
                SPY_Close_History.Add(args);
            };

            SPY_Close_EMA10.Updated += (sender, args) => SPY_Close_EMA10_History.Add(args);
            SPY_Close_EMA50.Updated += (sender, args) => SPY_Close_EMA50_History.Add(args);

            if (ObjectStore.ContainsKey(SPY_Close_ObjectStore_Key))
            {
                // our object store has our historical data saved, read the data
                // and push it through the indicators to warm everything up
                var values = ObjectStore.ReadJson <IndicatorDataPoint[]>(SPY_Close_ObjectStore_Key);
                Debug($"{SPY_Close_ObjectStore_Key} key exists in object store. Count: {values.Length}");

                foreach (var value in values)
                {
                    SPY_Close.Update(value);
                }
            }
            else
            {
                Debug($"{SPY_Close_ObjectStore_Key} key does not exist in object store. Fetching history...");

                // if our object store doesn't have our data, fetch the history to initialize
                // we're pulling the last year's worth of SPY daily trade bars to fee into our indicators
                var history = History(SPY, TimeSpan.FromDays(365), Resolution.Daily);

                foreach (var tradeBar in history)
                {
                    SPY_Close.Update(tradeBar.EndTime, tradeBar.Close);
                }

                // save our warm up data so next time we don't need to issue the history request
                var array = SPY_Close_History.Reverse().ToArray();
                ObjectStore.SaveJson(SPY_Close_ObjectStore_Key, array);

                // Can also use ObjectStore.SaveBytes(key, byte[])
                // and to read  ObjectStore.ReadBytes(key) => byte[]

                // we can also get a file path for our data. some ML libraries require model
                // weights to be loaded directly from a file path. The object store can provide
                // a file path for any key by: ObjectStore.GetFilePath(key) => string (file path)
            }
        }
            /// <summary>
            /// Calculate position value and update the SMA indicator and Rolling Window
            /// </summary>
            private bool UpdateIndicators(Slice data)
            {
                var positionValue = (_alpha * data[_longSymbol].Close) - (_beta * data[_shortSymbol].Close);

                _sma.Update(data[_longSymbol].EndTime, positionValue);
                _positionWindow.Add(positionValue);
                return(_sma.IsReady && _positionWindow.IsReady);
            }
        public void WhenAddingItem_Then_IndexZero_IsEqualToItem()
        {
            const int item = 3;
            var       sut  = new RollingWindow <int>(1);

            sut.Add(item);
            Assert.AreEqual(item, sut[0]);
        }
 private void UpdateInstantTrend(DateTime time)
 {
     if (barcount > 2)
     {
         // From Ehlers page 16 equation 2.9
         var it = (a - ((a / 2) * (a / 2))) * Price[0].Value + ((a * a) / 2) * Price[1].Value
                  - (a - (3 * (a * a) / 4)) * Price[2].Value + 2 * (1 - a) * instantTrend[0].Value
                  - ((1 - a) * (1 - a)) * instantTrend[1].Value;
         instantTrend.Add(idp(time, it));
         //instantTrendTrigger.Add(idp(time, instantTrend[2].Value));
     }
     else
     {
         instantTrend.Add(idp(time, Price[0].Value));
         //instantTrendTrigger.Add(idp(time, Price[0].Value));
     }
 }
Beispiel #34
0
        public void AddsData()
        {
            var window = new RollingWindow <int>(1);

            window.Add(1);
            Assert.AreEqual(1, window.Count);
            Assert.AreEqual(1, window.Samples);
            Assert.AreEqual(1, window.Size);
            Assert.IsFalse(window.IsReady);

            // add one more and the window is ready
            window.Add(2);
            Assert.AreEqual(1, window.Count);
            Assert.AreEqual(2, window.Samples);
            Assert.AreEqual(1, window.Size);
            Assert.IsTrue(window.IsReady);
        }
Beispiel #35
0
        public void AddTest()
        {
            RollingWindow<int> rollingWindow = new RollingWindow<int>(5);

            for (int i = 0; i < rollingWindow.WindowSize; i++)
            {
                Assert.AreEqual(i, rollingWindow.Count);
                rollingWindow.Add(i);
                Assert.AreEqual(i, rollingWindow[i]);
            }

            Assert.AreEqual(rollingWindow.WindowSize, rollingWindow.Count);
            rollingWindow.Add(rollingWindow.WindowSize);
            Assert.AreEqual(rollingWindow.WindowSize, rollingWindow.Count);

            for (int i = 0; i < rollingWindow.WindowSize; i++)
                Assert.AreEqual(i + 1, rollingWindow[i]);
        }
Beispiel #36
0
        public void RemoveTest()
        {
            RollingWindow<int> rollingWindow = new RollingWindow<int>(5);

            for (int i = 0; i < rollingWindow.WindowSize; i++)
                rollingWindow.Add(i);

            rollingWindow.Remove(1);
            rollingWindow.Remove(3);

            Assert.AreEqual(3, rollingWindow.Count);
            Assert.AreEqual(0, rollingWindow[0]);
            Assert.AreEqual(2, rollingWindow[1]);
            Assert.AreEqual(4, rollingWindow[2]);
        }
Beispiel #37
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ITrendStrategy"/> class.
        /// </summary>
        /// <param name="period">The period of the Instantaneous trend.</param>
        public ITrendStrategyJJ(Indicator price, int period, decimal tolerance = 0.001m, decimal revetPct = 1.0015m,
            RevertPositionCheck checkRevertPosition = RevertPositionCheck.vsTrigger)
        {
            _price = price;
            ITrend = new InstantaneousTrend(period).Of(price);
            ITrendMomentum = new Momentum(2).Of(ITrend);
            MomentumWindow = new RollingWindow<decimal>(2);

            Position = StockState.noInvested;
            EntryPrice = null;
            ActualSignal = OrderSignal.doNothing;

            _tolerance = tolerance;
            _revertPCT = revetPct;
            _checkRevertPosition = checkRevertPosition;

            ITrendMomentum.Updated += (object sender, IndicatorDataPoint updated) =>
            {
                if (ITrendMomentum.IsReady) MomentumWindow.Add(ITrendMomentum.Current.Value);
                if (MomentumWindow.IsReady) CheckSignal();
            };
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ITrendStrategy"/> class.
        /// </summary>
        /// <param name="period">The period of the Instantaneous trend.</param>
        public MultiSymbolStrategy(Indicator price, int period, decimal tolerance = 0.001m, decimal revetPct = 1.0015m,
            RevertPositionCheck checkRevertPosition = RevertPositionCheck.vsTrigger)
        {
            _price = price;
            sma = new SimpleMovingAverage(period).Of(price);
            SMAMomentum = new Momentum(2).Of(sma);
            MomentumWindow = new RollingWindow<decimal>(2);

            Position = StockState.noInvested;
            EntryPrice = null;
            ActualSignal = OrderSignal.doNothing;

            _tolerance = tolerance;
            _revertPCT = revetPct;
            _checkRevertPosition = checkRevertPosition;

            SMAMomentum.Updated += (object sender, IndicatorDataPoint updated) =>
            {
                if (SMAMomentum.IsReady) MomentumWindow.Add(SMAMomentum.Current.Value);
                if (MomentumWindow.IsReady) CheckSignal();
            };
        }
Beispiel #39
0
        /// <summary>
        /// The Deserializing constuctor
        /// </summary>
        /// <param name="info">the bag into which the serialized data was put</param>
        /// <param name="context">the stream to get the data from.</param>
        public Sig2(SerializationInfo info, StreamingContext context)
        {
            string s = (string)info.GetValue("Symbol", typeof(string));
            _symbol = new Symbol(s);
            //_algorithm = (QCAlgorithm)info.GetValue("algorithm", typeof(QCAlgorithm));
            Id = (int)info.GetValue("Id", typeof(int));

            trendHistory = new RollingWindow<decimal>(3);
            nEntryPrice = (decimal)info.GetValue("nEntryPrice", typeof(decimal));
            xOver = (int)info.GetValue("xOver", typeof(int));
            nTrig = (decimal)info.GetValue("nTrig", typeof(decimal));
            orderFilled = (Boolean)info.GetValue("orderFilled", typeof(Boolean));
            maketrade = (Boolean)info.GetValue("maketrade", typeof(Boolean));
            trendArray = (decimal[])info.GetValue("trendArray", typeof(decimal[]));
            foreach (decimal t in trendArray)
            {
                trendHistory.Add(t);
            }
            RevPct = 1.0015m;
            RngFac = .35m;
        }
Beispiel #40
0
        public void IndexOfTest()
        {
            RollingWindow<int> rollingWindow = new RollingWindow<int>(5);

            for (int i = 0; i < rollingWindow.WindowSize; i++)
                rollingWindow.Add(i);

            for (int i = 0; i < rollingWindow.WindowSize; i++)
                Assert.AreEqual(i, rollingWindow.IndexOf(i));
        }
Beispiel #41
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MSAStrategy" /> class.
        /// </summary>
        /// <param name="smoothedSeries">The smoothed series.</param>
        /// <param name="previousDaysN">How many daily means will be used to estimate the thresholds.</param>
        /// <param name="runsPerDay">How many runs will be used to estimate the daily mean.</param>
        /// <param name="minRunThreshold">The minimum run threshold.</param>
        /// <param name="DailyIndicatorReset">if set to <c>true</c> [daily indicator reset].</param>
        public MSAStrategy(IndicatorBase<IndicatorDataPoint> smoothedSeries, int previousDaysN = 3, int runsPerDay = 5, decimal minRunThreshold = 0.0001m, bool DailyIndicatorReset = true)
        {
            _runsPerDay = runsPerDay;
            _actualRun = 1m;
            _turnAround = false;
            _minRunThreshold = minRunThreshold;
            _dailyIndicatorReset = DailyIndicatorReset;

            _smoothedSeries = smoothedSeries;
            _smoothedSeriesROC = new RateOfChange(1).Of(_smoothedSeries);
            _SSROCRW = new RollingWindow<IndicatorDataPoint>(2);

            _todayRuns = new List<decimal>();
            _previousDaysDownwardRuns = new RollingWindow<decimal>(previousDaysN);
            _previousDaysUpwardRuns = new RollingWindow<decimal>(previousDaysN);

            ActualSignal = OrderSignal.doNothing;
            Position = StockState.noInvested;

            _smoothedSeriesROC.Updated += (object sender, IndicatorDataPoint updated) =>
                {
                    if (_smoothedSeriesROC.IsReady) _SSROCRW.Add(updated);
                    if (_SSROCRW.IsReady) RunStrategy();
                    if (_SSROCRW.IsReady && IsReady) CheckSignal();
                };
        }
Beispiel #42
0
        public void ContainsTest()
        {
            RollingWindow<int> rollingWindow = new RollingWindow<int>(5);

            for (int i = 0; i < rollingWindow.WindowSize; i++)
                rollingWindow.Add(i);

            for (int i = -5; i < 10; i++)
                Assert.AreEqual((i >= 0) && (i < 5), rollingWindow.Contains(i));
        }
Beispiel #43
0
        public Sig10Strategy(SecurityHolding sym, Indicator priceIdentity, int trendPeriod, decimal lossThreshhold, decimal tolerance, decimal revertPct)
        {

            trendArray = new decimal[trendPeriod + 1];       // initialized to 0.  Add a period for Deserialize to make IsReady true

            symbol = sym.Symbol;
            _holding = sym;
            _price = priceIdentity;
            _period = trendPeriod;
            _lossThreshhold = lossThreshhold;
            _tolerance = tolerance;
            RevPct = revertPct;
            Trend = new InstantaneousTrend(sym.Symbol.Value, 7, .24m).Of(priceIdentity);
            TrendMomentum = new Momentum(2).Of(Trend);
            MomentumWindow = new RollingWindow<decimal>(2);
            ActualSignal = OrderSignal.doNothing;

            Trend.Updated += (object sender, IndicatorDataPoint updated) =>
            {
                Barcount++;
                UpdateTrendArray(Trend.Current.Value);
                nTrig = Trend.Current.Value;
                if (Trend.IsReady)
                {
                    TrendMomentum.Update(Trend.Current);
                }
                if (TrendMomentum.IsReady) 
                    MomentumWindow.Add(TrendMomentum.Current.Value);
                if (MomentumWindow.IsReady) 
                    CheckSignal();
            };
        }
Beispiel #44
0
        public void CopyToTest()
        {
            RollingWindow<int> rollingWindow = new RollingWindow<int>(5);
            int[] array = new int[rollingWindow.WindowSize];

            for (int i = 0; i < rollingWindow.WindowSize + 1; i++)
                rollingWindow.Add(i);

            rollingWindow.CopyTo(array, 0);

            for (int i = 0; i < array.Length; i++)
                Assert.AreEqual(i + 1, array[i]);
        }
Beispiel #45
0
        /// <summary>
        /// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.
        /// </summary>
        /// <seealso cref="QCAlgorithm.SetStartDate(System.DateTime)"/>
        /// <seealso cref="QCAlgorithm.SetEndDate(System.DateTime)"/>
        /// <seealso cref="QCAlgorithm.SetCash(decimal)"/>
        public override void Initialize()
        {
            //            mylog.Debug(",CurrentBar,Time,Price,smooth,low,i1,cycle0,cycle1,cycle2,fish,medianDelta,DC,instaperiod, v2,DCPeriod,realpart,imagpart,dcphase");
            mylog.Debug(ondataheader);
            //mylog.Debug(",Time,CurrentBar,Direction,TradeProfit,,Price,Profit,HoldingCost,FillQty,Fees,TransAmt");
            //mylog.Debug(transheader);
            //Initialize
            SetStartDate(2015, 05, 12);
            SetEndDate(2015, 05, 12);
            SetCash(25000);

            //Add as many securities as you like. All the data will be passed into the event handler:
            AddSecurity(SecurityType.Equity, _symbol, Resolution.Minute);

            _indicators = new AlgoIndicators
            {
                //BB = BB(_symbol, 20, 1, MovingAverageType.Simple, Resolution.Daily),
                RSI = RSI(_symbol, 14, MovingAverageType.Simple, Resolution.Daily),
                //ATR = ATR(_symbol, 14, MovingAverageType.Simple, Resolution.Daily),
                //EMA = EMA(_symbol, 14, Resolution.Daily),
                //SMA = SMA(_symbol, 14, Resolution.Daily),
                MACD = MACD(_symbol, 12, 26, 9, MovingAverageType.Simple, Resolution.Minute)
                //AROON = AROON(_symbol, 20, Resolution.Daily),
                //MOM = MOM(_symbol, 20, Resolution.Daily),
                //MOMP = MOMP(_symbol, 20, Resolution.Daily),
                //STD = STD(_symbol, 20, Resolution.Daily),
                //MIN = MIN(_symbol, 14, Resolution.Daily), // by default if the symbol is a tradebar type then it will be the min of the low property
                //MAX = MAX(_symbol, 14, Resolution.Daily),  // by default if the symbol is a tradebar type then it will be the max of the high property

                //open = new WindowIndicator<IndicatorDataPoint>(4)
                //Ft = FT(_symbol, samplesize, Resolution.Minute),
                //Rvi = RVI(_symbol, samplesize, Resolution.Minute)

            };
            //open = new RollingWindow<IndicatorDataPoint>(samplesize);
            //close = new RollingWindow<IndicatorDataPoint>(samplesize);
            //high = new RollingWindow<IndicatorDataPoint>(samplesize);
            //low = new RollingWindow<IndicatorDataPoint>(samplesize);
            //i1 = new RollingWindow<IndicatorDataPoint>(samplesize);
            //instperiod = new RollingWindow<IndicatorDataPoint>(samplesize);
            //v2 = new RollingWindow<IndicatorDataPoint>(samplesize);
            //v1 = new RollingWindow<IndicatorDataPoint>(samplesize);
            //Rvi = new RollingWindow<IndicatorDataPoint>(samplesize);
            unrealized = new RollingWindow<IndicatorDataPoint>(samplesize);
            iFishes = new RollingWindow<IndicatorDataPoint>(samplesize);
            RsiHistory = new RollingWindow<IndicatorDataPoint>(samplesize);
            //Signal = new RollingWindow<IndicatorDataPoint>(samplesize);
            //maxRvi = new Maximum("RVI_Max", samplesize);
            //minRvi = new Minimum("RVi_Min", samplesize);
            //maxSignal = new Maximum("Sig_Max", samplesize);
            //minSignal = new Minimum("Sig_Min", samplesize);
            fish = new FisherTransform(samplesize);
            ifish = new InverseFisherTransform(samplesize);
            //Crossing = new RollingWindow<IndicatorDataPoint>(samplesize);
            //FisherHistory = new RollingWindow<IndicatorDataPoint>(samplesize);
            Rvi = new RelativeVigorIndex(_symbol, samplesize);

            for (int x = 0; x < samplesize; x++)
            {
                //open.Add(new IndicatorDataPoint(DateTime.MinValue, 0m));
                //close.Add(new IndicatorDataPoint(DateTime.MinValue, 0m));
                //high.Add(new IndicatorDataPoint(DateTime.MinValue, 0m));
                //low.Add(new IndicatorDataPoint(DateTime.MinValue, 0m));
                //i1.Add(new IndicatorDataPoint(DateTime.MinValue, 0m));
                //instperiod.Add(new IndicatorDataPoint(DateTime.MinValue, 0m));
                //v1.Add(new IndicatorDataPoint(DateTime.MinValue, 0m));
                //v2.Add(new IndicatorDataPoint(DateTime.MinValue, 0m));
                //Rvi.Add(new IndicatorDataPoint(DateTime.MinValue, 0m));
                unrealized.Add(new IndicatorDataPoint(DateTime.MinValue, 0m));
                iFishes.Add(new IndicatorDataPoint(DateTime.MinValue, 0m));
                //Signal.Add(new IndicatorDataPoint(DateTime.MinValue, 0m));
                //Crossing.Add(new IndicatorDataPoint(DateTime.MinValue, .0001m));

            }
        }
Beispiel #46
0
        public void RetievesNonZeroIndexProperlyAfterReset()
        {
            var window = new RollingWindow<int>(3);
            window.Add(0);
            Assert.AreEqual(1, window.Count);
            Assert.AreEqual(0, window[0]);

            window.Add(1);
            Assert.AreEqual(2, window.Count);
            Assert.AreEqual(0, window[1]);
            Assert.AreEqual(1, window[0]);

            window.Add(2);
            Assert.AreEqual(3, window.Count);
            Assert.AreEqual(0, window[2]);
            Assert.AreEqual(1, window[1]);
            Assert.AreEqual(2, window[0]);

            window.Add(3);
            Assert.AreEqual(3, window.Count);
            Assert.AreEqual(1, window[2]);
            Assert.AreEqual(2, window[1]);
            Assert.AreEqual(3, window[0]);

            window.Reset();
            window.Add(0);
            Assert.AreEqual(1, window.Count);
            Assert.AreEqual(0, window[0]);

            window.Add(1);
            Assert.AreEqual(2, window.Count);
            Assert.AreEqual(0, window[1]);
            Assert.AreEqual(1, window[0]);

            window.Add(2);
            Assert.AreEqual(3, window.Count);
            Assert.AreEqual(0, window[2]);
            Assert.AreEqual(1, window[1]);
            Assert.AreEqual(2, window[0]);

            window.Add(3);
            Assert.AreEqual(3, window.Count);
            Assert.AreEqual(1, window[2]);
            Assert.AreEqual(2, window[1]);
            Assert.AreEqual(3, window[0]);
        }
        /// <summary>
        /// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.
        /// </summary>
        /// <seealso cref="QCAlgorithm.SetStartDate(System.DateTime)"/>
        /// <seealso cref="QCAlgorithm.SetEndDate(System.DateTime)"/>
        /// <seealso cref="QCAlgorithm.SetCash(decimal)"/>
        public override void Initialize()
        {
            //mylog.Debug(transheader);
            mylog.Debug(ondataheader);

            //Initialize dates
            SetStartDate(2013, 10, 07);
            SetEndDate(2013, 10, 07);
            SetCash(25000);

            //Add as many securities as you like. All the data will be passed into the event handler:
            AddSecurity(SecurityType.Equity, _symbol, Resolution.Minute);

            maxHigh = new Maximum("MaxHigh", _period);
            minLow = new Minimum("MinLow", _period);
            value1 = new RollingWindow<IndicatorDataPoint>(_period);
            fish = new RollingWindow<IndicatorDataPoint>(_period);
            //wma = new LinearWeightedMovingAverage(5);       // induces 2 bar lag
            //wwma = new RollingWindow<IndicatorDataPoint>(_period);
            //fishHigh = new Maximum("FishHigh", 400);
            //fishLow = new Minimum("FishLow", 400);
            fx = new FisherTransform(_symbol,_period);
            //fx = FT(_symbol, _period, Resolution.Minute);

            // Add a bars to initialize the RollingWindow
            value1.Add(new IndicatorDataPoint(DateTime.MinValue, .0001m));
            value1.Add(new IndicatorDataPoint(DateTime.MinValue, .0001m));
            fish.Add(new IndicatorDataPoint(DateTime.MinValue, 0m));
            fish.Add(new IndicatorDataPoint(DateTime.MinValue, 0m));
            //wwma.Add(new IndicatorDataPoint(DateTime.MinValue, .0001m));
            //wwma.Add(new IndicatorDataPoint(DateTime.MinValue, .0001m));
        }
Beispiel #48
0
        public void ClearTest()
        {
            RollingWindow<int> rollingWindow = new RollingWindow<int>(5);

            for (int i = 0; i < rollingWindow.WindowSize; i++)
                rollingWindow.Add(i);

            Assert.AreEqual(rollingWindow.WindowSize, rollingWindow.Count);
            rollingWindow.Clear();
            Assert.AreEqual(0, rollingWindow.Count);
        }
Beispiel #49
0
        public void GetEnumeratorTest()
        {
            RollingWindow<int> rollingWindow = new RollingWindow<int>(5);
            int count = 0;

            for (int i = 0; i < rollingWindow.WindowSize + 1; i++)
                rollingWindow.Add(i);

            foreach (int i in rollingWindow)
                Assert.AreEqual(++count, i);
        }
        private Rectangle FindBoardBounds()
        {
            const int fromTop = 150;
            const int fromLeft = 90;
            const int width = 180;
            const int height = 360;

            int left = 0;
            int top = 0;

            {
                RollingWindow<int> lums = new RollingWindow<int>(10);
                for (int i = (int)(fromLeft * .9); i < fromTop * 1.1; i++)
                {
                    Color c = _bitmap.GetPixel(app.X + fromLeft + (width / 2), app.Y + i);

                    lums.Add((int)(c.GetBrightness() * 100));

                    if (lums.HasValue(2))
                    {
                        if (lums.Get(2) == 0 && lums.Get(1) == 16 && lums.Get(0) == 13)
                        {
                            top = i;
                            break;
                        }
                    }
                }
            }

            {
                RollingWindow<int> lums = new RollingWindow<int>(10);
                for (int i = (int)(fromLeft * .9); i < fromLeft * 1.1; i++)
                {
                    Color c = _bitmap.GetPixel(app.X + i, app.Y + fromTop + (height / 2));

                    lums.Add((int)(c.GetBrightness() * 100));

                    if (lums.HasValue(1))
                    {
                        if (lums.Get(1) == 0 && lums.Get(0) == 13)
                        {
                            left = i;
                            break;
                        }
                    }
                }
            }

            return new Rectangle(new Point(app.X + left, app.Y + top), new Size(width, height));
        }