예제 #1
0
        /// <summary>Integrate the series over the index range [index0,index1)</summary>
        public static double Integrate(this DataSeries series, Idx index0, Idx index1)
        {
            if (index0 > index1)
            {
                throw new Exception("Invalid index range: [{0},{1})".Fmt(index0, index1));
            }

            var idx0 = (int)(index0 + series.Count - 1);
            var idx1 = (int)(index1 + series.Count - 1);

            idx0 = Maths.Clamp(idx0, 0, series.Count);
            idx1 = Maths.Clamp(idx1, 0, series.Count);

            var sum = 0.0;

            for (int i = idx0; i != idx1; ++i)
            {
                sum += series[i];
            }

            return(sum);
        }
예제 #2
0
 public StationaryPoint(Idx index, QuoteCurrency price, int sign)
 {
     Index = index;
     Price = price;
     Sign  = sign;
 }
예제 #3
0
 [DebuggerStepThrough] public bool Within(Idx min, Idx max)
 {
     return(Index.Within(min, max));
 }
예제 #4
0
 public FutureIdx(Idx idx, double confidence) : this()
 {
     Index      = idx;
     Confidence = confidence;
 }
예제 #5
0
        /// <summary>Returns the price peaks using a window with size 'window_size'</summary>
        public IEnumerable <Peak> FindPeaks(Idx iend)
        {
            // Create window buffers for the high/low prices
            var price_hi = new QuoteCurrency[WindowSize];
            var price_lo = new QuoteCurrency[WindowSize];

            for (int i = 0; i != WindowSize; ++i)
            {
                price_hi[i] = -double.MaxValue;
                price_lo[i] = +double.MaxValue;
            }

            // Look for peaks
            int d = 0, hh = -1, ll = -1, hcount = 0, lcount = 0;

            for (Idx i = iend; i-- != Instrument.IdxFirst; d = (d + 1) % WindowSize)
            {
                var candle = Instrument[i];
                Beg = i;

                // Add the new price values
                price_hi[d] = candle.High;
                price_lo[d] = candle.Low;

                // Find the ring buffer index of the highest and lowest price
                var h = price_hi.IndexOfMaxBy(x => x);
                var l = price_lo.IndexOfMinBy(x => x);

                // If the high is the highest for the full window size, output it
                if (hh == h)
                {
                    if (++hcount == WindowSize)
                    {
                        // Skip index == 0 because it's not a complete candle
                        var idx = i + (d - hh + WindowSize) % WindowSize;
                        if (Instrument.IdxLast - idx > 1)
                        {
                            yield return(new Peak(idx, price_hi[hh], true));
                        }
                        hh     = -1;
                        hcount = 0;
                    }
                }
                else
                {
                    hh     = h;
                    hcount = 1;
                }

                // If the low is the lowest for the full window size, output it
                if (ll == l)
                {
                    if (++lcount == WindowSize)
                    {
                        // Skip index == 0 because it's not a complete candle
                        var idx = i + (d - ll + WindowSize) % WindowSize;
                        if (Instrument.IdxLast - idx > 1)
                        {
                            yield return(new Peak(idx, price_lo[ll], false));
                        }
                        ll     = -1;
                        lcount = 0;
                    }
                }
                else
                {
                    ll     = l;
                    lcount = 1;
                }
            }
        }
예제 #6
0
 public Peak(Idx index, QuoteCurrency price, bool high)
 {
     Index = index;
     Price = price;
     High  = high;
 }
예제 #7
0
        // Notes:
        //  - price is trending up if the lows are getting higher
        //  - price is trending down if the highs are getting lower
        //  - trend is unknown otherwise
        //  - Break outs can be detected by comparing two sets of price peaks

        /// <summary>Find the highs and lows of the price</summary>
        /// <param name="instr">The instrument to find peaks in</param>
        /// <param name="iend">The last candle, i.e. look backwards from here</param>
        public PricePeaks(Instrument instr, Idx iend, int window_size = 5)
        {
            Instrument   = instr;
            WindowSize   = window_size;
            ConfirmTrend = 0.5;
            Beg          = iend;
            End          = iend;
            Highs        = new List <Peak>();
            Lows         = new List <Peak>();

            #region Find peaks
            {
                var threshold = ConfirmTrend * Instrument.MCS;
                var corr_hi   = new Correlation();
                var corr_lo   = new Correlation();

                // The last high/low encountered
                var hi = (Peak)null;
                var lo = (Peak)null;

                var done_hi = false;
                var done_lo = false;

                // Iterate through the peaks
                foreach (var pk in FindPeaks(iend))
                {
                    // Save the first peak as it might be a break out
                    if (FirstPeak == null)
                    {
                        FirstPeak = pk;
                        continue;
                    }

                    var last  = pk.High ? hi        : lo;
                    var peaks = pk.High ? Highs     : Lows;
                    var corr  = pk.High ? corr_hi   : corr_lo;
                    var trend = pk.High ? TrendHigh : TrendLow;
                    var done  = pk.High ? done_hi   : done_lo;

                    // First peak encountered?
                    if (last == null)
                    {
                        // Just save the peak
                        corr.Add(pk.Index, pk.Price);
                        peaks.Add(pk);
                    }
                    // The trend has not been broken
                    else if (!done)
                    {
                        // Second peak encountered
                        if (trend == null)
                        {
                            // Form a trend line between the peaks
                            if (pk.High)
                            {
                                TrendHigh = Monic.FromPoints(pk.Index, pk.Price, last.Index, last.Price);
                            }
                            else
                            {
                                TrendLow = Monic.FromPoints(pk.Index, pk.Price, last.Index, last.Price);
                            }
                            corr.Add(pk.Index, pk.Price);
                            peaks.Add(pk);
                        }
                        // 3+ peak encountered, confirm trend strength
                        else
                        {
                            // Get the predicted value from the trend line
                            var p = trend.F(pk.Index);
                            if (Math.Abs(p - pk.Price) < threshold)
                            {
                                // If within tolerance, the trend is confirmed
                                corr.Add(pk.Index, pk.Price);
                                if (pk.High)
                                {
                                    TrendHigh = corr.LinearRegression;
                                }
                                else
                                {
                                    TrendLow = corr.LinearRegression;
                                }
                                peaks.Add(pk);
                            }
                            else
                            {
                                if (pk.High)
                                {
                                    done_hi = true;
                                }
                                else
                                {
                                    done_lo = true;
                                }

                                // Otherwise, if the trend does not have 3 points, it is rejected
                                if (peaks.Count < 3)
                                {
                                    if (pk.High)
                                    {
                                        TrendHigh = null;
                                    }
                                    else
                                    {
                                        TrendLow = null;
                                    }
                                }
                            }
                        }
                    }

                    // Save the peak as last
                    if (pk.High)
                    {
                        hi = pk;
                    }
                    else
                    {
                        lo = pk;
                    }

                    // If the high and low trends are done, break the loop
                    if (done_hi && done_lo)
                    {
                        break;
                    }
                }
            }
            #endregion
        }
예제 #8
0
 /// <summary>Get the second derivative at 'idx'</summary>
 public double ddF(Idx idx)
 {
     return(Curve.ddF(idx));
 }
예제 #9
0
 /// <summary>Get the predicted value</summary>
 public double this[Idx idx]
 {
     get { return(Curve.F(idx)); }
 }
예제 #10
0
 /// <summary>Return the second derivative of the data series at 'index'</summary>
 public double SecondDerivative(Idx idx, int series = 0)
 {
     return(Source[series].SecondDerivative(idx));
 }
예제 #11
0
 /// <summary>Return the first derivative of the data series at 'index'</summary>
 public double FirstDerivative(Idx idx, int series = 0)
 {
     return(Source[series].FirstDerivative(idx));
 }