业务需求 nuls_bx 交易对牟定盘口做市
但是要求牟定 bx_usdt 主流交易对, 真实晕 写了个递归 经过测试可用 转换路径如下
nuls_btc btc_usdt bx_eth eth_usdt 经过 四个交易对 转换成目标交易对 汇率
<?php
// 都需要对标 bx_usdt
$symbol = 'nuls_coin';
$benchmarkSymbolList = ['nuls_btc' , 'btc_usdt', 'coin_usdt'];
$benchmarkData = [
'nuls_btc' => [
'0.00015635',
'0.00015832',
],
// 'coin_btc' => [
// '0.00000278', // 买
// '0.00002329', // 卖
// ],
'btc_usdt' => [
'3995.00',
'3998.01',
],
'coin_usdt' => [
'0.0924',
'0.1926',
]
];
// $symbol = 'eos_bx';
// $benchmarkSymbolList = ['eos_usdt', 'bx_usdt'];
// $benchmarkData = [
// 'eos_usdt' => [
// 3.6627,
// 3.6549
// ],
// 'bx_usdt' =>[
// 0.1022,
// 0.1011
// ]
// ];
/**
* @des 交易对检测函数
* @param $symbol
* @param $checkSymbolList
* @return bool
* ------------------------------------------------------------
*/
function checkSymbolList($symbol, $checkSymbolList)
{
list($coinFrom, $coinTo) = explode('_', $symbol);
$coinList = [];
foreach ($checkSymbolList as $checkSymbol) {
list($cFrom, $cTo) = explode('_', $checkSymbol);
$coinList[$cFrom] = isset($coinList[$cFrom]) ? $coinList[$cFrom] + 1 : 1;
$coinList[$cTo] = isset($coinList[$cTo]) ? $coinList[$cTo] + 1 : 1;
}
// 目标币对 仅可以出现一个
if (empty($coinList[$coinFrom]) || $coinList[$coinFrom] != 1 || empty($coinList[$coinTo]) || $coinList[$coinTo] != 1) {
return false;
}
unset($coinList[$coinFrom], $coinList[$coinTo]);
// 除目标币种 外 其他币种最少出现两次
if (max($coinList) != 2 || min($coinList) != 2) {
return false;
}
return true;
}
/**
* @des 调用递归
* @param $symbol
* @param $benchmarkSymbolList
* @param $benchmarkData
* @return array
* ------------------------------------------------------------
*/
function integrateRateToBenchMarkPrice($symbol, $benchmarkSymbolList, $benchmarkData)
{
// 选择对标方向
list($coinFrom, $coinTo) = explode('_', $symbol);
// 效验交易对是否正确
if (!checkSymbolList($symbol, $benchmarkSymbolList)) return [];
return rateSymbolConversion($coinFrom, $coinTo, $benchmarkSymbolList, $benchmarkData);
}
/**
* @des 多交易对汇率转换 递归
* @param $coinFrom
* @param $coinTo
* @param $benchmarkSymbolList
* @param $benchmarkData
* @param array $params
* @return array
* ------------------------------------------------------------
*/
function rateSymbolConversion($coinFrom, $coinTo, $benchmarkSymbolList, $benchmarkData, $params = [])
{
// 容错 异常跳出递归
if (!$benchmarkSymbolList) return $params;
// 转换后数据 nuls_usdt
$askConversion = $params[0] ?? 0;
$bidConversion = $params[1] ?? 0;
$conversionCoin = $params[2] ?? '';
// 交易对排序
foreach ($benchmarkSymbolList as $k => $benchmarkSymbol) {
list($from, $to) = explode('_', $benchmarkSymbol);
// 提取交易对
list($bidBenchmark, $askBenchmark) = $benchmarkData[$benchmarkSymbol];
if ($conversionCoin == $from) {
unset($benchmarkSymbolList[$k]);
$askNewBenchmark = bcmul($askConversion, $askBenchmark, 10);
$bidNewBenchmark = bcmul($bidConversion, $bidBenchmark, 10);
echo $benchmarkSymbol ,' => from ', $conversionCoin,PHP_EOL;
return rateSymbolConversion($coinFrom, $coinTo, $benchmarkSymbolList, $benchmarkData, [$bidNewBenchmark, $askNewBenchmark, $to]);
} else if ($conversionCoin == $to) {
unset($benchmarkSymbolList[$k]);
echo $benchmarkSymbol ,' => to ', $conversionCoin, PHP_EOL;
echo 'askBenchmark =>',$askConversion,' ', $askBenchmark, ' bidBenchmark => ', $bidConversion,' ', $bidBenchmark, PHP_EOL;
$askNewBenchmark = bcdiv($askConversion, $bidBenchmark, 10);
$bidNewBenchmark = bcdiv($bidConversion, $askBenchmark, 10);
return rateSymbolConversion($coinFrom, $coinTo, $benchmarkSymbolList, $benchmarkData, [$bidNewBenchmark, $askNewBenchmark, $from]);
}
// 判断当前交易对 为代币 所在代币交易对
if ($coinFrom == $from) {
// 第一次 参数为空 直接复制 调用递归
if (!$params) {
// 注销使用过的数组元素
unset($benchmarkSymbolList[$k]);
echo $benchmarkSymbol ,' => null ', $coinFrom, PHP_EOL;
return rateSymbolConversion($coinFrom, $coinTo, $benchmarkSymbolList, $benchmarkData, [$bidBenchmark, $askBenchmark, $to]);
}
}
}
return $params;
}
$data = integrateRateToBenchMarkPrice($symbol, $benchmarkSymbolList, $benchmarkData);
var_export($data);
localhost:Desktop admin$ php test.php
# 执行顺序
nuls_btc => null nuls
btc_usdt => from btc
bz_usdt => to usdt
askBenchmark =>0.6324884000 0.1926 bidBenchmark => 0.6250888635 0.0924
array (
0 => '3.2455288862',
1 => '6.8451125541',
2 => 'coin',
)