作者 karlet

feat:bybit增加k线监听

  1 +<?php
  2 +
  3 +require_once __DIR__ . '/../trader/CmBroker.php';
  4 +require_once __DIR__ . '/../trader/struct/ApiInfo.php';
  5 +require_once __DIR__ . '/../jytools/BinanceFutures.php';
  6 +require_once __DIR__ . '/../jytools/func.php';
  7 +
  8 +use trader\struct\ApiInfo;
  9 +use trader\CmBroker;
  10 +use function jytools\output;
  11 +
  12 +$key = "c4JkKQWRXq34kuZahS";
  13 +$secret = "YdsPKpSBwaHzy67oizQhI7vuJNDeVO8cU5dP";
  14 +$apiInfo = new ApiInfo($key, $secret, "");
  15 +$broker = new CmBroker(CmBroker::PLAT_BYBIT, $apiInfo);
  16 +$broker->setWsHost("ws://bbws.keetu.com");
  17 +$broker->setRestHost("http://bbapi.keetu.com");
  18 +// $broker->accListen(function ($data) {
  19 +// // var_dump($data);
  20 +// });
  21 +
  22 +$broker->klineListen("BTCUSDT", "1m", function ($data) {
  23 + output($data->toArray());
  24 +});
@@ -5,6 +5,7 @@ namespace trader; @@ -5,6 +5,7 @@ namespace trader;
5 require_once __DIR__ . '/struct/ApiInfo.php'; 5 require_once __DIR__ . '/struct/ApiInfo.php';
6 require_once __DIR__ . '/exchange/okx/ExBroker.php'; 6 require_once __DIR__ . '/exchange/okx/ExBroker.php';
7 require_once __DIR__ . '/exchange/binance/ExBroker.php'; 7 require_once __DIR__ . '/exchange/binance/ExBroker.php';
  8 +require_once __DIR__ . '/exchange/bybit/ExBroker.php';
8 require_once __DIR__ . '/struct/Kline.php'; 9 require_once __DIR__ . '/struct/Kline.php';
9 require_once __DIR__ . '/struct/Order.php'; 10 require_once __DIR__ . '/struct/Order.php';
10 require_once __DIR__ . '/struct/WsData.php'; 11 require_once __DIR__ . '/struct/WsData.php';
@@ -21,6 +22,7 @@ require_once __DIR__ . '/../jytools/Websocket.php'; @@ -21,6 +22,7 @@ require_once __DIR__ . '/../jytools/Websocket.php';
21 use trader\struct\ApiInfo; 22 use trader\struct\ApiInfo;
22 use trader\exchange\okx\ExBroker as OkxBroker; 23 use trader\exchange\okx\ExBroker as OkxBroker;
23 use trader\exchange\binance\ExBroker as BinanceBroker; 24 use trader\exchange\binance\ExBroker as BinanceBroker;
  25 +use trader\exchange\bybit\ExBroker as BybitBroker;
24 use trader\struct\Kline; 26 use trader\struct\Kline;
25 use trader\struct\Order; 27 use trader\struct\Order;
26 use trader\struct\WsData; 28 use trader\struct\WsData;
@@ -47,7 +49,7 @@ class CmBroker @@ -47,7 +49,7 @@ class CmBroker
47 * @see PLAT_BITGET 49 * @see PLAT_BITGET
48 */ 50 */
49 public $plat; 51 public $plat;
50 - private OkxBroker|BinanceBroker $exBroker; 52 + private OkxBroker|BinanceBroker|BybitBroker $exBroker;
51 /** @var SymbolInfo[] $symbolInfos */ 53 /** @var SymbolInfo[] $symbolInfos */
52 public $symbolInfos = []; 54 public $symbolInfos = [];
53 /** @var Pos[] $positions */ 55 /** @var Pos[] $positions */
@@ -67,6 +69,9 @@ class CmBroker @@ -67,6 +69,9 @@ class CmBroker
67 if ($plat == self::PLAT_BINANCE) { 69 if ($plat == self::PLAT_BINANCE) {
68 $exBroker = new BinanceBroker($apiInfo); 70 $exBroker = new BinanceBroker($apiInfo);
69 } 71 }
  72 + if ($plat == self::PLAT_BYBIT) {
  73 + $exBroker = new BybitBroker($apiInfo);
  74 + }
70 $this->exBroker = $exBroker; 75 $this->exBroker = $exBroker;
71 } 76 }
72 public function setWsHost($host) 77 public function setWsHost($host)
@@ -200,13 +205,17 @@ class CmBroker @@ -200,13 +205,17 @@ class CmBroker
200 return; 205 return;
201 } 206 }
202 $symbol = $this->getSymbolOri($symbol, $this->plat); 207 $symbol = $this->getSymbolOri($symbol, $this->plat);
203 - $this->exBroker->klineListen($symbol, $peroid, function ($data) use ($onData) { 208 + $periodOri = $this->getPeriodOri($this->plat, $peroid);
  209 + $this->exBroker->klineListen($symbol, $periodOri, function ($data) use ($onData) {
204 if ($this->plat == self::PLAT_BINANCE) { 210 if ($this->plat == self::PLAT_BINANCE) {
205 $kline = Kline::transferBinance($data); 211 $kline = Kline::transferBinance($data);
206 } 212 }
207 if ($this->plat == self::PLAT_OKX) { 213 if ($this->plat == self::PLAT_OKX) {
208 $kline = Kline::transferOkx($data); 214 $kline = Kline::transferOkx($data);
209 } 215 }
  216 + if ($this->plat == self::PLAT_BYBIT) {
  217 + $kline = Kline::transferBybit($data);
  218 + }
210 $onData($kline); 219 $onData($kline);
211 }); 220 });
212 } 221 }
@@ -220,6 +229,38 @@ class CmBroker @@ -220,6 +229,38 @@ class CmBroker
220 throw new Exception('转换标准交易对错误' . $symbol . ' to ', $symbol); 229 throw new Exception('转换标准交易对错误' . $symbol . ' to ', $symbol);
221 } 230 }
222 } 231 }
  232 + //转换为原始周期
  233 + public function getPeriodOri($platTarget, $period)
  234 + {
  235 + if ($platTarget == self::PLAT_BINANCE) {
  236 + return $period;
  237 + }
  238 + if ($platTarget == self::PLAT_OKX) {
  239 + return str_replace('s', 'S', $period);
  240 + }
  241 + if ($platTarget == self::PLAT_BYBIT) {
  242 + $arr = [
  243 + '1m' => '1',
  244 + '3m' => '3',
  245 + '5m' => '5',
  246 + '15m' => '15',
  247 + '30m' => '30',
  248 + '1h' => '60',
  249 + '2h' => '120',
  250 + '4h' => '240',
  251 + '6h' => '360',
  252 + '12h' => '720',
  253 + '1d' => 'D',
  254 + '1w' => 'W',
  255 + '1M' => 'M',
  256 + ];
  257 + if (!isset($arr[$period])) {
  258 + throw new Exception('周期错误,' . $this->plat . '不支持的周期' . $period);
  259 + }
  260 + return $arr[$period];
  261 + }
  262 + throw new Exception('平台错误' + $platTarget);
  263 + }
223 264
224 //转换为原始交易对 265 //转换为原始交易对
225 public function getSymbolOri($symbol, $platTarget) 266 public function getSymbolOri($symbol, $platTarget)
@@ -231,7 +272,10 @@ class CmBroker @@ -231,7 +272,10 @@ class CmBroker
231 if ($platTarget == self::PLAT_OKX) { 272 if ($platTarget == self::PLAT_OKX) {
232 return str_replace('USDT', '-USDT-SWAP', $symbolSt); 273 return str_replace('USDT', '-USDT-SWAP', $symbolSt);
233 } 274 }
234 - throw new Exception('平台错误' + $platTarget); 275 + if ($platTarget == self::PLAT_BYBIT) {
  276 + return $symbolSt;
  277 + }
  278 + throw new Exception('平台错误' . $platTarget);
235 } 279 }
236 280
237 public function placeOrder(Order $order) 281 public function placeOrder(Order $order)
@@ -11,7 +11,7 @@ use function jytools\getMicrotime; @@ -11,7 +11,7 @@ use function jytools\getMicrotime;
11 11
12 class Api 12 class Api
13 { 13 {
14 - private $host = ''; 14 + private $host = 'https://api.bybit.com';
15 private ApiInfo $apiInfo; 15 private ApiInfo $apiInfo;
16 public function __construct(ApiInfo $apiInfo) 16 public function __construct(ApiInfo $apiInfo)
17 { 17 {
1 <?php 1 <?php
2 2
3 -namespace trader\exchange\binance; 3 +namespace trader\exchange\bybit;
4 4
5 require_once __DIR__ . '/../../struct/ApiInfo.php'; 5 require_once __DIR__ . '/../../struct/ApiInfo.php';
6 require_once __DIR__ . '/Api.php'; 6 require_once __DIR__ . '/Api.php';
@@ -15,7 +15,8 @@ use function jytools\output; @@ -15,7 +15,8 @@ use function jytools\output;
15 class ExBroker 15 class ExBroker
16 { 16 {
17 private $host = 'wss://stream.bybit.com'; 17 private $host = 'wss://stream.bybit.com';
18 - private $path = '/v5/private'; 18 + private $pathPri = '/v5/private'; //账户信息path
  19 + private $pathPub = '/v5/public/linear'; //行情信息path 永续
19 private ApiInfo $apiInfo; 20 private ApiInfo $apiInfo;
20 private BbApi $api; 21 private BbApi $api;
21 private ?Websocket $wsAcc; 22 private ?Websocket $wsAcc;
@@ -39,5 +40,24 @@ class ExBroker @@ -39,5 +40,24 @@ class ExBroker
39 40
40 public function accListen(callable $onData) {} 41 public function accListen(callable $onData) {}
41 42
42 - public function klineListen($symbol, $interval, callable $onData) {} 43 + public function klineListen($symbol, $interval, callable $onData)
  44 + {
  45 + $this->wsKline = new Websocket($this->host . $this->pathPub);
  46 + $this->wsKline->connect(
  47 + function () use ($symbol, $interval) {
  48 + $this->wsKline->push(json_encode([
  49 + 'op' => 'subscribe',
  50 + 'args' => [
  51 + "kline.{$interval}.{$symbol}"
  52 + ]
  53 + ]));
  54 + },
  55 + function ($data) use ($onData) {
  56 + $data = json_decode($data, true);
  57 + if (isset($data['data'])) {
  58 + $onData($data);
  59 + }
  60 + },
  61 + );
  62 + }
43 } 63 }
@@ -34,6 +34,7 @@ class Kline @@ -34,6 +34,7 @@ class Kline
34 'close' => $this->close, 34 'close' => $this->close,
35 'vol' => $this->vol, 35 'vol' => $this->vol,
36 'volQuote' => $this->volQuote, 36 'volQuote' => $this->volQuote,
  37 + 'uts' => $this->uts,
37 ]; 38 ];
38 } 39 }
39 public static function transferOkx($data) 40 public static function transferOkx($data)
@@ -65,4 +66,17 @@ class Kline @@ -65,4 +66,17 @@ class Kline
65 $uts = $data['E']; 66 $uts = $data['E'];
66 return new Kline($time, $open, $high, $low, $close, $vol, $volQuote, $uts); 67 return new Kline($time, $open, $high, $low, $close, $vol, $volQuote, $uts);
67 } 68 }
  69 + public static function transferBybit($data)
  70 + {
  71 + $kline = $data['data'][0];
  72 + $time = $kline['start'];
  73 + $open = $kline['open'];
  74 + $high = $kline['high'];
  75 + $low = $kline['low'];
  76 + $close = $kline['close'];
  77 + $vol = $kline['volume'];
  78 + $volQuote = $kline['turnover'];
  79 + $uts = $kline['timestamp'];
  80 + return new Kline($time, $open, $high, $low, $close, $vol, $volQuote, $uts);
  81 + }
68 } 82 }