Signature | Description |
---|---|
enum class exponential_decay_spec : unsigned char { center_of_gravity = 1, // Decay = 1 / (1 + value) For value >= 0 span = 2, // Decay = 2 / (1 + value) For value >= 1 halflife = 3, // Decay = 1 - elog(0.5)/value For value > 0 fixed = 4, // Decay = value For 0 < value <= 1 }; |
This spec determines how an exponentially moving stat decays. Based on this spec, the value parameter is converted to decay. |
Signature | Description | Parameters |
---|---|---|
#include <DataFrame/DataFrameStatsVisitors.h> template<typename T, typename I = unsigned long, std::size_t A = 0> struct ExponentiallyWeightedMeanVisitor; // ------------------------------------- template<typename T, typename I = unsigned long, std::size_t A = 0> using ewm_v = ExponentiallyWeightedMeanVisitor<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 exponentially weighted mean (EWM). EWM gives more weight to recent data by using a decay factor. Formula if finite_adjust is false (default): Yt = decay * Xt + (1 − decay) * Yt-1Formula if finite_adjust is true: Xt + (1 - decay) * Xt-1 + (1 - decay)2 * Xt-2 + ... + (1 - decay)t * X0 Yt = ------------------------------------------------------------------------ 1 + (1 - decay) + (1 - decay)2 + ... + (1 - decay)tConstructor: ExponentiallyWeightedMeanVisitor( exponential_decay_spec eds, // See exponential_decay_spec type double value, // Value to be decayed bool finite_adjust = false); // Adjust for the fact that this is not an infinite data set |
T: Column data type I: Index type A: Memory alignment boundary for vectors. Default is system default alignment |
Signature | Description | Parameters |
---|---|---|
#include <DataFrame/DataFrameStatsVisitors.h> template<typename T, typename I = unsigned long, std::size_t A = 0> struct ExponentiallyWeightedVarVisitor; // ------------------------------------- template<typename T, typename I = unsigned long, std::size_t A = 0> using ewm_var_v = ExponentiallyWeightedVarVisitor<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 exponentially weighted variance and standard deviation. It gives more weight to recent data by using a decay factor. get_result() returns the vector of EWM variances. There is also a get_std() that returns the vector of EWM standard deviations. Constructor: ExponentiallyWeightedVarVisitor( exponential_decay_spec eds, // See exponential_decay_spec type double value); // Value to be decayed |
T: Column data type I: Index type A: Memory alignment boundary for vectors. Default is system default alignment |
Signature | Description | Parameters |
---|---|---|
#include <DataFrame/DataFrameStatsVisitors.h> template<typename T, typename I = unsigned long, std::size_t A = 0> struct ExponentiallyWeightedCovVisitor; // ------------------------------------- template<typename T, typename I = unsigned long, std::size_t A = 0> using ewm_cov_v = ExponentiallyWeightedCovVisitor<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 exponentially weighted covariance. It gives more weight to recent data by using a decay factor. get_result() returns the vector of EWM covariances. Constructor: ExponentiallyWeightedCovVisitor( exponential_decay_spec eds, // See exponential_decay_spec type double value); // Value to be decayed |
T: Column data type I: Index type A: Memory alignment boundary for vectors. Default is system default alignment |
Signature | Description | Parameters |
---|---|---|
#include <DataFrame/DataFrameStatsVisitors.h> template<typename T, typename I = unsigned long, std::size_t A = 0> struct ExponentiallyWeightedCorrVisitor; // ------------------------------------- template<typename T, typename I = unsigned long, std::size_t A = 0> using ewm_corr_v = ExponentiallyWeightedCorrVisitor<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 exponentially weighted correlation. It gives more weight to recent data by using a decay factor. get_result() returns the vector of EWM correlations. Constructor: ExponentiallyWeightedCorrVisitor( exponential_decay_spec eds, // See exponential_decay_spec type double value); // Value to be decayed |
T: Column data type I: Index type A: Memory alignment boundary for vectors. Default is system default alignment |
static void test_ExponentiallyWeightedMeanVisitor() { std::cout << "\nTesting ExponentiallyWeightedMeanVisitor{ } ..." << std::endl; std::vector<unsigned long> idx = { 123450, 123451, 123452, 123453, 123454, 123455, 123456, 123457, 123458, 123459, 123460 }; std::vector<double> d1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; std::vector<double> d2 = { 8, 9, 10, 11, std::numeric_limits<double>::quiet_NaN(), 13, 14, std::numeric_limits<double>::quiet_NaN(), 16, 17, 18 }; std::vector<double> d3 = { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 }; std::vector<double> d4 = { 22, 23, 24, 25, 26, 27 }; std::vector<std::string> s1 = { "11", "22", "33", "aa", "bb", "cc", "dd" "tt", "uu", "ii", "88" }; MyDataFrame df; df.load_data(std::move(idx), std::make_pair("col_1", d1), std::make_pair("col_2", d2), std::make_pair("col_3", d3), std::make_pair("col_str", s1)); df.load_column("col_4", std::move(d4), nan_policy::dont_pad_with_nans); ewm_v<double> hl_expo_mean_roller(exponential_decay_spec::halflife, 0.5); const auto &hl_expo_result = df.single_act_visit<double>("col_3", hl_expo_mean_roller).get_result(); assert(hl_expo_result.size() == 11); assert(hl_expo_result[0] == 15.0); assert(fabs(hl_expo_result[1] - 15.75) < 0.01); assert(fabs(hl_expo_result[2] - 16.6875) < 0.0001); assert(fabs(hl_expo_result[5] - 19.667) < 0.001); assert(fabs(hl_expo_result[8] - 22.6667) < 0.0001); ewm_v<double> cg_expo_mean_roller(exponential_decay_spec::center_of_gravity, 0.5); const auto &cg_expo_result = df.single_act_visit<double>("col_3", cg_expo_mean_roller).get_result(); assert(cg_expo_result.size() == 11); assert(cg_expo_result[0] == 15.0); assert(fabs(cg_expo_result[1] - 15.6667) < 0.0001); assert(fabs(cg_expo_result[2] - 16.5556) < 0.0001); assert(fabs(cg_expo_result[5] - 19.5021) < 0.0001); assert(fabs(cg_expo_result[8] - 22.5001) < 0.0001); ewm_v<double> s_expo_mean_roller(exponential_decay_spec::span, 1.5); const auto &s_expo_result = df.single_act_visit<double>("col_3", s_expo_mean_roller).get_result(); assert(s_expo_result.size() == 11); assert(s_expo_result[0] == 15.0); assert(fabs(s_expo_result[1] - 15.8) < 0.01); assert(fabs(s_expo_result[2] - 16.76) < 0.001); assert(fabs(s_expo_result[5] - 19.7501) < 0.0001); assert(fabs(s_expo_result[8] - 22.75) < 0.001); ewm_v<double> f_expo_mean_roller(exponential_decay_spec::fixed, 0.5); const auto &f_expo_result = df.single_act_visit<double>("col_3", f_expo_mean_roller).get_result(); assert(f_expo_result.size() == 11); assert(f_expo_result[0] == 15.0); assert(fabs(f_expo_result[1] - 15.5) < 0.01); assert(fabs(f_expo_result[2] - 16.25) < 0.001); assert(fabs(f_expo_result[5] - 19.0312) < 0.0001); assert(fabs(f_expo_result[8] - 22.0039) < 0.0001); ewm_v<double> expo_mean_roller_3(exponential_decay_spec::span, 3); const auto &expo_result_3 = df.single_act_visit<double>("col_3", expo_mean_roller_3).get_result(); assert(expo_result_3.size() == 11); assert(expo_result_3[0] == 15.0); assert(std::fabs(expo_result_3[1] - 15.5) < 0.01); assert(std::fabs(expo_result_3[2] - 16.25) < 0.001); assert(std::fabs(expo_result_3[5] - 19.0312) < 0.0001); assert(std::fabs(expo_result_3[8] - 22.0039) < 0.0001); ewm_v<double> expo_mean_roller_3_t(exponential_decay_spec::span, 3, true); const auto &expo_result_3_t = df.single_act_visit<double>("col_3", expo_mean_roller_3_t).get_result(); assert(expo_result_3_t.size() == 11); assert(expo_result_3_t[0] == 15.0); assert(std::fabs(expo_result_3_t[1] - 15.6667) < 0.0001); assert(std::fabs(expo_result_3_t[2] - 16.4286) < 0.0001); assert(std::fabs(expo_result_3_t[5] - 19.0952) < 0.0001); assert(std::fabs(expo_result_3_t[8] - 22.0176) < 0.0001); }
// ----------------------------------------------------------------------------- static void test_ExponentiallyWeightedVarVisitor() { std::cout << "\nTesting ExponentiallyWeightedVarVisitor{ } ..." << std::endl; StlVecType<unsigned long> idx = { 123450, 123451, 123452, 123453, 123454, 123455, 123456, 123457, 123458, 123459, 123460, 123461, 123462, 123466, 123467, 123468 }; StlVecType<double> d1 = { 1.0, 1.5, 1.0, 1.2, 1.7, 1.5, 1.2, 1.7, 1.7, 1.3, 1.4, 1.5, 1.2, 1.1, 1.15, 1.0 }; StlVecType<double> d2 = { 0.2, 0.58, -0.60, -0.08, 0.05, 0.87, 0.2, 0.4, 0.5, 0.06, 0.3, -0.34, -0.9, 0.8, -0.4, 0.86 }; StlVecType<int> i1 = { 22, 23, 24, 25, 99 }; MyDataFrame df; df.load_data(std::move(idx), std::make_pair("values", d1), std::make_pair("benchmark", d2), std::make_pair("col_3", i1)); ewm_var_v<double> ewmvar(exponential_decay_spec::span, 3); const auto result = df.single_act_visit<double>("values", ewmvar).get_result(); assert(result.size() == 16); assert(std::isnan(result[0])); assert(fabs(result[1] - 0.125) < 0.001); assert(fabs(result[2] - 0.0893) < 0.0001); assert(fabs(result[3] - 0.0396) < 0.0001); assert(fabs(result[4] - 0.1258) < 0.0001); assert(fabs(result[15] - 0.0228) < 0.0001); assert(fabs(result[14] - 0.0205) < 0.0001); assert(fabs(result[13] - 0.0377) < 0.0001); }
// ----------------------------------------------------------------------------- static void test_ExponentiallyWeightedCovVisitor() { std::cout << "\nTesting ExponentiallyWeightedCovVisitor{ } ..." << std::endl; StlVecType<unsigned long> idx = { 123450, 123451, 123452, 123453, 123454, 123455, 123456, 123457, 123458, 123459, 123460, 123461, 123462, 123466, 123467, 123468 }; StlVecType<double> d1 = { 1.0, 1.5, 1.0, 1.2, 1.7, 1.5, 1.2, 1.7, 1.7, 1.3, 1.4, 1.5, 1.2, 1.1, 1.15, 1.0 }; StlVecType<double> d2 = { 1.5, 1.0, 1.1, 1.3, 1.35, 1.2, 1.2, 1.6, 1.6, 1.8, 1.4, 1.5, 1.25, 1.3, 1.25, 1.0 }; StlVecType<int> i1 = { 22, 23, 24, 25, 99 }; MyDataFrame df; df.load_data(std::move(idx), std::make_pair("X Column", d1), std::make_pair("Y Column", d2), std::make_pair("col_3", i1)); ewm_cov_v<double> ewmcov(exponential_decay_spec::span, 3); const auto &result = df.single_act_visit<double, double>("X Column", "Y Column", ewmcov).get_result(); assert(result.size() == 16); assert(std::isnan(result[0])); assert(fabs(result[1] - -0.125) < 0.001); assert(fabs(result[2] - -0.0321) < 0.0001); assert(fabs(result[3] - -0.0099) < 0.0001); assert(fabs(result[4] - 0.0219) < 0.0001); assert(fabs(result[15] - 0.0263) < 0.0001); assert(fabs(result[14] - 0.0121) < 0.0001); assert(fabs(result[13] - 0.0197) < 0.0001); }
// ----------------------------------------------------------------------------- static void test_ExponentiallyWeightedCorrVisitor() { std::cout << "\nTesting ExponentiallyWeightedCorrVisitor{ } ..." << std::endl; StlVecType<unsigned long> idx = { 123450, 123451, 123452, 123453, 123454, 123455, 123456, 123457, 123458, 123459, 123460, 123461, 123462, 123466, 123467, 123468 }; StlVecType<double> d1 = { 1.0, 1.5, 1.0, 1.2, 1.7, 1.5, 1.2, 1.7, 1.7, 1.3, 1.4, 1.5, 1.2, 1.1, 1.15, 1.0 }; StlVecType<double> d2 = { 1.5, 1.0, 1.1, 1.3, 1.35, 1.2, 1.2, 1.6, 1.6, 1.8, 1.4, 1.5, 1.25, 1.3, 1.25, 1.0 }; StlVecType<int> i1 = { 22, 23, 24, 25, 99 }; MyDataFrame df; df.load_data(std::move(idx), std::make_pair("X Column", d1), std::make_pair("Y Column", d2), std::make_pair("col_3", i1)); ewm_corr_v<double> ewmcorr(exponential_decay_spec::span, 3); const auto &result = df.single_act_visit<double, double>("X Column", "Y Column", ewmcorr).get_result(); assert(result.size() == 16); assert(std::isnan(result[0])); assert(fabs(result[1] - -1.0) < 0.001); assert(fabs(result[2] - -0.5153) < 0.0001); assert(fabs(result[3] - -0.2841) < 0.0001); assert(fabs(result[4] - 0.4287) < 0.0001); assert(fabs(result[15] - 0.8746) < 0.0001); assert(fabs(result[14] - 0.714) < 0.0001); assert(fabs(result[13] - 0.6865) < 0.0001); }