作者 karlet

feat:盘口订阅

<?php
require_once __DIR__ . '/../trader/CmBroker.php';
require_once __DIR__ . '/../trader/struct/ApiInfo.php';
require_once __DIR__ . '/../jytools/BinanceFutures.php';
use trader\struct\ApiInfo;
use trader\CmBroker;
use function jytools\output;
$key = "b34ae137-a085-4ec9-a7c7-d10283da9455";
$secret = "1896634401D28262A05BF538608D44E0";
$passphrase = "!@Name4tst";
$apiInfo = new ApiInfo($key, $secret, $passphrase);
$wsHost = "ws://okws.a.indigo888.com";
$restHost = "http://okapi.a.indigo888.com";
$broker = new CmBroker(CmBroker::PLAT_OKX, $apiInfo, $wsHost, $restHost);
$broker->subDepth('ADAUSDT', function ($data) {
// var_dump($data);
output("asks len:", count($data['asks']));
output("bids len:", count($data['bids']));
echo "-----" . PHP_EOL;
});
... ...
... ... @@ -862,7 +862,7 @@ class CmBroker
}
public function subDepth($symbol, callable $onData)
{
$this->exBroker->subDepth($symbol, $onData);
$this->exBroker->subDepth($this->getSymbolOri($symbol), $onData);
}
public function getIndexTickers()
{
... ...
... ... @@ -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'];
}
}
... ...