message: Added Bollinger Band visitor
diff: #pragma once
  +#include <DataFrame/DataFrameStatsVisitors.h>
  +
  #include <algorithm>
  #include <functional>
  #include <iterator>
  @@ -118,6 +120,10 @@ struct BollingerBand {
  private:
  + const double upper_band_multiplier_;
  + const double lower_band_multiplier_;
  + SimpleRollAdopter<MeanVisitor<T, I>, T, I> mean_roller_;
  + StdVisitor<T, I> std_visitor_;
  public:
  @@ -126,36 +132,59 @@ public:
  using size_type = std::size_t;
  using result_type = std::vector<value_type>;
  - inline BollingerBand() { }
  + inline BollingerBand(double upper_band_multiplier,
  + double lower_band_multiplier,
  + size_type moving_mean_period,
  + bool biased = false)
  + : upper_band_multiplier_(upper_band_multiplier),
  + lower_band_multiplier_(lower_band_multiplier),
  + mean_roller_(std::move(MeanVisitor<T, I>()), moving_mean_period),
  + std_visitor_(biased) { }
  template <typename K, typename H>
  inline void
  operator() (const K &idx, const H &column) {
  - }
  + const size_type col_s = std::min(idx.size(), column.size());
  - inline void pre () {
  + mean_roller_.pre();
  + mean_roller_(idx, column);
  + mean_roller_.post();
  - col_to_short_term_.clear();
  - col_to_long_term_.clear();
  - short_term_to_long_term_.clear();
  + std_visitor_.pre();
  + for (size_type i = 0; i < col_s; ++i)
  + std_visitor_(idx[i], column[i]);
  + std_visitor_.post();
  +
  + const value_type std_result = std_visitor_.get_result();
  + const value_type upper = std_result * upper_band_multiplier_;
  + const value_type lower = std_result * lower_band_multiplier_;
  + const auto &mean_result = mean_roller_.get_result();
  +
  + upper_band_to_raw_.reserve(col_s);
  + for (size_type i = 0; i < col_s; ++i)
  + upper_band_to_raw_.push_back((mean_result[i] + upper) - column[i]);
  + raw_to_lower_band_.reserve(col_s);
  + for (size_type i = 0; i < col_s; ++i)
  + raw_to_lower_band_.push_back(column[i] - (mean_result[i] - lower));
  }
  - inline void post () {
  + inline void pre () {
  +
  + upper_band_to_raw_.clear();
  + raw_to_lower_band_.clear();
  }
  + inline void post () { }
  const result_type &
  - get_raw_to_short_term() const { return (col_to_short_term_); }
  - const result_type &
  - get_raw_to_long_term() const { return (col_to_long_term_); }
  + get_upper_band_to_raw() const { return (upper_band_to_raw_); }
  const result_type &
  - get_short_term_to_long_term() const { return (short_term_to_long_term_); }
  + get_raw_to_lower_band() const { return (raw_to_lower_band_); }
  private:
  - result_type col_to_short_term_;
  - result_type col_to_long_term_;
  - result_type short_term_to_long_term_;
  + result_type upper_band_to_raw_;
  + result_type raw_to_lower_band_;
  };
  } // namespace hmdf
  