Skip to content

Instantly share code, notes, and snippets.

@hikarivina
Forked from darden1/tradingrrl.cpp
Created September 16, 2018 12:41
Show Gist options
  • Save hikarivina/d5c60c691b5fb6b661e854b969eb6021 to your computer and use it in GitHub Desktop.
Save hikarivina/d5c60c691b5fb6b661e854b969eb6021 to your computer and use it in GitHub Desktop.
c++ implementation of RRL.
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
#include <iostream>
#include <math.h>
#include <ctime>
using namespace std;
class TradingRRL{
public:
int T;
int M;
int init_t;
double mu;
double sigma;
double rho;
int n_epoch;
int progress_period;
double q_threshold;
vector<string> all_t;
vector<double> all_p;
vector<string> t;
vector<double> p;
vector<double> r;
vector< vector<double> > x;
vector<double> F;
vector<double> R;
vector<double> w;
vector<double> w_opt;
vector<double> epoch_S;
vector<double> sumR;
vector<double> sumR2;
double A;
double B;
double S;
double S_opt;
double dSdA;
double dSdB;
double dAdR;
vector<double> dBdR;
vector<double> dRdF;
vector<double> dRdFp;
vector<double> dFpdw;
vector<double> dFdw;
vector<double> dSdw;
private:
vector<string> split(string& input, char delimiter);
public:
// Constructor
TradingRRL(int T, int M, int init_t, double mu, double sigma, double rho, int n_epoch);
// Destructor
~TradingRRL();
// Menber functions
void load_csv(string fname);
int quant(double f, double threshold);
double sign(double f);
void set_t_p_r();
void set_x_F();
void calc_R();
void calc_sumR();
void calc_dSdw();
void update_w();
void fit();
void save_weight();
void load_weight();
};
// Constructor
TradingRRL::TradingRRL(int T, int M, int init_t, double mu, double sigma, double rho, int n_epoch)
:
T(T),
M(M),
init_t(init_t),
mu(mu),
sigma(sigma),
rho(rho),
n_epoch(n_epoch),
progress_period(100),
q_threshold(0.7),
x(T, vector<double>(M+2, 0.0)),
F(T+1, 0.0),
R(T, 0.0),
w(M+2, 1.0),
w_opt(M+2, 1.0),
sumR(T, 0.0),
sumR2(T, 0.0),
A(0.0),
B(0.0),
S(0.0),
S_opt(0.0),
dSdA(0.0),
dSdB(0.0),
dAdR(0.0),
dBdR(T, 0.0),
dRdF(T, 0.0),
dRdFp(T, 0.0),
dFpdw(M+2, 0.0),
dFdw(M+2, 0.0),
dSdw(M+2, 0.0)
{}
// Destructor
TradingRRL::~TradingRRL(){}
// Menber functions
vector<string> TradingRRL::split(string& input, char delimiter){
istringstream stream(input);
string field;
vector<string> result;
while (getline(stream, field, delimiter)) {
result.push_back(field);
}
return result;
}
void TradingRRL::load_csv(string fname){
ifstream ifs(fname.c_str());
vector<string> tmp_t;
vector<double> tmp_p;
string tmp_tstr;
double tmp_pdbl;
int read_count =0;
// --- read data
string line;
while (getline(ifs, line)){
vector<string> strvec = split(line, ',');
stringstream ss;
tmp_tstr = strvec.at(0) + " " + strvec.at(1);
ss << strvec.at(5);
ss >> tmp_pdbl;
tmp_t.push_back(tmp_tstr);
tmp_p.push_back(tmp_pdbl);
read_count +=1;
}
// --- Reverse chart data
for( int i=0 ; i<read_count ; ++i ){
all_t.push_back(tmp_t[read_count-1-i]);
all_p.push_back(tmp_p[read_count-1-i]);
}
}
int TradingRRL::quant(double f, double threshold){
if(fabs(f)< threshold){
return 0;
}
else if(f>0.0){
return 1;
}
else{
return -1;
}
}
double TradingRRL::sign(double f){
if(f==0.0){
return 0.0;
}
else if(f>0.0){
return 1.0;
}
else{
return -1.0;
}
}
void TradingRRL::set_t_p_r(){
int i;
for(i=0 ; i<T+M; ++i ){
t.push_back(all_t[init_t+i]);
p.push_back(all_p[init_t+i]);
r.push_back(all_p[init_t+i] - all_p[init_t+i+1]);
}
}
void TradingRRL::set_x_F(){
for(int i=T-1 ; i>=0 ; --i ){
x[i][0] = 1.0;
x[i][M+2-1] = F[i+1];
for(int j=1 ; j<M+2-1 ; ++j ){
x[i][j] = r[i+(j-1)];
}
double wdotx = 0.0;
for(int k=0 ; k<M+2 ; ++k ){
wdotx += w[k]*x[i][k];
}
F[i] = tanh(wdotx);
}
}
void TradingRRL::calc_R(){
int i;
for(i=T-1 ; i>=0 ; --i ){
R[i] = mu*(F[i+1]*r[i] - sigma*fabs(F[i] - F[i+1]));
}
}
void TradingRRL::calc_sumR(){
sumR[T-1] = R[T-1];
sumR2[T-1] = R[T-1]*R[T-1];
for(int i=T-2 ; i>=0 ; --i ){
sumR[i] = sumR[i+1] + R[i];
sumR2[i] = sumR2[i+1] + R[i]*R[i];
}
}
void TradingRRL::calc_dSdw(){
set_x_F();
calc_R();
calc_sumR();
A = sumR[0]/T;
B = sumR2[0]/T;
S = A/sqrt(B-A*A);
dSdA = S*(1+S*S)/A;
dSdB = -S*S*S/2/A/A;
dAdR = 1.0/T;
for(int j=0 ; j<M+2; ++j ){
dFpdw[j] = 0.0;
dFdw[j] = 0.0;
dSdw[j] = 0.0;
}
for(int i=T-1 ; i>=0 ; --i ){
dBdR[i] = 2.0/T*R[i];
dRdF[i] = - mu*sigma*sign(F[i] - F[i+1]);
dRdFp[i] = mu*r[i] + mu*sigma*sign(F[i] - F[i+1]);
for(int j=0 ; j<M+2; ++j ){
if(i!=T-1){
dFpdw[j] = dFdw[j];
}
dFdw[j]=(1.0 - F[i]*F[i])*(x[i][j] + w[M+2-1]*dFpdw[j]);
dSdw[j]+=(dSdA*dAdR + dSdB*dBdR[i])*(dRdF[i]*dFdw[j] + dRdFp[i]*dFpdw[j]);
}
}
}
void TradingRRL::update_w(){
for(int j=0 ; j<M+2; ++j ){
w[j] += rho * dSdw[j];
}
}
void TradingRRL::fit(){
time_t tic, toc;
int pre_epoch_times;
int e_index;
pre_epoch_times = epoch_S.size();
calc_dSdw();
cout<<"Epoch loop start. Initial sharp's ratio is "<<S<<"."<<endl;
S_opt = S;
tic = time(0);
for(e_index=0 ; e_index<n_epoch; ++e_index ){
calc_dSdw();
if(S > S_opt){
S_opt = S;
w_opt = w;
}
epoch_S.push_back(S);
update_w();
if(e_index%progress_period == progress_period-1){
toc = time(0);
cout << "Epoch: " << e_index + pre_epoch_times + 1 << " / " <<n_epoch + pre_epoch_times <<". Shape's ratio: "<<S<<". Elapsed time: "<< difftime(toc, tic) <<" sec."<< endl;
}
}
toc = time(0);
cout << "Epoch: " << e_index + pre_epoch_times << " / " <<n_epoch + pre_epoch_times <<". Shape's ratio: "<<S<<". Elapsed time: "<< difftime(toc, tic) <<" sec."<< endl;
w = w_opt;
calc_dSdw();
cout << "Epoch loop end. Optimized sharp's ratio is "<<S_opt<<"."<< endl;
}
void TradingRRL::save_weight(){
ofstream ofs1("w.csv");
for(int j=0 ; j<M+2; ++j ){
ofs1<<w[j]<<endl;
}
ofstream ofs2("epoch_S.csv");
for(int e_index=0; e_index < (int)epoch_S.size(); ++e_index)
{
ofs2<<epoch_S[e_index]<<endl;
}
/*
ofstream ofs3("r.csv");
for(int j=0 ; j<T+M; ++j ){
ofs3<<r[j]<<endl;
}
*/
}
void TradingRRL::load_weight(){
ifstream ifs("w.csv");
vector<double> tmp_w;
double tmp_wdbl;
int read_count =0;
// --- read data
string line;
while (getline(ifs, line)){
stringstream ss;
ss << line;
ss >> tmp_wdbl;
tmp_w.push_back(tmp_wdbl);
read_count +=1;
}
w = tmp_w;
}
int main()
{
string fname = "USDJPY30.csv";
int init_t = 6000;
int T = 1000;
int M = 200;
double mu = 10000;
double sigma = 0.04;
double rho = 1.0;
int n_epoch = 10000;
TradingRRL rrl(T, M, init_t, mu, sigma, rho, n_epoch);
rrl.load_csv(fname);
rrl.set_t_p_r();
rrl.fit();
rrl.save_weight();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment