// MONEY FLOW INDEX /// <include file='./info.xml' path='indicator/*' /> /// public static IEnumerable <MfiResult> GetMfi <TQuote>( IEnumerable <TQuote> history, int lookbackPeriod = 14) where TQuote : IQuote { // sort history List <TQuote> historyList = history.Sort(); // check parameter arguments ValidateMfi(history, lookbackPeriod); // initialize int size = historyList.Count; List <MfiResult> results = new List <MfiResult>(size); decimal[] tp = new decimal[size]; // true price decimal[] mf = new decimal[size]; // raw MF value int[] direction = new int[size]; // direction decimal?prevTP = null; // roll through history, to get preliminary data for (int i = 0; i < historyList.Count; i++) { TQuote h = historyList[i]; MfiResult result = new MfiResult { Date = h.Date }; // true price tp[i] = (h.High + h.Low + h.Close) / 3; // raw money flow mf[i] = tp[i] * h.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 = lookbackPeriod; i < results.Count; i++) { MfiResult r = results[i]; int index = i + 1; decimal sumPosMFs = 0; decimal sumNegMFs = 0; for (int p = index - lookbackPeriod; 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 = sumPosMFs / sumNegMFs; r.Mfi = 100 - (100 / (1 + mfRatio)); } return(results); }
// Money Flow Index public static IEnumerable <MfiResult> GetMfi(IEnumerable <Quote> history, int lookbackPeriod = 14) { // clean quotes List <Quote> historyList = history.Sort(); // check parameters ValidateMfi(history, lookbackPeriod); // initialize List <MfiResult> results = new List <MfiResult>(); decimal?prevTP = null; // preliminary data for (int i = 0; i < historyList.Count; i++) { Quote h = historyList[i]; MfiResult result = new MfiResult { Date = h.Date, TruePrice = (h.High + h.Low + h.Close) / 3 }; // raw money flow result.RawMF = result.TruePrice * h.Volume; // direction if (prevTP == null || result.TruePrice == prevTP) { result.Direction = 0; } else if (result.TruePrice > prevTP) { result.Direction = 1; } else if (result.TruePrice < prevTP) { result.Direction = -1; } results.Add(result); prevTP = result.TruePrice; } // add money flow index for (int i = lookbackPeriod; i < results.Count; i++) { MfiResult r = results[i]; int index = i + 1; decimal sumPosMFs = 0; decimal sumNegMFs = 0; for (int p = index - lookbackPeriod; p < index; p++) { MfiResult d = results[p]; if (d.Direction == 1) { sumPosMFs += d.RawMF; } else if (d.Direction == -1) { sumNegMFs += d.RawMF; } } // handle no negative case if (sumNegMFs == 0) { r.Mfi = 100; continue; } // calculate MFI normally decimal mfRatio = sumPosMFs / sumNegMFs; r.Mfi = 100 - (100 / (1 + mfRatio)); } return(results); }
// Money Flow Index public static IEnumerable <MfiResult> GetMfi(IEnumerable <Quote> history, int lookbackPeriod = 14) { // clean quotes Cleaners.PrepareHistory(history); // check parameters ValidateMfi(history, lookbackPeriod); // initialize List <Quote> historyList = history.ToList(); List <MfiResult> results = new List <MfiResult>(); decimal?prevTP = null; // preliminary data for (int i = 0; i < historyList.Count; i++) { Quote h = historyList[i]; MfiResult result = new MfiResult { Index = (int)h.Index, Date = h.Date, TruePrice = (h.High + h.Low + h.Close) / 3 }; // raw money flow result.RawMF = result.TruePrice * h.Volume; // direction if (prevTP == null || result.TruePrice == prevTP) { result.Direction = 0; } else if (result.TruePrice > prevTP) { result.Direction = 1; } else if (result.TruePrice < prevTP) { result.Direction = -1; } results.Add(result); prevTP = result.TruePrice; } // add money flow index for (int i = lookbackPeriod; i < results.Count; i++) { MfiResult r = results[i]; List <MfiResult> period = results .Where(x => x.Index > r.Index - lookbackPeriod && x.Index <= r.Index) .ToList(); List <MfiResult> posMFs = period.Where(x => x.Direction == 1).ToList(); List <MfiResult> negMFs = period.Where(x => x.Direction == -1).ToList(); // handle no negative case if (!negMFs.Any() || negMFs.Select(x => x.RawMF).Sum() == 0) { r.Mfi = 100; continue; } // calculate MFI normally decimal mfRatio = posMFs.Select(x => x.RawMF).Sum() / negMFs.Select(x => x.RawMF).Sum(); r.Mfi = 100 - (100 / (1 + mfRatio)); } return(results); }