Skip to content

Commit 2f46144

Browse files
committed
fix cmc scrape + remove price_btc+day_volume_btc from monitored_pairs
1 parent 35eb2e7 commit 2f46144

File tree

3 files changed

+39
-31
lines changed

3 files changed

+39
-31
lines changed

README.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
# OpenAT: Open Source Algorithmic Trading Library
2-
[![Build Status](https://travis-ci.org/galeone/openat.svg?branch=master)](https://travis-ci.org/galeone/openat)
32

43
OpenAT provides an easy to use C++ interface for working with (crypto-)currencies markets and exchanges.
54

@@ -230,8 +229,7 @@ typedef struct {
230229
std::string name;
231230
currency_pair_t pair;
232231
long long int day_volume_usd;
233-
double day_volume_btc;
234-
double price_usd, price_btc;
232+
double price_usd;
235233
float percent_volume;
236234
std::time_t last_updated;
237235
} cm_market_t;

include/at/types.hpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -493,8 +493,7 @@ typedef struct {
493493
std::string name;
494494
currency_pair_t pair;
495495
long long int day_volume_usd;
496-
double day_volume_btc;
497-
double price_usd, price_btc;
496+
double price_usd;
498497
float percent_volume;
499498
std::time_t last_updated;
500499
} cm_market_t;
@@ -504,8 +503,6 @@ inline void to_json(json& j, const cm_market_t& t)
504503
j = json{{"name", t.name},
505504
{"pair", t.pair},
506505
{"day_volume_usd", t.day_volume_usd},
507-
{"day_volume_btc", t.day_volume_btc},
508-
{"price_btc", t.price_btc},
509506
{"price_usd", t.price_usd},
510507
{"percent_volume", t.percent_volume},
511508
{"last_updated", t.last_updated}};
@@ -517,8 +514,6 @@ inline void from_json(const json& j, cm_market_t& t)
517514
t.pair = j.at("pair").get<currency_pair_t>();
518515
t.day_volume_usd =
519516
static_cast<long long int>(j.at("day_volume_usd").get<double>());
520-
t.day_volume_btc = j.at("day_volume_btc").get<double>();
521-
t.price_btc = j.at("price").get<double>();
522517
t.percent_volume = j.at("percent_volume").get<float>();
523518
t.last_updated = j.at("last_updated").get<std::time_t>();
524519
}

src/at/coinmarketcap.cc

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -59,33 +59,40 @@ std::vector<cm_market_t> CoinMarketCap::markets(std::string currency_symbol)
5959
toupper(currency_symbol);
6060
auto id = _symbol_to_id.find(currency_symbol);
6161
currency_symbol = id != _symbol_to_id.end() ? id->second : currency_symbol;
62-
std::string page =
63-
req.getHTML(_reverse_host + "currencies/" + currency_symbol + "/");
62+
std::string page = req.getHTML(_reverse_host + "currencies/" +
63+
currency_symbol + "/markets/");
6464

6565
CDocument doc;
6666
doc.parse(page.c_str());
67-
CSelection table = doc.find("#markets-table tbody");
67+
CSelection table = doc.find("tbody");
6868
if (table.nodeNum() == 0) {
69-
throw std::runtime_error(
70-
"Unable to find table with ID markets-table, on " + _reverse_host +
71-
"currencies/" + currency_symbol);
69+
throw std::runtime_error("Unable to find a table on " + _reverse_host +
70+
"currencies/" + currency_symbol + "/markets/");
7271
}
7372

7473
std::vector<cm_market_t> ret;
7574
CSelection rows = table.nodeAt(0).find("tr");
7675
auto now =
7776
std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
77+
78+
auto _to_number_string = [](std::string text) -> std::string {
79+
text.erase(std::remove(text.begin(), text.end(), ','), text.end());
80+
text.erase(std::remove(text.begin(), text.end(), '$'), text.end());
81+
text.erase(std::remove(text.begin(), text.end(), ' '), text.end());
82+
return text;
83+
};
7884
for (size_t i = 0; i < rows.nodeNum(); ++i) {
7985
CNode row = rows.nodeAt(i);
8086
CSelection fields = row.find("td");
81-
if (fields.nodeNum() != 9) {
82-
throw std::runtime_error("CMC markets: expected 9 columns, got " +
87+
if (fields.nodeNum() != 10) {
88+
throw std::runtime_error("CMC markets: expected 10 columns, got " +
8389
std::to_string(fields.nodeNum()));
8490
}
8591

8692
// Skip markets not updated recently
8793
// 8: updated
88-
std::string updated_string = fields.nodeAt(8).text();
94+
std::string updated_string =
95+
fields.nodeAt(9).find("div").nodeAt(0).text();
8996
at::tolower(updated_string);
9097
if (updated_string != "recently") {
9198
continue;
@@ -101,31 +108,39 @@ std::vector<cm_market_t> CoinMarketCap::markets(std::string currency_symbol)
101108
auto first = pair_string.substr(0, split_pos);
102109
auto second = pair_string.substr(split_pos + 1, pair_string.length());
103110

104-
// 3: volumes <span data-usd="value", data-btc="value">
105-
CNode span = fields.nodeAt(3).find("span").nodeAt(0);
106-
long long int day_volume_usd = std::stoull(span.attribute("data-usd"));
107-
double day_volume_btc = std::stod(span.attribute("data-btc"));
111+
// 3: volumes <div>$1,2,34,5</div>
112+
std::string usd_volume_string =
113+
_to_number_string(fields.nodeAt(3).find("div").nodeAt(0).text());
114+
115+
long long int day_volume_usd = std::stoull(usd_volume_string);
116+
117+
// 4: prices <tr>$12,12,12.xx</tr>
118+
std::string price_usd_string =
119+
_to_number_string(fields.nodeAt(4).text());
108120

109-
// 4: prices <span data-usd, data-btc
110-
span = fields.nodeAt(4).find("span").nodeAt(0);
111-
double price_usd = std::stod(span.attribute("data-usd"));
112-
double price_btc = std::stod(span.attribute("data-btc"));
121+
// If there is a * in the string, the price is an outlier
122+
// and we ignore this row.
123+
if (price_usd_string.find('*') != std::string::npos) {
124+
continue;
125+
}
126+
double price_usd = std::stod(price_usd_string);
113127

114-
// 5: xx.yy% percentage
115-
std::string percentage_string = fields.nodeAt(5).text();
128+
// 5: xx.yy% percentage <div>a.b%</div>
129+
std::string percentage_string =
130+
fields.nodeAt(5).find("div").nodeAt(0).text();
116131
// remove %
117132
percentage_string.pop_back();
118133
float percent_volume = std::stof(percentage_string);
119134

120-
// 6,7: category, feed type unused
135+
// 6 effective liquidity: unused
136+
// 7 category: unused
137+
// 8 fee type unused
121138

122139
cm_market_t market{
123140
.name = name,
124141
.pair = currency_pair_t(first, second),
125142
.day_volume_usd = day_volume_usd,
126-
.day_volume_btc = day_volume_btc,
127143
.price_usd = price_usd,
128-
.price_btc = price_btc,
129144
.percent_volume = percent_volume,
130145
.last_updated = now,
131146
};

0 commit comments

Comments
 (0)