From 997f0be1b581c2e6ae6ef14182dc230d25d868b2 Mon Sep 17 00:00:00 2001 From: Tanguy Pruvot Date: Tue, 22 Mar 2016 10:50:20 +0100 Subject: [PATCH] kraken api, to retrieve markets and btc balance --- web/serverconfig.sample.php | 1 + web/yaamp/commands/ExchangeCommand.php | 4 + web/yaamp/core/backend/markets.php | 49 ++++ web/yaamp/core/backend/rawcoins.php | 19 +- web/yaamp/core/exchange/exchange.php | 1 + web/yaamp/core/exchange/kraken.php | 263 ++++++++++++++++++ web/yaamp/core/trading/kraken_trading.php | 42 +++ web/yaamp/core/trading/trading.php | 2 +- web/yaamp/defaultconfig.php | 1 + web/yaamp/modules/site/SiteController.php | 5 + .../modules/thread/CronjobController.php | 1 + 11 files changed, 386 insertions(+), 2 deletions(-) create mode 100644 web/yaamp/core/exchange/kraken.php create mode 100644 web/yaamp/core/trading/kraken_trading.php diff --git a/web/serverconfig.sample.php b/web/serverconfig.sample.php index 9d10936..0ab43ac 100644 --- a/web/serverconfig.sample.php +++ b/web/serverconfig.sample.php @@ -42,6 +42,7 @@ define('EXCH_BLEUTRADE_KEY', ''); define('EXCH_YOBIT_KEY', ''); define('EXCH_CCEX_KEY', ''); define('EXCH_SAFECEX_KEY', ''); +define('EXCH_KRAKEN_KEY', ''); define('EXCH_BANX_USERNAME', ''); // Automatic withdraw to Yaamp btc wallet if btc balance > 0.3 diff --git a/web/yaamp/commands/ExchangeCommand.php b/web/yaamp/commands/ExchangeCommand.php index 84d01d6..f566575 100644 --- a/web/yaamp/commands/ExchangeCommand.php +++ b/web/yaamp/commands/ExchangeCommand.php @@ -73,6 +73,10 @@ class ExchangeCommand extends CConsoleCommand $balance = cryptopia_api_user('GetBalance',array("Currency"=>"BTC")); echo("cryptopia btc: ".json_encode($balance->Data)."\n"); } + if (!empty(EXCH_KRAKEN_KEY)) { + $balance = kraken_api_user('Balance'); + echo("kraken btc: ".json_encode($balance)."\n"); + } if (!empty(EXCH_CRYPTSY_KEY)) { $info = cryptsy_api_query('getinfo'); if (!arraySafeVal($info,'success',0) || !is_array($info['return'])) echo "error\n"; diff --git a/web/yaamp/core/backend/markets.php b/web/yaamp/core/backend/markets.php index 2001e5f..ad8ba85 100644 --- a/web/yaamp/core/backend/markets.php +++ b/web/yaamp/core/backend/markets.php @@ -7,6 +7,7 @@ function BackendPricesUpdate() updateBittrexMarkets(); updatePoloniexMarkets(); updateBleutradeMarkets(); + updateKrakenMarkets(); updateCCexMarkets(); updateCryptopiaMarkets(); updateYobitMarkets(); @@ -204,6 +205,54 @@ function updateBleutradeMarkets() ///////////////////////////////////////////////////////////////////////////////////////////// +function updateKrakenMarkets($force = false) +{ + $exchange = 'kraken'; + $result = kraken_api_query('AssetPairs'); + if(!is_array($result)) return; + + foreach($result as $pair => $data) + { + $pairs = explode('-', $pair); + $base = reset($pairs); $symbol = end($pairs); + if($symbol == 'BTC' || $base != 'BTC') continue; + if(in_array($symbol, array('GBP','CAD','EUR','USD','JPY'))) continue; + if(strpos($symbol,'.d') !== false) continue; + + $coin = getdbosql('db_coins', "symbol='{$symbol}'"); + if(!$coin || !$coin->installed) continue; + + debuglog("kraken: $symbol/$base ".json_encode($data)); + $fees = reset($currency['fees']); + $feepct = end($fees); + $market = getdbosql('db_markets', "coinid={$coin->id} and name='{$exchange}'"); + if(!$market) { + $market = new db_markets; + $market->coinid = $coin->id; + $market->name = $exchange; + } + + $market->txfee = $feepct; + + sleep(1); + $ticker = kraken_api_query('Ticker', $symbol); + if(!is_array($ticker) || !isset($ticker[$pair])) continue; + + $ticker = arraySafeVal($ticker,$pair); + if(!is_array($ticker) || !isset($ticker['b'])) continue; + + debuglog("kraken: $symbol/$base ticker ".json_encode($ticker)); + + $price2 = ($ticker['b'][0] + $ticker['a'][0]) / 2; + $market->price2 = AverageIncrement($market->price2, $price2); + $market->price = AverageIncrement($market->price, $ticker['b'][0]); + + $market->save(); + } +} + +///////////////////////////////////////////////////////////////////////////////////////////// + function updateBittrexMarkets($force = false) { $exchange = 'bittrex'; diff --git a/web/yaamp/core/backend/rawcoins.php b/web/yaamp/core/backend/rawcoins.php index bd66b23..fed841e 100644 --- a/web/yaamp/core/backend/rawcoins.php +++ b/web/yaamp/core/backend/rawcoins.php @@ -112,6 +112,21 @@ function updateRawcoins() } } + $list = kraken_api_query('AssetPairs'); + if(is_array($list)) + { + dborun("UPDATE markets SET deleted=true WHERE name='kraken'"); + foreach($list as $pair => $item) { + $pairs = explode('-', $pair); + $base = reset($pairs); $symbol = end($pairs); + if($symbol == 'BTC' || $base != 'BTC') continue; + if(in_array($symbol, array('GBP','CAD','EUR','USD','JPY'))) continue; + if(strpos($symbol,'.d') !== false) continue; + $symbol = strtoupper($symbol); + updateRawCoin('kraken', $symbol); + } + } + $list = alcurex_api_query('market','?info=on'); if(is_object($list) && isset($list->MARKETS)) { @@ -164,7 +179,9 @@ function updateRawcoins() $list = getdbolist('db_coins', "not enable and not installed and id not in (select distinct coinid from markets)"); foreach($list as $coin) { - debuglog("$coin->symbol is not longer active"); + if ($coin->visible) + debuglog("{$coin->symbol} is no longer active"); + // todo: proper cleanup in all tables (like "yiimp deletecoin ") // if ($coin->symbol != 'BTC') // $coin->delete(); } diff --git a/web/yaamp/core/exchange/exchange.php b/web/yaamp/core/exchange/exchange.php index 57af76b..c7ae652 100644 --- a/web/yaamp/core/exchange/exchange.php +++ b/web/yaamp/core/exchange/exchange.php @@ -4,6 +4,7 @@ require_once("poloniex.php"); require_once("bittrex.php"); require_once("ccexapi.php"); require_once("bleutrade.php"); +require_once("kraken.php"); require_once("yobit.php"); require_once("cryptsy.php"); require_once("safecex.php"); diff --git a/web/yaamp/core/exchange/kraken.php b/web/yaamp/core/exchange/kraken.php new file mode 100644 index 0000000..d28d4e8 --- /dev/null +++ b/web/yaamp/core/exchange/kraken.php @@ -0,0 +1,263 @@ +key = $key; + $this->secret = $secret; + $this->url = $url; + $this->version = $version; + $this->curl = curl_init(); + + curl_setopt_array($this->curl, array( + CURLOPT_SSL_VERIFYPEER => $sslverify, + CURLOPT_SSL_VERIFYHOST => 2, + CURLOPT_USERAGENT => 'Kraken PHP API Agent', + CURLOPT_POST => true, + CURLOPT_RETURNTRANSFER => true) + ); + } + + function __destruct() + { + curl_close($this->curl); + } + + /** + * Query public methods + * + * @param string $method method name + * @param array $request request parameters + * @return array request result on success + * @throws KrakenAPIException + */ + function QueryPublic($method, array $request = array()) + { + // build the POST data string + $postdata = http_build_query($request, '', '&'); + + // make request + curl_setopt($this->curl, CURLOPT_URL, $this->url . '/' . $this->version . '/public/' . $method); + curl_setopt($this->curl, CURLOPT_POSTFIELDS, $postdata); + curl_setopt($this->curl, CURLOPT_HTTPHEADER, array()); + $result = curl_exec($this->curl); + if($result===false) + throw new KrakenAPIException('CURL error: ' . curl_error($this->curl)); + + // decode results + $result = json_decode($result, true); + if(!is_array($result)) + throw new KrakenAPIException('JSON decode error'); + + return $result; + } + + /** + * Query private methods + * + * @param string $path method path + * @param array $request request parameters + * @return array request result on success + * @throws KrakenAPIException + */ + function QueryPrivate($method, array $request = array()) + { + if(!isset($request['nonce'])) { + // generate a 64 bit nonce using a timestamp at microsecond resolution + // string functions are used to avoid problems on 32 bit systems + $nonce = explode(' ', microtime()); + $request['nonce'] = $nonce[1] . str_pad(substr($nonce[0], 2, 6), 6, '0'); + } + + // build the POST data string + $postdata = http_build_query($request, '', '&'); + + // set API key and sign the message + $path = '/' . $this->version . '/private/' . $method; + $sign = hash_hmac('sha512', $path . hash('sha256', $request['nonce'] . $postdata, true), base64_decode($this->secret), true); + $headers = array( + 'API-Key: ' . $this->key, + 'API-Sign: ' . base64_encode($sign) + ); + + // make request + curl_setopt($this->curl, CURLOPT_URL, $this->url . $path); + curl_setopt($this->curl, CURLOPT_POSTFIELDS, $postdata); + curl_setopt($this->curl, CURLOPT_HTTPHEADER, $headers); + $result = curl_exec($this->curl); + if($result===false) + throw new KrakenAPIException('CURL error: ' . curl_error($this->curl)); + + // decode results + $result = json_decode($result, true); + if(!is_array($result)) + throw new KrakenAPIException('JSON decode error'); + + return $result; + } +} + +// convert ISO-4217-A3-X to generic crypto symbols +function kraken_ISOtoSymbol($iso, $default='') +{ + $conv = array( + 'XXBT'=>'BTC', + 'XXDG'=>'DOGE', + ); + if (empty($default)) $default = substr($iso, 1); + $symbol = arraySafeVal($conv, $iso, $default); + return $symbol; +} + +// convert yiimp symbols to ISO-4217-A3-X +function kraken_symbolToISO($symbol) +{ + $conv = array( + 'BTC' => 'XXBT', + 'DOGE' => 'XXDG', + ); + $iso = arraySafeVal($conv, $symbol, 'X'.$symbol); + return $iso; +} + +function kraken_convertPair($symbol, $base='BTC') +{ + $btc_k = kraken_symbolToISO($base); + $sym_k = kraken_symbolToISO($symbol); + $pair = $btc_k.$sym_k; + return $pair; +} + +// https://www.kraken.com/help/api + +function kraken_api_query($method, $params='') +{ + $kraken = new KrakenAPI('', ''); + + $arrParams = array(); + switch ($method) { + case 'Ticker': + $pair = kraken_convertPair($params); + $arrParams = array('pair'=>$pair); + break; + } + + $res = $kraken->QueryPublic($method, $arrParams); + + $proper = array(); + if (!empty($res) && isset($res['result']) && !empty($res['result'])) { + switch ($method) { + case 'Assets': + foreach ($res['result'] as $symk => $asset) { + $symbol = kraken_ISOtoSymbol($symk, $asset['altname']); + $proper[$symbol] = $asset; + } + return $proper; + case 'AssetPairs': + foreach ($res['result'] as $pairk => $asset) { + $symk = substr($pairk, 0, 4); + $symbol1 = kraken_ISOtoSymbol($symk); + $symk = substr($pairk, 4); + $symbol2 = kraken_ISOtoSymbol($symk); + $asset['base'] = kraken_ISOtoSymbol($asset['base']); + $asset['quote'] = kraken_ISOtoSymbol($asset['quote']); + $asset['fee_volume_currency'] = kraken_ISOtoSymbol($asset['fee_volume_currency']); + $proper[$symbol1.'-'.$symbol2] = $asset; + } + return $proper; + case 'Ticker': + foreach ($res['result'] as $pairk => $asset) { + $symk = substr($pairk, 0, 4); + $symbol1 = kraken_ISOtoSymbol($symk); + $symk = substr($pairk, 4); + $symbol2 = kraken_ISOtoSymbol($symk); + $proper[$symbol1.'-'.$symbol2] = $asset; + } + return $proper; + } + } + return $res; +} + +function kraken_api_user($method, $params='') +{ + require_once('/etc/yiimp/keys.php'); + if (!defined('EXCH_KRAKEN_SECRET')) return false; + + $apikey = EXCH_KRAKEN_KEY; // your API-key + $apisecret = EXCH_KRAKEN_SECRET; // your Secret-key + + $kraken = new KrakenAPI($apikey, $apisecret); + + $arrParams = array(); + switch ($method) { + case 'OpenOrders': + $arrParams = array('trades'=> (bool) ($params)); + break; + case 'Withdraw': + $arrParams = array('trades'=> (bool) ($params)); + break; + } + + $res = $kraken->QueryPrivate($method, $arrParams); + + $proper = array(); + if (!empty($res) && isset($res['result']) && !empty($res['result'])) { + switch ($method) { + case 'Balance': + foreach ($res['result'] as $symk => $balance) { + $symbol = kraken_ISOtoSymbol($symk); + $proper[$symbol] = $balance; + } + return $proper; + } + } + + return $res; +} diff --git a/web/yaamp/core/trading/kraken_trading.php b/web/yaamp/core/trading/kraken_trading.php new file mode 100644 index 0000000..401ce13 --- /dev/null +++ b/web/yaamp/core/trading/kraken_trading.php @@ -0,0 +1,42 @@ +balance = 0; + + foreach($balances as $symbol => $balance) + { + if ($symbol == 'BTC') { + $savebalance->balance = $balance; + $savebalance->save(); + continue; + } + + if (!YAAMP_ALLOW_EXCHANGE) { + // store available balance in market table + $coins = getdbolist('db_coins', "symbol=:symbol OR symbol2=:symbol", + array(':symbol'=>$symbol) + ); + if (empty($coins)) continue; + foreach ($coins as $coin) { + $market = getdbosql('db_markets', "coinid=:coinid AND name='kraken'", array(':coinid'=>$coin->id)); + if (!$market) continue; + if ($market->balance != $balance) { + $market->balance = $balance; + $market->save(); + } + } + } + } + + if (!YAAMP_ALLOW_EXCHANGE) return; +} diff --git a/web/yaamp/core/trading/trading.php b/web/yaamp/core/trading/trading.php index 058fe72..0d6ad7e 100644 --- a/web/yaamp/core/trading/trading.php +++ b/web/yaamp/core/trading/trading.php @@ -5,7 +5,7 @@ require_once('bittrex_trading.php'); require_once('bleutrade_trading.php'); require_once('cryptsy_trading.php'); require_once('c-cex_trading.php'); -require_once('empoex_trading.php'); +require_once('kraken_trading.php'); require_once('yobit_trading.php'); require_once('alcurex_trading.php'); require_once('banx_trading.php'); diff --git a/web/yaamp/defaultconfig.php b/web/yaamp/defaultconfig.php index 7bd68e7..cfec49b 100644 --- a/web/yaamp/defaultconfig.php +++ b/web/yaamp/defaultconfig.php @@ -30,6 +30,7 @@ if (!defined('EXCH_POLONIEX_KEY')) define('EXCH_POLONIEX_KEY', ''); if (!defined('EXCH_SAFECEX_KEY')) define('EXCH_SAFECEX_KEY', ''); if (!defined('EXCH_YOBIT_KEY')) define('EXCH_YOBIT_KEY', ''); if (!defined('EXCH_BANX_USERNAME')) define('EXCH_BANX_USERNAME', ''); +if (!defined('EXCH_KRAKEN_KEY')) define('EXCH_KRAKEN_KEY', ''); if (!defined('YAAMP_BTCADDRESS')) define('YAAMP_BTCADDRESS', ''); if (!defined('YAAMP_SITE_URL')) define('YAAMP_SITE_URL', 'localhost'); diff --git a/web/yaamp/modules/site/SiteController.php b/web/yaamp/modules/site/SiteController.php index 0222afa..7737af3 100644 --- a/web/yaamp/modules/site/SiteController.php +++ b/web/yaamp/modules/site/SiteController.php @@ -882,6 +882,11 @@ class SiteController extends CommonController updateBleutradeMarkets(); break; + case 'kraken': + doKrakenTrading(true); + updateKrakenMarkets(); + break; + case 'poloniex': doPoloniexTrading(true); updatePoloniexMarkets(); diff --git a/web/yaamp/modules/thread/CronjobController.php b/web/yaamp/modules/thread/CronjobController.php index 9e8c47d..83068eb 100644 --- a/web/yaamp/modules/thread/CronjobController.php +++ b/web/yaamp/modules/thread/CronjobController.php @@ -134,6 +134,7 @@ class CronjobController extends CommonController doCryptopiaTrading(); doSafecexTrading(); //doCryptsyTrading(); + doKrakenTrading(); doPoloniexTrading(); doYobitTrading(); doCCexTrading();