← Back to Documentations

Signature Description Parameters
#include <DataFrame/DataFrameFinancialVisitors.h>

template<typename T, typename I = unsigned long,
         std::size_t A = 0>
struct MoneyFlowIndexVisitor;

// -------------------------------------

template<typename T, typename I = unsigned long,
         std::size_t A = 0>
using mfi_v = MoneyFlowIndexVisitor<T, I, A>;
This is a “single action visitor”, meaning it is passed the whole data vector in one call and you must use the single_act_visit() interface.

This visitor calculates the Money Flow Index (MFI). It requires 4 input columns in the order of low, high, close, volume. The volume column may be of a different type than the price columns (for example, long). MFI is a momentum oscillator that incorporates volume, and is often described as a volume-weighted RSI. For each bar, it first computes the typical price, which is (high + low + close) / 3. It then multiplies that by the bar’s volume to get the raw money flow. A bar counts as positive money flow if its typical price is higher than the previous bar’s typical price. It counts as negative money flow if it is lower. Bars with an unchanged typical price count toward neither. Over a rolling window of period bars, MFI is the share of positive flow in the total flow, scaled from 0 to 100.

get_result() returns the MFI values. The result is a vector with the same number of items as the given columns. The first period items are NaN. The first bar has no previous bar to compare against, so the first valid value appears at index period. Values range from 0 to 100. If a window has no money flow at all (for example, the price did not change or the volume was zero throughout), the MFI for that bar is 0.
explicit
MoneyFlowIndexVisitor(size_type period = 14);

period: Rolling window over which positive and negative money flows are summed
        
T: Column data type
I: Index type
A: Memory alignment boundary for vectors. Default is system default alignment
static void test_MoneyFlowIndexVisitor()  {

    std::cout << "\nTesting StochasticOscillatorVisitor{ } ..." << std::endl;

    StrDataFrame    df;

    try  {
        df.read("IBM.csv", io_format::csv2);
    }
    catch (const DataFrameError &ex)  {
        std::cout << ex.what() << std::endl;
        ::exit(-1);
    }

    mfi_v<double, std::string>  mfi;

    df.single_act_visit<double, double, double, long>("IBM_Low", "IBM_High", "IBM_Adj_Close", "IBM_Volume", mfi);

    assert(mfi.get_result().size() == 5031);
    assert(std::isnan(mfi.get_result()[0]));
    assert(std::isnan(mfi.get_result()[13]));
    assert(std::abs(mfi.get_result()[14] - 53.2331) < 0.0001);
    assert(std::abs(mfi.get_result()[16] - 43.7236) < 0.0001);
    assert(std::abs(mfi.get_result()[23] - 46.3373) < 0.0001);
    assert(std::abs(mfi.get_result()[25] - 41.575) < 0.001);
    assert(std::abs(mfi.get_result()[30] - 28.458) < 0.001);
    assert(std::abs(mfi.get_result()[5022] - 51.9539) < 0.0001);
    assert(std::abs(mfi.get_result()[5029] - 26.7108) < 0.0001);
    assert(std::abs(mfi.get_result()[5030] - 33.2447) < 0.0001);
}

C++ DataFrame