Change data API from Poloniex to CryptoCompare.com

This commit is contained in:
Joshua Seigler 2018-02-15 16:06:30 -05:00
parent a6784a0240
commit 5ebec31d80
3 changed files with 93 additions and 79 deletions

View file

@ -18,7 +18,7 @@ $router->map('GET', '/', function() {
});
// map cryptocurrency stuff
$router->map( 'GET', '/charts/[dark|light|sparkline|candlestick|filled:theme]/[a:curA]-[btc|usdt:curB]/[a:duration]/[svg|png:format]', function($theme, $curA, $curB, $duration, $format) {
$router->map( 'GET', '/charts/[dark|light|sparkline|candlestick|filled:theme]/[a:curA]-[a:curB]/[a:duration]/[svg|png:format]', function($theme, $curA, $curB, $duration, $format) {
require __DIR__ . '/views/chart.php';
return renderChart(
$theme,
@ -38,11 +38,5 @@ if( !$match || !is_callable( $match['target'] ) || false === call_user_func_arra
header( $_SERVER["SERVER_PROTOCOL"] . ' 404 Not Found');
echo '<h1>404 Not Found</h1><p>Page not found</p>';
}
try {
} catch (Exception $e) {
header($_SERVER["SERVER_PROTOCOL"]." 500 Server Error", true, 500);
echo '<h1>500 Server Error</h1><p>There was a problem generating this page</p>';
return true;
}
?>

View file

@ -45,33 +45,8 @@ function renderChart(
$format = 'svg'
) {
$durations = [
/*
valid resolutions in seconds:
300 5m
900 15m
1800 30m
7200 2h
14400 4h
86400 24h
*/
'1y'=> [
'duration' => 60 * 60 * 24 * 365,
'resolution' => 86400 // 24h
],
'30d'=> [
'duration' => 60 * 60 * 24 * 30,
'resolution' => 14400 // 4h
],
'7d'=> [
'duration' => 60 * 60 * 24 * 7,
'resolution' => 7200 // 2h
],
'24h' => [
'duration' => 60 * 60 * 24 * 1,
'resolution' => 900 // 15m
]
];
$currencyA = strtoupper($currencyA);
$currencyB = strtoupper($currencyB);
$themes = [
'light'=>[
@ -137,47 +112,89 @@ function renderChart(
return false;
}
$durations = [
/* day, hour, minute */
'1y'=> [
'resolution' => 'day',
'limit' => 365,
'aggregate' => 7,
'cacheTimeSeconds' => 7 * 24 * 60 * 60
],
'30d'=> [
'resolution' => 'day',
'limit' => 30,
'aggregate' => 1,
'cacheTimeSeconds' => 24 * 60 * 60
],
'7d'=> [
'resolution' => 'hour',
'limit' => 7 * 24,
'aggregate' => 4,
'cacheTimeSeconds' => 4 * 24 * 60 * 60
],
'24h' => [
'resolution' => 'minute',
'limit' => 24 * 60,
'aggregate' => 15,
'cacheTimeSeconds' => 15 * 60
]
];
if (array_key_exists($duration, $durations)) {
$dataDuration = $durations[$duration]['duration'];
$dataResolution = $durations[$duration]['resolution'];
$resolution = $durations[$duration]['resolution'];
$limit = $durations[$duration]['limit'];
$aggregate = $durations[$duration]['aggregate'];
$cacheTimeSeconds = $durations[$duration]['cacheTimeSeconds'];
} else {
return false;
}
$supportedCurrencies = CacheManager::get('poloniex-supported-currencies');
if (is_null($supportedCurrencies)) {
$supportedCurrenciesJson = getJson('https://poloniex.com/public?command=returnCurrencies');
foreach ($supportedCurrenciesJson as $key => $value) {
if ($value->delisted == 0) {
$supportedCurrencies[] = strtolower($key);
}
}
CacheManager::set('poloniex-supported-currencies', $supportedCurrencies, 60 * 60 * 24 * 7); // asking once a week doesn't seem like too much
}
if (!in_array($currencyB, ['btc', 'usdt']) || !in_array($currencyA, $supportedCurrencies)) {
return false;
}
// $supportedCurrencies = CacheManager::get('cryptocompare-supported-currencies');
// if (is_null($supportedCurrencies)) {
// $supportedCurrenciesJson = getJson('https://min-api.cryptocompare.com/data/all/coinlist');
// $supportedCurrencies = [
// 'USD',
// 'EUR',
$pair = strtoupper($currencyB . '_' . $currencyA); // poloniex you strange
// ];
// foreach ($supportedCurrenciesJson->Data as $key => $value) {
// if ($value->IsTrading == 1) {
// $supportedCurrencies[] = $key;
// }
// }
// CacheManager::set('cryptocompare-supported-currencies', $supportedCurrencies, 60 * 60 * 24); // asking once a day seems reasonable
// }
$chartCacheKey = 'poloniex-'.$theme.'-'.$pair.'-'.$dataDuration.'-'.$format;
// $currencyA = strtoupper($currencyA);
// $currencyB = strtoupper($currencyB);
$result = CacheManager::get($chartCacheKey);
// if (!in_array($currencyA, $supportedCurrencies) || !in_array($currencyB, $supportedCurrencies)) {
// return false;
// }
$chartCacheKey = 'cryptocompare-'.$theme.'-'.$currencyA.'-'.$currencyB.'-'.$duration.'-'.$format;
$result = null;//CacheManager::get($chartCacheKey);
if (is_null($result)) {
$startTime = time() - $dataDuration;
$poloniexUrl = 'https://poloniex.com/public?command=returnChartData&currencyPair=' . $pair . '&start=' . $startTime . '&end=9999999999&period=' . $dataResolution;
$dataCacheKey = 'cryptocompare-'.$currencyA.'-'.$currencyB.'-'.$duration;
$cryptocompareJson = CacheManager::get($dataCacheKey);
$poloniexJson = CacheManager::get('poloniex-json-'.$pair.'-'.$dataDuration);
if(is_null($cryptocompareJson)) {
$cryptocompareJson = getJson('https://min-api.cryptocompare.com/data/histo'.
"$resolution?fsym=$currencyA&tsym=$currencyB&limit=$limit&aggregate=$aggregate");
if(is_null($poloniexJson)) {
$poloniexJson = getJson($poloniexUrl);
// Write to cache for next time
// Expires either in a minute, or 60s after the next data point is supposed to be available
$cacheTimeSeconds = max(60, end($poloniexJson)->date + $dataResolution - time() + 60);
CacheManager::set('poloniex-json-'.$pair.'-'.$dataDuration, $poloniexJson, $cacheTimeSeconds);
if ($cryptocompareJson->Response == 'Error') {
CacheManager::set($dataCacheKey, $cryptocompareJson, 60);
return false;
} else {
// Write to cache for next time
// Expires either in a minute, or 60s after the next data point is supposed to be available
$cacheTimeSeconds = max(60, $cryptocompareJson->TimeTo + $cacheTimeSeconds - time() + 60);
CacheManager::set($dataCacheKey, $cryptocompareJson, $cacheTimeSeconds);
}
} else {
$cacheTimeSeconds = max(60, end($poloniexJson)->date + $dataResolution - time() + 60);
$cacheTimeSeconds = max(60, $cryptocompareJson->TimeTo + $cacheTimeSeconds - time());
}
if ($format == 'svg') {
@ -192,16 +209,20 @@ function renderChart(
}
if ($theme == 'candlestick') {
$poloniexChart = new NeatCharts\CandlestickChart($poloniexJson, $chartOptions);
$chartData = $cryptocompareJson->Data;
foreach ($chartData as $item) {
$item->date = $item->time;
}
$neatChart = new NeatCharts\CandlestickChart($chartData, $chartOptions);
} else {
$chartData = [];
foreach ($poloniexJson as $item) {
$chartData[$item->date] = $item->weightedAverage;
foreach ($cryptocompareJson->Data as $item) {
$chartData[$item->time] = ($item->high + $item->low + $item->close) / 3;
}
$poloniexChart = new NeatCharts\LineChart($chartData, $chartOptions);
$neatChart = new NeatCharts\LineChart($chartData, $chartOptions);
}
$result = '<?xml version="1.0" standalone="no"?>' . PHP_EOL;
$result .= $poloniexChart->render();
$result .= $neatChart->render();
if ($format == 'png') {
$im = new Imagick();
@ -215,19 +236,18 @@ function renderChart(
CacheManager::set($chartCacheKey, $result, $cacheTimeSeconds);
$resultExpires = time() + $cacheTimeSeconds;
} else {
$resultExpires = CacheManager::getInfo($chartCacheKey)[ 'expired_time' ];
$resultExpires = CacheManager::getInfo($chartCacheKey)['expired_time'];
// TODO cache an object that has the data and a when-expired timestamp to avoid this cache-info lookup
$startTime = $resultExpires - $dataDuration;
}
header('Expires: '.gmdate(DateTime::RFC1123, $resultExpires));
if ($format == 'png') {
header('Content-Type: image/png');
header('Content-Disposition: inline; filename="Dash-chart-' . gmdate('Y-m-d\THis+0', $startTime) . '--' . gmdate('Y-m-d\THis+0') . '.png"');
header('Content-Disposition: inline; filename="Dash-chart-' . gmdate('Y-m-d\THis+0', $resultExpires) . '--' . gmdate('Y-m-d\THis+0') . '.png"');
echo $result;
} else if ($format == 'svg') {
header('Content-type: image/svg+xml; charset=utf-8');
header('Content-Disposition: inline; filename="Dash-chart-' . gmdate('Y-m-d\THis+0', $startTime) . '--' . gmdate('Y-m-d\THis+0') . '.svg"');
header('Content-Disposition: inline; filename="Dash-chart-' . gmdate('Y-m-d\THis+0', $resultExpires) . '--' . gmdate('Y-m-d\THis+0') . '.svg"');
$result = str_replace([
'@lineColor',
'@markerColor',

View file

@ -72,8 +72,8 @@
<section>
<h2>Transparent SVG and PNG charts with your favorite cryptocurrencies</h2>
<figure>
<img src="/charts/candlestick/dash-usdt/7d/svg" alt="Poloniex Dash/BTC price">
<figcaption>7 day Dash price candlesticks in USDT (Tether USD) <code><a href="/charts/candlestick/dash-usdt/7d/svg">https://cryptohistory.org/charts/candlestick/dash-usdt/7d/svg</a></code></figcaption>
<img src="/charts/candlestick/dash-usd/7d/svg" alt="Dash/USD price">
<figcaption>7 day Dash price candlesticks in USD <code><a href="/charts/candlestick/dash-usdt/7d/svg">https://cryptohistory.org/charts/candlestick/dash-usd/7d/svg</a></code></figcaption>
</figure>
<p>Sparklines too! ETH/BTC 7 days: <img src="/charts/sparkline/eth-btc/7d/svg" alt="ETH 7d chart" style="vertical-align: bottom;">
<code>&lt;img src=&quot;https://cryptohistory.org/charts/sparkline/eth-btc/7d/svg&quot; alt=&quot;ETH/BTC 7d chart&quot; style=&quot;vertical-align: bottom;&quot;&gt;</code>
@ -82,9 +82,9 @@
<section>
<h2>Build your own chart:</h2>
<p>The URL is flexible:<br>
<code>https://cryptohistory.org/charts/{theme}/{currency}-{btc|usdt}/{timespan}/{format}</code></p>
<code>https://cryptohistory.org/charts/{theme}/{currencyA}-{currencyB}/{timespan}/{format}</code></p>
<p>Theme: <code>dark</code>, <code>light</code>, or <code>sparkline</code>.</p>
<p>Currency: anything active on Poloniex. Supports prices in Bitcoin or Tether USD.</p>
<p>Currency: anything supported by CryptoCompare.com, including fiat.</p>
<p>Timespan: <code>1y</code>, <code>30d</code>, <code>7d</code>, or <code>24h</code>.</p>
<p>Format: <code>svg</code> (best) or <code>png</code>.</p>
<p>If you use svg format, you can control some of the colors with GET parameters: <code>lineColor</code>, <code>markerColor</code>, <code>risingColor</code>, <code>fallingColor</code>. Some examples: <code><a href="/charts/dark/maid-btc/7d/svg?lineColor=5593D7&markerColor=29578A">https://cryptohistory.com/charts/dark/maid-btc/7d/svg?lineColor=5593D7&amp;markerColor=29578A</a></code> <code><a href="/charts/candlestick/fct-btc/7d/svg?risingColor=FE8534&fallingColor=00BAE9">https://cryptohistory.org/charts/candlestick/fct-btc/7d/svg?risingColor=FE8534&amp;fallingColor=00BAE9</a></code>
@ -92,13 +92,13 @@
</section>
<section>
<h2>Examples:</h2>
<p>Ethereum 24h, dark SVG: <code><a href="/charts/dark/eth-btc/24h/svg" target="_blank">https://cryptohistory.org/charts/dark/eth-btc/24h/svg</a></code></p>
<p>Litecoin 30d, light PNG: <code><a href="/charts/light/ltc-btc/30d/png" target="_blank">https://cryptohistory.org/charts/light/ltc-btc/30d/png</a></code></p>
<p>Doge 1y, dark SVG, yellow line: <code><a href="/charts/dark/doge-btc/1y/svg?lineColor=BB9F32" target="_blank">https://cryptohistory.org/charts/dark/doge-btc/1y/svg?lineColor=BB9F32</a></code></p>
<p>Ethereum/Bitcoin 24h, dark SVG: <code><a href="/charts/dark/eth-btc/24h/svg" target="_blank">https://cryptohistory.org/charts/dark/eth-btc/24h/svg</a></code></p>
<p>Litecoin/Bitcoin 30d, light PNG: <code><a href="/charts/light/ltc-btc/30d/png" target="_blank">https://cryptohistory.org/charts/light/ltc-btc/30d/png</a></code></p>
<p>Doge/USD 1y, dark SVG, yellow line: <code><a href="/charts/dark/doge-usd/1y/svg?lineColor=BB9F32" target="_blank">https://cryptohistory.org/charts/dark/doge-usd/1y/svg?lineColor=BB9F32</a></code></p>
</section>
</main>
<footer>
Made by <a href="https://joshua.seigler.net/">Joshua Seigler</a> using <a href="https://github.com/seigler/neat-charts">seigler/neat-charts</a>, <a href="http://altorouter.com/">AltoRouter</a>, and <a href="http://www.phpfastcache.com/">phpfastcache</a> with data from the <a href="https://poloniex.com/support/api/">Poloniex public API</a>.
Made by <a href="https://joshua.seigler.net/">Joshua Seigler</a> using <a href="https://github.com/seigler/neat-charts">seigler/neat-charts</a>, <a href="http://altorouter.com/">AltoRouter</a>, and <a href="http://www.phpfastcache.com/">phpfastcache</a> with data from the <a href="https://www.cryptocompare.com/api/">CryptoCompare public API</a>.
</footer>
</body>
</html>