Skip to content

Instantly share code, notes, and snippets.

@1ma
Last active February 8, 2018 08:55
Show Gist options
  • Save 1ma/846bc62499362478ac902baa2b84da99 to your computer and use it in GitHub Desktop.
Save 1ma/846bc62499362478ac902baa2b84da99 to your computer and use it in GitHub Desktop.
<?php
declare(strict_types=1);
if (
1 === \version_compare('7.1.0', PHP_VERSION) ||
false === \extension_loaded('curl')
) {
\fwrite(STDERR, "bye bye\n");
exit(1);
}
// Usage: $ nohup php collector.php 1>> prices.csv 2>> problems.txt &
// Column description:
// 1. Unix timestamp of the reading (returned by Bitstamp's API), integer
// 2. highest bid from the order book (in USD), float
// 3. lowest ask from the order book (in USD), float
// 4. demand (in USD), summation of { bid(i).price times bid(i).amount}, float
// 5. supply (in USD), summation of { ask(i).price times ask(i).amount}, float
// 6. demand (in satoshis), summation of { bid(i).amount times 10^8 }, integer
// 6. supply (in satoshis), summation of { ask(i).amount times 10^8 }, integer
// Seconds in-between API calls.
// At the time of writing (2018-02-01) Bitstamp's HTTP API has a rate limiting
// policy set at 600 calls every 10 minutes (roughly 1 req/s).
// Bitstamp updates the book every 5-10 seconds.
\define('CALL_FREQUENCY', 10);
function parse(array $halfBook) {
$satSum = 0;
$usdSum = 0.0;
foreach ($halfBook as $record) {
$satSum += (int)\str_replace('.', '', $record[1]);
$usdSum += $record[0] * $record[1];
}
return [(string) $satSum, \number_format($usdSum, 2, '.', '')];
}
// Wait until approximately CALL_FREQUENCY seconds have passed
// since $from was initialised, or else don't wait at all.
function wait(int $from) {
if (CALL_FREQUENCY > $to = \time() - $from) {
\sleep(CALL_FREQUENCY - $to);
}
}
do {
try {
$from = \time();
$curl = \curl_init();
\curl_setopt($curl, CURLOPT_URL, 'https://www.bitstamp.net/api/order_book/');
\curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
\curl_setopt($curl, CURLOPT_TIMEOUT, CALL_FREQUENCY);
\curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, CALL_FREQUENCY);
if (false === $response = \curl_exec($curl)) {
throw new \RuntimeException(sprintf(
"cURL error %s: %s\n",
\curl_errno($curl), \curl_error($curl)
));
}
$book = \json_decode($response);
$when = $book->timestamp;
$bid = $book->bids[0][0];
$ask = $book->asks[0][0];
[$btcDemand, $usdDemand] = \parse($book->bids);
[$btcSupply, $usdSupply] = \parse($book->asks);
\fwrite(STDOUT, "$when,$bid,$ask,$usdDemand,$usdSupply,$btcDemand,$btcSupply\n");
} catch (\Throwable $t) {
\fwrite(STDERR, \sprintf(
"[%s] '%s' thrown: %s\n",
\date('Y-m-d H:i:s'), get_class($t), $t->getMessage()
));
} finally {
\wait($from);
}
} while(true);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment