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

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

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

template<typename T, typename I = unsigned long,
         std::size_t A = 0>
using symtmm_v = SymmTriangleMovingMeanVisitor<T, I>;
        
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 zero lag moving average based on exponential moving average.
The result is a vector of values with same number of items as the given columns. The first rolling periods items in the result will be NaN

In a symmetrically weighted moving average, the weights are based on a symmetric triangle. That means both older data and most recent data have lower weights. The data in between have higher weights. The highest weight is given to the data point at half the length of roll period.
    explicit
    SymmTriangleMovingMeanVisitor (size_t roll_period);
        
T: Column data type
I: Index type.
A: Memory alignment boundary for vectors. Default is system default alignment
static void test_SymmTriangleMovingMeanVisitor()  {

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

    StrDataFrame    df;

    try  {
        df.read("data/SHORT_IBM.csv", io_format::csv2);

        symtmm_v<double, std::string>   symm { 14 };

        df.single_act_visit<double>("IBM_Close", symm);

        assert(symm.get_result().size() == 1721);
        assert(std::isnan(symm.get_result()[0]));
        assert(std::isnan(symm.get_result()[13]));
        assert(std::abs(symm.get_result()[14] - 187.1136) < 0.0001);
        assert(std::abs(symm.get_result()[15] - 187.032) < 0.0001);
        assert(std::abs(symm.get_result()[16] - 186.8627) < 0.0001);
        assert(std::abs(symm.get_result()[18] - 185.9546) < 0.0001);
        assert(std::abs(symm.get_result()[25] - 177.925) < 0.0001);
        assert(std::abs(symm.get_result()[1720] - 118.6054) < 0.0001);
        assert(std::abs(symm.get_result()[1712] - 125.4893) < 0.0001);
        assert(std::abs(symm.get_result()[1707] - 122.153) < 0.0001);
    }
    catch (const DataFrameError &ex)  {
        std::cout << ex.what() << std::endl;
    }
}
C++ DataFrame