📄 tseries.head.hpp
字号:
return rows; } // returns the ABS of the tseries tseries abs() const { // will this work? tseries ans = tseries(*this); double *ans_data = ans.getData(); for(unsigned int i=0; i < (rows*cols); i++) { ans_data[i] = fabs(data[i]); } return ans; } tseries inverse() const { tseries ans = tseries(*this); double *ans_data = ans.getData(); for(unsigned int i=0; i < (rows*cols); i++) { ans_data[i] = 1/data[i]; } return ans; } // lag operator for tseries tseries lag(const unsigned int& periods) const { /* if(periods<0) { cerr << "lag(int periods): periods can't be negative." << endl; return tseries(); } */ if(periods > rows) { cerr << "lag(const unsigned int periods): periods is greater than rows of tseries." << endl; return tseries(); } if(periods==0) { return tseries(*this); } // faster since we do not init it tseries ans = tseries(rows,cols); // init first N rows to NAN for(unsigned int r=0; r < periods; r++) { for(unsigned int c=0; c < cols; c++) { ans.data[r+c*ans.rows] = NAN; } } double *ans_col = ans.data; double *this_col = data; for(unsigned int i=0;i < cols; i++) { memcpy(ans_col+periods,this_col,sizeof(double)*(rows-periods)); ans_col+=rows; this_col+=rows; } ans.setDates(dates); return ans; } // lead / lag operator tseries operator() (const int& periods) const { if(periods >= 0) { return lag(static_cast<unsigned int>(periods)); } else { return lead(static_cast<unsigned int>(std::abs(periods))); } } // lead operator for tseries tseries lead(const unsigned int& periods) const { /* if(periods<0) { cerr << "lead(int periods): periods can't be negative." << endl; return tseries(); } */ if(periods > rows) { cerr << "lead(unsigned int periods): periods is greater than rows of tseries." << endl; return tseries(); } if(periods==0) { return tseries(*this); } // faster since we do not init it tseries ans = tseries(rows,cols); // init last N rows to NAN for(unsigned int r=(rows-periods); r < rows; r++) { for(unsigned int c=0; c < cols; c++) { ans.data[r+c*ans.rows] = NAN; } } double *ans_col = ans.data; double *this_col = data; for(unsigned int i=0;i < cols; i++) { memcpy(ans_col,this_col+periods,sizeof(double)*(rows-periods)); ans_col+=rows; this_col+=rows; } ans.setDates(dates); return ans; } // diff function tseries diff(const unsigned int& periods) const { tseries ans = tseries(rows,cols); ans.setDates(dates); for(unsigned int i = 0; i < cols; i++) { diffVector(ans.getCol(i),getCol(i),rows,periods); } return ans; } // fill NA's with a value void fillval(const double& value) { for(unsigned int i = 0; i < cols*rows; i++) { if(isnan(data[i])) { data[i] = value; } } } void fillf() { for(unsigned int i = 0; i < cols; i++) { fillVectorForward(getCol(i),rows); } } // replace NA's with next value void fillb() { for(unsigned int i = 0; i < cols; i++) { fillVectorBackward(getCol(i),rows); } } // cumulative sum of tseries tseries cumSum(const bool &na_rm) const { tseries ans = tseries(rows,cols); for(unsigned int c = 0; c < cols; c++) { cumSumVector(&ans[c*rows],&data[c*rows],rows, na_rm); } ans.setDates(dates); return ans; } // returns the moving average of the series tseries movingAvg(const unsigned int& periods) const { tseries ans = tseries(*this); for(unsigned int i = 0; i < cols; i++) { movingAverageVector(ans.getCol(i),getCol(i),rows,periods); } return ans; } tseries movingSum(const unsigned int& periods) const { tseries ans = tseries(*this); for(unsigned int i = 0; i < cols; i++) { movingSumVector(ans.getCol(i),getCol(i),rows,periods); } return ans; } tseries movingMax(const unsigned int& periods) const { tseries ans = tseries(*this); for(unsigned int i = 0; i < cols; i++) { movingMaxVector(ans.getCol(i),getCol(i),rows,periods); } return ans; } tseries movingMin(const unsigned int& periods) const { tseries ans = tseries(*this); for(unsigned int i = 0; i < cols; i++) { movingMinVector(ans.getCol(i),getCol(i),rows,periods); } return ans; } tseries movingRank(const unsigned int& periods) const { tseries ans = tseries(*this); for(unsigned int i = 0; i < cols; i++) { movingRankVector(ans.getCol(i),getCol(i),rows,periods); } return ans; } tseries movingStandardDeviation(const unsigned int& periods) const { tseries ans = tseries(*this); for(unsigned int i = 0; i < cols; i++) { movingStdevVector(ans.getCol(i),getCol(i),rows,periods); } return ans; } tseries truerange() const { tseries ans = tseries(rows,1); double *high = getCol("high"); double *low = getCol("low"); double *close = getCol("close"); // if one of these cols is not found then return null series if(high==NULL || low==NULL || close==NULL) { return tseries(); } double rh; double rl; ans.data[0] = NAN; for(unsigned int i = 1; i < rows; i++) { if(close[i-1] > high[i]) { rh = close[i-1]; } else { rh = high[i]; } if(close[i-1] < low[i]) { rl = close[i-1]; } else { rl = low[i]; } ans.data[i] = rh - rl; } ans.setDates(dates); return ans; } tseries ring() const { double *high = getCol("high"); double *low = getCol("low"); if(high==NULL && low==NULL) { cerr << "ERROR: tseries ring() const" << endl; cerr << "high or low column not found." << endl; return tseries(); } double *rHigh = new double[rows]; double *rLow = new double[rows]; ringHighVector(rHigh,high,rows); ringLowVector(rLow,low,rows); tseries ans = tseries(rows,1); // if rHigh has a value, then use it, otherwise use rLow for(unsigned int i=0; i < rows ;i++) { ans.data[i] = (rHigh[i] > 0) ? rHigh[i] : rLow[i]; } delete []rHigh; delete []rLow; return ans; } friend tseries analog(const tseries &stationary, const tseries &moving, const unsigned int periods) { if(stationary.cols > 1 || moving.cols > 1) { cout << "using cols 1 of both series for comparison." << endl; } tseries ans = tseries(stationary.rows,1); analogVector(ans.data,stationary.getCol(0),moving.getCol(0),stationary.rows,moving.rows,periods); ans.setDates(stationary.dates); return ans; } // allocates a matrix and fills it with the last // row of the tseries vector<double> lastrow() const { vector<double> ans(cols); // loop through cols extracting the last row of each for(unsigned int i=0; i < cols; i++) { ans[i] = data[(rows-1) + i*rows]; } return ans; } void setDates(DateT* dts) { memcpy(dates,dts,sizeof(DateT)*rows); } tseries ret(const unsigned int& periods) const { return (*this)/lag(periods) - 1; } mask up() const { bool *ans_data = new bool[rows]; if(ans_data==NULL) { cerr << "ERROR: up() const" " out of memory." << endl; return mask(); } double *close_col = getCol("close"); ans_data[0] = false; // should be NA for(unsigned int i =1; i < rows; i++) { ans_data[i] = (close_col[i] > close_col[i-1]) ? true : false; } return mask(ans_data,rows); } mask down() const { bool *ans_data = new bool[rows]; if(ans_data==NULL) { cerr << "ERROR: down() const" " out of memory." << endl; return mask(); } double *close_col = getCol("close"); ans_data[0] = false; for(unsigned int i =1; i < rows; i++) { ans_data[i] = (close_col[i] < close_col[i-1]) ? true : false; } return mask(ans_data,rows); } vector<DateT> events(mask& m) const { vector<DateT> ans; if(rows!=m.size()) { cerr << "vector<double> events(mask m) const: bad mask" << endl; return ans; } for(unsigned int i=0; i < m.size(); i++) { if(m[i]) ans.push_back(dates[i]); } return ans; } string addTSextension(const string &s) { string ans(s); unsigned int ans_size = ans.size(); if(ans.substr(ans_size-3,ans_size)!=".ts") { return ans + ".ts"; } else { return ans; } } // can't be const because of call to external routine? //tseries linear_model(const tseries& x, const tseries& y) { // x is matrix of explanatory variables // y is independent variable double* linear_model(tseries& x, tseries& y) { cerr << "ERROR: double* linear_model(tseries& x, tseries& y)" << endl; cerr << "not implemented yet." << endl; return NULL; } tseries rowSum() const { if(cols==1) { return *this; } tseries ans(rows,1); ans.setDates(dates); ans = 0.0; for(unsigned int r = 0; r < rows; r++) { for(unsigned int c = 0; c < cols; c++) { ans[r] += data[r+c*rows]; } } return ans; } double& operator[](const unsigned int& i) { return data[i]; } friend bool all_equal(const tseries<DateT> &x, const tseries<DateT> &y) { // FIXME: make this a default argument // or better yet, globally setable const double tol=1e-06; // check dims if(x.rows!=y.rows || x.cols != y.cols) { return false; } // colnames length if(x.colnames.size()!=y.colnames.size()) { return false; } // individual colnames for(unsigned int i = 0; i < x.colnames.size(); i++) { if(x.colnames[i] != y.colnames[i]) { return false; } } // dates for(unsigned int row = 0; row < x.rows; row++) { if(x.dates[row] != y.dates[row]) { return false; } } // data for(unsigned int index = 0; index < x.rows*x.cols; index++) { if(std::abs(x.data[index] - y.data[index]) > tol ) { return false; } } // if passes all return true; } tseries& operator=(const tseries& right) { // self assignment if(this == &right) { return *this; } // kill old data delete []dates; delete []data; // alloc new data data = new double[right.rows*right.cols]; dates = new DateT[right.rows]; // if we do not get the memory, then print error, clear any mem we did get, set ptrs to NULL and return if(data==NULL||dates==NULL) { cerr << "void tseries::operator=(const tseries& right): memory allocaiton error." << endl; delete []data; delete []dates; data = NULL; dates = NULL; rows = 0; cols = 0; return *this; } // set new col and row values rows = right.rows; cols = right.cols; // copy data memcpy(data,right.data,sizeof(double)*rows*cols); memcpy(dates,right.dates,sizeof(DateT)*rows); // set new colnames colnames = right.colnames; local_data = true; return *this; } tseries& operator=(const double& right) { // loop through data and set to new value for(unsigned int i=0; i < rows*cols; i++) { data[i] = right; } return *this;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -