|
...
|
...
|
@@ -11,6 +11,7 @@ use trader\struct\ApiInfo; |
|
|
|
use trader\exchange\okx\Api as OkxApi;
|
|
|
|
use jytools\Websocket;
|
|
|
|
use function jytools\output;
|
|
|
|
use function jytools\getMicrotime;
|
|
|
|
|
|
|
|
|
|
|
|
class ExBroker
|
|
...
|
...
|
@@ -23,8 +24,15 @@ class ExBroker |
|
|
|
private OkxApi $api;
|
|
|
|
private ?Websocket $wsAcc;
|
|
|
|
private ?Websocket $wsKline;
|
|
|
|
private ?Websocket $wsDepth;
|
|
|
|
private $timerAccPing = 0;
|
|
|
|
private $timerKlinePing = 0;
|
|
|
|
private array $depthData = [
|
|
|
|
'lid' => 0, //lastUpdateId
|
|
|
|
'bids' => [],
|
|
|
|
'asks' => [],
|
|
|
|
'uts' => 0, //updateTime
|
|
|
|
];
|
|
|
|
|
|
|
|
public function __construct(?ApiInfo $apiInfo)
|
|
|
|
{
|
|
...
|
...
|
@@ -429,4 +437,74 @@ class ExBroker |
|
|
|
$res = $this->api->indexTickers($param);
|
|
|
|
return $res;
|
|
|
|
}
|
|
|
|
public function subDepth($symbol, callable $onData)
|
|
|
|
{
|
|
|
|
$this->wsDepth = new Websocket($this->host . $this->pathPublic);
|
|
|
|
$this->wsDepth->connect(
|
|
|
|
$onOpen = function () use ($symbol) {
|
|
|
|
$subData = json_encode(["op" => "subscribe", "args" => [['channel' => 'books', 'instId' => $symbol]]]);
|
|
|
|
$this->wsDepth->push($subData);
|
|
|
|
},
|
|
|
|
$onMessage = function ($data) use ($onData) {
|
|
|
|
// var_dump($data);
|
|
|
|
$data = json_decode($data, true);
|
|
|
|
if (!$data || !isset($data['data'])) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if ($data['action'] == 'snapshot') {
|
|
|
|
$this->udpateDepthSnapshot($data['data'][0]);
|
|
|
|
}
|
|
|
|
if ($data['action'] == 'update') {
|
|
|
|
$this->addDepthData($data['data'][0]);
|
|
|
|
}
|
|
|
|
$onData($this->depthData);
|
|
|
|
},
|
|
|
|
$onClose = null,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
function udpateDepthSnapshot($data)
|
|
|
|
{
|
|
|
|
// $this->depthData = $data;
|
|
|
|
$this->depthData['lid'] = $data['seqId'];
|
|
|
|
$this->depthData['bids'] = $this->formatDepthData($data['bids'], 'bids');
|
|
|
|
$this->depthData['asks'] = $this->formatDepthData($data['asks'], 'asks');
|
|
|
|
$this->depthData['uts'] = $data['ts'];
|
|
|
|
}
|
|
|
|
private function formatDepthData($data, $type)
|
|
|
|
{
|
|
|
|
$newData = [];
|
|
|
|
foreach ($data as $item) {
|
|
|
|
$price = ($item[0]);
|
|
|
|
$qty = ($item[1]);
|
|
|
|
$newData[$price] = $qty;
|
|
|
|
}
|
|
|
|
if ($type == 'asks') {
|
|
|
|
//从小到大排序
|
|
|
|
ksort($newData);
|
|
|
|
} else {
|
|
|
|
//从大到小排序
|
|
|
|
krsort($newData);
|
|
|
|
}
|
|
|
|
return $newData;
|
|
|
|
}
|
|
|
|
private function addDepthData($data)
|
|
|
|
{
|
|
|
|
$data['a'] = $this->formatDepthData($data['asks'], 'asks');
|
|
|
|
$data['b'] = $this->formatDepthData($data['bids'], 'bids');
|
|
|
|
$this->depthData['asks'] = array_merge($this->depthData['asks'], $data['a']);
|
|
|
|
$this->depthData['bids'] = array_merge($this->depthData['bids'], $data['b']);
|
|
|
|
//保留值不为0的数据
|
|
|
|
$this->depthData['asks'] = array_filter($this->depthData['asks'], function ($v) {
|
|
|
|
return floatval($v) != 0;
|
|
|
|
});
|
|
|
|
$this->depthData['bids'] = array_filter($this->depthData['bids'], function ($v) {
|
|
|
|
return floatval($v) != 0;
|
|
|
|
});
|
|
|
|
//从小到大排序
|
|
|
|
ksort($this->depthData['asks']);
|
|
|
|
//从大到小排序
|
|
|
|
krsort($this->depthData['bids']);
|
|
|
|
$this->depthData['lid'] = $data['seqId'];
|
|
|
|
$this->depthData['uts'] = $data['ts'];
|
|
|
|
}
|
|
|
|
} |
...
|
...
|
|