Untitled
Startunknown
plain_text
4 years ago
18 kB
29
Indexable
//
// main.cpp
// Advisorbot
//
// Created by Nihal Yusof on 11/6/22.
//
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
#include <map>
#include <iomanip>
using namespace std;
enum class OrderBookType
{
bid, ask, unknown, asksale, bidsale
};
class OrderBookEntry
{
public:
OrderBookEntry(double _price,
double _amount,
std::string _timestamp,
std::string _product,
OrderBookType _orderType,
std::string username = "dataset");
static OrderBookType stringToOrderBookType(std::string s);
static bool compareByTimestamp(OrderBookEntry& e1, OrderBookEntry& e2)
{
return e1.timestamp < e2.timestamp;
}
static bool compareByPriceAsc(OrderBookEntry& e1, OrderBookEntry& e2)
{
return e1.price < e2.price;
}
static bool compareByPriceDesc(OrderBookEntry& e1, OrderBookEntry& e2)
{
return e1.price > e2.price;
}
double price;
double amount;
std::string timestamp;
std::string product;
OrderBookType orderType;
std::string username;
};
OrderBookEntry::OrderBookEntry(double _price,
double _amount,
std::string _timestamp,
std::string _product,
OrderBookType _orderType,
std::string _username)
: price(_price),
amount(_amount),
timestamp(_timestamp),
product(_product),
orderType(_orderType),
username(_username)
{
}
OrderBookType OrderBookEntry::stringToOrderBookType(std::string s)
{
if (s == "ask")
{
return OrderBookType::ask;
}
if (s == "bid")
{
return OrderBookType::bid;
}
return OrderBookType::unknown;
}
std::vector<std::string> tokenise(std::string csvLine, char separator)
{
std::vector<std::string> tokens;
signed int start, end;
std::string token;
start = csvLine.find_first_not_of(separator, 0);
do {
end = csvLine.find_first_of(separator, start);
if (start == csvLine.length() || start == end) break;
if (end >= 0) token = csvLine.substr(start, end - start);
else token = csvLine.substr(start, csvLine.length() - start);
tokens.push_back(token);
start = end + 1;
} while (end > 0);
return tokens;
}
OrderBookEntry stringsToOBE(std::vector<std::string> tokens)
{
double price, amount;
if (tokens.size() != 5) // bad
{
std::cout << "Bad line " << std::endl;
throw std::exception{};
}
// we have 5 tokens
try {
price = std::stod(tokens[3]);
amount = std::stod(tokens[4]);
}
catch (const std::exception& e) {
std::cout << "CSVReader::stringsToOBE Bad float! " << tokens[3] << std::endl;
std::cout << "CSVReader::stringsToOBE Bad float! " << tokens[4] << std::endl;
throw;
}
OrderBookEntry obe{ price,
amount,
tokens[0],
tokens[1],
OrderBookEntry::stringToOrderBookType(tokens[2]) };
return obe;
}
vector <string> Stringsplit(string str, const const char split)
{
istringstream iss(str); // 输入流
string token; // 接收缓冲区
vector <string> vecstr;
while (getline(iss, token, split)) // 以split为分隔符
{
vecstr.push_back(token);
//cout << token << endl; // 输出
}
return vecstr;
}
// Function to compute moving average
// of previous K elements
void ComputeMovingAverage(map <time_t, double> &mapData, int K, vector <string> &vecdata)
{
int i;
float sum = 0;
map<time_t, double>::reverse_iterator it = mapData.rbegin();
vector <double>vecinfo;
for (; it != mapData.rend(); it++)
{
vecinfo.push_back(it->second);
}
// Initial sum of K elements.
for (i = 0; i < K; i++)
{
sum += vecinfo[i];
cout << setprecision(2) << std::fixed;
//cout << sum / K << " ";
}
float avg;
for (i = K; i < vecdata.size(); i++)
{
sum -= vecinfo[i - K];
sum += vecinfo[i];
avg = sum / K;
//cout << setprecision(2) << std::fixed;
//cout << avg << " ";
}
cout << "The predict " << vecdata[1] << " " << vecdata[2] << " price over the last " << K << " timesteps was " << fixed << setprecision(8) << (double)sum / K << endl;
#if 0
// Initial sum of K elements.
for (i = 0; i < K; i++)
{
sum += arr[i];
cout << setprecision(2) << std::fixed;
cout << sum / K << " ";
}
for (i = K; i < N; i++) {
sum -= arr[i - K];
sum += arr[i];
avg = sum / K;
cout << setprecision(2) << std::fixed;
cout << avg << " ";
}
#endif
}
std::string getNextTime(std::vector<OrderBookEntry> & orders, std::string timestamp)
{
std::string next_timestamp = "";
for (OrderBookEntry& e : orders)
{
if (e.timestamp > timestamp)
{
next_timestamp = e.timestamp;
break;
}
}
if (next_timestamp == "")
{
next_timestamp = orders[0].timestamp;
}
return next_timestamp;
}
time_t GetTime(string timestamp)
{
vector <string> vecstr = Stringsplit(timestamp, ' ');
vector <string> dateinfo = Stringsplit(vecstr[0], '/');
struct tm* target_time;
time_t rawtime;
time(&rawtime);
target_time = localtime(&rawtime); // 其它参数
if (dateinfo.size() > 2)
{
vector <string> timeinfo = Stringsplit(vecstr[1], ':');
target_time->tm_year = atoi(dateinfo[0].c_str()) - 1900;
target_time->tm_mon = atoi(dateinfo[1].c_str()) - 1; // 月 - 1
target_time->tm_mday = atoi(dateinfo[2].c_str()); // 日
if (timeinfo.size() > 2)
{
target_time->tm_hour = atoi(timeinfo[0].c_str()); // 时
target_time->tm_min = atoi(timeinfo[1].c_str()); // 分
vector <string> vecsec = Stringsplit(timeinfo[2], '.');
if (vecsec.size() > 0)
{
target_time->tm_sec = atoi(vecsec[0].c_str()); // 秒
time_t t1 = mktime(target_time);
//cout << timeinfo[0] << " " << timeinfo[1] << " " << timeinfo[2] << endl;
//cout << t1 << endl;
return t1;
}
//
}
}
return 0;
}
int main()
{
std::ifstream csvFile{ "/Users/nihal/Desktop/Advisorbot/Advisorbot/20200317.csv"};
std::string line;
std::vector<OrderBookEntry> entries;
std::string currentTime;
map <time_t, string>::iterator iter;
map <time_t, string>::iterator enditer;
map <time_t, string> mapstr;
bool first = true;
if (csvFile.is_open())
{
while (std::getline(csvFile, line))
{
try
{
// cout << "line=" << line << endl;
OrderBookEntry obe = stringsToOBE(tokenise(line, ','));
entries.push_back(obe);
//cout << "price=" << obe.price << " amount=" << obe.amount << " timestamp=" << obe.timestamp
// << " product=" << obe.product << " orderType="
//<< " username=" << obe.username << endl;
}
catch (const std::exception& e)
{
std::cout << "CSVReader::readCSV bad data" << std::endl;
}
}// end of while
}
else
std::cout << "open failure " << endl;;
while (1)
{
std::cout << "Please enter a command, or help for a list of commands: ";
char szBuf[32] = { 0 };
cin.getline(szBuf, 32);
string str = szBuf;
if (str.find("help") != string::npos)
{
//cout << "str=" << str << endl;
if (str == "help")
{
std::cout << "The available commands are help, help <cmd>, prod, min, max, avg, predict, time, step, last\n";
}
else
{
int pos = str.find(" ");
//cout << "pos=" << pos << endl;
if (pos != string::npos)
{
string cmd;
cmd.assign(str.c_str() + pos + 1, str.size() - pos - 1);
if (cmd == "avg")
{
std::cout << "avg ETH/BTC bid 10 -> average ETH/BTC bid over last 10 time steps\n";
}
else if (cmd == "prod")
{
std::cout << "prod -> ETH/BTC,DOGE/BTC\n";
}
else if (cmd == "min")
{
std::cout << "min ETH/BTC ask -> The min ask for ETH/BTC is 1.0\n";
}
else if (cmd == "max")
{
std::cout << "max ETH/BTC ask -> The max ask for ETH/BTC is 1.0\n";
}
else if (cmd == "predict")
{
std::cout << "predict max ETH/BTC bid -> The average ETH/BTC ask price over the last 10 timesteps was 1.0\n";
}
else if (cmd == "predict")
{
std::cout << "predict max ETH/BTC bid -> The average ETH/BTC ask price over the last 10 timesteps was 1.0\n";
}
else if (cmd == "time")
{
std::cout << "time -> 2020/03/17 17:01:24\n";
}
else if (cmd == "step")
{
std::cout << "step -> 2020/03/17 17:01:30\n";
}
else if (cmd == "last")
{
std::cout << "last -> 2020/03/17 17:01:30\n";
}
}
//std::cout << "avg ETH/BTC bid 10 -> average ETH/BTC bid over last 10 time steps\n";
}
}
else if (str == "prod")
{
//std::cout << "ETH/BTC,DOGE/BTC\n";
map <string, string> mapprod;
for (auto data : entries)
{
mapprod[data.product] = data.product;
}
for (auto data : mapprod)
{
cout << data.first << ",";
}
cout << endl;
}
else if (strncmp(str.c_str(), "min", 3) == 0)
{
vector <string> vecstr = Stringsplit(str, ' ');
OrderBookType type = OrderBookType::bid;
if (vecstr[2] == "ask")
type = OrderBookType::ask;
map <double, double> mapprice;
for (auto data : entries)
{
if (data.product == vecstr[1] && data.orderType == type)
mapprice[data.price] = mapprice[data.price];
}
if (mapprice.size() > 0)
cout << "The min " << vecstr[2] << " for " << vecstr[1] << " is " << fixed << setprecision(8) << mapprice.begin()->first << endl;
}
else if (strncmp(str.c_str(), "max", 3) == 0)
{
vector <string> vecstr = Stringsplit(str, ' ');
OrderBookType type = OrderBookType::bid;
if (vecstr[2] == "ask")
type = OrderBookType::ask;
map <double, double> mapprice;
for (auto data : entries)
{
if (data.product == vecstr[1] && data.orderType == type)
mapprice[data.price] = mapprice[data.price];
}
if (mapprice.size() > 0)
{
map <double, double>::iterator iter = --mapprice.end();
cout << "The max " << vecstr[2] << " for " << vecstr[1] << " is " << fixed << setprecision(8) << iter->first << endl;
// cout << " The max ask for ETH/BTC is " << fixed << setprecision(8) << iter->first << endl;
}
}
else if (str.find("avg") != string::npos)
{
vector <string> vecdata = Stringsplit(str, ' ');
cout << vecdata[0] << " [" << vecdata[1] << "] [" << vecdata[2] << "] [" << vecdata[3] << "]" << endl;
map <time_t, double> maptime;
for (auto data : entries)
{
OrderBookType type = OrderBookType::bid;
if (vecdata[2] == "ask")
type = OrderBookType::ask;
map <double, double> mapprice;
if (data.product != vecdata[1] || data.orderType != type)
continue;
//cout << " time= " << data.timestamp << " price=" << data.price << " pro=" << data.product << " orderType=" << static_cast<std::underlying_type<OrderBookType>::type>(data.orderType) << endl;
time_t cur = GetTime(data.timestamp);
maptime[cur] = data.price;
}
int num = atoi(vecdata[3].c_str());
int min = maptime.size() > num ? num : maptime.size();
double total = 0;
int count = 0;
map<time_t, double>::reverse_iterator it = maptime.rbegin();
while (1)
{
double s = it->second;
if (it == maptime.rend())
break;
it++;
if (it == maptime.rend())
break;
double s1 = it->second;
//cout << " s= " << s << " s1=" << s1 << endl;
//cout << "last time=" << s << endl;
//cout << "current time=" << s1 << endl;
total += (s1 + s);
count++;
if (count >= min)
break;
}
cout << "The average " << vecdata[1] << " " << vecdata[2] << " price over the last " << min << " timesteps was " << fixed << setprecision(8) << (double)total / num << endl;
}
else if (str.find("predict") != string::npos)
{
vector <string> vecdata = Stringsplit(str, ' ');
cout << vecdata[0] << " [" << vecdata[1] << "] [" << vecdata[2] << "] [" << vecdata[3] << "]" << endl;
map <time_t, double> maptime;
for (auto data : entries)
{
OrderBookType type = OrderBookType::bid;
if (vecdata[3] == "ask")
type = OrderBookType::ask;
map <double, double> mapprice;
if (data.product != vecdata[2] || data.orderType != type)
continue;
time_t cur = GetTime(data.timestamp);
maptime[cur] = data.price;
}
//int num = atoi(vecdata[3].c_str());
int num = 10;
int min = maptime.size() > num ? num : maptime.size();
ComputeMovingAverage(maptime, min, vecdata);
//cout << "The average ETH/BTC ask price over the last " << min << " timesteps was " << fixed << setprecision(2) << (double)total / num << endl;
}
else if (str.find("time") != string::npos)
{
if (first == true)
{
for (auto data : entries)
{
time_t cur = GetTime(data.timestamp);
vector <string> timeinfo = Stringsplit(data.timestamp, '.');
mapstr[cur] = timeinfo[0];
}
iter = mapstr.begin();
first = false;
}
cout << iter->second << endl;
}
else if (str.find("step") != string::npos)
{
if (first == true)
{
for (auto data : entries)
{
time_t cur = GetTime(data.timestamp);
vector <string> timeinfo = Stringsplit(data.timestamp, '.');
mapstr[cur] = timeinfo[0];
first = false;
}
iter = mapstr.begin();
}
else
iter++;
cout << iter->second << endl;
}
else if (str.find("last") != string::npos)
{
if (first == true)
{
for (auto data : entries)
{
time_t cur = GetTime(data.timestamp);
vector <string> timeinfo = Stringsplit(data.timestamp, '.');
mapstr[cur] = timeinfo[0];
}
first = false;
iter = mapstr.begin();
}
enditer = mapstr.end();
enditer--;
cout << enditer->second << endl;
}
}
//cout << str << endl;
return 0;
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单
// 入门使用技巧:
// 1. 使用解决方案资源管理器窗口添加/管理文件
// 2. 使用团队资源管理器窗口连接到源代码管理
// 3. 使用输出窗口查看生成输出和其他消息
// 4. 使用错误列表窗口查看错误
// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件
Editor is loading...