BinanceSpot.php 8.8 KB
<?php

namespace jiaoyin;

/*
    binance现货接口
*/

class BinanceSpot
{
    static private string $host   = 'https://api.binance.com';
    private string        $apikey = '';
    private string        $secret = '';

    public function __construct($apikey = '', $secret = '', $host = '')
    {
        $this->apikey = $apikey;
        $this->secret = $secret;
        if (!empty($host)) {
            self::$host = $host;
        }
    }

    static private function createUrl($path): string
    {
        return self::$host . $path;
    }

    static private function createHeader($apikey): array
    {
        return ["X-MBX-APIKEY:" . $apikey];
    }

    static private function createSign($secret, $param)
    {
        $len = count($param);
        if ($len == 0) {
            //            output('param 为空,签名失败');
            return $param;
        }
        $paramStr = http_build_query($param);
        return hash_hmac('sha256', $paramStr, $secret);
    }

    private function requestAccount($method, $path, $param)
    {
        $url                = $this->createUrl($path);
        $param['timestamp'] = getMicrotime();
        $param['signature'] = $this->createSign($this->secret, $param);
        $header             = $this->createHeader($this->apikey);
        if (!in_array(strtoupper($method), ['GET', 'POST', 'DELETE'])) {
            output('请求方法错误', $method, $path, $param);
            return 0;
        }
        $data = json_encode([]);
        if (strtoupper($method) == 'POST') {
            $data = Curl::httpPost($url, $param, $header);
        }
        if (strtoupper($method) == 'GET') {
            $data = Curl::httpGet($url, $param, $header);
        }
        if (strtoupper($method) == 'DELETE') {
            $data = Curl::httpDelete($url, $param, $header);
        }
        return json_decode($data, true);
    }
    private function requestListenKey($method, $path, $param)
    {
        $url                = $this->createUrl($path);
        //        $param['timestamp'] = getMicrotime();
        $param['signature'] = $this->createSign($this->secret, $param);
        $header             = $this->createHeader($this->apikey);
        if (!in_array(strtoupper($method), ['GET', 'POST', 'DELETE'])) {
            output('请求方法错误', $method, $path, $param);
            return 0;
        }
        $data = json_encode([]);
        if (strtoupper($method) == 'POST') {
            $data = Curl::httpPost($url, $param, $header);
        }
        if (strtoupper($method) == 'GET') {
            $data = Curl::httpGet($url, $param, $header);
        }
        if (strtoupper($method) == 'DELETE') {
            $data = Curl::httpDelete($url, $param, $header);
        }
        return json_decode($data, true);
    }

    static private function requestMarket($method, $path, $param)
    {
        $url = self::createUrl($path);
        if (!in_array(strtoupper($method), ['GET', 'POST', 'DELETE'])) {
            output('请求方法错误', $method, $path, $param);
            return 0;
        }
        $data = json_encode([]);
        if (strtoupper($method) == 'POST') {
            $data = Curl::httpPost($url, $param);
        }
        if (strtoupper($method) == 'GET') {
            $data = Curl::httpGet($url, $param);
        }
        if (strtoupper($method) == 'DELETE') {
            $data = Curl::httpDelete($url, $param);
        }
        return json_decode($data, true);
    }

    /**
     * @param string $path (binance api path)
     * @param string $method (GET POST DELETE)
     * @param array $param (binance api param)
     * @param int $type (=1:行情等接口,不需要签名;=2:账户等接口需要签名)
     * @return array|int|mixed
     */
    public function request(string $path, string $method, array $param, int $type = 1)
    {
        if ($type == 2) {
            return self::requestAccount($method, $path, $param);
        } else if ($type == 1) {
            return self::requestMarket($method, $path, $param);
        } else {
            return ['code' => 1000, 'msg' => 'type参数错误'];
        }
    }

    //查询用户万向划转历史
    public function getTransfer($param)
    {
        $path   = '/sapi/v1/asset/transfer';
        $method = 'GET';
        return $this->requestAccount($method, $path, $param);
    }
    //查询子账户划转历史 (仅适用子账户)
    public function  subUserHistory($param)
    {
        $path = '/sapi/v1/sub-account/transfer/subUserHistory';
        $method = 'GET';
        return $this->requestAccount($method, $path, $param);
    }
    //合约资金划转
    public function  futuresTransfer($param)
    {
        $path = '/sapi/v1/futures/transfer';
        $method = 'POST';
        return $this->requestAccount($method, $path, $param);
    }
    //子账户向子账户划转
    public function  subToSub($param)
    {
        $path = '/sapi/v1/sub-account/transfer/subToSub';
        $method = 'POST';
        return $this->requestAccount($method, $path, $param);
    }
    //获取用户资产
    public function  getUserAsset($param)
    {
        $path = '/sapi/v3/asset/getUserAsset';
        $method = 'POST';
        return $this->requestAccount($method, $path, $param);
    }
    //查询子账户API Key IP白名单 (适用母账户)
    public function  ipRestrictionQuery($param)
    {
        $path = '/sapi/v1/sub-account/subAccountApi/ipRestriction';
        $method = 'GET';
        return $this->requestAccount($method, $path, $param);
    }
    //删除子账户API Key IP白名单 (适用母账户)
    public function  ipRestrictionDelete($param)
    {
        $path = '/sapi/v1/sub-account/subAccountApi/ipRestriction/ipList';
        $method = 'DELETE';
        return $this->requestAccount($method, $path, $param);
    }
    //为子账户API Key增加IP白名单 (适用母账户)
    public function  ipRestrictionAdd($param)
    {
        $path = '/sapi/v2/sub-account/subAccountApi/ipRestriction';
        $method = 'POST';
        return $this->requestAccount($method, $path, $param);
    }
    //查询子账户Margin/Futures状态 (适用主账户)
    public function  subAccountStatus($param)
    {
        $path = '/sapi/v1/sub-account/status';
        $method = 'GET';
        return $this->requestAccount($method, $path, $param);
    }
    //生成 Listen Key (USER_STREAM)
    public function  listenKey($param)
    {
        $path = '/api/v3/userDataStream';
        $method = 'POST';
        return $this->requestListenKey($method, $path, $param);
    }
    //延长 Listen Key 有效期 (USER_STREAM)
    public function  listenKeyDelay($param)
    {
        $path = '/api/v3/userDataStream';
        $method = 'PUT';
        return $this->requestListenKey($method, $path, $param);
    }
    public function  order($param)
    {
        $path = '/api/v3/order';
        $method = 'POST';
        return $this->requestAccount($method, $path, $param);
    }

    public function cancelOrderById($param)
    {
        $path = '/api/v3/order';
        $method = 'DELETE';
        return $this->requestAccount($method, $path, $param);
    }

    public function openOrders($param)
    {
        $path = '/api/v3/openOrders';
        $method = 'GET';
        return $this->requestAccount($method, $path, $param);
    }

    /*
     * ==================================
     * 以下杠杆账户接口
     * ==================================
     */
    //杠杆账户生成 Listen Key (USER_STREAM)
    public function  listenKeyMargin($param)
    {
        $path = '/sapi/v1/userDataStream';
        $method = 'POST';
        return $this->requestListenKey($method, $path, $param);
    }
    //杠杆账户下单
    public function orderMargin($param)
    {
        $path = '/sapi/v1/margin/order';
        $method = 'POST';
        return $this->requestAccount($method, $path, $param);
    }
    //杠杆账户撤销订单 (TRADE)
    public function cancelOrderMargin($param)
    {
        $path = '/sapi/v1/margin/order';
        $method = 'DELETE';
        return $this->requestAccount($method, $path, $param);
    }
    //杠杆账户订单列表
    public function openOrdersMargin($param)
    {
        $path = '/sapi/v1/margin/openOrders';
        $method = 'GET';
        return $this->requestAccount($method, $path, $param);
    }
    //调整全仓最大杠杆 (USER_DATA)
    public function maxLeverageMargin($param)
    {
        $path = '/sapi/v1/margin/max-leverage';
        $method = 'POST';
        return $this->requestAccount($method, $path, $param);
    }

    /*
     * ==================================
     * 以下公共接口,无限apikey
     * ==================================
     */
    //24小时成交数据
    //    static public function ticker24hr($param = [])
    //    {
    //        $path   = '/fapi/v1/ticker/24hr';
    //        $method = 'GET';
    //        return self::requestMarket($method, $path, $param);
    //    }

}