作者 karlet

faet:bybit初始化交易对信息

... ... @@ -12,13 +12,13 @@ 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");
$wsHost = "ws://bbws.keetu.com";
$restHost = "http://bbapi.keetu.com";
$broker = new CmBroker(CmBroker::PLAT_BYBIT, $apiInfo, $wsHost, $restHost);
// $broker->accListen(function ($data) {
// // var_dump($data);
// });
output("开始监听");
$broker->klineListen("BTCUSDT", "1m", function ($data) {
output($data->toArray());
});
... ...
... ... @@ -62,7 +62,7 @@ class CmBroker
public $uid;
public function __construct($plat, ApiInfo $apiInfo)
public function __construct($plat, ApiInfo $apiInfo, $wsHost = null, $restHost = null)
{
$this->plat = $plat;
$exBroker = null;
... ... @@ -76,15 +76,14 @@ class CmBroker
$exBroker = new BybitBroker($apiInfo);
}
$this->exBroker = $exBroker;
$this->init();
if ($wsHost) {
$this->exBroker->setWsHost($wsHost);
}
public function setWsHost($host)
{
$this->exBroker->setWsHost($host);
if ($restHost) {
$this->exBroker->setRestHost($restHost);
}
public function setRestHost($host)
{
$this->exBroker->setRestHost($host);
var_dump("初始化。。。。");
$this->init();
}
public function setName($name)
{
... ... @@ -355,7 +354,7 @@ class CmBroker
private function initSymbolInfos($count = 1)
{
if ($count > 3) {
new Exception("broker初始化交易对信息失败");
throw new Exception("broker初始化交易对信息失败");
}
if ($this->plat == self::PLAT_OKX) {
//获取所有USDT SWAP 交易对
... ... @@ -384,6 +383,19 @@ class CmBroker
}
$this->symbolInfos = $infos;
}
if ($this->plat == self::PLAT_BYBIT) {
$res = $this->exBroker->getSymbolInfos();
$infos = [];
foreach ($res as $key => $value) {
if ($value['quoteCoin'] == 'USDT' && $value['status'] == 'Trading' && $value['contractType'] == 'LinearPerpetual') {
$info = SymbolInfo::transferBybit($value, function ($symbol) {
return $this->getSymbolSt($symbol);
});
$infos[$info->symbol] = $info;
}
}
$this->symbolInfos = $infos;
}
if (count($this->symbolInfos) == 0) {
$this->initSymbolInfos($count + 1);
return;
... ...
... ... @@ -4,6 +4,7 @@ namespace trader\exchange\bybit;
require_once __DIR__ . '/../../struct/ApiInfo.php';
require_once __DIR__ . '/../../../jytools/func.php';
require_once __DIR__ . '/../../../jytools/Curl.php';
use trader\struct\ApiInfo;
use jytools\Curl;
... ... @@ -13,12 +14,115 @@ class Api
{
private $host = 'https://api.bybit.com';
private ApiInfo $apiInfo;
public function __construct(ApiInfo $apiInfo)
{
$this->apiInfo = $apiInfo;
}
public function setHost($host)
{
$this->host = $host;
}
//----------- public interface ------------
// 获取交易对信息
public function instruments($param)
{
$path = "/v5/market/instruments-info";
$method = 'GET';
return $this->request($path, $method, $param);
}
// 获取K线数据
public function klines($param)
{
$path = "/v5/market/kline";
$method = 'GET';
return $this->request($path, $method, $param);
}
//----------- private interface ------------
// 下单
public function placeOrder($param)
{
$path = '/v5/order/create';
$method = 'POST';
return $this->request($path, $method, $param, true);
}
// 查询持仓
public function getPositions($param)
{
$path = '/v5/position/list';
$method = 'GET';
return $this->request($path, $method, $param, true);
}
// 设置杠杆
public function setLeverage($param)
{
$path = '/v5/position/set-leverage';
$method = 'POST';
return $this->request($path, $method, $param, true);
}
// 查询账户余额
public function accountBalance($param)
{
$path = '/v5/account/wallet-balance';
$method = 'GET';
return $this->request($path, $method, $param, true);
}
//-------------------------------------
private function createSign($timestamp, $method, $path, $params = [])
{
$recv_window = '5000';
$queryString = '';
if ($method == 'GET' && !empty($params)) {
$queryString = http_build_query($params);
}
$sign_str = $timestamp . $this->apiInfo->key . $recv_window . $path . $queryString;
if ($method == 'POST' && !empty($params)) {
$sign_str .= json_encode($params);
}
return hash_hmac('sha256', $sign_str, $this->apiInfo->secret);
}
private function request($path, $method, $param, $auth = false)
{
$header = [];
$body = '';
$fullPath = $path;
$timestamp = getMicrotime() * 1000;
if ($method == 'GET' && !empty($param)) {
$fullPath = $path . '?' . http_build_query($param);
} else {
$header[] = 'Content-Type: application/json';
$body = json_encode($param);
}
if ($auth) {
$header[] = 'X-BAPI-API-KEY: ' . $this->apiInfo->key;
$header[] = 'X-BAPI-TIMESTAMP: ' . $timestamp;
$header[] = 'X-BAPI-RECV-WINDOW: 5000';
$header[] = 'X-BAPI-SIGN: ' . $this->createSign($timestamp, $method, $path, $param);
}
$url = $this->host . $path;
$result = "";
if ($method == 'POST') {
$result = Curl::httpPost($url, $param, $header);
} else {
$result = Curl::httpGet($url, $param, $header);
}
return json_decode($result, true);
}
}
... ...
... ... @@ -60,4 +60,13 @@ class ExBroker
},
);
}
public function getSymbolInfos()
{
$res = $this->api->instruments(["category" => "linear"]);
if ($res['retCode'] != '0') {
output('bybit获取所有交易对信息失败');
return [];
}
return $res['result']['list'];
}
}
... ...
... ... @@ -80,6 +80,20 @@ class SymbolInfo
$info = new SymbolInfo($symbolOri, $symbolSt, $ctVal, $pricePrec, $qtyPrec, $lotPrec, $minLot, $minQty, $mul);
return $info;
}
public static function transferBybit($data, callable $getSymbolSt): SymbolInfo
{
$symbolOri = $data['symbol'];
$symbolSt = $getSymbolSt($symbolOri); //转换为标准交易对
$ctVal = 1;
$pricePrec = getPrecision($data['priceFilter']['tickSize']);
$qtyPrec = getPrecision($data['lotSizeFilter']['qtyStep']);
$lotPrec = $qtyPrec;
$minQty = $data['lotSizeFilter']['minOrderQty'];
$minLot = $minQty * $ctVal;
$mul = self::extractNumber($symbolOri);
$info = new SymbolInfo($symbolOri, $symbolSt, $ctVal, $pricePrec, $qtyPrec, $lotPrec, $minLot, $minQty, $mul);
return $info;
}
public static function extractNumber($str)
{
// 示例
... ...