diff --git a/config_default.php b/config_default.php
index c329046..4117d18 100644
--- a/config_default.php
+++ b/config_default.php
@@ -5,7 +5,7 @@
date_default_timezone_set('UTC');
if (version_compare(phpversion(),"8.0.0",'>=')
- || version_compare(phpversion(),"7.0.0",'<'))
+|| version_compare(phpversion(),"7.0.0",'<'))
die ('requires php version 7.x.x, running ' . phpversion());
ini_set('memory_limit', '64M'); # memory limit, set '-1' for unlimited, default 32M
@@ -33,8 +33,10 @@
/* telegram settings */
-$config['chatId'] = 'chatId'; # default telegram chat id
-$config['chatPath'] = 'https://api.telegram.org/bot132'; # bot API path and key
+// bot name aaaaaa
+$config['chatPath'] = 'https://api.telegram.org/bot000000000:AAAAAAAAA_AAAAAAAA_AAAAAAAA'; # bot API path and key
+// user name aaaaaa
+$config['chatId'] = '111111111'; # chat id for bot and user
$config['chatText'] = 'message failed';
/* database arrays */
@@ -226,6 +228,13 @@ function config_exchange($config) {
$config['hist_pairs'] = array('BTC/USDT', 'ETH/USDT', 'LTC/USDT', 'ETC/USDT', 'XRP/USDT', 'EOS/USDT', 'BCH/USDT', 'BSV/USDT', 'TRX/USDT');
break;
+ case 'etherscan':
+ $config['method'] = 'GET';
+ $config['api_key'] = '000';
+ $config['url'] = 'https://api.etherscan.io/api?';
+ $config['address_eth'] = '0x000';
+ break;
+
case 'uniswap':
$config['url'] = 'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v2';
$config['address_uniswap'] = '0x0000000000000000000000000000000000000000';
diff --git a/functions.analysis.php b/functions.analysis.php
index 3a680b8..241cbff 100644
--- a/functions.analysis.php
+++ b/functions.analysis.php
@@ -5,7 +5,7 @@
function technical_analysis($config, $pair_id = FALSE) {
$query = "SELECT DISTINCT pair, period, source, currency, history_start FROM asset_pairs WHERE analyse";
- if($pair_id) $query .= " AND pair_id = " . $pair_id;
+ if ($pair_id) $query .= " AND pair_id = " . $pair_id;
$pairs = query($query, $config);
$stop = $config['timestamp'];
@@ -18,145 +18,155 @@ function technical_analysis($config, $pair_id = FALSE) {
$rsios = 25; // oversold, 'rsi'.$n.'os'
$ema = array(6, 12, 26, 50, 100, 200); // 'ema'.$n, crossover upwards 'ema'.$n.'cu', crossover downwards 'ema'.$n.'cd'
$roc = array(1, 2, 4, 6, 12, 24); // 'roc'.$n
- $corr = array('BTC' => array(50),
- 'ETH' => array(50)); // 'corr'.$n.'btc'
+ $corr = array(
+ 'BTC' => array(50),
+ 'ETH' => array(50)
+ ); // 'corr'.$n.'btc'
foreach ($pairs as $pair) {
- $period_txt = $config['period'][$pair['period']];
- $period = $pair['period'] * 60000;
- $start = $stop - $period * ($points + $points_buffer);
-
- $query = "SELECT history_id, timestamp, close FROM price_history
- WHERE pair = '" . $pair['pair'] . "'
- AND source = '" . $pair['source'] . "'
- AND period = '" . $period_txt . "'
- AND timestamp >= " . $start . "
- AND timestamp <= " . $stop . "
- ORDER BY timestamp ASC";
- $hist = query($query, $config);
- if($config['debug']) echo $query . PHP_EOL;
- if(empty($hist)) continue 1;
- //var_dump($hist);
- //var_dump($query);
-
- $last = $hist[0]['timestamp'] - $period;
- $missing_data = FALSE;
- $i = 0;
- foreach ($hist as $h) {
- $diff_obs = $h['timestamp'] - $last;
- if ($period !== $diff_obs) {
- $missing_data = TRUE;
- $missing_obs = $h['timestamp'] - $period;
- $missing_array = $i;
- }
- $last = $h['timestamp'];
- $i++;
- }
- if($missing_data) {
- echo 'missing data at array position ' . $missing_array . ',
time ' . date('Y-m-d H:i T', $missing_obs / 1000) . ',
timestamp ' . $missing_obs . ',
period ' . $period . '
';
- var_dump($hist[$missing_array - 1]);
- var_dump($hist[$missing_array]);
- continue 1;
- }
-
- $count = count($hist);
- $dc = array_column($hist, 'close');
-
- foreach($rsi as $n) {
- $r = trader_rsi($dc, $n);
- $j = 0;
- for($i = 0; $i < $count; $i++) {
- if(isset($r[$i])) {
- $hist[$i]['rsi'.$n] = $r[$i];
- if(isset($r[$j])) {
- if($r[$j] <= $rsiob && $r[$i] > $rsiob)
- $hist[$i]['rsi'.$n.'ob'] = 1;
- else
- $hist[$i]['rsi'.$n.'ob'] = 0;
- if($r[$j] >= $rsios && $r[$i] < $rsios)
- $hist[$i]['rsi'.$n.'os'] = 1;
- else
- $hist[$i]['rsi'.$n.'os'] = 0;
- }
+ $period_txt = $config['period'][$pair['period']];
+ $period = $pair['period'] * 60000;
+ $start = $stop - $period * ($points + $points_buffer);
+
+ $query = "
+ SELECT history_id, timestamp, close FROM price_history
+ WHERE pair = '" . $pair['pair'] . "'
+ AND source = '" . $pair['source'] . "'
+ AND period = '" . $period_txt . "'
+ AND timestamp >= " . $start . "
+ AND timestamp <= " . $stop . "
+ ORDER BY timestamp ASC
+ ";
+ $hist = query($query, $config);
+ if ($config['debug']) echo $query . PHP_EOL;
+ if (empty($hist)) continue 1;
+
+ $last = $hist[0]['timestamp'] - $period;
+ $missing_data = FALSE;
+ $i = 0;
+ foreach ($hist as $h) {
+ $diff_obs = $h['timestamp'] - $last;
+ if ($period !== $diff_obs) {
+ $missing_data = TRUE;
+ $missing_obs = $h['timestamp'] - $period;
+ $missing_array = $i;
+ }
+ $last = $h['timestamp'];
+ $i++;
+ }
+ if ($missing_data) {
+ echo '
+ missing data at array position ' . $missing_array . ',
+ time ' . date('Y-m-d H:i T', $missing_obs / 1000) . ',
+ timestamp ' . $missing_obs . ',
+ period ' . $period . '
+ ';
+ var_dump($hist[$missing_array - 1]);
+ var_dump($hist[$missing_array]);
+ continue 1;
+ }
+
+ $count = count($hist);
+ $dc = array_column($hist, 'close');
+
+ foreach ($rsi as $n) {
+ $r = trader_rsi($dc, $n);
+ $j = 0;
+ for ($i = 0; $i < $count; $i++) {
+ if (isset($r[$i])) {
+ $hist[$i]['rsi'.$n] = $r[$i];
+ if (isset($r[$j])) {
+ if ($r[$j] <= $rsiob && $r[$i] > $rsiob)
+ $hist[$i]['rsi'.$n.'ob'] = 1;
+ else
+ $hist[$i]['rsi'.$n.'ob'] = 0;
+ if ($r[$j] >= $rsios && $r[$i] < $rsios)
+ $hist[$i]['rsi'.$n.'os'] = 1;
+ else
+ $hist[$i]['rsi'.$n.'os'] = 0;
}
- $j = $i;
}
+ $j = $i;
}
-
- foreach($ema as $n) {
- $r = trader_ema($dc, $n);
- $j = 0;
- for($i = 0; $i < $count; $i++) {
- if(isset($r[$i])) {
- $hist[$i]['ema'.$n] = $r[$i];
- if(isset($r[$j])) {
- if($dc[$j] <= $r[$j] && $dc[$i] > $r[$i]) {
- $hist[$i]['ema'.$n.'cu'] = 1; // crossover upwards
- } else {
- $hist[$i]['ema'.$n.'cu'] = 0;
- }
- if($dc[$j] >= $r[$j] && $dc[$i] < $r[$i]) {
- $hist[$i]['ema'.$n.'cd'] = 1; // crossover downwards
- } else {
- $hist[$i]['ema'.$n.'cd'] = 0;
- }
+ }
+
+ foreach ($ema as $n) {
+ $r = trader_ema($dc, $n);
+ $j = 0;
+ for ($i = 0; $i < $count; $i++) {
+ if (isset($r[$i])) {
+ $hist[$i]['ema'.$n] = $r[$i];
+ if (isset($r[$j])) {
+ if ($dc[$j] <= $r[$j] && $dc[$i] > $r[$i]) {
+ $hist[$i]['ema'.$n.'cu'] = 1; // crossover upwards
+ } else {
+ $hist[$i]['ema'.$n.'cu'] = 0;
+ }
+ if ($dc[$j] >= $r[$j] && $dc[$i] < $r[$i]) {
+ $hist[$i]['ema'.$n.'cd'] = 1; // crossover downwards
+ } else {
+ $hist[$i]['ema'.$n.'cd'] = 0;
}
}
- $j = $i;
}
+ $j = $i;
}
+ }
- foreach($roc as $n) {
- $r = trader_roc($dc, $n);
- for($i = 0; $i < $count; $i++) {
- if(isset($r[$i]))
- $hist[$i]['roc'.$n] = $r[$i];
- }
+ foreach ($roc as $n) {
+ $r = trader_roc($dc, $n);
+ for ($i = 0; $i < $count; $i++) {
+ if (isset($r[$i]))
+ $hist[$i]['roc'.$n] = $r[$i];
}
-
- foreach($corr as $key => $array) {
- $query = "SELECT DISTINCT pair_id, pair, source, currency, history_start FROM asset_pairs
- WHERE analyse
- AND period = " . $pair['period'] . "
- AND pair LIKE '%" . $key . "/USD%'";
+ }
+
+ foreach ($corr as $key => $array) {
+ $query = "
+ SELECT DISTINCT pair_id, pair, source, currency, history_start FROM
+ WHERE analyse
+ AND period = " . $pair['period'] . "
+ AND pair LIKE '%" . $key . "/USD%'
+ ";
+ $res = query($query, $config);
+ if (!empty($res)) {
+ $query = "
+ SELECT timestamp, close FROM price_history
+ WHERE pair = '" . $res[0]['pair'] . "'
+ AND source = '" . $res[0]['source'] . "'
+ AND period = '" . $period_txt . "'
+ AND timestamp >= " . $hist[0]['timestamp'] . "
+ AND timestamp <= " . $hist[$count-1]['timestamp'] . "
+ ORDER BY timestamp ASC
+ ";
$res = query($query, $config);
- if(!empty($res)) {
- $query = "SELECT timestamp, close FROM price_history
- WHERE pair = '" . $res[0]['pair'] . "'
- AND source = '" . $res[0]['source'] . "'
- AND period = '" . $period_txt . "'
- AND timestamp >= " . $hist[0]['timestamp'] . "
- AND timestamp <= " . $hist[$count-1]['timestamp'] . "
- ORDER BY timestamp ASC";
- $res = query($query, $config);
- if(!empty($res) && count($res) == $count) {
- $cc = array_column($res, 'close');
- foreach($array as $n) {
- $r = trader_correl($dc, $cc, $n);
- for($i = 0; $i < $count; $i++) {
- if(isset($r[$i]))
- $hist[$i]['corr'.$n.$key] = $r[$i];
- }
+ if (!empty($res) && count($res) == $count) {
+ $cc = array_column($res, 'close');
+ foreach ($array as $n) {
+ $r = trader_correl($dc, $cc, $n);
+ for ($i = 0; $i < $count; $i++) {
+ if (isset($r[$i]))
+ $hist[$i]['corr'.$n.$key] = $r[$i];
}
}
}
}
-
- $omit = array('history_id', 'timestamp', 'open', 'high', 'low', 'close', 'volume');
- foreach($hist as $h) {
- $sep = '';
- $query = "UPDATE price_history SET ";
- foreach($h as $key => $val) {
- if(!in_array($key, $omit, TRUE)) {
- $query .= $sep . $key . " = '" . $val . "'";
- $sep = ',';
- }
+ }
+
+ $omit = array('history_id', 'timestamp', 'open', 'high', 'low', 'close', 'volume');
+ foreach ($hist as $h) {
+ $sep = '';
+ $query = "UPDATE price_history SET ";
+ foreach ($h as $key => $val) {
+ if (!in_array($key, $omit, TRUE)) {
+ $query .= $sep . $key . " = '" . $val . "'";
+ $sep = ',';
}
- $query .= " WHERE history_id = " . $h['history_id'];
- query($query, $config);
- //die;
}
+ $query .= " WHERE history_id = " . $h['history_id'];
+ query($query, $config);
+ }
}
diff --git a/functions.history.php b/functions.history.php
index ff7b46e..2563526 100644
--- a/functions.history.php
+++ b/functions.history.php
@@ -4,17 +4,25 @@
function history_orders($config) {
- # make query string
+ // make query string
switch ($config['exchange']) {
case 'bitmax':
$config['api_request'] = 'order/hist/current';
- $config['url'] .= $config['group'] . $config['order_history'] . '?n=1000&symbol=' . $config['pair'];
- break;
+ $config['url'] .=
+ $config['group'] .
+ $config['order_history'] .
+ '?n=1000&symbol=' .
+ $config['pair']
+ ;
+ break;
case 'okex':
- $config['api_request'] = '/api/spot/v3/orders?instrument_id=' . str_replace('/', '-', $config['pair'])
- . '&state=2';
+ $config['api_request'] =
+ '/api/spot/v3/orders' .
+ '?instrument_id=' . str_replace('/', '-', $config['pair'])
+ . '&state=2'
+ ;
$config['url'] .= $config['api_request'];
- break;
+ break;
}
return info($config);
@@ -25,55 +33,61 @@ function history_orders($config) {
function check_transaction($config, $transaction_id) {
- $values = array();
- $values['filterquery'] = " WHERE transaction_id = " . $transaction_id;
- $t = query('get_transactions', $config, $values);
-
- $config['exchange'] = $t[0]['exchange'];
- $config = config_exchange($config);
- $config['method'] = 'GET';
-
- switch($t[0]['exchange']) {
+ $values = array();
+ $values['filterquery'] = " WHERE transaction_id = " . $transaction_id;
+ $t = query('get_transactions', $config, $values);
- case 'bitmax':
- $config['api_request'] = 'order/status';
- $config['url'] .= $config['group'] . $config['orders_status']
- . '?orderId=' . $t[0]['exchange_transaction_id'];
- break;
- case 'okex':
- $config['api_request'] = $config['orders_status'] . $t[0]['exchange_transaction_id']
- . '?instrument_id='
- . str_replace('/', '-', $t[0]['pair_asset']);
- $config['url'] .= $config['orders_status'] . $t[0]['exchange_transaction_id'];
- break;
+ $config['exchange'] = $t[0]['exchange'];
+ $config = config_exchange($config);
+ $config['method'] = 'GET';
- }
+ switch($t[0]['exchange']) {
+ case 'bitmax':
+ $config['api_request'] = 'order/status';
+ $config['url'] .=
+ $config['group'] .
+ $config['orders_status'] .
+ '?orderId=' . $t[0]['exchange_transaction_id']
+ ;
+ break;
+ case 'okex':
+ $config['api_request'] =
+ $config['orders_status'] .
+ $t[0]['exchange_transaction_id'] .
+ '?instrument_id=' . str_replace('/', '-', $t[0]['pair_asset'])
+ ;
+ $config['url'] .=
+ $config['orders_status'] .
+ $t[0]['exchange_transaction_id']
+ ;
+ break;
+ }
- $transaction = info($config);
+ $transaction = info($config);
- if($t[0]['exchange'] == 'bitmax') {
- if($transaction['code'] !== 0) {
- return FALSE;
- } else {
- $transaction = $transaction[0]['data'];
- }
+ if ($t[0]['exchange'] == 'bitmax') {
+ if ($transaction['code'] !== 0) {
+ return FALSE;
+ } else {
+ $transaction = $transaction[0]['data'];
}
+ }
- if($t[0]['exchange'] == 'okex') {
- if($transaction['error_code'] !== 0) {
- return FALSE;
- }
- } else {
- $transaction = $transaction[0];
+ if ($t[0]['exchange'] == 'okex') {
+ if ($transaction['error_code'] !== 0) {
+ return FALSE;
}
+ } else {
+ $transaction = $transaction[0];
+ }
- $transaction['exchange'] = $t[0]['exchange'];
+ $transaction['exchange'] = $t[0]['exchange'];
- /* map array to exchange-specific format */
- $transaction = map_transaction('', $transaction, $config);
- query('update_transaction', $config, $transaction);
+ /* map array to exchange-specific format */
+ $transaction = map_transaction('', $transaction, $config);
+ query('update_transaction', $config, $transaction);
- return $transaction;
+ return $transaction;
}
@@ -82,96 +96,103 @@ function check_transaction($config, $transaction_id) {
function update_transactions($config) {
// select all possible combinations of exchange and pair_asset
- $query = "SELECT DISTINCT exchange, pair_asset FROM transactions";
- $sub_query = " WHERE exchange_transaction_status != 'cancelled'
- AND from_asset != to_asset";
- if(!empty($config['exchange'])) {
+ $query = "
+ SELECT DISTINCT
+ exchange,
+ pair_asset
+ FROM transactions
+ ";
+ $sub_query = "
+ WHERE exchange_transaction_status != 'cancelled'
+ AND from_asset != to_asset
+ ";
+ if (!empty($config['exchange'])) {
$sub_query .= " AND exchange = '" . $config['exchange'] . "'";
} else {
$sub_query .= " AND exchange IN (" . $config['exchanges_trade'] . ")";
}
- if(!empty($config['pair'])) $sub_query .= " AND pair_asset = '" . $config['pair'] . "'";
+ if (!empty($config['pair'])) $sub_query .= " AND pair_asset = '" . $config['pair'] . "'";
$pairs = query($query . $sub_query, $config);
- if($config['debug']) var_dump($pairs);
- if(empty($pairs)) return FALSE;
+ if ($config['debug']) var_dump($pairs);
+ if (empty($pairs)) return FALSE;
// for each combination, query the exchange and put result in $transactions
$transactions = array();
- foreach($pairs as $pair) {
- $config['exchange'] = $pair['exchange'];
- $config = config_exchange($config);
- $config['pair'] = $pair['pair_asset'];
- $result = history_orders($config);
- if(!empty($result)) {
- // countdim checks the array depth
- if(countdim($result) == 1) {
- $result['exchange'] = $config['exchange'];
- array_push($transactions, $result);
- } elseif(countdim($result) > 1) {
- foreach ($result as $res) {
- $res['exchange'] = $config['exchange'];
- array_push($transactions, $res);
- }
+ foreach ($pairs as $pair) {
+ $config['exchange'] = $pair['exchange'];
+ $config = config_exchange($config);
+ $config['pair'] = $pair['pair_asset'];
+ $result = history_orders($config);
+ if (!empty($result)) {
+ // countdim checks the array depth
+ if (countdim($result) == 1) {
+ $result['exchange'] = $config['exchange'];
+ array_push($transactions, $result);
+ } elseif (countdim($result) > 1) {
+ foreach ($result as $res) {
+ $res['exchange'] = $config['exchange'];
+ array_push($transactions, $res);
}
}
- // pause to limit number of requests to exchange per second
- sleep(0.2);
+ }
+ // pause to limit number of requests to exchange per second
+ sleep(0.2);
}
- if(empty($transactions)) return FALSE;
+ if (empty($transactions)) return FALSE;
$query = "SELECT * FROM transactions"; # whole records
- $existing = query($query . $sub_query, $config);
+ $existing = query($query . $sub_query, $config);
foreach ($transactions as $t) {
-
- if($t['exchange'] == 'bitmax') {
- if(!empty($t['data'])) {
+ if ($t['exchange'] == 'bitmax') {
+ if (!empty($t['data'])) {
process_transaction($config, $existing, $t['data']);
}
}
-
- if($t['exchange'] == 'okex') {
- if(!empty($t)) {
+ if ($t['exchange'] == 'okex') {
+ if (!empty($t)) {
process_transaction($config, $existing, $t);
}
}
-
}
+
}
/* transform transaction data from exchange and save in database */
-function process_transaction($config, $existing, $order){
-
- /* map order id only, not other order details
- note that $order_id_only = TRUE */
- $order = map_transaction('', $order, $config, TRUE);
-
- /* if transaction exists in database, use existing record */
- $exists = FALSE;
- if(!empty($existing)) foreach ($existing as $exist) {
- if ($exist['exchange_transaction_id'] == $order['exchange_transaction_id']
- && $exist['exchange'] == $order['exchange']
- ) {
- $exists = TRUE;
- $values = $exist;
- echo 'existing transaction' . PHP_EOL;
- }
+function process_transaction($config, $existing, $order) {
+
+ // map order id only, not other order details
+ // note that $order_id_only = TRUE
+ $order = map_transaction('', $order, $config, TRUE);
+
+ // if transaction exists in database, use existing record
+ $exists = FALSE;
+ if (!empty($existing))
+ foreach ($existing as $exist) {
+ if (
+ $exist['exchange_transaction_id'] == $order['exchange_transaction_id']
+ && $exist['exchange'] == $order['exchange']
+ ) {
+ $exists = TRUE;
+ $values = $exist;
+ echo 'existing transaction' . PHP_EOL;
}
+ }
- /* if transaction not exists in database, create new entry with default values */
- if(!$exists) {
- $values = $config['transaction'];
- $values['purpose'] = 'trade';
- $values['exchange'] = $config['exchange'];
- echo 'new transaction' . PHP_EOL;
- }
+ // if transaction not exists in database, create new entry with default values
+ if (!$exists) {
+ $values = $config['transaction'];
+ $values['purpose'] = 'trade';
+ $values['exchange'] = $config['exchange'];
+ echo 'new transaction' . PHP_EOL;
+ }
- /* map exchange data array */
- $values = map_transaction($values, $order, $config, FALSE);
+ /* map exchange data array */
+ $values = map_transaction($values, $order, $config, FALSE);
- query('update_transaction', $config, $values);
+ query('update_transaction', $config, $values);
}
@@ -180,17 +201,15 @@ function process_transaction($config, $existing, $order){
function map_transaction($values, $order, $config, $order_id_only = FALSE) {
switch ($order['exchange']) {
-
case 'bitmax':
$order['exchange_transaction_id'] = $order['orderId'];
- break;
+ break;
case 'okex':
$order['exchange_transaction_id'] = $order['order_id'];
- break;
-
+ break;
}
- if($order_id_only) return $order;
+ if ($order_id_only) return $order;
$time = NULL;
$status = NULL;
@@ -206,27 +225,26 @@ function map_transaction($values, $order, $config, $order_id_only = FALSE) {
switch ($order['exchange']) {
case 'bitmax':
-
$time = $order['lastExecTime'];
switch($order['status']) {
case 'Filled':
$status = 'filled';
$values['time_closed'] = $time;
- break;
+ break;
case 'New':
case 'PartiallyFilled':
$status = 'open';
$values['time_opened'] = $time;
- break;
+ break;
case 'PendingNew':
$status = 'pending_trigger';
$values['time_opened'] = $time;
- break;
+ break;
case 'Canceled': # (server typo spelled Canceled)
case 'Reject':
$status = 'cancelled';
$values['time_closed'] = $time;
- break;
+ break;
}
$pair_price = $order['price'];
$symbol = $order['symbol'];
@@ -236,33 +254,31 @@ function map_transaction($values, $order, $config, $order_id_only = FALSE) {
$fee = $order['cumFee'];
$fee_asset = $order['feeAsset'];
$direction = $order['side'];
-
break;
case 'okex':
-
switch($order['state']) {
case '2': # Fully Filled
$status = 'filled';
- break;
+ break;
case '0': # Open
case '1': # Partially Filled
$status = 'open';
- break;
+ break;
case '3': # Submitting
case '4': # Canceling
$status = 'unconfirmed';
- break;
+ break;
case '-1': # Canceled
case '-2': # Failed
$status = 'cancelled';
- break;
+ break;
}
$values['time_opened'] = strtotime($order['created_at']);
#$values['time_closed'] = strtotime($order['timestamp']);
$pair_price = $order['price_avg'];
$symbol = str_replace('-', '/', $order['instrument_id']);
- if($order['type'] == 'limit') {
+ if ($order['type'] == 'limit') {
$quantity = $order['size'];
$filled = $order['filled_size'];
} elseif ($order['type'] == 'market') {
@@ -273,31 +289,30 @@ function map_transaction($values, $order, $config, $order_id_only = FALSE) {
$fee = ABS($order['fee']);
$fee_asset = $order['fee_currency'];
$direction = $order['side'];
-
break;
- }
+ }
/* order filled */
- if($status == 'filled') {
- $values['exchange_transaction_status'] = 'complete';
+ if ($status == 'filled') {
+ $values['exchange_transaction_status'] = 'complete';
}
/* order open */
- if($status == 'open') {
- $values['exchange_transaction_status'] = 'open';
- $values['pair_price'] = $pair_price;
+ if ($status == 'open') {
+ $values['exchange_transaction_status'] = 'open';
+ $values['pair_price'] = $pair_price;
}
/* order open, but pending trigger */
- if($status == 'pending_trigger') {
- $values['exchange_transaction_status'] = 'trigger open';
- $values['pair_price'] = $pair_price;
+ if ($status == 'pending_trigger') {
+ $values['exchange_transaction_status'] = 'trigger open';
+ $values['pair_price'] = $pair_price;
}
/* order cancelled */
- if($status == 'cancelled') {
- $values['exchange_transaction_status'] = 'cancelled';
+ if ($status == 'cancelled') {
+ $values['exchange_transaction_status'] = 'cancelled';
}
/* simple order information */
@@ -309,48 +324,48 @@ function map_transaction($values, $order, $config, $order_id_only = FALSE) {
/* read amounts */
$values['percent_complete'] = round(100 * $filled / $quantity, 0);
- if($filled > 0) {
- $price = $avg_price;
+ if ($filled > 0) {
+ $price = $avg_price;
} else {
- $price = $pair_price;
+ $price = $pair_price;
}
/* sell order */
- if(strtolower($direction) == 'sell') {
- $values['from_asset'] = $pair[0];
- $values['from_amount'] = $quantity;
- $values['to_asset'] = $pair[1];
- $values['to_amount'] = $price * $quantity;
- if($fee_asset == $pair[1]) {
- $values['to_fee'] = $fee;
- } else {
- $values['to_fee'] = $fee * $price;
- }
- $values['pair_price'] = $values['to_amount'] / $values['from_amount'];
- if(in_array($pair[1], array('USDT','USD','USDC','DAI'))) {
- $values['from_price_usd'] = $values['to_amount'] / $values['from_amount'];
- $values['to_price_usd'] = 1;
- $values['price_reference'] = $order['exchange'];
- }
+ if (strtolower($direction) == 'sell') {
+ $values['from_asset'] = $pair[0];
+ $values['from_amount'] = $quantity;
+ $values['to_asset'] = $pair[1];
+ $values['to_amount'] = $price * $quantity;
+ if ($fee_asset == $pair[1]) {
+ $values['to_fee'] = $fee;
+ } else {
+ $values['to_fee'] = $fee * $price;
+ }
+ $values['pair_price'] = $values['to_amount'] / $values['from_amount'];
+ if (in_array($pair[1], array('USDT','USD','USDC','DAI'))) {
+ $values['from_price_usd'] = $values['to_amount'] / $values['from_amount'];
+ $values['to_price_usd'] = 1;
+ $values['price_reference'] = $order['exchange'];
+ }
}
/* buy order */
- if(strtolower($direction) == 'buy') {
- $values['from_asset'] = $pair[1];
- $values['from_amount'] = $price * $quantity;
- $values['to_asset'] = $pair[0];
- $values['to_amount'] = $quantity;
- if($fee_asset == $pair[0]) {
- $values['to_fee'] = $fee;
- } else {
- $values['to_fee'] = $fee / $price;
- }
- $values['pair_price'] = $values['from_amount'] / $values['to_amount'];
- if(in_array($pair[1], array('USDT','USD','USDC','DAI'))) {
- $values['from_price_usd'] = 1;
- $values['to_price_usd'] = $values['from_amount'] / $values['to_amount'];
- $values['price_reference'] = $order['exchange'];
- }
+ if (strtolower($direction) == 'buy') {
+ $values['from_asset'] = $pair[1];
+ $values['from_amount'] = $price * $quantity;
+ $values['to_asset'] = $pair[0];
+ $values['to_amount'] = $quantity;
+ if ($fee_asset == $pair[0]) {
+ $values['to_fee'] = $fee;
+ } else {
+ $values['to_fee'] = $fee / $price;
+ }
+ $values['pair_price'] = $values['from_amount'] / $values['to_amount'];
+ if (in_array($pair[1], array('USDT','USD','USDC','DAI'))) {
+ $values['from_price_usd'] = 1;
+ $values['to_price_usd'] = $values['from_amount'] / $values['to_amount'];
+ $values['price_reference'] = $order['exchange'];
+ }
}
return $values;
@@ -361,36 +376,49 @@ function map_transaction($values, $order, $config, $order_id_only = FALSE) {
function calculate_orders($config) {
- $query = "SELECT a.transaction_id, b.close AS price_aud_usd, 'https://twelvedata.com/' AS aud_usd_reference
- FROM transactions a
- CROSS JOIN price_history b
- INNER JOIN (
- SELECT a.transaction_id, MIN(ABS(a.time_closed - b.timestamp)) AS min_abs_value
- FROM transactions a
- CROSS JOIN price_history b
- WHERE a.price_aud_usd = 0
- AND a.exchange_transaction_status = 'complete'
- AND b.pair = 'AUD/USD'
- GROUP BY a.transaction_id
- ) t
- ON a.transaction_id = t.transaction_id
- AND ABS(a.time_closed - b.timestamp) = t.min_abs_value
- WHERE a.price_aud_usd = 0
- AND a.exchange_transaction_status = 'complete'
- AND b.pair = 'AUD/USD'
- ";
+ $query = "
+ SELECT
+ a.transaction_id,
+ b.close AS price_aud_usd,
+ 'https://twelvedata.com/' AS aud_usd_reference
+ FROM transactions a
+ CROSS JOIN price_history b
+ INNER JOIN (
+ SELECT
+ a.transaction_id,
+ MIN(ABS(a.time_closed - b.timestamp)) AS min_abs_value
+ FROM transactions a
+ CROSS JOIN price_history b
+ WHERE a.price_aud_usd = 0
+ AND a.exchange_transaction_status = 'complete'
+ AND b.pair = 'AUD/USD'
+ GROUP BY a.transaction_id
+ ) t
+ ON a.transaction_id = t.transaction_id
+ AND ABS(a.time_closed - b.timestamp) = t.min_abs_value
+ WHERE a.price_aud_usd = 0
+ AND a.exchange_transaction_status = 'complete'
+ AND b.pair = 'AUD/USD'
+ ";
$orders = query($query, $config);
- foreach($orders as $order) {
- $query = "UPDATE transactions SET price_aud_usd = " . $order['price_aud_usd'] . ", aud_usd_reference = '" . $order['aud_usd_reference'] . "' WHERE transaction_id = " . $order['transaction_id'];
+ foreach ($orders as $order) {
+ $query = "
+ UPDATE transactions
+ SET price_aud_usd = " . $order['price_aud_usd'] . ",
+ aud_usd_reference = '" . $order['aud_usd_reference'] . "'
+ WHERE transaction_id = " . $order['transaction_id']
+ ;
query($query, $config);
}
# capital estimate
- $query = "UPDATE transactions SET
- fee_amount_usd = to_fee * to_price_usd,
- capital_amount = to_amount * to_price_usd / price_aud_usd,
- capital_fee = fee_amount_usd / price_aud_usd
- WHERE exchange_transaction_status = 'complete'
- ";
+ $query = "
+ UPDATE transactions SET
+ fee_amount_usd = to_fee * to_price_usd,
+ capital_amount = to_amount * to_price_usd / price_aud_usd,
+ capital_fee = fee_amount_usd / price_aud_usd
+ WHERE exchange_transaction_status = 'complete'
+ ";
query($query, $config);
+
}
diff --git a/functions.order.php b/functions.order.php
index 17d8ce8..c225288 100644
--- a/functions.order.php
+++ b/functions.order.php
@@ -1,16 +1,16 @@
call($httpheader, $config['method'], $order);
+ $class = new APIREST($config['url']);
+ $result = $class -> call($httpheader, $config['method'], $order);
- return json_decode($result, TRUE);
+ return json_decode($result, TRUE);
}
@@ -18,7 +18,11 @@ function order($config, $order) {
function place_order($config, $order_query, $orderId = '') {
- if(isset($order_query['orderId'])) { $orderId = $order_query['orderId']; } else { $orderId = ''; }
+ if (isset($order_query['orderId'])) {
+ $orderId = $order_query['orderId'];
+ } else {
+ $orderId = '';
+ }
$order = array();
@@ -26,79 +30,91 @@ function place_order($config, $order_query, $orderId = '') {
case 'bitmax':
$config['api_request'] = 'order';
- $config['url'] .= $config['group'] . $config['order'];
- $config['method'] = 'POST';
- $order['id'] = 'a' . # a for order via rest api
- dechex($config['timestamp']) . # convert timestamp to hex
- $config['user_id'] . # user id
- $orderId; # order num with 9 characters/numbers, ending with a character
- # self-generated order id by choice, or provided if empty
- #if(strlen($order['id']) !== 32) die;
+ $config['url'] .= $config['group'] . $config['order'];
+ $config['method'] = 'POST';
+ $order['id'] =
+ 'a' . # a for order via rest api
+ dechex($config['timestamp']) . # convert timestamp to hex
+ $config['user_id'] . # user id
+ $orderId # order num 9 characters/numbers, ending with a character, system-generated if empty
+ ;
+ if (strlen($order['id']) !== 32) {
+ $config['chatText'] = 'incorrect order id for bitmax';
+ telegram($config);
+ die;
+ }
$order['time'] = (int)$config['timestamp'];
- $order['symbol'] = $order_query['symbol'];
- $order['orderPrice'] = $order_query['orderPrice'];
- $order['orderQty'] = $order_query['orderQty'];
- $order['orderType'] = $order_query['orderType']; # market, limit, stop_market, stop_limit
- $order['side'] = $order_query['side']; # buy, sell
- $order['respInst'] = $order_query['respInst']; # ACK, ACCEPT, DONE
-
- break;
+ $order['symbol'] = $order_query['symbol'];
+ $order['orderPrice'] = $order_query['orderPrice'];
+ $order['orderQty'] = $order_query['orderQty'];
+ $order['orderType'] = $order_query['orderType']; # market, limit, stop_market, stop_limit
+ $order['side'] = $order_query['side']; # buy, sell
+ $order['respInst'] = $order_query['respInst']; # ACK, ACCEPT, DONE
+ break;
+
case 'okex':
$order['type'] = $order_query['orderType']; # limit or market. When placing market orders, order_type must be 0
$order['side'] = $order_query['side']; # buy or sell
$order['instrument_id'] = str_replace('/', '-', $order_query['symbol']);
- if($orderId !== '') $order['client_oid'] = $orderId; # between 1-32 characters
- if($order['type'] == 'limit') {
+ if ($orderId !== '') $order['client_oid'] = $orderId; # between 1-32 characters
+ if ($order['type'] == 'limit') {
$order['size'] = $order_query['orderQty'];
$order['price'] = $order_query['orderPrice'];
- if(!empty($order_query['orderTypeCode'])) $order['order_type'] = $order_query['orderTypeCode']; # 0: Normal order (Unfilled and 0 imply normal limit order) 1: Post only 2: Fill or Kill 3: Immediate Or Cancel
+ if (!empty($order_query['orderTypeCode']))
+ # 0: Normal order (Unfilled and 0 imply normal limit order)
+ # 1: Post only
+ # 2: Fill or Kill
+ # 3: Immediate Or Cancel
+ $order['order_type'] = $order_query['orderTypeCode'];
}
- if($order['type'] == 'market') {
- if($order['side'] == 'buy') $order['notional'] = $order_query['orderQty'];
- else $order['size'] = $order_query['orderQty'];
+ if ($order['type'] == 'market') {
+ if ($order['side'] == 'buy') {
+ $order['notional'] = $order_query['orderQty'];
+ } else {
+ $order['size'] = $order_query['orderQty'];
+ }
#$order['order_type'] = '0';
}
$config['method'] = 'POST';
$config['api_request'] = $config['order'] . json_encode($order, JSON_UNESCAPED_SLASHES);
$config['url'] .= $config['order'];
- break;
+ break;
}
- if($config['debug']) { echo $config['url'] . PHP_EOL; echo $config['api_request'] . PHP_EOL; }
+ if ($config['debug']) echo $config['url'] . PHP_EOL . $config['api_request'] . PHP_EOL;
- $res = order($config, $order);
- if($config['debug']) print_r($res);
- $result = array('res' => array(
- 'placed' => FALSE,
- 'code' => '',
- 'message' => '',
- 'exchange_transaction_id' => ''
- ),
- 'query' => $order);
+ $res = order($config, $order);
+ if ($config['debug']) print_r($res);
+ $result = array(
+ 'res' => array(
+ 'placed' => FALSE,
+ 'code' => '',
+ 'message' => '',
+ 'exchange_transaction_id' => ''
+ ),
+ 'query' => $order
+ );
switch($config['exchange']) {
-
case 'bitmax':
$result['res']['code'] = $res['code'];
- if($res['code'] == 0) {
+ if ($res['code'] == 0) {
$result['res']['placed'] = TRUE;
$result['res']['exchange_transaction_id'] = $res['info']['id'];
} else {
$result['res']['message'] = $res['reason'] . ' ' . $res['message'];
}
- break;
-
+ break;
case 'okex':
$result['res']['code'] = $res['error_code'];
- if($res['error_code'] == 0) {
+ if ($res['error_code'] == 0) {
$result['res']['placed'] = TRUE;
$result['res']['exchange_transaction_id'] = $res['order_id'];
} else {
$result['res']['message'] = $res['error_message'];
}
- break;
-
+ break;
}
return $result;
@@ -111,58 +127,54 @@ function cancel_order($config, $order_query) {
$order = array();
switch($config['exchange']) {
-
case 'bitmax':
$order['orderId'] = $order_query['orderId'];
$order['symbol'] = $order_query['symbol'];
$order['time'] = (int)$config['timestamp'];
$config['api_request'] = 'order';
- $config['url'] .= $config['group'] . $config['order'];
- $config['method'] = 'DELETE';
- break;
-
+ $config['url'] .= $config['group'] . $config['order'];
+ $config['method'] = 'DELETE';
+ break;
case 'okex':
$config['method'] = 'POST';
$order['instrument_id'] = str_replace('/', '-', $order_query['symbol']);
$config['api_request'] = $config['delete'] . $order_query['orderId'];
$config['url'] .= $config['api_request'];
$config['api_request'] .= json_encode($order, JSON_UNESCAPED_SLASHES);
- break;
-
+ break;
}
$res = order($config, $order);
- if($config['debug']) print_r($res);
- $result = array('res' => array(
- 'placed' => FALSE,
- 'code' => '',
- 'message' => '',
- 'exchange_transaction_id' => ''
- ),
- 'query' => $order);
+ if ($config['debug']) print_r($res);
+ $result = array(
+ 'res' => array(
+ 'placed' => FALSE,
+ 'code' => '',
+ 'message' => '',
+ 'exchange_transaction_id' => ''
+ ),
+ 'query' => $order
+ );
switch($config['exchange']) {
-
case 'bitmax':
$result['res']['code'] = $res['code'];
- if($res['code'] == 0) {
+ if ($res['code'] == 0) {
$result['res']['placed'] = TRUE;
} else {
$result['res']['message'] = $res['reason'] . ' ' . $res['message'];
}
- break;
-
+ break;
case 'okex':
$result['res']['code'] = $res['error_code'];
- if($res['error_code'] == 0) {
+ if ($res['error_code'] == 0) {
$result['res']['placed'] = TRUE;
} else {
$result['res']['message'] = $res['error_message'];
}
- break;
-
+ break;
}
- return $result;
+ return $result;
}
diff --git a/functions.php b/functions.php
index 145a33d..0d1d048 100644
--- a/functions.php
+++ b/functions.php
@@ -4,98 +4,111 @@
function info($config) {
- $httpheader = http_headers($config);
- #var_dump($httpheader);
- $class = new APIREST($config['url']);
- $result = $class -> call($httpheader, $config['method']);
+ $httpheader = http_headers($config);
- return json_decode($result, TRUE);
+ $class = new APIREST($config['url']);
+ $result = $class -> call($httpheader, $config['method']);
+
+ return json_decode($result, TRUE);
}
/* send notification message to telegram bot */
function telegram($config) {
- /* bot name: univert
+ /*
- show chat id (needs webhook disabled):
- https://api.telegram.org/bot0000000000:xxx_API_KEY_xxx/getUpdates
+ show chat id (needs webhook disabled):
+ https://api.telegram.org/bot0000000000:xxx_API_KEY_xxx/getUpdates
- Use $config['chatPath'] the HTTP API:
+ Use $config['chatPath'] the HTTP API:
- For a description of the Bot API, see this page: https://core.telegram.org/bots/api
+ For a description of the Bot API, see this page: https://core.telegram.org/bots/api
- for interactive bot
- example: https://nordicapis.com/how-to-build-your-first-telegram-bot-using-php-in-under-30-minutes/
+ for interactive bot
+ example: https://nordicapis.com/how-to-build-your-first-telegram-bot-using-php-in-under-30-minutes/
- activate webhook:
- https://api.telegram.org/bot0000000000:xxx_API_KEY_xxx/setwebhook?url=https://your.server.com/telegram.php
+ activate webhook:
+ https://api.telegram.org/bot0000000000:xxx_API_KEY_xxx/setwebhook?url=https://your.server.com/telegram.php
- deactivate webhook:
- https://api.telegram.org/bot0000000000:xxx_API_KEY_xxx/setwebhook?url=
+ deactivate webhook:
+ https://api.telegram.org/bot0000000000:xxx_API_KEY_xxx/setwebhook?url=
- */
+ */
- $httpheader = http_headers($config, TRUE);
- $query = $config['chatPath'] . '/sendmessage?chat_id=' . $config['chatId'] . '&parse_mode=html&text=' . $config['chatText'];
+ $httpheader = http_headers($config, TRUE);
+ $query =
+ $config['chatPath'] .
+ '/sendmessage?chat_id=' . $config['chatId'] .
+ '&parse_mode=html&text=' . $config['chatText']
+ ;
- $class = new APIREST($query);
- $result = $class -> call($httpheader, $config['method']);
+ $class = new APIREST($query);
+ $result = $class -> call($httpheader, $config['method']);
- return json_decode($result, TRUE);
+ return json_decode($result, TRUE);
}
/* define http headers and parameters for exchange API */
function http_headers($config, $default = FALSE) {
- if($default) {
+ if ($default) {
+
$httpheader = array(
- 'Accept: ' . $config['accept'],
- 'Content-Type: ' . $config['content_type']
- );
+ 'Accept: ' . $config['accept'],
+ 'Content-Type: ' . $config['content_type']
+ );
+
} else {
- switch ($config['exchange']) {
+ switch ($config['exchange']) {
case 'bitmax':
- $config['msg'] = $config['timestamp'] . '+' . $config['api_request'];
- $config['signature'] = hmac($config['msg'], $config['secret']);
- $httpheader = array(
- 'Accept: ' . $config['accept'],
- 'Content-Type: ' . $config['content_type'],
- 'x-auth-key: ' . $config['api_key'],
- 'x-auth-signature: ' . $config['signature'],
- 'x-auth-timestamp: ' . $config['timestamp']
- );
- break;
+ $config['msg'] =
+ $config['timestamp'] .
+ '+' .
+ $config['api_request']
+ ;
+ $config['signature'] = hmac($config['msg'], $config['secret']);
+ $httpheader = array(
+ 'Accept: ' . $config['accept'],
+ 'Content-Type: ' . $config['content_type'],
+ 'x-auth-key: ' . $config['api_key'],
+ 'x-auth-signature: ' . $config['signature'],
+ 'x-auth-timestamp: ' . $config['timestamp']
+ );
+ break;
case 'okex':
- #$timestamp = date('Y-m-d\TH:i:s.000', $config['timestamp'] / 1000) . 'Z'; # ISO 8601 standard format with Z
- $config['msg'] = (string) $config['timestamp'] . $config['method'] . $config['api_request'];
- $config['signature'] = hmac($config['msg'], $config['secret']);
- $httpheader = array(
- 'Accept: ' . $config['accept'],
- 'Content-Type: ' . $config['content_type'],
- 'ok-access-key: ' . $config['api_key'],
- 'ok-access-sign: ' . $config['signature'],
- 'ok-access-timestamp: ' . $config['timestamp'] / 1000,
- 'ok-access-passphrase: ' . $config['pass']
- #'OK-TEXT-TO-SIGN: ' . $config['msg']
- );
- break;
+ #$timestamp = date('Y-m-d\TH:i:s.000', $config['timestamp'] / 1000) . 'Z'; # ISO 8601 standard format with Z
+ $config['msg'] =
+ (string) $config['timestamp'] .
+ $config['method'] .
+ $config['api_request']
+ ;
+ $config['signature'] = hmac($config['msg'], $config['secret']);
+ $httpheader = array(
+ 'Accept: ' . $config['accept'],
+ 'Content-Type: ' . $config['content_type'],
+ 'ok-access-key: ' . $config['api_key'],
+ 'ok-access-sign: ' . $config['signature'],
+ 'ok-access-timestamp: ' . $config['timestamp'] / 1000,
+ 'ok-access-passphrase: ' . $config['pass']
+ #'OK-TEXT-TO-SIGN: ' . $config['msg']
+ );
+ break;
default:
$httpheader = array(
- 'Accept: ' . $config['accept'],
- 'Content-Type: ' . $config['content_type']
- );
+ 'Accept: ' . $config['accept'],
+ 'Content-Type: ' . $config['content_type']
+ );
- }
+ }
}
- #if(isset($config['get_param'])) array_push($httpheader, $config['get_param']);
- return $httpheader;
+ return $httpheader;
}
diff --git a/functions.price.php b/functions.price.php
index f782b0f..adf050c 100644
--- a/functions.price.php
+++ b/functions.price.php
@@ -7,25 +7,37 @@ function price_query($config, $pq) {
# make query string
switch ($config['exchange']) {
case 'twelve':
- $config['price_history'] = $config['url'] . $config['price_history'] . '?symbol=' . $pq['pair'] . '&apikey=' . $config['api_key']
- . '&interval=' . $config['period_exchange'][$pq['period']] . '&outputsize=' . $pq['obs_iter'] . '&format=JSON&timezone=UTC';
- break;
+ $config['price_history'] =
+ $config['url'] .
+ $config['price_history'] .
+ '?symbol=' . $pq['pair'] .
+ '&apikey=' . $config['api_key'] .
+ '&interval=' . $config['period_exchange'][$pq['period']] .
+ '&outputsize=' . $pq['obs_iter'] .
+ '&format=JSON&timezone=UTC'
+ ;
+ break;
case 'bitmax':
$config['api_request'] = 'barhist';
- $config['price_history'] = $config['url'] . $config['price_history'] . '?symbol=' . $pq['pair'] . '&n=' . $pq['obs_iter'];
- $config['price_history'] .= '&interval=' . $config['period_exchange'][$pq['period']];
- break;
+ $config['price_history'] =
+ $config['url'] .
+ $config['price_history'] .
+ '?symbol=' . $pq['pair'] .
+ '&n=' . $pq['obs_iter'] .
+ '&interval=' . $config['period_exchange'][$pq['period']]
+ ;
+ break;
case 'okex':
$config['price_history'] .= str_replace('/', '-', $pq['pair']);
- if($pq['hist_long']) $config['price_history'] .= '/history';
+ if ($pq['hist_long']) $config['price_history'] .= '/history';
$config['price_history'] = $config['url'] . $config['price_history'];
- break;
+ break;
}
- # set start time; stop at current time; add number of periods minutes;
+ # set start time; stop at current time; add number of periods minutes;
$j = ($pq['period_ms'] * $pq['obs_iter']);
$i = ceil(($pq['stop'] - $pq['start']) / $j);
- if($i > 1) {
+ if ($i > 1) {
$to = $pq['start'] + $j - $pq['period_ms']; # we need 1 period less than the maximum for looping
} else {
$i = 1; # in case $i = 0
@@ -35,119 +47,150 @@ function price_query($config, $pq) {
$from = $pq['start'];
# split the query into separate API requests if the number of records exceeds the maximum allowed
- for ($i; $i > 0; $i--) {
-
- echo '$from: ' . $from . ' $to: ' . $to . ' units: ' . floor(($to - $from) / $pq['period_ms']) . ' of ' . floor(($pq['stop'] - $pq['obs_iter']) / $pq['period_ms']) . PHP_EOL;
- echo '$i: ' . $i . ' $j: ' . $j . ' $period_ms: ' . $pq['period_ms'] . PHP_EOL;
-
- # create the API request string
- switch ($config['exchange']) {
- case 'twelve':
- $config['url'] = $config['price_history'] . '&start_date=' . date('Y-m-d H:i:s', $from / 1000) . '&end_date=' . date('Y-m-d H:i:s', $to / 1000);
- $config['url'] = str_replace(' ', ' ', $config['url']);
- break;
- case 'bitmax':
- $config['url'] = $config['price_history'] . '&from=' . $from . '&to=' . $to;
- break;
- case 'okex':
- if($pq['hist_long']) $config['api_request'] = '/candles'
- # okex dates in reverse order for /history
- # seems like a bug in their code
- . '?start=' . date('Y-m-d\TH:i:s.000', $to / 1000) . 'Z'
- . '&end=' . date('Y-m-d\TH:i:s.000', $from / 1000) . 'Z'
- . '&granularity=' . $config['period_exchange'][$pq['period']];
- else $config['api_request'] = '/candles'
- . '?granularity=' . $config['period_exchange'][$pq['period']]
- # okex dates in normal order for not /history
- . '&start=' . date('Y-m-d\TH:i:s.000', $from / 1000) . 'Z'
- . '&end=' . date('Y-m-d\TH:i:s.000', $to / 1000) . 'Z';
- $config['url'] = $config['price_history'] . $config['api_request'];
- break;
- }
+ for ($i; $i > 0; $i--) {
+
+ echo
+ '$from: ' . $from .
+ ' $to: ' . $to .
+ ' units: ' . floor(($to - $from) / $pq['period_ms']) .
+ ' of ' . floor(($pq['stop'] - $pq['obs_iter']) / $pq['period_ms']) .
+ PHP_EOL
+ ;
+ echo
+ '$i: ' . $i .
+ ' $j: ' . $j .
+ ' $period_ms: ' . $pq['period_ms'] .
+ PHP_EOL
+ ;
+
+ # create the API request string
+ switch ($config['exchange']) {
+
+ case 'twelve':
+ $config['url'] =
+ $config['price_history'] .
+ '&start_date=' . date('Y-m-d H:i:s', $from / 1000) .
+ '&end_date=' . date('Y-m-d H:i:s', $to / 1000)
+ ;
+ $config['url'] = str_replace(' ', ' ', $config['url']);
+ break;
+
+ case 'bitmax':
+ $config['url'] =
+ $config['price_history'] .
+ '&from=' . $from .
+ '&to=' . $to
+ ;
+ break;
- echo 'url: ' . $config['url'] . PHP_EOL;
+ case 'okex':
+ if ($pq['hist_long'])
+ $config['api_request'] =
+ '/candles' .
+ # okex dates in reverse order for /history
+ # seems like a bug in their code
+ '?start=' . date('Y-m-d\TH:i:s.000', $to / 1000) . 'Z' .
+ '&end=' . date('Y-m-d\TH:i:s.000', $from / 1000) . 'Z' .
+ '&granularity=' . $config['period_exchange'][$pq['period']]
+ ;
+ else
+ $config['api_request'] =
+ '/candles' .
+ '?granularity=' . $config['period_exchange'][$pq['period']] .
+ # okex dates in normal order for not /history
+ '&start=' . date('Y-m-d\TH:i:s.000', $from / 1000) . 'Z' .
+ '&end=' . date('Y-m-d\TH:i:s.000', $to / 1000) . 'Z'
+ ;
+ $config['url'] = $config['price_history'] . $config['api_request'];
+ break;
+
+ }
+
+ echo 'url: ' . $config['url'] . PHP_EOL;
- $result = info($config);
+ $result = info($config);
+
+ # process response
+ if (!empty($result)) {
+
+ $values = array();
+ $values['pair'] = $pq['pair'];
+ $values['source'] = $config['exchange'];
+ $values['period'] = $config['period'][$pq['period']];
+ $values['imputed'] = 0;
+
+ # read the response in the array format for the exchange
+ # okex already in correct format
+ if ($config['exchange'] == 'twelve') {
+ $values['pair'] = $result['meta']['symbol'];
+ $result = $result['values'];
+ }
+ if ($config['exchange'] == 'bitmax') {
+ $array = array();
+ foreach ($result['data'] as $data) array_push($array, $data['data']);
+ $result = $array;
+ }
- # process response
- if(!empty($result)) {
+ echo 'result: ' . count((array)$result) . PHP_EOL;
+ if ($config['debug']) print_r($result);
- $values = array();
- $values['pair'] = $pq['pair'];
- $values['source'] = $config['exchange'];
- $values['period'] = $config['period'][$pq['period']];
- $values['imputed'] = 0;
+ # process result one row (price bar) at a time because it will be
+ # easier to check the database if the record already exists using a single row
+ if (!empty($result))
+ foreach ($result as $price) {
- # read the response in the array format for the exchange
- # okex already in correct format
if ($config['exchange'] == 'twelve') {
- $values['pair'] = $result['meta']['symbol'];
- $result = $result['values'];
+ # server seems to expect requested data on separate dates
+ $values['timestamp'] = strtotime($price['datetime']) * 1000; # bar start time
+ $values['open'] = $price['open'];
+ $values['high'] = $price['high'];
+ $values['low'] = $price['low'];
+ $values['close'] = $price['close'];
+ $values['volume'] = $price['volume'];
}
+
if ($config['exchange'] == 'bitmax') {
- $array = array();
- foreach ($result['data'] as $data) array_push($array, $data['data']);
- $result = $array;
+ # possible that server returns missing value for bar
+ $values['timestamp'] = $price['ts']; # bar start time
+ $values['open'] = $price['o'];
+ $values['high'] = $price['h'];
+ $values['low'] = $price['l'];
+ $values['close'] = $price['c'];
+ $values['volume'] = $price['v'];
}
- echo 'result: ' . count((array)$result) . PHP_EOL;
- if($config['debug']) print_r($result);
-
- # process result one row (price bar) at a time because it will be
- # easier to check the database if the record already exists using a single row
- if(!empty($result))
- foreach ($result as $price) {
-
- if ($config['exchange'] == 'twelve') {
- # server seems to expect requested data on separate dates
- $values['timestamp'] = strtotime($price['datetime']) * 1000; # bar start time
- $values['open'] = $price['open'];
- $values['high'] = $price['high'];
- $values['low'] = $price['low'];
- $values['close'] = $price['close'];
- $values['volume'] = $price['volume'];
- }
-
- if ($config['exchange'] == 'bitmax') {
- # possible that server returns missing value for bar
- $values['timestamp'] = $price['ts']; # bar start time
- $values['open'] = $price['o'];
- $values['high'] = $price['h'];
- $values['low'] = $price['l'];
- $values['close'] = $price['c'];
- $values['volume'] = $price['v'];
- }
-
- if ($config['exchange'] == 'okex') {
- $values['pair'] = str_replace('-', '/', $values['pair']);
- $values['timestamp'] = strtotime($price[0]) * 1000; # convert to unix time
- $values['open'] = $price[1];
- $values['high'] = $price[2];
- $values['low'] = $price[3];
- $values['close'] = $price[4];
- $values['volume'] = $price[5];
- }
-
- # save row
- query('update_history', $config, $values);
- #var_dump($values);break 2;
- # option to skip deduplication within iteration
- # would still need to call price_history_dedupe after all iterations
- # not currently used, but could be for performance improvement
- if(!$pq['dedupe_hist']) continue 1;
- # check if duplicate price history record and remove oldest ones
- $values['filterquery'] = "AND a.pair = '" . $values['pair'] . "'
- AND a.source = '" . $values['source'] . "'
- AND a.timestamp = " . $values['timestamp'] . "
- AND a.period = '" . $values['period'] . "'";
- query('deduplicate_history', $config, $values);
+ if ($config['exchange'] == 'okex') {
+ $values['pair'] = str_replace('-', '/', $values['pair']);
+ $values['timestamp'] = strtotime($price[0]) * 1000; # convert to unix time
+ $values['open'] = $price[1];
+ $values['high'] = $price[2];
+ $values['low'] = $price[3];
+ $values['close'] = $price[4];
+ $values['volume'] = $price[5];
}
+
+ # save row
+ query('update_history', $config, $values);
+ #var_dump($values);break 2;
+ # option to skip deduplication within iteration
+ # would still need to call price_history_dedupe after all iterations
+ # not currently used, but could be for performance improvement
+ if (!$pq['dedupe_hist']) continue 1;
+ # check if duplicate price history record and remove oldest ones
+ $values['filterquery'] = "
+ AND a.pair = '" . $values['pair'] . "'
+ AND a.source = '" . $values['source'] . "'
+ AND a.timestamp = " . $values['timestamp'] . "
+ AND a.period = '" . $values['period'] . "'
+ ";
+ query('deduplicate_history', $config, $values);
}
+ }
- $from += $j;
- $to += $j;
- sleep(0.2); # use delay to reduce server load
- }
+ $from += $j;
+ $to += $j;
+ sleep(0.2); # use delay to reduce server load
+ }
}
/* check for all possible duplicate price history record and remove oldest ones */
@@ -155,45 +198,67 @@ function price_query($config, $pq) {
function price_history_dedupe($config) {
# quick check if all records are unique
- $total = query('SELECT COUNT(*) AS count FROM `price_history`', $config);
- $dedupes = query('SELECT COUNT(DISTINCT
- `pair`,
- `source`,
- `timestamp`,
- `period`
- ) AS count
- FROM `price_history`
- ', $config);
+ $query_all = "
+ SELECT COUNT(*) AS count FROM `price_history`
+ ";
+ $total = query($query_all, $config);
+ $query_dis = "
+ SELECT COUNT(
+ DISTINCT
+ `pair`,
+ `source`,
+ `timestamp`,
+ `period`
+ ) AS count
+ FROM `price_history`
+ ";
+ $dedupes = query($query_dis, $config);
$dupes = $total[0]['count'] - $dedupes[0]['count'];
echo $dupes . ' duplicates' . PHP_EOL;
- if(!$dupes) return;
+ if (!$dupes) return;
echo 'deduplicating ...';
# list all possible asset pairs and periods
- $permutations = query('SELECT DISTINCT
- `pair`,
- `source`,
- `period`
- FROM `price_history`
- ', $config);
+ $query_pair = "
+ SELECT DISTINCT
+ `pair`,
+ `source`,
+ `period`
+ FROM `price_history`
+ ";
+ $permutations = query($query_pair, $config);
# process each possible pair
+ $query_ded = "
+ SELECT DISTINCT
+ `pair`,
+ `source`,
+ `timestamp`,
+ `period`
+ FROM `price_history`
+ ";
foreach ($permutations as $p) {
- $filter = "WHERE pair = '" . $p['pair'] . "' AND source = '" . $p['source'] . "' AND period = '" . $p['period'] . "'";
- $total = query("SELECT COUNT(*) AS count FROM `price_history` " . $filter, $config);
- $dedupes = query("SELECT DISTINCT `pair`, `source`, `timestamp`, `period` FROM `price_history`" . $filter, $config);
+ $filter = "
+ WHERE pair = '" . $p['pair'] . "'
+ AND source = '" . $p['source'] . "'
+ AND period = '" . $p['period'] . "'
+ ";
+ $total = query($query_all . $filter, $config);
+ $dedupes = query($query_ded . $filter, $config);
$dupes = $total[0]['count'] - count($dedupes);
- if(!$dupes) continue 1;
- echo $dupes . ' ' . $filter . PHP_EOL;
+ if (!$dupes) continue 1;
+ echo $dupes . ' dupes ' . $filter . PHP_EOL;
foreach ($dedupes as $record) {
- $values['filterquery'] = "AND a.pair = '" . $record['pair'] . "'
- AND a.source = '" . $record['source'] . "'
- AND a.timestamp = " . $record['timestamp'] . "
- AND a.period = '" . $record['period'] . "'";
+ $values['filterquery'] = "
+ AND a.pair = '" . $record['pair'] . "'
+ AND a.source = '" . $record['source'] . "'
+ AND a.timestamp = " . $record['timestamp'] . "
+ AND a.period = '" . $record['period'] . "'
+ ";
query('deduplicate_history', $config, $values);
}
}
@@ -204,30 +269,54 @@ function price_history_dedupe($config) {
function price_history_trim($config) {
# get all asset pairs
- $query = "SELECT DISTINCT pair, source, period FROM asset_pairs";
+ $query = "
+ SELECT DISTINCT
+ pair,
+ source,
+ period
+ FROM asset_pairs
+ ";
$history = query($query, $config);
# get history_id without asset pairs
$query = "SELECT history_id FROM price_history WHERE 1=1";
foreach ($history as $hist) {
- if($config['debug']) foreach($hist as $key => $val) {
- echo $key . ': ' . $val . ' ';
- }
+ if ($config['debug'])
+ foreach ($hist as $key => $val) {
+ echo $key . ': ' . $val . ' ';
+ }
echo PHP_EOL;
- $query .= " AND (pair != '" . $hist['pair'] . "' AND source != '" . $hist['source'] . "' AND period != '" . $hist['period'] . "')";
+ $query .= "
+ AND (
+ pair != '" . $hist['pair'] . "'
+ AND source != '" . $hist['source'] . "'
+ AND period != '" . $hist['period'] . "'
+ )
+ ";
}
$drop_ids = query($query, $config);
# delete those history_id if any
echo PHP_EOL;
- if(!empty($drop_ids)) {
- $query = "FROM price_history WHERE history_id IN (0";
- foreach ($drop_ids as $array) $query .= ", " . $array['history_id'];
- $query .= ")";
- $result = query("SELECT DISTINCT pair, source, period " . $query, $config);
+ if (!empty($drop_ids)) {
+ $filter = "
+ FROM price_history
+ WHERE history_id
+ IN (0
+ ";
+ foreach ($drop_ids as $array) $filter .= ", " . $array['history_id'];
+ $filter .= ")";
+ $query = "
+ SELECT DISTINCT
+ pair,
+ source,
+ period
+ ";
+ $result = query($query . $filter, $config);
echo 'deleting history_id without asset pairs: ' . PHP_EOL;
var_dump($result);
- query("DELETE " . $query, $config);
+ $query = "DELETE ";
+ query($query . $filter, $config);
} else {
echo 'no history_id without asset pairs';
}
@@ -240,34 +329,42 @@ function history_currency($config, $query, $pq) {
$history = query($query, $config);
$count = count($history);
- $currency = $history[$count-1]['timestamp'];
+ $currency = $history[$count - 1]['timestamp'];
$hist = array();
- if(!empty($history)) {
+ if (!empty($history)) {
foreach ($history as $array) {
array_push($hist, $array['timestamp']);
}
for ($i = 1; $i < $count; $i++) {
- if($hist[$i] - $hist[$i-1] !== $pq['period_ms']) {
+ if ($hist[$i] - $hist[$i - 1] !== $pq['period_ms']) {
# expect some asset pairs are not recorded on weekends
- if(!$pq['weekends']) {
+ if (!$pq['weekends']) {
$missing = 0;
- for ($j = $hist[$i-1] + $pq['period_ms']; $j < $hist[$i]; $j += $pq['period_ms']) {
+ for (
+ $j = $hist[$i - 1] + $pq['period_ms'];
+ $j < $hist[$i];
+ $j += $pq['period_ms']
+ ) {
$day = date('l', $j / 1000);
- if(!($day == 'Sunday' || $day == 'Monday')) $missing++;
+ if (!($day == 'Sunday' || $day == 'Monday')) $missing++;
}
- if(!$missing) continue 1;
+ if (!$missing) continue 1;
} else {
- $currency = $hist[$i-1];
+ $currency = $hist[$i - 1];
break 1;
}
}
}
}
echo '$currency: UTC ' . date('Y-m-d H:i:s', $currency / 1000) . PHP_EOL;
- $query = "UPDATE asset_pairs SET currency = " . $currency . " WHERE pair_id = " . $pq['pair_id'];
+ $query = "
+ UPDATE asset_pairs
+ SET currency = " . $currency . "
+ WHERE pair_id = " . $pq['pair_id']
+ ;
query($query, $config);
}
@@ -277,19 +374,24 @@ function history_currency($config, $query, $pq) {
function price_history($config, $pair_id = FALSE) {
# select asset_pairs due for refreshing
- $query = "SELECT * FROM asset_pairs
- WHERE collect
- AND (
- (history_end > " . milliseconds() . "
- AND currency < (" . milliseconds() . " - refresh * 60000))
- OR (history_end < " . milliseconds() . "
- AND currency < (history_end - period * 60000))
- )";
- if($pair_id) $query .= " AND pair_id = " . $pair_id;
+ $query = "
+ SELECT * FROM asset_pairs
+ WHERE collect
+ AND (
+ (
+ history_end > " . milliseconds() . "
+ AND currency < (" . milliseconds() . " - refresh * 60000)
+ ) OR (
+ history_end < " . milliseconds() . "
+ AND currency < (history_end - period * 60000)
+ )
+ )
+ ";
+ if ($pair_id) $query .= " AND pair_id = " . $pair_id;
$pairs = query($query, $config);
# check if any results
- if(empty($pairs)) echo 'current';
+ if (empty($pairs)) echo 'current';
else
# process each result
foreach ($pairs as $pair) {
@@ -311,52 +413,61 @@ function price_history($config, $pair_id = FALSE) {
$pq['stop'] = milliseconds();
# define time parameters
- if($pair['history_start'] > $pq['start']) $pq['start'] = $pair['history_start'];
- if($pair['history_end'] < $pq['stop']) $pq['stop'] = $pair['history_end'];
+ if ($pair['history_start'] > $pq['start']) $pq['start'] = $pair['history_start'];
+ if ($pair['history_end'] < $pq['stop']) $pq['stop'] = $pair['history_end'];
# exit if time period incorrect
- if($pq['start'] >= $pq['stop']) continue 1;
+ if ($pq['start'] >= $pq['stop']) continue 1;
# ignore weekends for certain asset classes
# and set start - 3 days
$pq['weekends'] = weekends($pair['class']);
- if(!$pq['weekends']) $pq['start'] = $pq['start'] - 1440 * 60000 * 3;
+ if (!$pq['weekends']) $pq['start'] = $pq['start'] - 1440 * 60000 * 3;
# some APIs limit available history for some coins, check if longer history needed
switch ($config['exchange']) {
case 'okex':
- if((milliseconds() - $pq['start']) / $pq['period_ms'] > $config['obs_hist_max']) {
+ if ((milliseconds() - $pq['start']) / $pq['period_ms'] > $config['obs_hist_max']) {
# check if longer history available
- if(in_array($pair['pair'], $config['hist_pairs'])) {
+ if (in_array($pair['pair'], $config['hist_pairs'])) {
$pq['hist_long'] = TRUE;
} else {
- $config['chatText'] = 'requested price history too long for pair_id ' . $pair['pair_id'] . ', you need to manually define earliest query in asset_pairs table';
+ $config['chatText'] =
+ 'requested price history too long for pair_id ' . $pair['pair_id'] .
+ ', you need to manually define earliest query in asset_pairs table'
+ ;
telegram($config);
echo $config['chatText'] . PHP_EOL;
continue 2; # continue to next iteration in nearest containing loop (value is +1 when inside 'switch' but not 'if' statement, as of php 7.3)
}
}
- break;
+ break;
}
# select recorded timestamps
$query_part = "
- AND pair = '" . $pair['pair'] . "'
- AND source = '" . $pair['source'] . "'
- AND period = '" . $config['period'][$pq['period']] . "'
- AND timestamp >= " . $pq['start'] . "
- AND timestamp <= " . $pq['stop'] . "
- ORDER BY timestamp";
- $query = "SELECT timestamp FROM price_history
- WHERE (timestamp = (SELECT MIN(timestamp) FROM price_history WHERE 1=1 " . $query_part . ")
- OR timestamp = (SELECT MAX(timestamp) FROM price_history WHERE 1=1 " . $query_part . "))";
+ AND pair = '" . $pair['pair'] . "'
+ AND source = '" . $pair['source'] . "'
+ AND period = '" . $config['period'][$pq['period']] . "'
+ AND timestamp >= " . $pq['start'] . "
+ AND timestamp <= " . $pq['stop'] . "
+ ORDER BY timestamp
+ ";
+ $query = "
+ SELECT timestamp
+ FROM price_history
+ WHERE (
+ timestamp = (SELECT MIN(timestamp) FROM price_history WHERE 1=1 " . $query_part . ")
+ OR timestamp = (SELECT MAX(timestamp) FROM price_history WHERE 1=1 " . $query_part . ")
+ )
+ ";
$history = query($query . $query_part, $config);
$count = count($history);
# define query result parameters
- if($count <= 1) {
+ if ($count <= 1) {
# handle exception of small result
$oldest = milliseconds();
$newest = milliseconds();
@@ -366,15 +477,21 @@ function price_history($config, $pair_id = FALSE) {
}
# print parameters
- if($config['debug']) {
- echo 'history_start: ' . date('Y-m-d H:i:s', $pair['history_start'] / 1000)
- . ' history_end: ' . date('Y-m-d H:i:s', $pair['history_end'] / 1000) . PHP_EOL;
- echo '$count: ' . $count . ' $currency: ' . date('Y-m-d H:i:s', $pq['start'] / 1000) . ' $pq[start]: ' . date('Y-m-d H:i:s', $pq['start'] / 1000)
- . ' $oldest: ' . date('Y-m-d H:i:s', $oldest / 1000) . PHP_EOL;
+ if ($config['debug']) {
+ echo
+ 'history_start: ' . date('Y-m-d H:i:s', $pair['history_start'] / 1000) .
+ ' history_end: ' . date('Y-m-d H:i:s', $pair['history_end'] / 1000) . PHP_EOL
+ ;
+ echo
+ '$count: ' . $count .
+ ' $currency: ' . date('Y-m-d H:i:s', $pq['start'] / 1000) .
+ ' $pq[start]: ' . date('Y-m-d H:i:s', $pq['start'] / 1000) .
+ ' $oldest: ' . date('Y-m-d H:i:s', $oldest / 1000) . PHP_EOL
+ ;
}
# check if the earliest required record is in the database, and if not then query price history
- if($oldest > $pq['start'] + $pq['period_ms']) {
+ if ($oldest > $pq['start'] + $pq['period_ms']) {
$pqa = $pq;
$pqa['stop'] = $oldest + $pq['period_ms'];
price_query($config, $pqa);
@@ -385,8 +502,11 @@ function price_history($config, $pair_id = FALSE) {
$history = query($query . $query_part, $config);
# if there is no existing records, there is a problem
- if(empty($history)) {
- $config['chatText'] = 'unknown problem with price history update for pair_id ' . $pair['pair_id'] . ', unable to query data';
+ if (empty($history)) {
+ $config['chatText'] =
+ 'unknown problem with price history update for pair_id ' . $pair['pair_id'] .
+ ', unable to query data'
+ ;
telegram($config);
echo $config['chatText'] . PHP_EOL;
continue 1;
@@ -397,12 +517,13 @@ function price_history($config, $pair_id = FALSE) {
# update asset history summary
$query_part = "
- AND pair = '" . $pair['pair'] . "'
- AND source = '" . $pair['source'] . "'
- AND period = '" . $config['period'][$pq['period']] . "'
- AND timestamp >= " . $pair['history_start'] . "
- AND timestamp <= " . $pair['history_end'] . "
- ORDER BY timestamp";
+ AND pair = '" . $pair['pair'] . "'
+ AND source = '" . $pair['source'] . "'
+ AND period = '" . $config['period'][$pq['period']] . "'
+ AND timestamp >= " . $pair['history_start'] . "
+ AND timestamp <= " . $pair['history_end'] . "
+ ORDER BY timestamp
+ ";
history_currency($config, $query . $query_part, $pq);
}
@@ -413,14 +534,16 @@ function price_history($config, $pair_id = FALSE) {
function price_recent($config, $pair_id = FALSE) {
- $query = "SELECT * FROM asset_pairs
- WHERE collect
- AND history_end > " . milliseconds() . "
- AND currency + refresh * 60000 < " . milliseconds();
- if($pair_id) $query .= " AND pair_id = " . $pair_id;
+ $query = "
+ SELECT * FROM asset_pairs
+ WHERE collect
+ AND history_end > " . milliseconds() . "
+ AND currency + refresh * 60000 < " . milliseconds()
+ ;
+ if ($pair_id) $query .= " AND pair_id = " . $pair_id;
$pairs = query($query, $config);
- if(empty($pairs)) echo 'current';
+ if (empty($pairs)) echo 'current';
else
foreach ($pairs as $pair) {
@@ -442,11 +565,11 @@ function price_recent($config, $pair_id = FALSE) {
# define time parameters
$i = floor((milliseconds() - $pq['start']) / $pq['period_ms']);
- if($i > $config['obs_curr_max']) $i = $config['obs_curr_max'];
+ if ($i > $config['obs_curr_max']) $i = $config['obs_curr_max'];
$pq['stop'] = $pq['start'] + $i * $pq['period_ms'];
# exit if time period incorrect
- if($pq['start'] >= $pq['stop']) continue 1;
+ if ($pq['start'] >= $pq['stop']) continue 1;
# query price history first
# if the history is complete it will not execute
@@ -455,12 +578,14 @@ function price_recent($config, $pair_id = FALSE) {
# ignore weekends for certain asset classes
$pq['weekends'] = weekends($pair['class']);
- $query = "SELECT timestamp FROM price_history
- WHERE pair = '" . $pq['pair'] . "'
- AND source = '" . $pq['source'] . "'
- AND period = '" . $config['period'][$pq['period']] . "'
- AND timestamp >= " . $pq['start'] . "
- ORDER BY timestamp";
+ $query = "
+ SELECT timestamp FROM price_history
+ WHERE pair = '" . $pq['pair'] . "'
+ AND source = '" . $pq['source'] . "'
+ AND period = '" . $config['period'][$pq['period']] . "'
+ AND timestamp >= " . $pq['start'] . "
+ ORDER BY timestamp
+ ";
history_currency($config, $query, $pq);
@@ -487,9 +612,9 @@ function price_missing($config, $history, $pq) {
for ($i = 1; $i < $count; $i++) {
# check if it indicates a broken sequence of timestamps
# otherwise resume loop
- if($hist[$i] - $hist[$i-1] !== $pq['period_ms']) {
+ if ($hist[$i] - $hist[$i - 1] !== $pq['period_ms']) {
# define the first missing record in the sequence
- $from = $hist[$i-1] + $pq['period_ms'];
+ $from = $hist[$i - 1] + $pq['period_ms'];
# define the last missing record in the sequence, could be the same as the first
$to = $hist[$i] - $pq['period_ms'];
# query the API for the missing record(s)
@@ -497,38 +622,44 @@ function price_missing($config, $history, $pq) {
$pq['stop'] = $to;
price_query($config, $pq);
# check if missing record is returned
- $query_sub = "SELECT * FROM price_history
- WHERE pair = '" . $pq['pair'] . "'
- AND source = '" . $pq['source'] . "'
- AND period = '" . $config['period'][$pq['period']] . "'
- /* query records from either side of the missing record(s) */
- AND timestamp >= " . ($from - $pq['period_ms']) . "
- AND timestamp <= " . ($to + $pq['period_ms']) .
- /* option to not impute values from today or yesterday */
- /* " AND timestamp < " . (milliseconds() - 1440 * 2) . */
- " ORDER BY timestamp";
+ $query_sub = "
+ SELECT * FROM price_history
+ WHERE pair = '" . $pq['pair'] . "'
+ AND source = '" . $pq['source'] . "'
+ AND period = '" . $config['period'][$pq['period']] . "'" .
+ /* query records from either side of the missing record(s) */
+ "AND timestamp >= " . ($from - $pq['period_ms']) . "
+ AND timestamp <= " . ($to + $pq['period_ms']) .
+ /* option to not impute values from today or yesterday */
+ /* " AND timestamp < " . (milliseconds() - 1440 * 2) . */
+ " ORDER BY timestamp
+ ";
$sub_hist = query($query_sub, $config);
# check if missing records have now been updated
- if(empty($sub_hist) || count($sub_hist) < 2) break 1;
+ if (empty($sub_hist) || count($sub_hist) < 2) break 1;
# otherwise impute missing records
# create array of timestamps
$timestamps = array();
- foreach($sub_hist as $sub) array_push($timestamps, $sub['timestamp']);
+ foreach ($sub_hist as $sub) array_push($timestamps, $sub['timestamp']);
# process each timestamp
for ($j = 1; $j < count($timestamps); $j++) {
- $from = $timestamps[$j-1];
+ $from = $timestamps[$j - 1];
# check timestamp array is valid
- if(!isset($timestamps[$j])) { echo 'ERROR $j: ' . $j . PHP_EOL; var_dump($timestamps); die; }
+ if (!isset($timestamps[$j])) {
+ echo 'ERROR $j: ' . $j . PHP_EOL;
+ var_dump($timestamps);
+ die;
+ }
$to = $timestamps[$j];
# count missing records
$iter = ($to - $from) / $pq['period_ms'];
# if there will be a long string of missing records, exit
# accounting for weekends
- if($pq['weekends']) {
- if($iter > $config['obs_imp_max']) continue 1;
+ if ($pq['weekends']) {
+ if ($iter > $config['obs_imp_max']) continue 1;
} else {
$wmiss = count_on_weekends($from, $to, $pq['period_ms']);
- if($iter - $wmiss > $config['obs_imp_max']) continue 1;
+ if ($iter - $wmiss > $config['obs_imp_max']) continue 1;
}
# iterate for each missing record
for ($k = 1; $k < $iter; $k++) {
@@ -537,14 +668,14 @@ function price_missing($config, $history, $pq) {
$values['pair'] = $pq['pair'];
$values['source'] = $pq['source'];
$values['timestamp'] = $from + $k * $pq['period_ms'];
- $values['period'] = $sub_hist[$j-1]['period'];
- $values['open'] = $sub_hist[$j-1]['open'];
- $values['close'] = $sub_hist[$j-1]['close'];
- $values['high'] = $sub_hist[$j-1]['high'];
- $values['low'] = $sub_hist[$j-1]['low'];
- $values['volume'] = $sub_hist[$j-1]['volume'];
+ $values['period'] = $sub_hist[$j - 1]['period'];
+ $values['open'] = $sub_hist[$j - 1]['open'];
+ $values['close'] = $sub_hist[$j - 1]['close'];
+ $values['high'] = $sub_hist[$j - 1]['high'];
+ $values['low'] = $sub_hist[$j - 1]['low'];
+ $values['volume'] = $sub_hist[$j - 1]['volume'];
$values['imputed'] = 1;
- if($config['debug']) var_dump($values);
+ if ($config['debug']) var_dump($values);
# update database
query('update_history', $config, $values);
}
@@ -561,7 +692,7 @@ function price_history_imputed($config) {
$query = "SELECT * FROM asset_pairs WHERE collect";
$pairs = query($query, $config);
- if(!empty($pairs))
+ if (!empty($pairs))
foreach ($pairs as $pair) {
print_r($pair);
@@ -580,45 +711,47 @@ function price_history_imputed($config) {
$pq['obs_iter'] = $config['obs_iter_max'];
# query imputed records
- $query_sub = "SELECT * FROM price_history
- WHERE pair = '" . $pq['pair'] . "'
- AND source = '" . $pq['source'] . "'
- AND period = '" . $config['period'][$pq['period']] . "'
- AND imputed = 1
- ORDER BY timestamp";
+ $query_sub = "
+ SELECT * FROM price_history
+ WHERE pair = '" . $pq['pair'] . "'
+ AND source = '" . $pq['source'] . "'
+ AND period = '" . $config['period'][$pq['period']] . "'
+ AND imputed = 1
+ ORDER BY timestamp
+ ";
$sub_hist = query($query_sub, $config);
# check if imputed records exist
- if(empty($sub_hist)) continue 1;
+ if (empty($sub_hist)) continue 1;
# check if the asset pair is only reported on weekends
/*
- if(!$pq['weekends']) {
+ if (!$pq['weekends']) {
$missing = count_on_weekends($from, $to, $period_ms);
- if(!$missing) continue 1;
+ if (!$missing) continue 1;
}
*/
# create array of timestamps
$timestamps = array();
- foreach($sub_hist as $sub) array_push($timestamps, $sub['timestamp']);
+ foreach ($sub_hist as $sub) array_push($timestamps, $sub['timestamp']);
$count = count($timestamps);
- if($count == 1) $count = 2;
+ if ($count == 1) $count = 2;
$pq['start'] = $timestamps[0];
for ($j = 1; $j < $count; $j++) {
# check if timestamp is not a sequence with the previous one
- if($timestamps[$j] - $timestamps[$j-1] !== $pq['period_ms']) {
+ if ($timestamps[$j] - $timestamps[$j - 1] !== $pq['period_ms']) {
# if it is a new sequence then query the previous sequence
- $pq['stop'] = $timestamps[$j-1];
+ $pq['stop'] = $timestamps[$j - 1];
# query the API for the missing record(s)
price_query($config, $pq);
# define the new sequence
$pq['start'] = $timestamps[$j];
}
# check if the final timestamp
- if($j == $count) {
+ if ($j == $count) {
# query the final sequence
$pq['stop'] = $timestamps[$j];
price_query($config, $pq);
@@ -628,36 +761,37 @@ function price_history_imputed($config) {
}
function info_uniswap($config) {
- # https://uniswap.org/docs/v2/API/queries/#pair-data
- # create as array, then json_encode
- $query = '
+ # https://uniswap.org/docs/v2/API/queries/#pair-data
+ # create as array, then json_encode
+ /*
+ $query = '
{
- pair(id: "0xa478c2975ab1ea89e8196811f51a7b7ade33eb11"){
- token0 {
- id
- symbol
- name
- derivedETH
- }
- token1 {
- id
- symbol
- name
- derivedETH
- }
- reserve0
- reserve1
- reserveUSD
- trackedReserveETH
- token0Price
- token1Price
- volumeUSD
- txCount
+pair(id: "0xa478c2975ab1ea89e8196811f51a7b7ade33eb11"){
+ token0 {
+ id
+ symbol
+ name
+ derivedETH
+ }
+ token1 {
+ id
+ symbol
+ name
+ derivedETH
+ }
+ reserve0
+ reserve1
+ reserveUSD
+ trackedReserveETH
+ token0Price
+ token1Price
+ volumeUSD
+ txCount
}
}';
- $config['url'] = $config['url_uniswap_graph'] . $query;
-
+ $config['url'] = $config['url_uniswap_graph'] . $query;
+*/
}
diff --git a/functions.tactics.php b/functions.tactics.php
index 1d62ab9..be09213 100644
--- a/functions.tactics.php
+++ b/functions.tactics.php
@@ -7,37 +7,37 @@ function actionable_tactics($config, $tactic_id = FALSE) {
/* query actionable tactics */
$values['filterquery'] = " WHERE status = 'actionable'";
- if($tactic_id) $values['filterquery'] .= " AND tactic_id IN (" . $tactic_id . ")";
+ if ($tactic_id) $values['filterquery'] .= " AND tactic_id IN (" . $tactic_id . ")";
$tactics = query('get_tactics', $config, $values);
- if($config['debug']) { print_r($tactics); }
+ if ($config['debug']) { print_r($tactics); }
- # process each action
- if (!empty($tactics)) foreach ($tactics as $t) {
+ # process each action
+ if (!empty($tactics))
+ foreach ($tactics as $t) {
- # check if time limit for executing action has been exceeded, for instance when order attempts have failed
- if($t['currency'] + $t['action_time_limit'] * 60000 < $config['timestamp']) {
+ # check if time limit for executing action has been exceeded, for instance when order attempts have failed
+ if ($t['currency'] + $t['action_time_limit'] * 60000 < $config['timestamp']) {
- $query = "UPDATE tactics SET
- status = 'failed',
- currency = " . $config['timestamp'] . ",
- WHERE tactic_id = " . $t['tactic_id']
- ;
- query($query, $config);
+ $query = "
+ UPDATE tactics SET
+ status = 'failed',
+ currency = " . $config['timestamp'] . ",
+ WHERE tactic_id = " . $t['tactic_id']
+ ;
+ query($query, $config);
- $config['chatText'] = 'actionable tactic unable to execute for tactic_id ' . $t['tactic_id'];
+ $config['chatText'] = 'actionable tactic unable to execute for tactic_id ' . $t['tactic_id'];
telegram($config);
- continue 1;
+ continue 1;
}
$config['exchange'] = $t['exchange'];
$config = config_exchange($config);
- # if action is to place an order
- if(in_array($t['action'],
- array('limit', 'market'),
- TRUE)) {
+ # if action is to place an order
+ if (in_array($t['action'], array('limit', 'market'), TRUE)) {
# construct order
$order_query = array(
@@ -46,84 +46,87 @@ function actionable_tactics($config, $tactic_id = FALSE) {
'orderType' => $t['action']
);
- if(strpos($t['pair_asset'], $t['from_asset'] . '/') !== FALSE) {
+ if (strpos($t['pair_asset'], $t['from_asset'] . '/') !== FALSE) {
$order_query['side'] = 'sell';
} else {
$order_query['side'] = 'buy';
}
- if(!empty($t['from_amount'])) {
+ if (!empty($t['from_amount'])) {
$order_query['orderQty'] = $t['from_amount'];
} elseif (!empty($t['from_percent'])) {
- # to do: if percent is defined instead of amount,
- # query available funds on exchange and calculate trade amount from percent
+ # to do:
+ # if percent is defined instead of amount,
+ # query available funds on exchange and calculate trade amount from percent
}
- if($order_query['orderType'] == 'limit') $order_query['orderPrice'] = $t['trade_price'];
+ if ($order_query['orderType'] == 'limit') $order_query['orderPrice'] = $t['trade_price'];
switch($t['exchange']) {
case 'bitmax':
- # define response requested from exchange
+ # define response requested from exchange
$order_query['respInst'] = 'ACCEPT';
- break;
+ break;
case 'okex':
- # 0: limit order (max price and quantity)
- # 1: market order (quantity only)
- # 2: fill or kill (ignore)
- # 3: immediate or cancel (ignore)
- if($t['action'] == 'limit') $order_query['orderTypeCode'] = 0;
- if($t['action'] == 'market') $order_query['orderTypeCode'] = 1;
- break;
+ # 0: limit order (max price and quantity)
+ # 1: market order (quantity only)
+ # 2: fill or kill (ignore)
+ # 3: immediate or cancel (ignore)
+ if ($t['action'] == 'limit') $order_query['orderTypeCode'] = 0;
+ if ($t['action'] == 'market') $order_query['orderTypeCode'] = 1;
+ break;
}
- # place order
+ # place order
$result = place_order($config, $order_query, $orderId = '');
#var_dump($result);
- # process response of order placed success
- if($result['res']['placed']) {
+ # process response of order placed success
+ if ($result['res']['placed']) {
# slight risk order is placed but response not received
# could check number of open orders matches number in tactics and/or transactions
- # ignore risk for now
-
- # record order in transactions table
- $query = "INSERT INTO transactions
- (exchange, exchange_transaction_id)
- VALUES
- ('" . $t['exchange'] . "', '" . $result['res']['exchange_transaction_id'] . "')
- ";
+ # ignore risk for now
+
+ # record order in transactions table
+ $query = "
+ INSERT INTO transactions
+ (exchange, exchange_transaction_id)
+ VALUES
+ ('" . $t['exchange'] . "', '" . $result['res']['exchange_transaction_id'] . "')
+ ";
query($query, $config);
- # record order in tactics table
- $query = "SELECT transaction_id FROM transactions
- WHERE exchange = '" . $t['exchange'] . "'
- AND exchange_transaction_id = '" . $result['res']['exchange_transaction_id'] . "'
- ";
+ # record order in tactics table
+ $query = "
+ SELECT transaction_id FROM transactions
+ WHERE exchange = '" . $t['exchange'] . "'
+ AND exchange_transaction_id = '" . $result['res']['exchange_transaction_id'] . "'
+ ";
$id = query($query, $config);
- $query = "UPDATE tactics SET
- status = 'ordered',
- currency = " . $config['timestamp'] . ",
- transaction_id = " . $id[0]['transaction_id'] . "
- WHERE tactic_id = " . $t['tactic_id']
- ;
+ $query = "
+ UPDATE tactics SET
+ status = 'ordered',
+ currency = " . $config['timestamp'] . ",
+ transaction_id = " . $id[0]['transaction_id'] . "
+ WHERE tactic_id = " . $t['tactic_id']
+ ;
query($query, $config);
- # note that can leave order history to update itself
+ # note that we can leave order history to update itself
} else {
- # process response of order placed failure
- # if an order fails send a message to telegram
- # next time actionable_tactics function is called, bot will try to place order again
+ # process response of order placed failure
+ # if an order fails send a message to telegram
+ # next time actionable_tactics function is called, bot will try to place order again
$config['chatText'] = 'order attempt failed for tactic_id ' . $t['tactic_id'];
telegram($config);
-
}
}
@@ -132,42 +135,43 @@ function actionable_tactics($config, $tactic_id = FALSE) {
/* if action is to delete order */
if ($t['action'] == 'delete') {
- /* get tactic's order */
- $values['filterquery'] = " WHERE transaction_id = '" . $t['transaction_id'] . "'";
- $transaction = query('get_transactions', $config, $values);
+ /* get tactic's order */
+ $values['filterquery'] = " WHERE transaction_id = '" . $t['transaction_id'] . "'";
+ $transaction = query('get_transactions', $config, $values);
- /* delete order */
- $order_query = array();
- #$order['id'] = $t['transaction_id']; # optional, for echo back
- $order_query['orderId'] = $transaction[0]['exchange_transaction_id'];
- $order_query['symbol'] = $transaction[0]['pair_asset'];
+ /* delete order */
+ $order_query = array();
+ #$order['id'] = $t['transaction_id']; # optional, for echo back
+ $order_query['orderId'] = $transaction[0]['exchange_transaction_id'];
+ $order_query['symbol'] = $transaction[0]['pair_asset'];
- $result = cancel_order($config, $order_query);
+ $result = cancel_order($config, $order_query);
- # process response of order deleted success
- if($result['res']['placed']) {
+ # process response of order deleted success
+ if ($result['res']['placed']) {
- $transaction = check_transaction($config, $t['transaction_id']);
+ $transaction = check_transaction($config, $t['transaction_id']);
- if($transaction !== FALSE && $transaction['exchange_transaction_status'] == 'cancelled') {
+ if ($transaction !== FALSE && $transaction['exchange_transaction_status'] == 'cancelled') {
- $query = "UPDATE tactics SET
- status = 'inactive',
- currency = " . $config['timestamp'] . ",
- action = 'none'
- WHERE tactic_id = " . $t['tactic_id']
- ;
- query($query, $config);
+ $query = "
+ UPDATE tactics SET
+ status = 'inactive',
+ currency = " . $config['timestamp'] . ",
+ action = 'none'
+ WHERE tactic_id = " . $t['tactic_id']
+ ;
+ query($query, $config);
- }
+ }
- } else {
+ } else {
- # process response of order deleted failure
- $config['chatText'] = 'delete order attempt failed for tactic_id ' . $t['tactic_id'];
- telegram($config);
+ # process response of order deleted failure
+ $config['chatText'] = 'delete order attempt failed for tactic_id ' . $t['tactic_id'];
+ telegram($config);
- }
+ }
}
@@ -180,74 +184,77 @@ function actionable_tactics($config, $tactic_id = FALSE) {
function conditional_tactics($config, $tactic_id = FALSE) {
$subquery = "";
- if($tactic_id) $subquery = " AND tactic_id IN (" . $tactic_id . ")";
-
- /* query current tactics */
- $values['filterquery'] = " WHERE status = 'conditional'
- AND currency < (" . $config['timestamp'] . " - refresh * 60000)
- " . $subquery . "
- ORDER BY condition_tactic DESC";
- $tactics = query('get_tactics', $config, $values);
- if($config['debug']) print_r($tactics);
-
- # process each tactic
- if (!empty($tactics)) foreach ($tactics as $t) {
+ if ($tactic_id) $subquery = " AND tactic_id IN (" . $tactic_id . ")";
+
+ /* query current tactics */
+ $values['filterquery'] = "
+ WHERE status = 'conditional'
+ AND currency < (" . $config['timestamp'] . " - refresh * 60000)
+ " . $subquery . "
+ ORDER BY condition_tactic DESC
+ ";
+ $tactics = query('get_tactics', $config, $values);
+ if ($config['debug']) print_r($tactics);
+
+ # process each tactic
+ if (!empty($tactics))
+ foreach ($tactics as $t) {
$update = FALSE;
- /*
- notes:
- there are 3 possible conditions, recorded in tactics table in database:
- time delay condition (condition_time)
- dependent tactic condition (condition_tactic)
- pair price indicator condition (condition_pair_*)
- condition_time requires that a fixed amount of time has passed
- condition_tactic requires that another tactic status has changed to 'executed'
- condition_pair_* requires that a pair price indicator value passes a threshold value
- all 3 conditions need to be met for tactic status to change from 'conditional' to 'actionable'
- when a condition is met, its test variable is set to 1
- if a condition is not yet met, its test variable is set to 0
- the test variables are:
- condition_time_test
- condition_tactic_test
- condition_pair_test
- if any conditions are not used for a tactic, the test variable is set to 1 by default
- */
-
- # test time delay condition (condition_time), if not yet satisfied (condition_time_test=0)
- if(!$t['condition_time_test']) {
- if($t['condition_time'] < $config['timestamp']) {
+ /*
+ notes:
+ there are 3 possible conditions, recorded in tactics table in database:
+ time delay condition (condition_time)
+ dependent tactic condition (condition_tactic)
+ pair price indicator condition (condition_pair_*)
+ condition_time requires that a fixed amount of time has passed
+ condition_tactic requires that another tactic status has changed to 'executed'
+ condition_pair_* requires that a pair price indicator value passes a threshold value
+ all 3 conditions need to be met for tactic status to change from 'conditional' to 'actionable'
+ when a condition is met, its test variable is set to 1
+ if a condition is not yet met, its test variable is set to 0
+ the test variables are:
+ condition_time_test
+ condition_tactic_test
+ condition_pair_test
+ if any conditions are not used for a tactic, the test variable is set to 1 by default
+ */
+
+ # test time delay condition (condition_time), if not yet satisfied (condition_time_test=0)
+ if (!$t['condition_time_test']) {
+ if ($t['condition_time'] < $config['timestamp']) {
$t['condition_time_test'] = 1;
$update = TRUE;
- if($config['debug']) echo 'condition_time_test positive' . PHP_EOL;
+ if ($config['debug']) echo 'condition_time_test positive' . PHP_EOL;
}
}
- # test dependent tactic condition (condition_tactic), if not yet satisfied (condition_tactic_test=0)
- # and time delay condition already satisfied
- if(!$t['condition_tactic_test'] && $t['condition_time_test']) {
+ # test dependent tactic condition (condition_tactic), if not yet satisfied (condition_tactic_test=0)
+ # and time delay condition already satisfied
+ if (!$t['condition_tactic_test'] && $t['condition_time_test']) {
$values['filterquery'] = " WHERE tactic_id = " . $t['condition_tactic'];
- $res = query('get_tactics', $config, $values);
- if($res[0]['status'] == 'executed') {
+ $res = query('get_tactics', $config, $values);
+ if ($res[0]['status'] == 'executed') {
$t['condition_tactic_test'] = 1;
$update = TRUE;
- if($config['debug']) echo 'condition_tactic_test positive' . PHP_EOL;
- } elseif($res[0]['status'] == 'inactive' || $res[0]['status'] == 'failed') {
- # if dependent tactic is inactive or failed, change status
- /* change tactic status */
- $values['tactic_id'] = $res[0]['tactic_id'];
- $values['field'] = 'status';
- $values['value'] = 'inactive';
- query('update_tactic', $config, $values);
- continue 1;
- }
+ if ($config['debug']) echo 'condition_tactic_test positive' . PHP_EOL;
+ } elseif ($res[0]['status'] == 'inactive' || $res[0]['status'] == 'failed') {
+ # if dependent tactic is inactive or failed, change status
+ /* change tactic status */
+ $values['tactic_id'] = $res[0]['tactic_id'];
+ $values['field'] = 'status';
+ $values['value'] = 'inactive';
+ query('update_tactic', $config, $values);
+ continue 1;
+ }
}
- # test pair price indicator condition (condition_pair_*), if not yet satisfied (condition_pair_test=0)
- # and time delay and dependent tactic conditions already satisfied
- if(!$t['condition_pair_test'] && $t['condition_time_test'] && $t['condition_tactic_test']) {
+ # test pair price indicator condition (condition_pair_*), if not yet satisfied (condition_pair_test=0)
+ # and time delay and dependent tactic conditions already satisfied
+ if (!$t['condition_pair_test'] && $t['condition_time_test'] && $t['condition_tactic_test']) {
- # query the most recent price and calculate indicators first
+ # query the most recent price and calculate indicators first
price_recent($config, $t['condition_pair_id']);
technical_analysis($config, $t['condition_pair_id']);
@@ -256,49 +263,61 @@ function conditional_tactics($config, $tactic_id = FALSE) {
$res = query($query, $config);
$a = $res[0];
$currency_min = $config['timestamp'] - $t['condition_pair_currency_min'] * 60000;
- if($config['debug']) echo 'condition_pair_test if ' . $a['currency'] . ' >= ' . $currency_min . PHP_EOL;
+ if ($config['debug']) echo 'condition_pair_test if ' . $a['currency'] . ' >= ' . $currency_min . PHP_EOL;
# check if the asset_pair is current enough, also depends on asset_pair refresh rate
- if($a['currency'] >= $currency_min) {
- $query = "SELECT history_id FROM price_history
- WHERE pair = '" . $a['pair'] . "'
- AND source = '" . $a['source'] . "'
- AND period = '" . $config['period'][$a['period']] . "'
- AND timestamp = " . $a['currency'] . "
- AND " . $t['condition_pair_indicator'] . $t['condition_pair_value_operand'] . $t['condition_pair_value'];
+ if ($a['currency'] >= $currency_min) {
+ $query = "
+ SELECT history_id FROM price_history
+ WHERE pair = '" . $a['pair'] . "'
+ AND source = '" . $a['source'] . "'
+ AND period = '" . $config['period'][$a['period']] . "'
+ AND timestamp = " . $a['currency'] . "
+ AND " . $t['condition_pair_indicator'] . $t['condition_pair_value_operand'] . $t['condition_pair_value']
+ ;
$res = query($query, $config);
- if($config['debug']) echo 'condition_pair_test: ' . $query . PHP_EOL;
- # if any result was returned from the sql query this proves the condition has been met
- if(!empty($res)) {
+ if ($config['debug']) echo 'condition_pair_test: ' . $query . PHP_EOL;
+ # if any result was returned from the sql query this proves the condition has been met
+ if (!empty($res)) {
$t['condition_pair_test'] = 1;
$update = TRUE;
- if($config['debug']) echo 'condition_pair_test positive' . PHP_EOL;
+ if ($config['debug']) echo 'condition_pair_test positive' . PHP_EOL;
}
}
}
- # test if all 3 condition tests have been met, and if the status has changed ($update=TRUE)
- if($t['condition_pair_test'] && $t['condition_time_test'] && $t['condition_tactic_test'] && $update) {
- if($config['debug']) echo 'status change' . PHP_EOL;
- if($t['action'] == 'none') {
+ # test if all 3 condition tests have been met, and if the status has changed ($update=TRUE)
+ if (
+ $t['condition_pair_test'] &&
+ $t['condition_time_test'] &&
+ $t['condition_tactic_test'] &&
+ $update
+ ) {
+ if ($config['debug']) echo 'status change' . PHP_EOL;
+ if ($t['action'] == 'none') {
$t['status'] = 'executed';
} else {
$t['status'] = 'actionable';
- $config['chatText'] = 'trade ready, attempting to ' . $t['action'] . ' order for ' . $t['from_asset'] . ' ' . $t['to_asset'] . ' on ' . $t['exchange'];
+ $config['chatText'] =
+ 'trade ready, attempting to ' . $t['action'] .
+ ' order for ' . $t['from_asset'] . ' ' . $t['to_asset'] .
+ ' on ' . $t['exchange'];
telegram($config);
}
}
- # update the tactics status if necessary
- if($update) {
- $query = "UPDATE tactics SET
- status = '" . $t['status'] . "'
- ,condition_tactic_test = " . $t['condition_tactic_test'] . "
- ,condition_time_test = " . $t['condition_time_test'] . "
- ,condition_pair_test = " . $t['condition_pair_test'] . "
- ,currency = " . $config['timestamp'] . "
- WHERE tactic_id = " . $t['tactic_id'];
- query($query, $config);
- if($config['debug']) echo 'update record' . PHP_EOL;
+ # update the tactics status if necessary
+ if ($update) {
+ $query = "
+ UPDATE tactics SET
+ status = '" . $t['status'] . "'
+ ,condition_tactic_test = " . $t['condition_tactic_test'] . "
+ ,condition_time_test = " . $t['condition_time_test'] . "
+ ,condition_pair_test = " . $t['condition_pair_test'] . "
+ ,currency = " . $config['timestamp'] . "
+ WHERE tactic_id = " . $t['tactic_id']
+ ;
+ query($query, $config);
+ if ($config['debug']) echo 'update record' . PHP_EOL;
}
}
}
@@ -308,70 +327,76 @@ function conditional_tactics($config, $tactic_id = FALSE) {
function ordered_tactics($config, $tactic_id = FALSE) {
/* query tactics */
- $subquery = "";
- if($tactic_id) $subquery = " AND tactic_id IN (" . $_GET['tactic_id'] . ")";
-
- $values['filterquery'] = " WHERE status = 'ordered'
- AND currency < (" . $config['timestamp'] . " - refresh * 60000)"
- . $subquery;
- if($tactic_id) $values['filterquery'] .= " AND tactic_id IN (" . $tactic_id . ")";
+ $subquery = "";
+ if ($tactic_id) $subquery = " AND tactic_id IN (" . $_GET['tactic_id'] . ")";
+
+ $values['filterquery'] = "
+ WHERE status = 'ordered'
+ AND currency < (" . $config['timestamp'] . " - refresh * 60000)" .
+ $subquery
+ ;
+ if ($tactic_id) $values['filterquery'] .= " AND tactic_id IN (" . $tactic_id . ")";
$tactics = query('get_tactics', $config, $values);
- if($config['debug']) { print_r($tactics); }
+ if ($config['debug']) { print_r($tactics); }
- if (!empty($tactics)) foreach ($tactics as $t) {
+ if (!empty($tactics))
+ foreach ($tactics as $t) {
/* get tactic's order */
- if(!empty($t['transaction_id'])) {
-
- $order = check_transaction($config, $t['transaction_id']);
+ if (!empty($t['transaction_id'])) {
+
+ $order = check_transaction($config, $t['transaction_id']);
} else {
- # process response of transaction_id not recorded
- $config['chatText'] = 'query tactic transaction_id attempt failed for tactic_id ' . $t['tactic_id'];
- telegram($config);
+ # process response of transaction_id not recorded
+ $config['chatText'] = 'query tactic transaction_id attempt failed for tactic_id ' . $t['tactic_id'];
+ telegram($config);
- continue 1;
+ continue 1;
- }
+ }
- if($config['debug']) { echo $config['url'] . PHP_EOL; print_r($order); }
+ if ($config['debug']) { echo $config['url'] . PHP_EOL; print_r($order); }
- $update = FALSE;
+ $update = FALSE;
/* check if order completed */
if ($order['exchange_transaction_status'] == 'complete') {
- $values['value'] = 'executed';
- $update = TRUE;
+ $values['value'] = 'executed';
+ $update = TRUE;
}
/* check if order cancelled */
- if ($order['exchange_transaction_status'] == 'cancelled') {
+ if ($order['exchange_transaction_status'] == 'cancelled') {
- $values['value'] = 'inactive';
- $update = TRUE;
+ $values['value'] = 'inactive';
+ $update = TRUE;
}
- /* process update */
- if($update) {
-
- /* change tactic status */
- $values['tactic_id'] = $t['tactic_id'];
- $values['field'] = 'status';
- query('update_tactic', $config, $values);
+ /* process update */
+ if ($update) {
+
+ /* change tactic status */
+ $values['tactic_id'] = $t['tactic_id'];
+ $values['field'] = 'status';
+ query('update_tactic', $config, $values);
+
+ /* query any conditional tactics */
+ $values['filterquery'] = "
+ WHERE status = 'conditional'
+ AND condition_tactic = '" . $t['tactic_id'] . "'"
+ ;
+ $triggers = query('get_tactics', $config, $values);
+ if ($config['debug']) print_r($triggers);
+ if (!empty($triggers))
+ foreach ($triggers as $trigger)
+ conditional_tactics($config, $trigger['tactic_id']);
- /* query any conditional tactics */
- $values['filterquery'] = " WHERE status = 'conditional'
- AND condition_tactic = '" . $t['tactic_id'] . "'";
- $triggers = query('get_tactics', $config, $values);
- if($config['debug']) { print_r($triggers); }
- if (!empty($triggers)) foreach ($triggers as $trigger)
- conditional_tactics($config, $trigger['tactic_id']);
-
- }
+ }
}
diff --git a/functions.util.php b/functions.util.php
index 9c5dd91..a84fc02 100644
--- a/functions.util.php
+++ b/functions.util.php
@@ -1,107 +1,115 @@
url = $url;
- }
-
- /**
- * @param $httpheader array of headers
- * @return response
- */
- public function call($httpheader, $method, $query = NULL)
- {
- try
- {
- $curl = curl_init();
- if (FALSE === $curl)
- throw new Exception('Failed to initialize');
-
- $curl_opt = array(
- CURLOPT_URL => $this->url,
- CURLOPT_RETURNTRANSFER => true,
- CURLOPT_ENCODING => "",
- CURLOPT_MAXREDIRS => 10,
- CURLOPT_TIMEOUT => 60, /* number of seconds to wait for response */
- CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
- CURLOPT_CUSTOMREQUEST => $method,
- CURLOPT_POSTFIELDS => $query,
- CURLOPT_HTTPHEADER => $httpheader
- );
- curl_setopt_array($curl, $curl_opt);
-
- $response = curl_exec($curl);
- if (FALSE === $response)
- throw new Exception(curl_error($curl), curl_errno($curl));
-
- $http_status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
-
- if (200 != $http_status)
- throw new Exception($response, $http_status);
- curl_close($curl);
- }
- catch(Exception $e)
- {
- $response= $e->getCode() . $e->getMessage();
-
- echo $response;
- }
- return $response;
- }
+class APIREST {
+
+ private $url;
+
+ public function __construct($url) {
+ $this->url = $url;
+ }
+
+ /**
+ * @param $httpheader array of headers
+ * @return response
+ */
+ public function call($httpheader, $method, $query = NULL) {
+
+ try {
+
+ $curl = curl_init();
+ if (FALSE === $curl)
+ throw new Exception('Failed to initialize');
+
+ $curl_opt = array(
+ CURLOPT_URL => $this->url,
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_ENCODING => "",
+ CURLOPT_MAXREDIRS => 10,
+ CURLOPT_TIMEOUT => 60, /* number of seconds to wait for response */
+ CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
+ CURLOPT_CUSTOMREQUEST => $method,
+ CURLOPT_POSTFIELDS => $query,
+ CURLOPT_HTTPHEADER => $httpheader
+ );
+ curl_setopt_array($curl, $curl_opt);
+
+ $response = curl_exec($curl);
+ if (FALSE === $response)
+ throw new Exception(curl_error($curl), curl_errno($curl));
+
+ $http_status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
+
+ if (200 != $http_status)
+ throw new Exception($response, $http_status);
+ curl_close($curl);
+
+ } catch(Exception $e) {
+ $response= $e->getCode() . $e->getMessage();
+ echo $response;
+ }
+
+ return $response;
+ }
}
/* get timestamp */
function milliseconds() {
- list($msec, $sec) = explode(' ', microtime());
- return (int) ($sec . substr($msec, 2, 3));
+
+ list($msec, $sec) = explode(' ', microtime());
+ return (int) ($sec . substr($msec, 2, 3));
+
}
/* encrypt key */
function hmac($msg, $secret) {
- $hmac = hash_hmac('sha256', $msg, $secret, true);
- $hmac = base64_encode($hmac);
- return $hmac;
+
+ $hmac = hash_hmac('sha256', $msg, $secret, true);
+ $hmac = base64_encode($hmac);
+ return $hmac;
+
}
/* array depth */
function countdim($array) {
- if (is_array(reset($array))) {
- $return = countdim(reset($array)) + 1;
- } else {
- $return = 1;
- }
- return $return;
+
+ if (is_array(reset($array))) {
+ $return = countdim(reset($array)) + 1;
+ } else {
+ $return = 1;
+ }
+ return $return;
+
}
-/* asset pair only reported on weekdays
- expect some asset pairs are not recorded on weekends, for instance fiat currencies like $AUD to $USD
+/*
+asset pair only reported on weekdays
+expect some asset pairs are not recorded on weekends, for instance fiat currencies like $AUD to $USD
*/
function weekends($class) {
- if($class == 'fiat' || $class == 'stock') {
- $weekend = FALSE;
- } else {
- $weekend = TRUE;
- }
- return $weekend;
+
+ if ($class == 'fiat' || $class == 'stock') {
+ $weekend = FALSE;
+ } else {
+ $weekend = TRUE;
+ }
+ return $weekend;
+
}
/* count number of observations falling on weekends */
function count_on_weekends($from, $to, $period_ms) {
- $wmiss = 0;
- for ($j = $from; $j <= $to; $j += $period_ms) {
- $day = date('l', $j / 1000);
- if(!($day == 'Sunday' || $day == 'Monday')) $wmiss++;
- #echo 'check UTC ' . date('Y-m-d H:i:s', $j / 1000) . ' ' . $day . PHP_EOL;
- }
- return $wmiss;
+
+ $wmiss = 0;
+ for ($j = $from; $j <= $to; $j += $period_ms) {
+ $day = date('l', $j / 1000);
+ if (!($day == 'Sunday' || $day == 'Monday')) $wmiss++;
+ }
+ return $wmiss;
+
}
diff --git a/index.php b/index.php
index 3957520..922668f 100644
--- a/index.php
+++ b/index.php
@@ -2,45 +2,45 @@
include('includes.php');
-if(isset($_GET['exchange'])) { $config['exchange'] = $_GET['exchange']; } else { $config['exchange'] = ''; }
-if(isset($_GET['query'])) { $query = $_GET['query']; } else { $query = ''; }
-if(isset($_GET['action'])) { $action = $_GET['action']; } else { $action = ''; }
-if(isset($_GET['id'])) { $id = $_GET['id']; } else { $id = ''; }
-if(isset($_GET['var1'])) { $var1 = $_GET['var1']; } else { $var1 = ''; }
-if(isset($_GET['var2'])) { $var2 = $_GET['var2']; } else { $var2 = ''; }
-if(isset($_GET['var3'])) { $var3 = $_GET['var3']; } else { $var3 = ''; }
-if(isset($_GET['var4'])) { $var4 = $_GET['var4']; } else { $var4 = ''; }
-if(isset($_GET['var5'])) { $var5 = $_GET['var5']; } else { $var5 = ''; }
-if(isset($_GET['var6'])) { $var6 = $_GET['var6']; } else { $var6 = ''; }
-if(isset($_GET['var7'])) { $var7 = $_GET['var7']; } else { $var7 = ''; }
+if (isset($_GET['exchange'])) { $config['exchange'] = $_GET['exchange']; } else { $config['exchange'] = ''; }
+if (isset($_GET['query'])) { $query = $_GET['query']; } else { $query = ''; }
+if (isset($_GET['action'])) { $action = $_GET['action']; } else { $action = ''; }
+if (isset($_GET['id'])) { $id = $_GET['id']; } else { $id = ''; }
+if (isset($_GET['var1'])) { $var1 = $_GET['var1']; } else { $var1 = ''; }
+if (isset($_GET['var2'])) { $var2 = $_GET['var2']; } else { $var2 = ''; }
+if (isset($_GET['var3'])) { $var3 = $_GET['var3']; } else { $var3 = ''; }
+if (isset($_GET['var4'])) { $var4 = $_GET['var4']; } else { $var4 = ''; }
+if (isset($_GET['var5'])) { $var5 = $_GET['var5']; } else { $var5 = ''; }
+if (isset($_GET['var6'])) { $var6 = $_GET['var6']; } else { $var6 = ''; }
+if (isset($_GET['var7'])) { $var7 = $_GET['var7']; } else { $var7 = ''; }
$config = config_exchange($config);
echo '
'; # test uniswap -# y.jules.net.au/index.php?action=action_tactics&id=1 -if($action == 'uniswap') { +# index.php?action=uniswap&id=1 +if ($action == 'uniswap') { - $result = info_uniswap($config); - var_dump($result); + $result = info_uniswap($config); + var_dump($result); } # process actionable tactics -# y.jules.net.au/index.php?action=check_transaction&transaction_id=171 -if($action == 'check_transaction') { +# index.php?action=check_transaction&transaction_id=171 +if ($action == 'check_transaction') { check_transaction($config, $_GET['transaction_id']); } # process actionable tactics -# y.jules.net.au/index.php?action=actionable_tactics&tactic_id=108,107 -if($action == 'actionable_tactics') { +# index.php?action=actionable_tactics&tactic_id=108,107 +if ($action == 'actionable_tactics') { $tactic_id = FALSE; - if(isset($_GET['tactic_id'])) $tactic_id = $_GET['tactic_id']; + if (isset($_GET['tactic_id'])) $tactic_id = $_GET['tactic_id']; actionable_tactics($config, $tactic_id); @@ -48,63 +48,61 @@ # refresh tactic -# y.jules.net.au/index.php?action=conditional_tactics&tactic_id=108,107 -if($action == 'conditional_tactics') { +# index.php?action=conditional_tactics&tactic_id=108,107 +if ($action == 'conditional_tactics') { - $tactic_id = FALSE; - if(isset($_GET['tactic_id'])) $tactic_id = $_GET['tactic_id']; + $tactic_id = FALSE; + if (isset($_GET['tactic_id'])) $tactic_id = $_GET['tactic_id']; conditional_tactics($config, $tactic_id); } # refresh tactic -# y.jules.net.au/index.php?action=ordered_tactics&tactic_id=108,107 -if($action == 'ordered_tactics') { +# index.php?action=ordered_tactics&tactic_id=108,107 +if ($action == 'ordered_tactics') { - $tactic_id = FALSE; - if(isset($_GET['tactic_id'])) $tactic_id = $_GET['tactic_id']; + $tactic_id = FALSE; + if (isset($_GET['tactic_id'])) $tactic_id = $_GET['tactic_id']; ordered_tactics($config, $tactic_id); } # current price -# y.jules.net.au/index.php?exchange=bitmax&query=price_current&var1=STAKE/USDT -if($query == 'price_current') { - $config['api_request'] = 'balance'; - $coins = '?symbol=' . $var1; - $config['url'] .= $config['price'] . $coins; - $result = info($config); - if($config['debug']) { echo $config['url'] . PHP_EOL; print_r($result); } +# index.php?exchange=bitmax&query=price_current&var1=STAKE/USDT +if ($query == 'price_current') { + + $config['api_request'] = 'balance'; + $coins = '?symbol=' . $var1; + $config['url'] .= $config['price'] . $coins; + $result = info($config); + if ($config['debug']) { echo $config['url'] . PHP_EOL; print_r($result); } + } # historical price -# y.jules.net.au/index.php?exchange=bitmax&query=price_history&var1=STAKE/USDT&var2=10080&var3=5&var4=1600473700000&var5=1605677000000 -# y.jules.net.au/index.php?exchange=okex&query=price_history&archive=TRUE&var1=BTC-USDT&var2=1440&var3=200&var4=1592573700000&var5=1593677000000 -# y.jules.net.au/index.php?exchange=twelve&query=price_history&var1=ETH/BTC&var2=1440&var3=5000&var4=1592573700000&var5=1593677000000 - -# y.jules.net.au/index.php?exchange=okex&query=price_history&archive=TRUE&pair=BTC-USDT&period=1440&obs_iter=200&start=1592573700000&stop=1593677000000 -if($query == 'price_history') { - - if(isset($_GET['pair'])) { $pair = $_GET['pair']; } else { $pair = ''; } - if(isset($_GET['period'])) { $period = $_GET['period']; } else { $period = ''; } - if(isset($_GET['archive'])) { $archive = $_GET['archive']; } else { $archive = FALSE; } - if(isset($_GET['obs_iter'])) { $obs_iter = $_GET['obs_iter']; } else { - if($archive) { - $obs_iter = $config['obs_iter_hist']; +# index.php?exchange=okex&query=price_history&archive=TRUE&pair=BTC-USDT&period=1440&obs_iter=200&start=1592573700000&stop=1593677000000 +if ($query == 'price_history') { + + if (isset($_GET['pair'])) { $pair = $_GET['pair']; } else { $pair = ''; } + if (isset($_GET['period'])) { $period = $_GET['period']; } else { $period = ''; } + if (isset($_GET['archive'])) { $archive = $_GET['archive']; } else { $archive = FALSE; } + if (isset($_GET['obs_iter'])) { $obs_iter = $_GET['obs_iter']; } else { + if ($archive) { + $obs_iter = $config['obs_iter_hist']; } else $obs_iter = $config['obs_iter_curr']; } # calculate time periods $period_ms = $period * 60000; $current_period = floor(milliseconds()/$period_ms) * $period_ms; - if(isset($_GET['start'])) { $start = $_GET['start']; } else { $start = $current_period - $period_ms * $obs_iter; } - if(isset($_GET['stop'])) { $stop = $_GET['stop']; } else { $stop = $current_period; } + if (isset($_GET['start'])) { $start = $_GET['start']; } else { $start = $current_period - $period_ms * $obs_iter; } + if (isset($_GET['stop'])) { $stop = $_GET['stop']; } else { $stop = $current_period; } echo '$start: ' . $start . ' $stop: ' . $stop . '
'; echo '$start: ' . date('Y-m-d H:i:s', $start / 1000) . ' $stop: ' . date('Y-m-d H:i:s', $stop / 1000) . '
'; - # array format defined in config.php + # array format defined in config.php $ph = $config['price_query']; $ph['pair'] = $pair; $ph['period'] = $period; @@ -119,104 +117,121 @@ } # deduplicate history -# y.jules.net.au/index.php?query=price_history_dedupe -if($query == 'price_history_dedupe') { +# index.php?query=price_history_dedupe +if ($query == 'price_history_dedupe') { + + echo ''; + price_history_dedupe(); - echo ''; - price_history_dedupe(); } # order book -if($query == 'order_book') { - $config['api_request'] = 'depth'; - $coins = '?symbol=' . $var1; - $config['url'] .= $config['order_book'] . $coins; - $result = info($config); - if($config['debug']) { echo $config['url'] . PHP_EOL; print_r($result); } +if ($query == 'order_book') { + + $config['api_request'] = 'depth'; + $coins = '?symbol=' . $var1; + $config['url'] .= $config['order_book'] . $coins; + $result = info($config); + if ($config['debug']) { echo $config['url'] . PHP_EOL; print_r($result); } + } # recent trades -if($query == 'recent_trades') { - $config['api_request'] = 'trades'; - $coins = '?symbol=' . $var1; - $number = '&n=100'; - $config['url'] .= $config['recent_trades'] . $coins . $number; - $result = info($config); - if($config['debug']) { echo $config['url'] . PHP_EOL; print_r($result); } +if ($query == 'recent_trades') { + + $config['api_request'] = 'trades'; + $coins = '?symbol=' . $var1; + $number = '&n=100'; + $config['url'] .= $config['recent_trades'] . $coins . $number; + $result = info($config); + if ($config['debug']) { echo $config['url'] . PHP_EOL; print_r($result); } + } # account balance -if($query == 'balance') { - $config['api_request'] = 'balance'; - $config['url'] .= $config['group'] . $config['balance']; - $result = info($config); - if($config['debug']) { echo $config['url'] . PHP_EOL; print_r($result); } +if ($query == 'balance') { + + $config['api_request'] = 'balance'; + $config['url'] .= $config['group'] . $config['balance']; + $result = info($config); + if ($config['debug']) { echo $config['url'] . PHP_EOL; print_r($result); } + } # account info -if($query == 'account_info') { +if ($query == 'account_info') { - switch ($config['exchange']) { + switch ($config['exchange']) { - case 'bitmax': $config['api_request'] = 'user/info'; - break; + case 'bitmax': + $config['api_request'] = 'user/info'; + break; - case 'okex': $config['api_request'] = $config['account_info']; - break; + case 'okex': + $config['api_request'] = $config['account_info']; + break; - } + } + + $config['url'] .= $config['account_info']; + $result = info($config); + if ($config['debug']) { echo 'url: ' . $config['url'] . PHP_EOL . 'result: '; print_r($result); } - $config['url'] .= $config['account_info']; - $result = info($config); - if($config['debug']) { echo 'url: ' . $config['url'] . PHP_EOL . 'result: '; print_r($result); } } # update open orders -if($query == 'open_orders') { - # http://y.jules.net.au/index.php?exchange=bitmax&query=open_orders - $config['api_request'] = 'order/open'; - $config['url'] .= $config['group'] . $config['open_orders']; - $result = info($config); +if ($query == 'open_orders') { + + # index.php?exchange=bitmax&query=open_orders + $config['api_request'] = 'order/open'; + $config['url'] .= $config['group'] . $config['open_orders']; + $result = info($config); - if($config['debug']) { echo $config['url'] . PHP_EOL; print_r($result); } + if ($config['debug']) { echo $config['url'] . PHP_EOL; print_r($result); } + + update_transactions($config, $result); - update_transactions($config, $result); } # update history orders -if($query == 'history_orders' && $action == 'save') { - # http://y.jules.net.au/index.php?exchange=bitmax&query=history_orders&action=save - # http://y.jules.net.au/index.php?exchange=okex&query=history_orders&action=save&pair=CVP/USDT +if ($query == 'history_orders' && $action == 'save') { + + # index.php?exchange=bitmax&query=history_orders&action=save + # index.php?exchange=okex&query=history_orders&action=save&pair=CVP/USDT - if(isset($_GET['pair'])) $config['pair'] = $_GET['pair']; - if(isset($_GET['exchange'])) $config['exchange'] = $_GET['exchange']; - update_transactions($config); + if (isset($_GET['pair'])) $config['pair'] = $_GET['pair']; + if (isset($_GET['exchange'])) $config['exchange'] = $_GET['exchange']; + update_transactions($config); } # calculate orders -if($query == 'calculate_orders') { - # http://y.jules.net.au/index.php?query=calculate_orders +if ($query == 'calculate_orders') { + + # index.php?query=calculate_orders calculate_orders($config); } # list history orders -if($query == 'history_orders' && $action == 'print') { - # http://y.jules.net.au/index.php?exchange=bitmax&query=history_orders&action=print - $config['api_request'] = 'order/hist/current'; - $config['url'] .= $config['group'] . $config['order_history']; - $config['url'] .= '?executedOnly=1&n=1000'; - $result = info($config); - if($config['debug']) { echo $config['url'] . PHP_EOL; print_r($result); } +if ($query == 'history_orders' && $action == 'print') { + + # index.php?exchange=bitmax&query=history_orders&action=print + $config['api_request'] = 'order/hist/current'; + $config['url'] .= $config['group'] . $config['order_history']; + $config['url'] .= '?executedOnly=1&n=1000'; + $result = info($config); + if ($config['debug']) { echo $config['url'] . PHP_EOL; print_r($result); } + } # place order -if($query == 'place_order') { +if ($query == 'place_order') { + /* - y.jules.net.au/index.php?exchange=bitmax&query=place_order&symbol=STAKE/USDT&orderPrice=40.00&orderQty=1&orderType=limit&side=sell&respInst=ACCEPT - y.jules.net.au/index.php? + index.php?exchange=bitmax&query=place_order&symbol=STAKE/USDT&orderPrice=40.00&orderQty=1&orderType=limit&side=sell&respInst=ACCEPT + index.php? exchange=bitmax &query=place_order &orderId=12345678Z @@ -227,8 +242,8 @@ &side=sell &respInst=ACCEPT - y.jules.net.au/index.php?exchange=okex&query=place_order&symbol=ETH/USDT&orderPrice=40.00&orderQty=1&orderType=limit&orderTypeCode=0&side=sell - y.jules.net.au/index.php? + index.php?exchange=okex&query=place_order&symbol=ETH/USDT&orderPrice=40.00&orderQty=1&orderType=limit&orderTypeCode=0&side=sell + index.php? exchange=bitmax &query=place_order &orderId=12345678Z @@ -247,36 +262,39 @@ } # cancel order -if($query == 'cancel_order') { - # y.jules.net.au/index.php?exchange=bitmax&query=cancel_order&var1=12345678Z&var2=12345678Z&var3=STAKE/USDT +if ($query == 'cancel_order') { + + # index.php?exchange=bitmax&query=cancel_order&var1=12345678Z&var2=12345678Z&var3=STAKE/USDT - $order = array(); - $order['id'] = $var1; # optional, for echo back - $order['orderId'] = $var2; - $order['symbol'] = $var3; - $order['time'] = (int)$config['timestamp']; + $order = array(); + $order['id'] = $var1; # optional, for echo back + $order['orderId'] = $var2; + $order['symbol'] = $var3; + $order['time'] = (int)$config['timestamp']; - $result = cancel_order($config, $order); + $result = cancel_order($config, $order); } # delete all orders (by symbol) -if($query == 'delete_all_order') { - # y.jules.net.au/index.php?exchange=bitmax&query=delete_all_order&var1=ETH/USDT - $config['api_request'] = 'order/all'; - $config['url'] .= $config['group'] . $config['delete_all']; - $config['method'] = 'DELETE'; - - $order = array(); - $order['symbol'] = $var1; # optional limit to coin pair - - $result = order($config, $order); - - if($config['debug']) { - echo $config['url'] . PHP_EOL; - print_r($order) . PHP_EOL; - print_r($result) . PHP_EOL; - } +if ($query == 'delete_all_order') { + + # index.php?exchange=bitmax&query=delete_all_order&var1=ETH/USDT + $config['api_request'] = 'order/all'; + $config['url'] .= $config['group'] . $config['delete_all']; + $config['method'] = 'DELETE'; + + $order = array(); + $order['symbol'] = $var1; # optional limit to coin pair + + $result = order($config, $order); + + if ($config['debug']) { + echo $config['url'] . PHP_EOL; + print_r($order) . PHP_EOL; + print_r($result) . PHP_EOL; + } + } include('system_metrics.php'); diff --git a/mysql.db.php b/mysql.db.php index ded01c3..490e55a 100644 --- a/mysql.db.php +++ b/mysql.db.php @@ -4,66 +4,57 @@ function query($querylabel, $config, $values=NULL) { - # grab correct query string from query library array - # values automatically inserted into array - $query = getsql($config, $values, $querylabel); - - # perform query - $result=doQuery($query, $config); - - # for testing only: display query - if ($config['debug_sql']) { - echo "Query: ". $querylabel . PHP_EOL; - echo "Values: "; - print_r($values) . PHP_EOL; - echo "Result: "; - print_r($result) . PHP_EOL; - echo "Config: "; - var_dump($config) . PHP_EOL; - } - - return $result; + # grab correct query string from query library array + # values automatically inserted into array + $query = getsql($config, $values, $querylabel); + + # perform query + $result=doQuery($query, $config); + + # for testing only: display query + if ($config['debug_sql']) { + echo "Query: ". $querylabel . PHP_EOL; + echo "Values: "; + print_r($values) . PHP_EOL; + echo "Result: "; + print_r($result) . PHP_EOL; + echo "Config: "; + var_dump($config) . PHP_EOL; + } + + return $result; } function doQuery($query, $config) { - $reply = mysqli_query($config['sql_link'], $query); - - # failed query - return FALSE - if ($reply === FALSE) { - - $result = FALSE; - - # return number of rows changed - } elseif ($reply === TRUE) { - - $result = mysqli_affected_rows($config['sql_link']); - - # check if select returns zero - } else if (mysqli_num_rows($reply) === 0) { - - $result = 0; - - # successful select - return array of results - } else { - - # note that very large result (> 100000) can exceed memory limit - - $result = array(); - while ($mysql_result = mysqli_fetch_assoc($reply)) - $result[] = $mysql_result; - - } + $reply = mysqli_query($config['sql_link'], $query); + + # failed query - return FALSE + if ($reply === FALSE) { + $result = FALSE; + # return number of rows changed + } elseif ($reply === TRUE) { + $result = mysqli_affected_rows($config['sql_link']); + # check if select returns zero + } else if (mysqli_num_rows($reply) === 0) { + $result = 0; + # successful select - return array of results + } else { + # note that very large result (> 100000) can exceed memory limit + $result = array(); + while ($mysql_result = mysqli_fetch_assoc($reply)) + $result[] = $mysql_result; + } - # get last autoincrement insert id - # $GLOBALS['lastinsertid'] = mysqli_insert_id($config['sql_link']); + # get last autoincrement insert id + # $GLOBALS['lastinsertid'] = mysqli_insert_id($config['sql_link']); - $error = mysqli_errno($config['sql_link']); - if ($error) $_SESSION['message'][]= - "Error $error in query: '" . mysqli_error($config['sql_link']) . "'"; + $error = mysqli_errno($config['sql_link']); + if ($error) $_SESSION['message'][] = + "Error $error in query: '" . mysqli_error($config['sql_link']) . "'"; - return $result; + return $result; } @@ -78,18 +69,15 @@ function safeIntoDB(&$value, $key, $config) { } else { # don't clean filters - we've cleaned those separately in the sqlparts function - if (strpos($key,'filterquery') === FALSE - && !preg_match("/^'\d\d\d\d-\d\d-\d\d'$/",$value) ) { // and don't clean dates - + if ( + strpos($key,'filterquery') === FALSE + && !preg_match("/^'\d\d\d\d-\d\d-\d\d'$/",$value) + ) { // and don't clean dates if (ini_get('magic_quotes_gpc') && !empty($value) && is_string($value)) $value = stripslashes($value); - $value = mysqli_real_escape_string($config['sql_link'], $value); - } else { - - return $value; - + return $value; } return $value; diff --git a/mysql.inc.php b/mysql.inc.php index 062cfee..ac9b04c 100644 --- a/mysql.inc.php +++ b/mysql.inc.php @@ -2,211 +2,223 @@ function getsql($config, $values, $querylabel) { - if (is_array($values)) - foreach ($values as $key => $value) - $values[$key] = safeIntoDB($value, $key, $config); + if (is_array($values)) + foreach ($values as $key => $value) + $values[$key] = safeIntoDB($value, $key, $config); switch ($querylabel) { - case 'select_indicators': - $sql = "SELECT - `function`, - `description`, - `indication`, - `class` - FROM `indicators` {$values['filterquery']} - "; - break; - - case 'select_history': - $sql = "SELECT - `history_id`, - `timestamp`, - `open`, - `close`, - `high`, - `low`, - `volume` - FROM `price_history` {$values['filterquery']} - "; - break; - - case 'update_history': - $sql = "INSERT INTO `price_history` - ( - `pair`, - `source`, - `timestamp`, - `period`, - `open`, - `close`, - `high`, - `low`, - `volume`, - `imputed` - ) - VALUES - ( - '{$values['pair']}', - '{$values['source']}', - '{$values['timestamp']}', - '{$values['period']}', - '{$values['open']}', - '{$values['close']}', - '{$values['high']}', - '{$values['low']}', - '{$values['volume']}', - '{$values['imputed']}' - ) - "; - break; - - # keep the most recent record - case 'deduplicate_history': - - # warning this is inefficient with a large db, better to iterate with $values filter to small number of records - $sql = " - DELETE a FROM `price_history` a - INNER JOIN `price_history` b - ON a.pair = b.pair - AND a.timestamp = b.timestamp - AND a.period = b.period - AND a.source = b.source - WHERE - a.history_id < b.history_id - {$values['filterquery']} - ; - "; - - break; - - case 'update_content': - $sql = "REPLACE INTO `web_content` - ( - `content_id`, - `content`, - `timestamp`, - `notified` - ) - VALUES - ( - '{$values['content_id']}', - '{$values['content']}', - '{$values['timestamp']}', - '{$values['notified']}' - ) - "; - break; - - case 'get_content': - $sql = "SELECT * FROM `web_content` {$values['filterquery']}"; - break; - - case 'get_tactics': - $sql = "SELECT * FROM `tactics` {$values['filterquery']}"; - break; - - case 'update_tactic': - $sql = "UPDATE `tactics` SET `{$values['field']}` = '{$values['value']}' WHERE `tactic_id` = '{$values['tactic_id']}'"; - break; - - case 'get_transactions': - $sql = "SELECT * FROM `transactions` {$values['filterquery']}"; - break; + case 'select_indicators': + $sql = " + SELECT + `function`, + `description`, + `indication`, + `class` + FROM `indicators` {$values['filterquery']} + "; + break; + + case 'select_history': + $sql = "SELECT + `history_id`, + `timestamp`, + `open`, + `close`, + `high`, + `low`, + `volume` + FROM `price_history` {$values['filterquery']} + "; + break; + + case 'update_history': + $sql = " + INSERT INTO `price_history` + ( + `pair`, + `source`, + `timestamp`, + `period`, + `open`, + `close`, + `high`, + `low`, + `volume`, + `imputed` + ) + VALUES + ( + '{$values['pair']}', + '{$values['source']}', + '{$values['timestamp']}', + '{$values['period']}', + '{$values['open']}', + '{$values['close']}', + '{$values['high']}', + '{$values['low']}', + '{$values['volume']}', + '{$values['imputed']}' + ) + "; + break; + + # keep the most recent record + case 'deduplicate_history': + # warning this is inefficient with a large db, better to iterate with $values filter to small number of records + $sql = " + DELETE a FROM `price_history` a + INNER JOIN `price_history` b + ON a.pair = b.pair + AND a.timestamp = b.timestamp + AND a.period = b.period + AND a.source = b.source + WHERE + a.history_id < b.history_id + {$values['filterquery']} + ; + "; + break; + + case 'update_content': + $sql = " + REPLACE INTO `web_content` + ( + `content_id`, + `content`, + `timestamp`, + `notified` + ) + VALUES + ( + '{$values['content_id']}', + '{$values['content']}', + '{$values['timestamp']}', + '{$values['notified']}' + ) + "; + break; + + case 'get_content': + $sql = "SELECT * FROM `web_content` {$values['filterquery']}"; + break; + + case 'get_tactics': + $sql = "SELECT * FROM `tactics` {$values['filterquery']}"; + break; + + case 'update_tactic': + $sql = "UPDATE `tactics` SET `{$values['field']}` = '{$values['value']}' WHERE `tactic_id` = '{$values['tactic_id']}'"; + break; + + case 'get_transactions': + $sql = "SELECT * FROM `transactions` {$values['filterquery']}"; + break; case 'update_transaction': - $sql = "REPLACE INTO `transactions` - ( - `transaction_id`, - `investment_id`, - `investment_proportion`, - `time_opened`, - `time_closed`, - `capital_amount`, - `capital_fee`, - `purpose`, - `exchange`, - `exchange_transaction_id`, - `exchange_transaction_status`, - `percent_complete`, - `pair_asset`, - `from_asset`, - `from_amount`, - `to_asset`, - `to_amount`, - `to_fee`, - `pair_price`, - `from_price_usd`, - `to_price_usd`, - `price_reference`, - `fee_amount_usd`, - `price_aud_usd`, - `aud_usd_reference`, - `from_wallet`, - `to_wallet`, - `tactic_id`, - `strategy_result_usd` - ) - VALUES ( - '{$values['transaction_id']}', - '{$values['investment_id']}', - '{$values['investment_proportion']}', - '{$values['time_opened']}', - '{$values['time_closed']}', - '{$values['capital_amount']}', - '{$values['capital_fee']}', - '{$values['purpose']}', - '{$values['exchange']}', - '{$values['exchange_transaction_id']}', - '{$values['exchange_transaction_status']}', - '{$values['percent_complete']}', - '{$values['pair_asset']}', - '{$values['from_asset']}', - '{$values['from_amount']}', - '{$values['to_asset']}', - '{$values['to_amount']}', - '{$values['to_fee']}', - '{$values['pair_price']}', - '{$values['from_price_usd']}', - '{$values['to_price_usd']}', - '{$values['price_reference']}', - '{$values['fee_amount_usd']}', - '{$values['price_aud_usd']}', - '{$values['aud_usd_reference']}', - '{$values['from_wallet']}', - '{$values['to_wallet']}', - '{$values['tactic_id']}', - '{$values['strategy_result_usd']}' - )"; - break; - - default: // default to assuming that the label IS the query - $sql=$querylabel; - break; - - } + $sql = " + REPLACE INTO `transactions` + ( + `transaction_id`, + `investment_id`, + `investment_proportion`, + `time_opened`, + `time_closed`, + `capital_amount`, + `capital_fee`, + `purpose`, + `exchange`, + `exchange_transaction_id`, + `exchange_transaction_status`, + `percent_complete`, + `pair_asset`, + `from_asset`, + `from_amount`, + `to_asset`, + `to_amount`, + `to_fee`, + `pair_price`, + `from_price_usd`, + `to_price_usd`, + `price_reference`, + `fee_amount_usd`, + `price_aud_usd`, + `aud_usd_reference`, + `from_wallet`, + `to_wallet`, + `tactic_id`, + `strategy_result_usd` + ) + VALUES + ( + '{$values['transaction_id']}', + '{$values['investment_id']}', + '{$values['investment_proportion']}', + '{$values['time_opened']}', + '{$values['time_closed']}', + '{$values['capital_amount']}', + '{$values['capital_fee']}', + '{$values['purpose']}', + '{$values['exchange']}', + '{$values['exchange_transaction_id']}', + '{$values['exchange_transaction_status']}', + '{$values['percent_complete']}', + '{$values['pair_asset']}', + '{$values['from_asset']}', + '{$values['from_amount']}', + '{$values['to_asset']}', + '{$values['to_amount']}', + '{$values['to_fee']}', + '{$values['pair_price']}', + '{$values['from_price_usd']}', + '{$values['to_price_usd']}', + '{$values['price_reference']}', + '{$values['fee_amount_usd']}', + '{$values['price_aud_usd']}', + '{$values['aud_usd_reference']}', + '{$values['from_wallet']}', + '{$values['to_wallet']}', + '{$values['tactic_id']}', + '{$values['strategy_result_usd']}' + ) + "; + break; + + default: // default to assuming that the label IS the query + $sql = $querylabel; + break; + + } + return $sql; + } function sqlparts($part,$config,$values) { - if (is_array($values)) - foreach ($values as $key=>$value) - $values[$key] = safeIntoDB($value, $key, $config); + if (is_array($values)) + foreach ($values as $key=>$value) + $values[$key] = safeIntoDB($value, $key, $config); + + switch ($part) { + + case "test": + $sqlpart = " "; + break; - switch ($part) { + default: + if ($config['debug_sql']) echo "Failed to find sql component '$part'
'"; + $sqlpart=$part; + break; - case "test": - $sqlpart = " "; - break; - default: - if ($config['debug_sql']) echo "Failed to find sql component '$part'
'"; - $sqlpart=$part; - break; - } + } - if ($config['debug_sql']) - echo "Sqlparts '$part': Result $sqlpart'; + if ($config['debug_sql']) + echo + "
Sanitised values in sqlparts: ",print_r($values,true),'Sqlparts '$part': Result $sqlpart" + ; - return $sqlpart; + return $sqlpart; } diff --git a/price_history.php b/price_history.php index 2196ca0..3da166b 100644 --- a/price_history.php +++ b/price_history.php @@ -4,7 +4,7 @@ echo '
Sanitised values in sqlparts: " . + print_r($values,true) . + "'; if(isset($_GET['pair_id'])) $pair_id = $_GET['pair_id']; - else $pair_id = FALSE; +else $pair_id = FALSE; price_history($config, $pair_id); diff --git a/price_recent.php b/price_recent.php index cfa08c0..cbcb7bb 100644 --- a/price_recent.php +++ b/price_recent.php @@ -4,7 +4,7 @@ echo ''; if(isset($_GET['pair_id'])) $pair_id = $_GET['pair_id']; - else $pair_id = FALSE; +else $pair_id = FALSE; price_recent($config, $pair_id); diff --git a/system_metrics.php b/system_metrics.php index 376e474..daa1aaa 100644 --- a/system_metrics.php +++ b/system_metrics.php @@ -1,4 +1,9 @@ ' . PHP_EOL . 'query took ' . - round((milliseconds() - $config['timestamp']) / 1000, 2) . ' seconds'; +echo + '' . + PHP_EOL . + 'query took ' . + round((milliseconds() - $config['timestamp']) / 1000, 2) . + ' seconds' +; diff --git a/technical_analysis.php b/technical_analysis.php index d20df30..edfc845 100644 --- a/technical_analysis.php +++ b/technical_analysis.php @@ -6,8 +6,8 @@ echo ''; -if(isset($_GET['pair_id'])) $pair_id = $_GET['pair_id']; - else $pair_id = FALSE; +if (isset($_GET['pair_id'])) $pair_id = $_GET['pair_id']; +else $pair_id = FALSE; technical_analysis($config, $pair_id); @@ -15,106 +15,108 @@ /* - # ignore all following code - - - $values['filterquery'] = " WHERE pair = '" . $pair . "' - AND source = '" . $source . "' - AND period = '" . $period_txt . "' - AND timestamp >= " . $start . " - AND timestamp <= " . $stop; - $history = query('select_history', $config, $values); - - echo 'pair: ' . $pair . '
'; - echo 'source: ' . $source . '
'; - echo 'period: ' . $period . '
'; - echo 'observations: ' . count($history). '
'; - - usort($history, function($a, $b) { - return $a['timestamp'] - $b['timestamp']; - }); - - $last = $history[0]['timestamp'] - $diff; - $missing_data = FALSE; - $i = 0; - foreach ($history as $hist) { - $diff_obs = $hist['timestamp'] - $last; - if ($diff !== $diff_obs) { - $missing_data = TRUE; - $missing_obs = $hist['timestamp'] - $diff; - $missing_array = $i; - } - $last = $hist['timestamp']; - $i++; - } - if($missing_data) { - echo 'missing data at array position ' . $missing_array . ',
time ' . date('Y-m-d H:i T', $missing_obs / 1000) . ',
timestamp ' . $missing_obs . ',
period ' . $diff . '
'; - var_dump($history[$missing_array - 1]); - var_dump($history[$missing_array]); - } - $data_open = array_column($history, 'open'); - $data_high = array_column($history, 'high'); - $data_low = array_column($history, 'low'); - $data_close = array_column($history, 'close'); - $data_volume = array_column($history, 'volume'); - - $values['filterquery'] = " WHERE class = 'candlestick'"; - $indicators = query('select_indicators', $config, $values); - - foreach ($indicators as $indicator) { - $result = $indicator['function']($data_open, $data_high, $data_low, $data_close); - #if(end($result)) echo $indicator['description'] . ': ' . end($result) . '
'; - if ($indicator['reliability']) - for ($i = count($result) - 5; $i <= count($result); $i++) { - if($result[$i]) { - echo $i . ' ' . $indicator['description'] . ': ' . $result[$i] . ', '; - echo $indicator['indication'] . ', ' . $indicator['reliability'] . '
'; - } - } - } - - $result = trader_ema($data_close, 12); - echo 'ema 12: ' . end($result); - if (end($data_close) > end($result)) { - echo ' above
'; - } else { - echo ' below
'; - } - - $result = trader_ema($data_close, 50); - echo 'ema 50: ' . end($result) . '
'; - - $result = trader_ema($data_close, 200); - echo 'ema 200: ' . end($result) . '
'; - - $result = trader_rsi($data_close, 14); - echo 'rsi 14: ' . end($result) . '
'; - - $result = trader_rsi($data_close, 24); - echo 'rsi 24: ' . end($result) . '
'; - - $last = count($history); - $history_recent = array(); - $volume_recent = array(); - for ($i = $last - $points; $i < $last; $i++) { - array_push($history_recent, array( - $history[$i]['timestamp'], - $history[$i]['open'], - $history[$i]['high'], - $history[$i]['low'], - $history[$i]['close'] - )); - array_push($volume_recent, array( - $history[$i]['timestamp'], - (int)$history[$i]['volume'] - )); - } - #var_dump($history_recent); - echo '
from ' . date('Y-m-d H:i T', $history_recent[$points - 1][0] / 1000); - echo ' to ' . date('Y-m-d H:i T', $history_recent[0][0] / 1000) . '
'; - echo $points . ' observations'; - - ?> +# ignore all following code + + +$values['filterquery'] = " + WHERE pair = '" . $pair . "' + AND source = '" . $source . "' + AND period = '" . $period_txt . "' + AND timestamp >= " . $start . " + AND timestamp <= " . $stop +; +$history = query('select_history', $config, $values); + +echo 'pair: ' . $pair . '
'; +echo 'source: ' . $source . '
'; +echo 'period: ' . $period . '
'; +echo 'observations: ' . count($history). '
'; + +usort($history, function($a, $b) { + return $a['timestamp'] - $b['timestamp']; +}); + +$last = $history[0]['timestamp'] - $diff; +$missing_data = FALSE; +$i = 0; +foreach ($history as $hist) { + $diff_obs = $hist['timestamp'] - $last; + if ($diff !== $diff_obs) { + $missing_data = TRUE; + $missing_obs = $hist['timestamp'] - $diff; + $missing_array = $i; + } + $last = $hist['timestamp']; + $i++; +} +if ($missing_data) { + echo 'missing data at array position ' . $missing_array . ',
time ' . date('Y-m-d H:i T', $missing_obs / 1000) . ',
timestamp ' . $missing_obs . ',
period ' . $diff . '
'; + var_dump($history[$missing_array - 1]); + var_dump($history[$missing_array]); +} +$data_open = array_column($history, 'open'); +$data_high = array_column($history, 'high'); +$data_low = array_column($history, 'low'); +$data_close = array_column($history, 'close'); +$data_volume = array_column($history, 'volume'); + +$values['filterquery'] = " WHERE class = 'candlestick'"; +$indicators = query('select_indicators', $config, $values); + +foreach ($indicators as $indicator) { + $result = $indicator['function']($data_open, $data_high, $data_low, $data_close); + #if (end($result)) echo $indicator['description'] . ': ' . end($result) . '
'; + if ($indicator['reliability']) + for ($i = count($result) - 5; $i <= count($result); $i++) { + if ($result[$i]) { + echo $i . ' ' . $indicator['description'] . ': ' . $result[$i] . ', '; + echo $indicator['indication'] . ', ' . $indicator['reliability'] . '
'; + } + } +} + +$result = trader_ema($data_close, 12); +echo 'ema 12: ' . end($result); +if (end($data_close) > end($result)) { + echo ' above
'; +} else { + echo ' below
'; +} + +$result = trader_ema($data_close, 50); +echo 'ema 50: ' . end($result) . '
'; + +$result = trader_ema($data_close, 200); +echo 'ema 200: ' . end($result) . '
'; + +$result = trader_rsi($data_close, 14); +echo 'rsi 14: ' . end($result) . '
'; + +$result = trader_rsi($data_close, 24); +echo 'rsi 24: ' . end($result) . '
'; + +$last = count($history); +$history_recent = array(); +$volume_recent = array(); +for ($i = $last - $points; $i < $last; $i++) { + array_push($history_recent, array( + $history[$i]['timestamp'], + $history[$i]['open'], + $history[$i]['high'], + $history[$i]['low'], + $history[$i]['close'] + )); + array_push($volume_recent, array( + $history[$i]['timestamp'], + (int)$history[$i]['volume'] + )); +} +#var_dump($history_recent); +echo '
from ' . date('Y-m-d H:i T', $history_recent[$points - 1][0] / 1000); +echo ' to ' . date('Y-m-d H:i T', $history_recent[0][0] / 1000) . '
'; +echo $points . ' observations'; + +?> @@ -130,82 +132,82 @@ --> - ++- +