Skip to content

Commit

Permalink
kucoin exchange api + balances and icons
Browse files Browse the repository at this point in the history
Signed-off-by: Tanguy Pruvot <[email protected]>
  • Loading branch information
tpruvot committed Jan 7, 2018
1 parent 7729b5c commit ab5e411
Show file tree
Hide file tree
Showing 12 changed files with 322 additions and 5 deletions.
1 change: 1 addition & 0 deletions web/keys.sample.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
define('EXCH_EMPOEX_SECKEY', '');
define('EXCH_HITBTC_SECRET', '');
define('EXCH_KRAKEN_SECRET','');
define('EXCH_KUCOIN_SECRET', '');
define('EXCH_LIVECOIN_SECRET', '');
define('EXCH_NOVA_SECRET','');
define('EXCH_POLONIEX_SECRET', '');
Expand Down
3 changes: 3 additions & 0 deletions web/serverconfig.sample.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,15 @@
define('EXCH_BTER_KEY', '');
define('EXCH_YOBIT_KEY', '');
define('EXCH_CCEX_KEY', '');
define('EXCH_CEXIO_ID', '');
define('EXCH_CEXIO_KEY', '');
define('EXCH_COINMARKETS_USER', '');
define('EXCH_COINMARKETS_PIN', '');
define('EXCH_BITSTAMP_ID','');
define('EXCH_BITSTAMP_KEY','');
define('EXCH_HITBTC_KEY','');
define('EXCH_KRAKEN_KEY', '');
define('EXCH_KUCOIN_KEY', '');
define('EXCH_LIVECOIN_KEY', '');
define('EXCH_NOVA_KEY', '');
define('EXCH_STOCKSEXCHANGE_KEY', '');
Expand Down
42 changes: 38 additions & 4 deletions web/yaamp/commands/CoindbCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public function run($args)
$nbUpdated += $this->grabBittrexIcons(); // can be huge ones
$nbUpdated += $this->grabCoinExchangeIcons();
$nbUpdated += $this->grabAlcurexIcons();
$nbUpdated += $this->grabKuCoinIcons();
$nbUpdated += $this->grabNovaIcons();

echo "total updated: $nbUpdated\n";
Expand Down Expand Up @@ -504,8 +505,7 @@ public function grabAlcurexIcons()
echo "alcurex: try to download new icons...\n";
foreach ($coins as $coin) {
$coin = getdbo('db_coins', $coin["id"]);
$symbol = $coin->symbol;
if (!empty($coin->symbol2)) $symbol = $coin->symbol2;
$symbol = $coin->getOfficialSymbol();
$local = $this->basePath."/images/coin-{$symbol}.png";
try {
$data = @ file_get_contents($url.strtoupper($symbol).'.png');
Expand All @@ -525,6 +525,41 @@ public function grabAlcurexIcons()
return $nbUpdated;
}

/**
* Icon grabber - KuCoin
*/
public function grabKuCoinIcons()
{
$url = 'https://assets.kucoin.com/www/1.2.0/assets/coins/';//QLC.png
$nbUpdated = 0;
$sql = "SELECT DISTINCT coins.id FROM coins INNER JOIN markets M ON M.coinid = coins.id ".
"WHERE M.name='kucoin' AND IFNULL(coins.image,'') = ''";
$coins = dbolist($sql);
if (empty($coins))
return 0;
echo "kucoin: try to download new icons...\n";
foreach ($coins as $coin) {
$coin = getdbo('db_coins', $coin["id"]);
$symbol = $coin->getOfficialSymbol();
$local = $this->basePath."/images/coin-{$symbol}.png";
try {
$data = @ file_get_contents($url.$symbol.'.png');
} catch (Exception $e) {
continue;
}
if (strlen($data) < 2048) continue;
echo $symbol." icon found\n";
file_put_contents($local, $data);
if (filesize($local) > 0) {
$coin->image = "/images/coin-{$symbol}.png";
$nbUpdated += $coin->save();
}
}
if ($nbUpdated)
echo "$nbUpdated icons downloaded from kucoin\n";
return $nbUpdated;
}

/**
* Icon grabber - NovaExchange
*/
Expand All @@ -540,8 +575,7 @@ public function grabNovaIcons()
echo "nova: try to download new icons...\n";
foreach ($coins as $coin) {
$coin = getdbo('db_coins', $coin["id"]);
$symbol = $coin->symbol;
if (!empty($coin->symbol2)) $symbol = $coin->symbol2;
$symbol = $coin->getOfficialSymbol();
$local = $this->basePath."/images/coin-{$symbol}.png";
try {
$data = @ file_get_contents($url.strtolower($symbol).'.png');
Expand Down
5 changes: 5 additions & 0 deletions web/yaamp/commands/ExchangeCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,11 @@ public function testApiKeys()
$balance = kraken_api_user('Balance');
echo("kraken btc: ".json_encode($balance)."\n");
}
if (!empty(EXCH_KUCOIN_KEY)) {
$balance = kucoin_api_user('account/BTC/balance');
if (!is_object($balance) || !isset($balance->data)) echo "kucoin error ".json_encode($balance)."\n";
else echo("kucoin: ".json_encode($balance->data)."\n");
}
if (!empty(EXCH_LIVECOIN_KEY)) {
$livecoin = new LiveCoinApi;
$balance = $livecoin->getBalances('BTC');
Expand Down
59 changes: 58 additions & 1 deletion web/yaamp/core/backend/markets.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ function BackendPricesUpdate()
updatePoloniexMarkets();
updateBleutradeMarkets();
updateKrakenMarkets();
updateKuCoinMarkets();
updateCCexMarkets();
updateCryptopiaMarkets();
updateHitBTCMarkets();
Expand Down Expand Up @@ -1167,6 +1168,62 @@ function updateEmpoexMarkets()
}
}

function updateKuCoinMarkets()
{
$exchange = 'kucoin';
if (exchange_get($exchange, 'disabled')) return;

$markets = kucoin_api_query('open/symbols','market=BTC');
if(!is_object($markets) || !isset($markets->data) || empty($markets->data)) return;

$coininfo = NULL; //kucoin_api_query('market/open/coins');
if(!is_object($coininfo) || !isset($coininfo->data) || empty($coininfo->data)) {
$coininfo = NULL;
}

$list = getdbolist('db_markets', "name='$exchange'");
foreach($list as $market)
{
$coin = getdbo('db_coins', $market->coinid);
if(!$coin) continue;

$symbol = $coin->getOfficialSymbol();
if (market_get($exchange, $symbol, "disabled")) {
$market->disabled = 1;
$market->message = 'disabled from settings';
$market->save();
continue;
}

$pair = strtoupper($symbol).'-BTC';

foreach ($markets->data as $ticker) {
if ($ticker->symbol != $pair) continue;

$market->price = AverageIncrement($market->price, $ticker->buy);
$market->price2 = AverageIncrement($market->price2, $ticker->sell);
if (!empty($coininfo)) foreach ($coininfo->data as $info) {
if ($info->coin == $symbol) {
//todo: $market->withdrawfee = $info->withdrawMinFee;
break;
}
}
$market->txfee = $ticker->feeRate * 100; // is 0.1% for trades (0.001)
$market->priority = -1;
$market->pricetime = time();

if (floatval($ticker->vol) > 0.01)
$market->save();

if (empty($coin->price2)) {
$coin->price = $market->price;
$coin->price2 = $market->price2;
$coin->save();
}
}
}
}

function updateLiveCoinMarkets()
{
$exchange = 'livecoin';
Expand Down Expand Up @@ -1489,7 +1546,7 @@ function updateShapeShiftMarkets()

$market->price = AverageIncrement($market->price, $ticker['rate']);
$market->price2 = AverageIncrement($market->price2, $ticker['rate']);
$market->txfee = $ticker['minerFee'];
$market->txfee = $ticker['minerFee'] * 100;
$market->pricetime = time();
$market->priority = -1; // not ready for trading
$market->save();
Expand Down
14 changes: 14 additions & 0 deletions web/yaamp/core/backend/rawcoins.php
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,20 @@ function updateRawcoins()
}
}

if (!exchange_get('kucoin', 'disabled')) {
$list = kucoin_api_query('market/open/coins');
if(is_object($list) && isset($list->data) && !empty($list->data))
{
dborun("UPDATE markets SET deleted=true WHERE name='kucoin'");
foreach($list->data as $item) {
$symbol = $item->coin;
$name = $item->name;
if (strpos($item->withdrawRemark,'Ethereum')) continue;
updateRawCoin('kucoin', $symbol, $name);
}
}
}

if (!exchange_get('livecoin', 'disabled')) {
$list = livecoin_api_query('exchange/ticker');
if(is_array($list))
Expand Down
3 changes: 3 additions & 0 deletions web/yaamp/core/exchange/exchange.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ function strip_data($data)
require_once("binance.php");
require_once("cryptopia.php");
require_once("hitbtc.php");
require_once("kucoin.php");
require_once("livecoin.php");
require_once("nova.php");
require_once("coinexchange.php");
Expand Down Expand Up @@ -101,6 +102,8 @@ function getMarketUrl($coin, $marketName)
$url = "http://jubi.com/coin/{$lowsymbol}";
else if($market == 'hitbtc')
$url = "https://hitbtc.com/exchange/{$symbol}-to-{$base}";
else if($market == 'kucoin')
$url = "https://www.kucoin.com/#/trade.pro/{$symbol}-{$base}";
else if($market == 'livecoin')
$url = "https://www.livecoin.net/trade/?currencyPair={$symbol}%2F{$base}";
else if($market == 'nova')
Expand Down
133 changes: 133 additions & 0 deletions web/yaamp/core/exchange/kucoin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
<?php
// see https://kucoinapidocs.docs.apiary.io/
// https://api.kucoin.com/v1/open/symbols/?market=BTC

function kucoin_api_query($method, $params='', $returnType='object')
{
$url = "https://api.kucoin.com/v1/$method/";
if (!empty($params))
$url .= "?$params";

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; KuCoin API PHP client; '.php_uname('s').'; PHP/'.phpversion().')');
curl_setopt($ch, CURLOPT_ENCODING , '');
//curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

$execResult = curl_exec($ch);
if ($returnType == 'object')
$ret = json_decode($execResult);
else
$ret = json_decode($execResult,true);

return $ret;
}

// https://api.kucoin.com/v1/account/<coin>/wallet/address

function kucoin_api_user($method, $params=NULL, $isPostMethod=false)
{
require_once('/etc/yiimp/keys.php');
if (!defined('EXCH_KUCOIN_SECRET')) define('EXCH_KUCOIN_SECRET', '');

if (empty(EXCH_KUCOIN_KEY) || empty(EXCH_KUCOIN_SECRET)) return false;

$api_host = 'https://api.kucoin.com';
$mt = explode(' ', microtime());
$nonce = $mt[1].substr($mt[0], 2, 3);
$url = $endpoint = "/v1/$method";
$tosign = "$endpoint/$nonce/";

if (empty($params)) $params = array();
$query = http_build_query($params);
if (strlen($query) && !$isPostMethod) {
$url .= '&'.$query; $query = '';
}
if ($isPostMethod) $post_data = $params;
$hmac = strtolower(hash_hmac('sha256', base64_encode($tosign.$query), EXCH_KUCOIN_SECRET));

$headers = array(
'Content-Type: application/json;charset=UTF-8',
'KC-API-KEY: '.EXCH_KUCOIN_KEY,
'KC-API-NONCE: '.$nonce,
'KC-API-SIGNATURE: '.$hmac,
);

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $api_host.$url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
if ($isPostMethod) {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; KuCoin API PHP client; '.php_uname('s').'; PHP/'.phpversion().')');
curl_setopt($ch, CURLOPT_ENCODING , '');
//curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
//curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
//curl_setopt($ch, CURLOPT_VERBOSE, 1);

$res = curl_exec($ch);
if($res === false) {
$e = curl_error($ch);
debuglog("kucoin: $e");
curl_close($ch);
return false;
}

$result = json_decode($res);
if(!is_object($result) && !is_array($result)) {
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
debuglog("kucoin: $method failed ($status) ".strip_data($res));
}

curl_close($ch);

return $result;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

// manual update of one market
function kucoin_update_market($market)
{
$exchange = 'kucoin';
if (is_string($market))
{
$symbol = $market;
$coin = getdbosql('db_coins', "symbol=:sym", array(':sym'=>$symbol));
if(!$coin) return false;
$pair = $symbol.'-BTC';
$market = getdbosql('db_markets', "coinid={$coin->id} AND name='$exchange'");
if(!$market) return false;

} else if (is_object($market)) {

$coin = getdbo('db_coins', $market->coinid);
if(!$coin) return false;
$symbol = $coin->getOfficialSymbol();
$pair = $symbol.'-BTC';
if (!empty($market->base_coin)) $pair = $symbol.'-'.$market->base_coin;
}

$t1 = microtime(true);
$query = kucoin_api_query("$pair/open/tick");
if(!is_object($query) || !isset($query->data)) return false;
$ticker = $ticker->data;

$price2 = ((double) $ticker->buy + (double)$ticker->sell)/2;
$market->price2 = AverageIncrement($market->price2, $price2);
$market->price = AverageIncrement($market->price, $ticker->buy);
$market->pricetime = time();
$market->save();

$apims = round((microtime(true) - $t1)*1000,3);
user()->setFlash('message', "$exchange $symbol price updated in $apims ms");

return true;
}
Loading

0 comments on commit ab5e411

Please sign in to comment.