Coinbase PHP API Historic prices in GBP - coinbase-api

I collect crypto prices and save them to a database every minute.
There are times every now and then when my system is down, which creates gaps in my prices data.
I found out how to get Historic Prices between two time stamps. e.g:
https://api.pro.coinbase.com/products/ALGO-GBP/candles?start=2021-05-13T02:20:06.0Z&end=2021-05-13T09:44:12.0Z&granularity=300
When the system comes back up I have a PHP script that checks for gaps and then constructs the above URL call to get the prices.
This works well for most of the crypto, but for a few I get no data being returned, e.g. ATOM-GBP.
After some investigation I found it is because for these I must specify ATOM-USD, or ATOM-BTC.
The problem here is first knowing which one to use, and secondly, how to convert the returned price to GBP at the timestamp concerned.
Here is my snippet code:
<?php
date_default_timezone_set('Europe/London'); // YOUR timezone, of the server
ini_set('memory_limit', '256M');
?>
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css?v=<?=time();?>">
</head>
<body>
<H1> Missing Prices <?= date("Y-m-d H:i:s") ?> </H1>
<p>
<?php
error_reporting(E_ALL);
include 'cfg.php';
require_once ('vendor/autoload.php');
include ('db_conn.php');
use Coinbase\Wallet\Client as Client;
use Coinbase\Wallet\Configuration as Configuration;
$configuration = Configuration::apiKey($cbase_API_Key, $cbase_API_Secret);
$client = Client::create($configuration);
// List prices from local database
$price_sql = "
SELECT p1.ccode,
CONVERT_TZ(p1.tstamp,'Europe/London','UTC') ts1,
UNIX_TIMESTAMP(CONVERT_TZ(p1.tstamp,'Europe/London','UTC')) ut
FROM prices p1
WHERE p1.tstamp BETWEEN (NOW() - INTERVAL 5 DAY ) AND (NOW() - INTERVAL 3 DAY )
ORDER BY 1, 2
";
$stmt = $dbh->prepare($price_sql);
$stmt->execute();
$result = $stmt->get_result();
$data = $result->fetch_all(MYSQLI_ASSOC);
$num_rows = $result -> num_rows;
$prev_ut = -1;
$prev_ts = "";
$prev_curr = "";
$c = 0;
foreach ($data as $row)
{
if ( $prev_ut == -1 )
{
$prev_ut = $row['ut'];
$prev_ts = $row['ts1'];
$prev_curr = $row['ccode'];
}
$ut_diff = $row['ut'] - $prev_ut;
if ( $prev_curr != $row['ccode'] )
{
$ut_diff = 0;
}
// If the gap between current and previous row is over 5 minutes then we have a gap
if ( $ut_diff > 300 )
{
echo '<H2> Missing data for ' . $row['ccode'] . " between " .
$row['ts1'] . " and " . $prev_ts . " diff " . $ut_diff . "</H2>";
// Build up URL
$nxt_ts = DateTime::createFromFormat('Y-m-d H:i:s', $prev_ts );
$pts = $nxt_ts->format('Y-m-d H:i:s');
$strt = str_replace(' ', 'T', $prev_ts);
$end = str_replace(' ', 'T', $row['ts1']);
$url = "https://api.pro.coinbase.com/products/" . $row['ccode'] . "-GBP/candles?start=" . $strt . ".0Z&end=" . $end . ".0Z&granularity=300";
echo '<h3> ' . $url . '</h3>';
echo '<table border="1">';
echo '<tr>';
echo '<th> No</th>';
echo '<th> Currency </th>';
echo '<th> Time </th>';
echo '<th> Low </th>';
echo '<th> High </th>';
echo '<th> Open </th>';
echo '<th> Close </th>';
echo '<th> Volume </th>';
echo '</tr>';
// Use curl to get the data
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
$prices_json = json_decode(curl_exec($ch), true);
foreach($prices_json as $price )
{
$c++;
$utime = gmdate( 'r', $price[0]);
$low = $price[1];
$high = $price[2];
$open = $price[3];
$close = $price[4];
$volume = $price[5];
echo '<tr>';
echo '<td>' . $c . '</td>';
echo '<td>' . $row['ccode'] . '</td>';
echo '<td>' . $utime . '</td>';
echo '<td>' . $low . '</td>';
echo '<td>' . $high . '</td>';
echo '<td>' . $open . '</td>';
echo '<td>' . $close . '</td>';
echo '<td>' . $volume . '</td>';
echo '</tr>';
}
}
echo '</table>';
$prev_ut = $row['ut'];
$prev_ts = $row['ts1'];
$prev_curr = $row['ccode'];
}
?>
Results snippet:
Missing data for ATOM between 2021-05-13 09:44:12 and 2021-05-13 02:20:06 diff 26646
https://api.pro.coinbase.com/products/ATOM-GBP/candles?start=2021-05-13T02:20:06.0Z&end=2021-05-13T09:44:12.0Z&granularity=300
Warning: gmdate() expects parameter 2 to be integer, string given in fillpricegaps.php on line 172
No Currency Time Low High Open Close Volume
409 ATOM o t F o u
Missing data for BAL between 2021-05-13 09:44:15 and 2021-05-13 02:20:10 diff 26645
https://api.pro.coinbase.com/products/BAL-GBP/candles?start=2021-05-13T02:20:10.0Z&end=2021-05-13T09:44:15.0Z&granularity=300
Warning: gmdate() expects parameter 2 to be integer, string given in fillpricegaps.php on line 172
No Currency Time Low High Open Close Volume
410 BAL o t F o u
Missing data for BAND between 2021-05-13 09:44:13 and 2021-05-13 02:20:08 diff 26645
https://api.pro.coinbase.com/products/BAND-GBP/candles?start=2021-05-13T02:20:08.0Z&end=2021-05-13T09:44:13.0Z&granularity=300
No Currency Time Low High Open Close Volume
411 BAND Thu, 13 May 2021 09:40:00 +0000 10.4942 10.5993 10.5939 10.5248 1080.08
412 BAND Thu, 13 May 2021 09:35:00 +0000 10.6262 10.7359 10.717 10.627 185.25
413 BAND Thu, 13 May 2021 09:30:00 +0000 10.6525 10.8151 10.6525 10.7991 338.32
414 BAND Thu, 13 May 2021 09:25:00 +0000 10.641 10.7716 10.7521 10.641 134.54

Can you not grab the BTCUSD and also BTCGBP to find the conversion rate between USD and GBP?

Related

Coinbase API getBalance ignoring ETC currency

The PHP uses the Coinbase API to get the current balance and list what currencies the account has money in. It has been used for a few weeks now, but since swapping one currency into ETC (Ethereum Classic), the balance ignores this currency. It works for all other currencies I have tried, so what is special about ETC that Coinbase is not returing anything via the API. The coinbase website portfolio does report the ETC balance correctly, so it's definitely a API issue.
<?php
include 'cfg.php'; // Contains API key
require_once ('vendor/autoload.php'); // Loads the API libraries
use Coinbase\Wallet\Client as Client;
use Coinbase\Wallet\Configuration as Configuration;
use Coinbase\Wallet\Enum\Param;
use Coinbase\Wallet\Resource\Transaction;
$configuration = Configuration::apiKey($cbase_API_Key, $cbase_API_Secret);
$client = Client::create($configuration);
$stime = $client->getTime();
echo '<h2> Server Time ' . $stime['iso'] . '</h2>';
$balance = 0.00;
$accounts = $client->getAccounts(); // Get the account(s)
echo '<table>';
foreach ( $accounts as $acct )
{
$amt = $acct->getBalance()->getAmount() ;
echo '<tr>';
echo '<td>' . $acct->getCurrency() . '</td>';
echo '<td>' . $acct->getName() . '</td>';
echo '<td>' . $acct->getBalance()->getAmount() . '</td>';
echo '<td>' . $acct->getNativeBalance()->getAmount() . '</td>';
echo '</tr>';
$balance = $balance + $acct->getNativeBalance()->getAmount();
}
echo '<table>';
echo '<h2> Total Balance: ' . $balance . '</h2>';
?>
The issue came down to pagination:
The fix therefore was to set the pagination limit to 100 (max allowed).
The default is 24, hence why the returned list was incomplete.
$accounts = $client->getAccounts(['limit' => 100]);

Updated: How to hide marker from a marker array?

I have an array $d of postcodes, this generates markers of my google map.
I want only show markers which were created less than 3 seconds, over 3 seconds will be hidden.
$postcodes = array();
$diff = array(); // time difference variable
foreach($stmt as $x){
//////////////time calculation start////////////////////////////
$posts[] = $x['date'];
$timePosted = new DateTime($posts[] = $x['date']);
echo 'Time Posted : '. $timePosted ->format("d-m-Y H:i:s");
echo "</br>";
date_default_timezone_set('Europe/London');
$today = date('d-m-Y H:i:s');
echo 'Current time is : '. $today;
echo "</br>";
$today = new DateTime(date('d-m-Y H:i:s'));
$interval = $timePosted->diff($today);
"Difference " . $interval->d. " days ". $interval->h. " hours ".$interval->i." minutes ".$interval->s." seconds ";
echo "</br>";
//$diff[] = $interval->h. " hours ".$interval->i." minutes ".$interval->s." seconds ";
$diff[] = $interval->s; //last array seconds
/////////////////////time calculation finish here/////////////////////////
global $postcodes;
//$postcodes[] = $x['postcode']; //postcodes
foreach ($diff as $time => $seconds) {
echo var_dump($seconds);
if($seconds >=3){
echo "larger than 3 seconds<br />";
}else{
echo "smaller than 3 seconds.<br />";
$postcodes[] = $x['postcode']; //this need to be globle not working yet
}
}//time foreach loop finish here
} /// main foreach loop finish here
$d=' "'.implode('","',$postcodes).'"'; //postcodes inside $postcode array
I can't believe how simple this can be, it turns out I don't need to write this in php at all, I can just do it in SQL all I need is to add date >= now() - INTERVAL 3 second; to my sql statement. Hope this can help someone.

how to print out all certian json data in database?

What I'm trying is I have a page which you can input 3 angel integers and submit.
After you submit the data will be saved in database using json encode
{"angle1":"60","angle2":"60","angle3":"90","submit":"Submit"}
The above is what's saved into a row
I used
<?php
$sql = "SELECT * FROM wp_options WHERE option_name LIKE 'angle%' ORDER BY option_name";
$options = $wpdb->get_results($sql);
foreach ( $options as $option )
{
echo '<p><b>'.$option->option_name.'</b> = '
.esc_attr($option->option_value).'</p>'.PHP_EOL;
$line = json_decode($option->option_value, true);
}
echo '<span style="color:#f00;">'.'Angel 1 : '.$line['angle1'].'</span><br>';
echo '<span style="color:#0f0;">'.'Angel 2 : '.$line['angle2'].'</span><br>';
echo '<span style="color:#00f;">'.'Angel 3 : '.$line['angle3'].'</span><br>';
This prints out angel 1 : ## where ## is the angle entered and so on.
I also made a simple 2d piechart which shows the angles.
the problem I'm having is if I submit another 3 angles then my result only shows the MOST RECENT angles entered even if there are two or more in the database.
For example in my database I can see
{"angle1":"60","angle2":"60","angle3":"90","submit":"Submit"}
{"angle1":"60","angle2":"60","angle3":"180","submit":"Submit"}
{"angle1":"30","angle2":"60","angle3":"180","submit":"Submit"}
but the result only prints 30 60 and 180 instead of printing all three.
Anyone mind giving me a hand on how I can print all three data out or at least all three sets of the angles. I believe once I figured that out I can then print out all the piecharts with all the angles instead right now only the most recent angle and the piechart are printed.
Thanks a lot people~
P.S.
I'm so so so stupid I didn't put those echo into the foreach loop but my other question is I believe I need to input my codes below into the foreach loop but there are so many tags is there a way to input all those into the foreach loop instead of doing something like echo canvas id="piechart1" blah blah blah and do it bit by bit?
<canvas id="piechart1" width="100" height="100"></canvas>
<script src="<?php echo get_stylesheet_directory_uri().'/piechart.js'; ?>"></script>
<script>
var chartId = "piechart1";
var colours = ["#f00", "#0f0", "#00f"];
var angles = [<?php echo $line['comp2052_angle1'].','.
$line['comp2052_angle2'].','.
$line['comp2052_angle3'];
?>];
piechart(chartId, colours, angles);
</script>
It not print 3 results, because you put them out of for scope. It only print the last $line because $line will replace every for loops.
To fixed it.
<?php
$sql = "SELECT * FROM wp_options WHERE option_name LIKE 'angle%' ORDER BY option_name";
$options = $wpdb->get_results($sql);
foreach ( $options as $option )
{
echo '<p><b>'.$option->option_name.'</b> = '
.esc_attr($option->option_value).'</p>'.PHP_EOL;
$line = json_decode($option->option_value, true);
// put the echo in for scope
echo '<span style="color:#f00;">'.'Angel 1 : '.$line['angle1'].'</span><br>';
echo '<span style="color:#0f0;">'.'Angel 2 : '.$line['angle2'].'</span><br>';
echo '<span style="color:#00f;">'.'Angel 3 : '.$line['angle3'].'</span><br>';
echo '<hr/>'; // to separate each data
}
You can stored line into array then print their when you want it. for example.
<?php
$sql = "SELECT * FROM wp_options WHERE option_name LIKE 'angle%' ORDER BY option_name";
$options = $wpdb->get_results($sql);
// added to stored line
$line = array();
foreach ( $options as $option )
{
echo '<p><b>'.$option->option_name.'</b> = '
.esc_attr($option->option_value).'</p>'.PHP_EOL;
$line[] = json_decode($option->option_value, true);
}
Then. You can mixed html and php in the pretty ways like code below.
<?php foreach($line as $i => $l): ?>
<canvas id="piechart<?php echo $i?>" width="100" height="100"></canvas>
<script>
var chartId = "piechart<?php echo $i?>";
var colours = ["#f00", "#0f0", "#00f"];
var angles = [<?php echo $l['angle1'].','.
$l['angle2'].','.
$l['angle3'];
?>];
piechart(chartId, colours, angles);
</script>
<?php endforeach; ?>
Put this anywhere in html before the code above
<script src="<?php echo get_stylesheet_directory_uri().'/piechart.js'; ?>"></script>

Horizontal calendar using PHP

You can see what I am trying to make here http://perthurbanist.com/website/calendarloader.php. Basically it is a horizontal calendar and you will use arrows to move. What I want to do is have the code display all the months horizontally along with all the days (starting from the current month and day). I know how to get the current day using the date function but I don't know how to make the calendar start at that date. I also want it to load lots of months (maybe 2-3 years worth). How do I do those two things.
<?php
$showday = date("j");
$displaymonth = date("M");
$showmonth = date("n");
$showyear = date("Y");
$day_count = cal_days_in_month(CAL_GREGORIAN, $showmonth, $showyear);
echo '<ul class="calendarnavigation">';
echo '<li class="month">' . $displaymonth . '</li>';
for($i=1; $i<= $day_count; $i++) {
echo '<li>' . $i . '</li>';
}
echo '</div>';
?>
If you know (or are able to calculate how far ahead you want to go in days you could try this:
for($i=0; $i<$numberOfDays; $i++)
{
$timestamp=mktime(0,0,0,date("m"),date("d")+$i,date("Y"));
$day=date("d", $timestamp);
$month=date("m", $timestamp);
$year=date("Y", $timestamp);
...Your display stuff here...
}
On each iteration of the loop the $timestamp will advance one day and using it in your date functions will give you the information about the date that you need to create your display.
Maybe in your case you can use
echo '<ul class="calendarnavigation">';
for($i=0; $i<$numberOfDays; $i++)
{
$timestamp=mktime(0,0,0,date("m"),date("d")+$i,date("Y"));
$showday=date("j", $timestamp);
$displaymonth=date("M", $timestamp);
$showmonth=date("n", $timestamp);
$showyear=date("Y", $timestamp);
if($showday=="1")
{
echo '<li>'.$displaymonth.'</li>';
}
echo '<li>'.$showday.'</li>';
}
echo '</ul>';

How to send email after registering

After that someone registers in a site, a mail is usually sent to his mail account. But to generate this link or what info can be placed in this link so that it can be used to activate the user account??
you can place any thing which can identify a valid user
1- A Hash Value
2- An Encrypted String
3- A Guid
and when user clicks on the link , you can validate the value.
Check this part of code:
Generate code and e-mail:
/* if $acces = 0 everything is perfect so the system send a confirmation mail */
if($acces == 0)
{
print("<br>A mail has been send to " . $mail . "<br><br>") ;
/* prepare the vars */
$activ = $user . $pass ;
$code = md5($activ) ;
/* to how send to mail */
$to = $mail ;
/* prepare the subject */
$subject = "You need to confirm you registration to " . $_SERVER['HTTP_HOST'] ;
/* start writing the message */
$message = "Hello " . $user . ",\r\n\r\n" ;
$message .= "Thank you for registering at " . $_SERVER['HTTP_HOST'] . " Your account is created and must be activated before you can use it.\r\n" ;
$message .= "To activate the account click on the following link or copy-paste it in your browser :\r\n\r\n" ;
$message .= "http://" . $_SERVER['HTTP_HOST'] . "/~carron/registration/register_send.php?user=" . $user . "&activation=" . $code . "\r\n\r\n" ;
$message .= "After activation you may login to http://" . $_SERVER['HTTP_HOST'] . " using the following username and password:\r\n\r\n" ;
$message .= "Username - " . $user . "\r\nPassword - " . $pass . "\r\n" ;
/* To send HTML mail, you can set the Content-type header. */
$headers = "MIME-Version: 1.0";
$headers .= "Content-type: text/html; charset=iso-8859-1";
/* set up additional headers */
$headers .= "To: " . $to . "<br>\n" ;
$headers .= "From: " . $from . $addmail ;
/* writing data in the base */
$query = "INSERT INTO registration (user, pass, activ, mail) VALUES ('$user', '$pass', '$code', '$mail') ;" ;
$result = mysql_query($query, $db);
if ($result == false)
die("Failed " . $query);
else
{
/* everything went well so we can mail it now */
mail($to, $subject, $message, $headers);
}
}
Check activation:
/* controle if the validation link is right */
$x = 0 ;
$query = "SELECT user, pass, activ, mail FROM registration WHERE user = '" . $username . "';" ;
$result = mysql_query($query, $db);
if ($result == false) die("Failed " . $query);
while ($fields = mysql_fetch_row($result))
{
for ($i=0, $max=sizeof($fields) ; $i < $max ; $i++)
{
$tmp[$i] = $fields[$i] ;
}
/* the activation link is right so we can update
the datas in the data base */
if($activation == $tmp[2] AND $username == $tmp[0])
{
$x = 1 ;
$query2 = "UPDATE registration SET activated = '1' WHERE user = '" . $username . "' AND activ = '" . $activation . "' ;" ;
$result2 = mysql_query($query2, $db);
if ($result2 == false)
die("Failed " . $query2);
}
else
$x = -1 ;
}
/* give a confirmation message to the user */
if($x == 1)
print($username . " your activation has been done perfectly<br> Thank you...") ;
else
print($username . " your activation has not been done corectly<br> Please try again later...") ;
Script from PHPclasses.org
The idea is to have a link that only the recipient of the email knows. So when that link is visited on your site, you know that someone has read the email you sent and clicked on the link and so you can presume that the person who registered and the person who read the email are the same.
As such, you just need a link that can't be easily guessed. Pick something random (and record it in the user's profile) or hash the user name + a seed, or something.
When user registered, you can use uniqid() to create an activate code and stored in database. Then in mail, give a link like: http://....../activate.php?code=[uniqid()]
In activate.php, you can read activate code from database and check it.

Resources