Created
December 27, 2019 09:50
-
-
Save journeytosilius/dcb171ef5ddfe4a87b9f2242135ff866 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
SAFETY PIG _ | |
_._ _..._ .-', _.._(`)) | |
'-. ` ' /-._.-' ',/ | |
) \ '. | |
/ _ _ | \ | |
| a a / | | |
\ .-. ; | |
'-('' ).-' ,' ; | |
'-; | .' | |
\ \ / | |
| 7 .__ _.-\ \ | |
| | | ``/ /` / */ | |
/* | |
#include "../influxdb.hpp" */ | |
#include "lib/influxdb-cpp/influxdb.hpp" | |
#include "lib/json/single_include/nlohmann/json.hpp" | |
#include "lib/yaml-cpp/include/yaml-cpp/yaml.h" | |
#include <algorithm> | |
#include <array> | |
#include <chrono> | |
#include <fstream> | |
#include <functional> | |
#include <iomanip> | |
#include <iostream> | |
#include <map> | |
#include <plplot/plstream.h> | |
#include <ta-lib/ta_func.h> | |
#include <thread> | |
#include <tuple> | |
#include <typeinfo> | |
#include <vector> | |
using namespace std; | |
using namespace std::chrono; | |
using namespace nlohmann; | |
template <typename T> using d_duration = duration<double, T>; | |
enum class EPrecision { SECONDS, MILLISECONDS, MICROSECONDS, NANOSECONDS }; | |
class Precision { | |
private: | |
double convert_to_req_precision(nanoseconds epoch, EPrecision precision) { | |
switch (precision) { | |
case EPrecision::SECONDS: { | |
return d_duration<ratio<1, 1>>(epoch).count(); | |
} break; | |
case EPrecision::MILLISECONDS: { | |
return d_duration<milli>(epoch).count(); | |
} break; | |
case EPrecision::MICROSECONDS: { | |
return d_duration<micro>(epoch).count(); | |
} break; | |
case EPrecision::NANOSECONDS: { | |
return d_duration<nano>(epoch).count(); | |
} break; | |
} | |
} | |
public: | |
double stamp_to_precision(unsigned long long a_timestamp, | |
EPrecision required_precision) { | |
size_t val_count = to_string(a_timestamp).length(); | |
static map<size_t, EPrecision> valid_epoch_lenghts = { | |
{10, EPrecision::SECONDS}, | |
{13, EPrecision::MILLISECONDS}, | |
{16, EPrecision::MICROSECONDS}, | |
{19, EPrecision::NANOSECONDS}}; | |
if (auto it = valid_epoch_lenghts.find(val_count); | |
it != valid_epoch_lenghts.end()) | |
{ | |
auto &[key, input_precision] = *it; | |
switch (input_precision) { | |
case EPrecision::SECONDS: { | |
auto is_seconds = seconds(a_timestamp); | |
return convert_to_req_precision(is_seconds, required_precision); | |
} break; | |
case EPrecision::MILLISECONDS: { | |
auto is_milliseconds = milliseconds(a_timestamp); | |
return convert_to_req_precision(is_milliseconds, required_precision); | |
} break; | |
case EPrecision::MICROSECONDS: { | |
auto is_microseconds = microseconds(a_timestamp); | |
return convert_to_req_precision(is_microseconds, required_precision); | |
} break; | |
case EPrecision::NANOSECONDS: { | |
auto is_nanoseconds = nanoseconds(a_timestamp); | |
return convert_to_req_precision(is_nanoseconds, required_precision); | |
} break; | |
} | |
} else { | |
cout << "No valid epoch lenght provided, terminating" << endl; | |
} | |
} | |
}; | |
class TestVector { | |
public: | |
struct vector_contents { | |
vector<string> content; | |
}; | |
public: | |
auto return_vec_of_vecs() { | |
vector<vector_contents> final_vec(3); | |
for (size_t i = 0; i < 3; i++) { | |
vector<string> vector_box; | |
ostringstream str_stream; | |
str_stream << "vec string " << to_string(i); | |
string final_string = str_stream.str(); | |
cout << final_string << endl; | |
vector_box.push_back(final_string); | |
cout << vector_box.size() << endl; | |
final_vec.at(i).content = vector_box; | |
} | |
cout << final_vec.size() << endl; | |
return final_vec; | |
} | |
}; | |
class IntervalConverter { | |
public: | |
struct interval_struct { | |
std::string label; | |
int minutes; | |
}; | |
std::vector<interval_struct> intervals = { | |
{"1m", 1}, {"2m", 2}, {"3m", 3}, | |
{"4m", 4}, {"5m", 5}, {"6m", 6}, | |
{"8m", 8}, {"9m", 9}, {"10m", 10}, | |
{"12m", 12}, {"15m", 15}, {"16m", 16}, | |
{"18m", 18}, {"20m", 20}, {"24m", 24}, | |
{"30m", 30}, {"32m", 32}, {"36m", 36}, | |
{"40m", 40}, {"45m", 45}, {"48m", 48}, | |
{"60m", 60}, {"72m", 72}, {"80m", 80}, | |
{"90m", 90}, {"96m", 96}, {"120m", 120}, | |
{"144m", 144}, {"160m", 160}, {"180m", 180}, | |
{"240m", 240}, {"288m", 288}, {"360m", 360}, | |
{"480m", 480}, {"720m", 720}, {"1440m", 1440}, | |
{"1h", 60}, {"2h", 120}, {"3h", 180}, | |
{"4h", 240}, {"6h", 360}, {"8h", 480}, | |
{"12h", 720}, {"24h", 1440} | |
}; | |
public: | |
string getMinutes(string req_interval) | |
{ | |
for (auto &[k, v] : intervals) | |
{ | |
if (k == req_interval) { | |
string minutes_string = to_string(v); | |
return minutes_string; | |
} else { | |
continue; | |
} | |
} | |
} | |
}; | |
class LoadAggregateDataInRange { | |
public: | |
string queryGenerator(int from_time, int till_time, string interval) { | |
IntervalConverter convert_interval; | |
ostringstream quote_stream; | |
quote_stream << "\"binance_nanousdt_1m\""; | |
string quote_measurement = "\"crypto\".\"autogen\"." + quote_stream.str(); | |
string interval_str = convert_interval.getMinutes(interval); | |
char const *offset = "0"; | |
string from_time_str = to_string(from_time); | |
string till_time_str = to_string(till_time); | |
char const *fill_type = "previous"; | |
string select = | |
"time AS \"time\", first(\"open\") AS \"open\",last(\"close\") AS " | |
"\"close\",max(\"high\") AS \"high\",min(\"low\") AS " | |
"\"low\",sum(\"volume\") AS \"volume\""; | |
string select_extended = | |
"sum(\"trades\") AS \"trades\",sum(\"buy_vol\") AS " | |
"\"buy_vol\",sum(\"sell_vol\") AS \"sell_vol\",mean(\"vol_pct_buy\" ) " | |
"AS \"vol_pct_buy\",mean(\"vol_pct_sell\") AS \"vol_pct_sell\""; | |
string quote_select = "time AS \"time\", last(\"close\") AS \"quote_dv\""; | |
ostringstream query_string; | |
query_string << "SELECT " << select << " FROM " << quote_measurement | |
<< " WHERE time >= " << from_time_str << "s" | |
<< " AND time <= " << till_time_str << "s" | |
<< " GROUP BY time(" << interval_str << "m" | |
<< "," << offset << "m" | |
<< ")" | |
<< "FILL(" << fill_type << ")" | |
<< " ORDER BY time DESC"; | |
string final_string = query_string.str(); | |
return final_string; | |
} | |
}; | |
class YamlParser { | |
public: | |
struct indicator_table { | |
string indicator; | |
map<string, int> params; | |
map<string, vector<int>> outputs; | |
map<string, string> clone_tag; | |
string module; | |
string group_tag; | |
bool in_group; | |
}; | |
public: | |
struct indicator { | |
vector<indicator_table> ind_cont; | |
}; | |
public: | |
auto parseYaml() { | |
const YAML::Node config = YAML::LoadFile("../simple.yaml"); | |
int ind_num = config.size(); | |
vector<indicator> indicator_container(ind_num); | |
vector<indicator_table> grouped_table; | |
for (auto const &iter : config) | |
{ | |
indicator_table table; | |
/* vector<indicator_table> grouped_table; | |
*/ | |
table.indicator = iter["indicator"].as<string>(); | |
const YAML::Node &par = iter["params"]; | |
const YAML::Node &outs = iter["outputs"]; | |
const YAML::Node &clone_t = iter["clone_tag"]; | |
const YAML::Node &group_t = iter["group_tag"]; | |
table.module = iter["module"].as<string>(); | |
table.group_tag = iter["group_tag"].as<string>(); | |
table.in_group = iter["in_group"].as<bool>(); | |
for (auto iter = clone_t.begin(); iter != clone_t.end(); ++iter) { | |
auto variable = *iter; | |
for (size_t i = 0; i < 2; i++) { | |
vector<string> vec(2); | |
vec[i] = variable.as<string>(); | |
pair<string, string> pr; | |
pr.first = vec[0]; | |
pr.second = vec[1]; | |
table.clone_tag.emplace(pr); | |
} | |
} | |
for (auto out_iter = outs.begin(); out_iter != outs.end(); ++out_iter) | |
{ | |
const YAML::Node &output_name = *out_iter; | |
for (auto const &inner_iter : *out_iter) | |
{ | |
for (auto sub_iter = inner_iter.begin(); sub_iter != inner_iter.end(); | |
++sub_iter) { | |
string output_id = output_name[0].as<string>(); | |
const YAML::Node &rgb_value = *sub_iter; | |
vector<int> colors; | |
colors.push_back(rgb_value.as<int>()); | |
table.outputs.insert(pair<string, vector<int>>(output_id, colors)); | |
} | |
} | |
} | |
for (auto it = par.begin(); it != par.end(); ++it) | |
{ | |
YAML::Node key = it->first; | |
YAML::Node value = it->second; | |
string param_name = key.as<string>(); | |
int param_value = value.as<int>(); | |
table.params.insert(pair<string, int>(param_name, param_value)); | |
} | |
grouped_table.push_back(table); | |
} | |
for (size_t i = 0; i < ind_num; i++) { | |
indicator_container.at(i).ind_cont = grouped_table; | |
} | |
return indicator_container; | |
} | |
}; | |
class MarketObject { | |
public: | |
struct market_data { | |
vector<string> dates; | |
vector<double> open; | |
vector<double> close; | |
vector<double> high; | |
vector<double> low; | |
vector<double> volume; | |
}; | |
public: | |
auto jsontoArray(string resp) | |
{ | |
json data_json = json::parse(resp); | |
auto get_values = data_json["results"][0]["series"][0]["values"]; | |
market_data m; | |
int const json_count = get_values.size(); | |
for (int i = 0; i < json_count; ++i) { | |
m.dates.push_back(get_values[i][0]); | |
m.open.push_back(get_values[i][1]); | |
m.close.push_back(get_values[i][2]); | |
m.high.push_back(get_values[i][3]); | |
m.low.push_back(get_values[i][4]); | |
m.volume.push_back(get_values[i][5]); | |
} | |
return m; | |
} | |
public: | |
auto thread_jsontoArray(string, resp) | |
{ | |
json data_json = json::parse(resp); | |
auto get_values = data_json["results"][0]["series"][0]["values"]; | |
market_data m; | |
int const json_count = get_values.size(); | |
for (int i = 0; i < json_count; ++i) { | |
m.dates.push_back(get_values[i][0]); | |
m.open.push_back(get_values[i][1]); | |
m.close.push_back(get_values[i][2]); | |
m.high.push_back(get_values[i][3]); | |
m.low.push_back(get_values[i][4]); | |
m.volume.push_back(get_values[i][5]); | |
} | |
return m; | |
} | |
}; | |
int main(int argc, char const *argv[]) | |
{ | |
influxdb_cpp::server_info si("127.0.0.1", 8086, "crypto", "rtmtb_admin", | |
"rtmtb_password"); | |
string resp; | |
LoadAggregateDataInRange load_data; | |
Precision get_precision; | |
unsigned long long const epoch_start = 1569196800; | |
unsigned long long const epoch_end = 1569283199; | |
/* unsigned long long const epoch_start = 1569888000; | |
unsigned long long const epoch_end = 1572566399; */ | |
/* unsigned long long const epoch_start = 1546300800; | |
unsigned long long const epoch_end = 1577836799; */ | |
char const *interval = "5m"; | |
double from_time = | |
get_precision.stamp_to_precision(epoch_start, EPrecision::SECONDS); | |
double till_time = | |
get_precision.stamp_to_precision(epoch_end, EPrecision::SECONDS); | |
influxdb_cpp::query( | |
resp, load_data.queryGenerator(from_time, till_time, interval), si); | |
MarketObject ret_market_object; | |
auto axe = ret_market_object.jsontoArray(resp); | |
YamlParser parse_template; | |
auto ind_table = parse_template.parseYaml(); | |
cout << ind_table.size() << endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment