Back to Documentations

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

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

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

template<typename T, typename I = unsigned long,
         std::size_t A = 0>
using pav_v = PeaksAndValleysVisitor<T, I, A>;
This calculates peaks and valleys in a time-series. A peak is a datapoint that is higher than the previous and next datapoints. Similarly, a valley is a datapoint that is lower than the previous and next datapoints. If these conditions are not met, the previous values of peaks and valleys are copied over.
The results are two vectors, namely peaks and valleys with the same size as the input time-series.
get_result() returns the vector of peaks.
get_peaks() returns the vector of peaks.
get_valleys() returns the vector of valleys.

Result vectors are vectors of this struct:

  struct ResultItem  {

      T   value { };  // Peak or valley
      I   index { };  // Index corresponding to the value

      // Convenient print function
      template<typename S>
      friend S &operator << (S &stream, const ResultItem &ri)  {

          stream << ri.value << '@' << ri.index;
          return (stream);
      }
  };
        
T: Column data type
I: Index type
A: Memory alignment boundary for vectors. Default is system default alignment
static void test_PeaksAndValleysVisitor()  {

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

    typedef StdDataFrame64<std::string> StrDataFrame;

    StrDataFrame    df;

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

        pav_v<double, std::string, 64>  pav;

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

        assert(pav.get_peaks().size() == 1721);
        assert(std::abs(pav.get_peaks()[0].value - 185.53) < 0.0001);
        assert(pav.get_peaks()[0].index == "2014-01-02");
        assert(std::abs(pav.get_peaks()[1].value - 186.64) < 0.0001);
        assert(pav.get_peaks()[1].index == "2014-01-03");
        assert(std::abs(pav.get_peaks()[19].value - 182.73) < 0.0001);
        assert(pav.get_peaks()[19].index == "2014-01-23");
        assert(std::abs(pav.get_peaks()[20].value - 177.36) < 0.0001);
        assert(pav.get_peaks()[20].index == "2014-01-30");
        assert(std::abs(pav.get_peaks()[24].value - 177.36) < 0.0001);
        assert(pav.get_peaks()[24].index == "2014-01-30");
        assert(std::abs(pav.get_peaks()[25].value - 177.36) < 0.0001);
        assert(pav.get_peaks()[25].index == "2014-01-30");
        assert(std::abs(pav.get_peaks()[1720].value - 116.0) < 0.0001);
        assert(pav.get_peaks()[1720].index == "2020-10-23");
        assert(std::abs(pav.get_peaks()[1712].value - 125.93) < 0.0001);
        assert(pav.get_peaks()[1712].index == "2020-10-16");
        assert(std::abs(pav.get_peaks()[1707].value - 131.49) < 0.0001);
        assert(pav.get_peaks()[1707].index == "2020-10-08");

        assert(pav.get_valleys().size() == 1721);
        assert(std::abs(pav.get_valleys()[0].value - 185.53) < 0.0001);
        assert(pav.get_valleys()[0].index == "2014-01-02");
        assert(std::abs(pav.get_valleys()[1].value - 186.64) < 0.0001);
        assert(pav.get_valleys()[1].index == "2014-01-03");
        assert(std::abs(pav.get_valleys()[19].value - 176.4) < 0.0001);
        assert(pav.get_valleys()[19].index == "2014-01-29");
        assert(std::abs(pav.get_valleys()[20].value - 176.4) < 0.0001);
        assert(pav.get_valleys()[20].index == "2014-01-29");
        assert(std::abs(pav.get_valleys()[24].value - 172.84) < 0.0001);
        assert(pav.get_valleys()[24].index == "2014-02-04");
        assert(std::abs(pav.get_valleys()[25].value - 172.84) < 0.0001);
        assert(pav.get_valleys()[25].index == "2014-02-04");
        assert(std::abs(pav.get_valleys()[1720].value - 106.65) < 0.0001);
        assert(pav.get_valleys()[1720].index == "2020-10-28");
        assert(std::abs(pav.get_valleys()[1712].value - 124.89) < 0.0001);
        assert(pav.get_valleys()[1712].index == "2020-10-15");
        assert(std::abs(pav.get_valleys()[1707].value - 121.97) < 0.0001);
        assert(pav.get_valleys()[1707].index == "2020-10-06");
    }
    catch (const DataFrameError &ex)  {
        std::cout << ex.what() << std::endl;
    }
}

C++ DataFrame