//
// Created by Jolen on 2021/6/22.
//
#include <iostream>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>
#include <math.h>
using namespace std;
typedef vector<vector<string>> CSV;
typedef vector<double> NumArray;
typedef vector<NumArray> NumDATA;
class Asset
{
public:
Asset(vector<double> nums)
{
size_t len = nums.size() - 1;
for (size_t i = 1; i <= len; i++)
reward_rate.push_back((nums[i] / nums[i - 1] - 1) * 100);
for (double i : reward_rate) {
reward_avg += (i / len);
}
for (double i : reward_rate)
reward_std += (i - reward_avg) * (i - reward_avg);
reward_std /= (reward_rate.size() - 1);
reward_std = sqrt(reward_std);
}
string name;
vector<double> data;
vector<double> reward_rate;
double reward_avg = 0;
double reward_std = 0;
};
double covariance(Asset a, Asset b)
{
vector<double> ra = a.reward_rate;
vector<double> rb = b.reward_rate;
double ra_avg = a.reward_avg;
double rb_avg = b.reward_avg;
double ans = 0;
for (size_t i = 0; i < ra.size(); i++) {
ans += ((ra[i] - ra_avg) * (rb[i] - rb_avg) / (ra.size()));
}
return ans;
}
vector<vector<double>> correlation(vector<vector<double>> cov)
{
size_t len = cov.size();
vector<vector<double>> cor(len, vector<double>(len, 0));
for (size_t i = 0; i < len; i++)
for (size_t j = 0; j < len; j++) {
cor[i][j] = cov[i][j] / sqrt(cov[i][i] * cov[j][j]);
}
return cor;
}
//加载csv文件
int load_csv(CSV& csv, const std::string& filename)
{
ifstream in(filename);
if (in.fail()) {
return -1;
}
string line;
string s;
vector<string> csvline;
cout << "---------- " << filename << " ----------" << endl;
csv.clear();
while (!in.eof()) {
//读取一行
getline(in, line);
//忽略空行
if (line.empty()) {
continue;
}
//cout << line << endl;
//字符流
stringstream stm(line);
//解析
csvline.clear();
while (!stm.eof()) {
getline(stm, s, ',');
cout.width(10);
cout << s;
csvline.push_back(s);
}
cout << endl;
//添加进列表
if (!csvline.empty()) {
csv.push_back(csvline);
}
}
cout << endl;
return csv.empty() ? -1 : 0;
}
void print(ostream& out, const CSV& csv, const NumDATA& data)
{
for (size_t i = 1; i < csv[0].size(); i++) {
out << csv[0][i] << endl;
}
for (size_t i = 0; i < data.size(); i++) {
if (i == 0) {
out << "[ ";
}
else {
out << " ";
}
if (!data[i].empty()) {
for (size_t j = 0; j < data[i].size() - 1; j++) {
out << data[i][j] << ",";
}
if (i == data.size() - 1) {
out << data[i][data.size() - 1] << "]" << endl;
}
else {
out << data[i][data.size() - 1] << endl;
}
}
}
}
int main(int argc, char *argv[])
{
if (argc < 2) {
cout << "You have entered the wrong number of argument." << endl;
return 0;
}
CSV csv;
vector<vector<double>> user_arr;
vector<double> line;
if (load_csv(csv, argv[1]) == -1) {
cout << "csv load failed." << endl;
return -1;
}
//遍历所有行,忽略第一行
for (size_t y = 1; y < csv.size(); ++y) {
line.clear();
for (size_t x = 1; x < csv[y].size(); ++x) {
double n = atof(csv[y][x].c_str());
cout.width(10);
cout << n;
line.push_back(n);
}
cout << endl;
user_arr.push_back(line);
}
cout << endl;
vector<vector<double>> data;
for (size_t i = 0; i < user_arr[0].size(); i++) {
line.clear();
for (size_t j = 0; j < user_arr.size(); j++) {
line.push_back(user_arr[j][i]);
}
data.push_back(line);
}
for (size_t i = 0; i < data.size(); i++) {
for (size_t j = 0; j < data[0].size(); j++) {
if (data[i][j] == 0) data[i][j] = data[i][j - 1];
}
}
for (size_t i = 0; i < data.size(); i++) {
for (size_t j = 0; j < data[0].size(); j++) {
if (data[i][j] == 0) data[i][j] = data[i][j - 1];
}
}
cout << "init data ok: " << data[0].size() << " x " << data.size() << endl;
size_t num = data.size();
// Asset asset[num] = {Asset(data[0]), Asset(data[1])};
vector<Asset> asset;
for (size_t i = 0; i < num; i++) {
asset.push_back(Asset(data[i]));
}
vector<vector<double>> cov(num, vector<double>(num, 0));
vector<vector<double>> cor(num, vector<double>(num, 0));
for (size_t i = 0; i < num; i++) {
for (size_t j = 0; j < num; j++) {
cov[i][j] = covariance(asset[i], asset[j]);
}
}
for (size_t i = 0; i < num; i++) {
for (size_t j = 0; j < num; j++) {
cor[i][j] = cov[i][j] / (asset[i].reward_std * asset[j].reward_std);
}
cor[i][i] = 1;
}
cout << "---------- debug ----------" << endl;
for (size_t i = 0; i < num; i++) {
for (size_t j = 0; j < num; j++) {
printf("%0.4f", cor[i][j]);
}
printf("\n");
}
// output
cout << "---------- output ----------" << endl;
print(cout, csv, cor);
ofstream outFile("result.txt");
outFile.precision(4);
outFile.setf(std::ios::fixed, std::ios::floatfield);
print(outFile, csv, cor);
outFile.close();
return 0;
}