예제 #1
0
    public void Removed()
    {
        int lookbackPeriods      = 14;
        List <MfiResult> results = quotes.GetMfi(lookbackPeriods)
                                   .RemoveWarmupPeriods()
                                   .ToList();

        // assertions
        Assert.AreEqual(502 - 14, results.Count);

        MfiResult last = results.LastOrDefault();

        Assert.AreEqual(39.9494m, Math.Round((decimal)last.Mfi, 4));
    }
예제 #2
0
    public void Standard()
    {
        int lookbackPeriods      = 14;
        List <MfiResult> results = quotes.GetMfi(lookbackPeriods).ToList();

        // assertions

        // proper quantities
        // should always be the same number of results as there is quotes
        Assert.AreEqual(502, results.Count);
        Assert.AreEqual(488, results.Where(x => x.Mfi != null).Count());

        // sample values
        MfiResult r1 = results[439];

        Assert.AreEqual(69.0622m, Math.Round((decimal)r1.Mfi, 4));

        MfiResult r2 = results[501];

        Assert.AreEqual(39.9494m, Math.Round((decimal)r2.Mfi, 4));
    }
예제 #3
0
        public void GetMfiTest()
        {
            int lookbackPeriod = 14;
            IEnumerable <MfiResult> results = Indicator.GetMfi(history, lookbackPeriod);

            // assertions

            // proper quantities
            // should always be the same number of results as there is history
            Assert.AreEqual(502, results.Count());
            Assert.AreEqual(502 - lookbackPeriod, results.Where(x => x.Mfi != null).Count());

            // sample values
            MfiResult r1 = results.Where(x => x.Index == 502).FirstOrDefault();

            Assert.AreEqual(39.9494m, Math.Round((decimal)r1.Mfi, 4));

            MfiResult r2 = results.Where(x => x.Index == 440).FirstOrDefault();

            Assert.AreEqual(69.0622m, Math.Round((decimal)r2.Mfi, 4));
        }
예제 #4
0
        public void GetMfiSmall()
        {
            int lookbackPeriod       = 4;
            List <MfiResult> results = Indicator.GetMfi(history, lookbackPeriod).ToList();

            // assertions

            // proper quantities
            // should always be the same number of results as there is history
            Assert.AreEqual(502, results.Count);
            Assert.AreEqual(502 - lookbackPeriod, results.Where(x => x.Mfi != null).Count());

            // sample values
            MfiResult r1 = results[31];

            Assert.AreEqual(100m, Math.Round((decimal)r1.Mfi, 4));

            MfiResult r2 = results[43];

            Assert.AreEqual(0m, Math.Round((decimal)r2.Mfi, 4));
        }
예제 #5
0
    // MONEY FLOW INDEX
    /// <include file='./info.xml' path='indicator/*' />
    ///
    public static IEnumerable <MfiResult> GetMfi <TQuote>(
        this IEnumerable <TQuote> quotes,
        int lookbackPeriods = 14)
        where TQuote : IQuote
    {
        // convert quotes
        List <QuoteD> quotesList = quotes.ConvertToList();

        // check parameter arguments
        ValidateMfi(lookbackPeriods);

        // initialize
        int length = quotesList.Count;
        List <MfiResult> results = new(length);

        double[] tp        = new double[length]; // true price
        double[] mf        = new double[length]; // raw MF value
        int[]    direction = new int[length];    // direction

        double?prevTP = null;

        // roll through quotes, to get preliminary data
        for (int i = 0; i < quotesList.Count; i++)
        {
            QuoteD q = quotesList[i];

            MfiResult result = new()
            {
                Date = q.Date
            };

            // true price
            tp[i] = (q.High + q.Low + q.Close) / 3;

            // raw money flow
            mf[i] = tp[i] * q.Volume;

            // direction
            if (prevTP == null || tp[i] == prevTP)
            {
                direction[i] = 0;
            }
            else if (tp[i] > prevTP)
            {
                direction[i] = 1;
            }
            else if (tp[i] < prevTP)
            {
                direction[i] = -1;
            }

            results.Add(result);

            prevTP = tp[i];
        }

        // add money flow index
        for (int i = lookbackPeriods; i < results.Count; i++)
        {
            MfiResult r     = results[i];
            int       index = i + 1;

            double sumPosMFs = 0;
            double sumNegMFs = 0;

            for (int p = index - lookbackPeriods; p < index; p++)
            {
                if (direction[p] == 1)
                {
                    sumPosMFs += mf[p];
                }
                else if (direction[p] == -1)
                {
                    sumNegMFs += mf[p];
                }
            }

            // handle no negative case
            if (sumNegMFs == 0)
            {
                r.Mfi = 100;
                continue;
            }

            // calculate MFI normally
            decimal mfRatio = (decimal)(sumPosMFs / sumNegMFs);

            r.Mfi = 100 - (100 / (1 + mfRatio));
        }

        return(results);
    }