作者 karlet

feat:bybit增加k线监听

<?php
require_once __DIR__ . '/../trader/CmBroker.php';
require_once __DIR__ . '/../trader/struct/ApiInfo.php';
require_once __DIR__ . '/../jytools/BinanceFutures.php';
require_once __DIR__ . '/../jytools/func.php';
use trader\struct\ApiInfo;
use trader\CmBroker;
use function jytools\output;
$key = "c4JkKQWRXq34kuZahS";
$secret = "YdsPKpSBwaHzy67oizQhI7vuJNDeVO8cU5dP";
$apiInfo = new ApiInfo($key, $secret, "");
$broker = new CmBroker(CmBroker::PLAT_BYBIT, $apiInfo);
$broker->setWsHost("ws://bbws.keetu.com");
$broker->setRestHost("http://bbapi.keetu.com");
// $broker->accListen(function ($data) {
// // var_dump($data);
// });
$broker->klineListen("BTCUSDT", "1m", function ($data) {
output($data->toArray());
});
... ...
... ... @@ -5,6 +5,7 @@ namespace trader;
require_once __DIR__ . '/struct/ApiInfo.php';
require_once __DIR__ . '/exchange/okx/ExBroker.php';
require_once __DIR__ . '/exchange/binance/ExBroker.php';
require_once __DIR__ . '/exchange/bybit/ExBroker.php';
require_once __DIR__ . '/struct/Kline.php';
require_once __DIR__ . '/struct/Order.php';
require_once __DIR__ . '/struct/WsData.php';
... ... @@ -21,6 +22,7 @@ require_once __DIR__ . '/../jytools/Websocket.php';
use trader\struct\ApiInfo;
use trader\exchange\okx\ExBroker as OkxBroker;
use trader\exchange\binance\ExBroker as BinanceBroker;
use trader\exchange\bybit\ExBroker as BybitBroker;
use trader\struct\Kline;
use trader\struct\Order;
use trader\struct\WsData;
... ... @@ -47,7 +49,7 @@ class CmBroker
* @see PLAT_BITGET
*/
public $plat;
private OkxBroker|BinanceBroker $exBroker;
private OkxBroker|BinanceBroker|BybitBroker $exBroker;
/** @var SymbolInfo[] $symbolInfos */
public $symbolInfos = [];
/** @var Pos[] $positions */
... ... @@ -67,6 +69,9 @@ class CmBroker
if ($plat == self::PLAT_BINANCE) {
$exBroker = new BinanceBroker($apiInfo);
}
if ($plat == self::PLAT_BYBIT) {
$exBroker = new BybitBroker($apiInfo);
}
$this->exBroker = $exBroker;
}
public function setWsHost($host)
... ... @@ -200,13 +205,17 @@ class CmBroker
return;
}
$symbol = $this->getSymbolOri($symbol, $this->plat);
$this->exBroker->klineListen($symbol, $peroid, function ($data) use ($onData) {
$periodOri = $this->getPeriodOri($this->plat, $peroid);
$this->exBroker->klineListen($symbol, $periodOri, function ($data) use ($onData) {
if ($this->plat == self::PLAT_BINANCE) {
$kline = Kline::transferBinance($data);
}
if ($this->plat == self::PLAT_OKX) {
$kline = Kline::transferOkx($data);
}
if ($this->plat == self::PLAT_BYBIT) {
$kline = Kline::transferBybit($data);
}
$onData($kline);
});
}
... ... @@ -220,6 +229,38 @@ class CmBroker
throw new Exception('转换标准交易对错误' . $symbol . ' to ', $symbol);
}
}
//转换为原始周期
public function getPeriodOri($platTarget, $period)
{
if ($platTarget == self::PLAT_BINANCE) {
return $period;
}
if ($platTarget == self::PLAT_OKX) {
return str_replace('s', 'S', $period);
}
if ($platTarget == self::PLAT_BYBIT) {
$arr = [
'1m' => '1',
'3m' => '3',
'5m' => '5',
'15m' => '15',
'30m' => '30',
'1h' => '60',
'2h' => '120',
'4h' => '240',
'6h' => '360',
'12h' => '720',
'1d' => 'D',
'1w' => 'W',
'1M' => 'M',
];
if (!isset($arr[$period])) {
throw new Exception('周期错误,' . $this->plat . '不支持的周期' . $period);
}
return $arr[$period];
}
throw new Exception('平台错误' + $platTarget);
}
//转换为原始交易对
public function getSymbolOri($symbol, $platTarget)
... ... @@ -231,7 +272,10 @@ class CmBroker
if ($platTarget == self::PLAT_OKX) {
return str_replace('USDT', '-USDT-SWAP', $symbolSt);
}
throw new Exception('平台错误' + $platTarget);
if ($platTarget == self::PLAT_BYBIT) {
return $symbolSt;
}
throw new Exception('平台错误' . $platTarget);
}
public function placeOrder(Order $order)
... ...
... ... @@ -11,7 +11,7 @@ use function jytools\getMicrotime;
class Api
{
private $host = '';
private $host = 'https://api.bybit.com';
private ApiInfo $apiInfo;
public function __construct(ApiInfo $apiInfo)
{
... ...
<?php
namespace trader\exchange\binance;
namespace trader\exchange\bybit;
require_once __DIR__ . '/../../struct/ApiInfo.php';
require_once __DIR__ . '/Api.php';
... ... @@ -15,7 +15,8 @@ use function jytools\output;
class ExBroker
{
private $host = 'wss://stream.bybit.com';
private $path = '/v5/private';
private $pathPri = '/v5/private'; //账户信息path
private $pathPub = '/v5/public/linear'; //行情信息path 永续
private ApiInfo $apiInfo;
private BbApi $api;
private ?Websocket $wsAcc;
... ... @@ -39,5 +40,24 @@ class ExBroker
public function accListen(callable $onData) {}
public function klineListen($symbol, $interval, callable $onData) {}
public function klineListen($symbol, $interval, callable $onData)
{
$this->wsKline = new Websocket($this->host . $this->pathPub);
$this->wsKline->connect(
function () use ($symbol, $interval) {
$this->wsKline->push(json_encode([
'op' => 'subscribe',
'args' => [
"kline.{$interval}.{$symbol}"
]
]));
},
function ($data) use ($onData) {
$data = json_decode($data, true);
if (isset($data['data'])) {
$onData($data);
}
},
);
}
}
... ...
... ... @@ -34,6 +34,7 @@ class Kline
'close' => $this->close,
'vol' => $this->vol,
'volQuote' => $this->volQuote,
'uts' => $this->uts,
];
}
public static function transferOkx($data)
... ... @@ -65,4 +66,17 @@ class Kline
$uts = $data['E'];
return new Kline($time, $open, $high, $low, $close, $vol, $volQuote, $uts);
}
public static function transferBybit($data)
{
$kline = $data['data'][0];
$time = $kline['start'];
$open = $kline['open'];
$high = $kline['high'];
$low = $kline['low'];
$close = $kline['close'];
$vol = $kline['volume'];
$volQuote = $kline['turnover'];
$uts = $kline['timestamp'];
return new Kline($time, $open, $high, $low, $close, $vol, $volQuote, $uts);
}
}
... ...