Last active
February 8, 2018 08:55
-
-
Save 1ma/846bc62499362478ac902baa2b84da99 to your computer and use it in GitHub Desktop.
This file contains 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
<?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