📄 array.cpp
字号:
#include <cmath>#include <iostream>#include "array.hpp" // delay functionsvoid lagVector(double *ans, double *data, const int &length, const int &periods) { // check bounds // if periods bigger than whole series // set all NAN if(periods > length) { for(int i = 0; i < length; i++) { ans[i] = NAN; } return; } // initialize the first n periods to NA for(int i = 0; i<periods; i++) ans[i] = NAN; // fill remaining vector to delayed values for(int i = periods; i<length; i++) ans[i] = data[i-periods];}void leadVector(double *ans, double *data, const int &length, const int &periods) { // check bounds // if periods bigger than whole series // set all NAN if(periods > length) { for(int i = 0; i < length; i++) { ans[i] = NAN; } return; } // initialize the last n periods to NA for(int i = (length-1); i>(length-periods-1); i--) ans[i] = NAN; // fill remaining vector to delayed values for(int i = (length-periods-1); i>=0; i--) ans[i] = data[i+periods];}// diff functionvoid diffVector(double *ans, double *data, const int &length, const int &periods) { // check bounds // if periods bigger than whole series // set all NAN if(periods > length) { for(int i = 0; i < length; i++) { ans[i] = NAN; } return; } // initialize the first n periods to NA for(int i = 0; i<periods; i++) ans[i] = NAN; // fill remaining vector to delayed values for(int i = periods; i < length; i++) { if(isnan(data[i-periods])||isnan(data[i])) { ans[i] = NAN; } else { ans[i] = data[i] - data[i-periods]; } }}// fill functionsvoid fillVectorValue(double *data, const int &length, const double &value) { for(int i=0;i < length;i++) if(isnan(data[i])) { data[i] = value; }}void fillVectorForward(double *data, const int &length) { for(int i=1;i < length;i++) if(isnan(data[i])) { data[i] = data[i-1]; }}void fillVectorBackward(double *data, const int &length) { // length -2 is the end because array // bounds start at 0 and end at Len - 1 // so len -2 is the 2nd element from the bottom for(int i=(length-2);i >= 0;i--) if(isnan(data[i])) { data[i] = data[i+1]; }}void movingAverageVector(double *ans, double *data, const int &length, const int &periods) { // check bounds // if periods bigger than whole series // set all NAN if(periods > length) { for(int i = 0; i < length; i++) { ans[i] = NAN; } return; } // take the rolling sum // then convert it to an average movingSumVector(ans, data, length, periods); for(int i = (periods-1); i < length; i++) { if(!isnan(ans[i])) ans[i] = ans[i]/periods; }}void movingSumVector(double *ans, double *data, const int &length, const int &periods) { // check bounds // if periods bigger than whole series // set all NAN if(periods > length) { for(int i = 0; i < length; i++) { ans[i] = NAN; } return; } double rollingSum = 0.0; int goodValues = 0; for (int i = 0; i < length; i++) { if(std::isfinite(data[i])) { goodValues++; rollingSum+=data[i]; } else { goodValues = 0; rollingSum = 0.0; } if(goodValues >= periods) { ans[i] = rollingSum; rollingSum -= data[i - periods + 1]; } else { ans[i] = NAN; } }}void movingMaxVector(double *ans, double *data, const int &length, const int &periods) { // check bounds // if periods bigger than whole series // set all NAN if(periods > length) { for(int i = 0; i < length; i++) { ans[i] = NAN; } return; } for(int i = 0; i < (periods-1); i++) ans[i] = NAN; for(int i = (periods-1); i < length; i++) ans[i] = max(&data[i-periods+1],periods);}void movingMinVector(double *ans, double *data, const int &length, const int &periods) { // check bounds // if periods bigger than whole series // set all NAN if(periods > length) { for(int i = 0; i < length; i++) { ans[i] = NAN; } return; } for(int i = 0; i < (periods-1); i++) ans[i] = NAN; for(int i = (periods-1); i < length; i++) ans[i] = min(&data[i-periods+1],periods);}// compute the ring high or low for each row of a tseriesvoid ringHighVector(double *ans, double *data, const int &length) { // since there is no prior value to compare with it ans[0] = 0; // no value after ans[length-1] = 0; // this function assumes there are NO NAs in the data if(length < 3) { ans[1] = NAN; return; } else { for(int i = 1; i < (length-1); i++) ans[i] = (double)findRingHigh(data,i,length); }}void ringLowVector(double *ans, double *data, const int &length) { // since there is no prior value to compare with it ans[0] = 0; // no value after ans[length-1] = 0; // this function assumes there are NO NAs in the data if(length < 3) { return; } else { for(int i = 1; i < (length-1); i++) ans[i] = (double)findRingLow(data,i,length); }}double findRingHigh(double *data, const int ¤tPosition, const int &length) { int index = 0; int left_counter = currentPosition - 1; int right_counter = currentPosition + 1; double currentData = data[currentPosition]; // within bounds && still a ring high while(left_counter >= 0 && right_counter < length && currentData >= data[left_counter] && currentData >= data[right_counter]) { index++; left_counter--; right_counter++; } return index;}double findRingLow(double *data, const int ¤tPosition, const int &length) { int index = 0; int left_counter = currentPosition - 1; int right_counter = currentPosition + 1; double currentData = data[currentPosition]; // within bounds && still a ring low while(left_counter >= 0 && right_counter < length && currentData <= data[left_counter] && currentData <= data[right_counter]) { index++; left_counter--; right_counter++; } return -index;} void movingRankVector(double *ans, double *data, const int &length, const int &periods) { // check bounds // if periods bigger than whole series // set all NAN if(periods > length) { for(int i = 0; i < length; i++) { ans[i] = NAN; } return; } for(int i = 0; i < (periods-1); i++) ans[i] = NAN; for(int i = (periods-1); i < length; i++) ans[i] = rank(&data[i-periods+1],periods);}void movingStdevVector(double *ans, double *data, const int &length, const int &periods) { // check bounds // if periods bigger than whole series // set all NAN if(periods > length) { for(int i = 0; i < length; i++) { ans[i] = NAN; } return; } for(int i = 0; i < (periods-1); i++) ans[i] = NAN; for(int i = (periods-1); i < length; i++) ans[i] = stdev(&data[i-periods+1],periods);}// assumes that dates have been aligned// ans will have same length as moving ts// assume periods is 10// we will be computing corr of last 10 days of stationary// with a moving 10 day period of movingvoid analogVector(double *ans, double *stationary, double *moving, const int &len_stationary, const int &len_moving, const int &periods) { if(ans==NULL||stationary==NULL||moving==NULL) { std::cout << "ERROR: analogVector: NULL pointer passed in" << std::endl; return; } // if we don't have enough data, then fill NAs and return if(periods >len_stationary || periods > len_moving) { for(int i = 0; i < len_moving; i++) ans[i] = NAN; return; } // fill first n-1 periods w/ NA for(int i = 0; i < (periods-1);i++) ans[i] = NAN; // stationary starting position does not change double *stationary_start = &stationary[len_stationary - periods]; double *moving_start; // formula is cov/(sd*sd) so we can precalc sd of the stationary series double stationary_sd = stdev(stationary_start,periods); double moving_sd; double denom; double num; for(int i = (periods-1); i < len_moving; i++) { moving_start = &(moving[i-periods+1]); moving_sd = stdev(moving_start,periods); denom = stationary_sd*moving_sd; num = cov(stationary_start,moving_start,periods); ans[i] = (num/denom); }}void cumSumVector(double *ans, double *data, const unsigned int &rows, const bool &rm_nan) { double movingSum = 0.0; if(rm_nan) { for(unsigned int r = 0; r < rows; r++) { if(!isnan(data[r])) { movingSum += data[r]; } ans[r] = movingSum; } } else { for(unsigned int r = 0; r < rows; r++) { movingSum += data[r]; ans[r] = movingSum; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -