Beispiel #1
0
    def sign(self, request: Request) -> Request:
        """
        Generate OKEXo signature.
        """
        # Sign
        timestamp = get_timestamp()
        request.data = json.dumps(request.data)

        if request.params:
            path = request.path + "?" + urlencode(request.params)
        else:
            path = request.path

        msg = timestamp + request.method + path + request.data
        signature = generate_signature(msg, self.secret)

        # Add headers
        request.headers = {
            "OK-ACCESS-KEY": self.key,
            "OK-ACCESS-SIGN": signature,
            "OK-ACCESS-TIMESTAMP": timestamp,
            "OK-ACCESS-PASSPHRASE": self.passphrase,
            "Content-Type": "application/json"
        }
        return request
Beispiel #2
0
    def sign(self, request: Request) -> Request:
        """生成欧易V5签名"""
        # 签名
        timestamp: str = generate_timestamp()
        request.data = json.dumps(request.data)

        if request.params:
            path: str = request.path + "?" + urlencode(request.params)
        else:
            path: str = request.path

        msg: str = timestamp + request.method + path + request.data
        signature: bytes = generate_signature(msg, self.secret)

        # 添加请求头
        request.headers = {
            "OK-ACCESS-KEY": self.key,
            "OK-ACCESS-SIGN": signature,
            "OK-ACCESS-TIMESTAMP": timestamp,
            "OK-ACCESS-PASSPHRASE": self.passphrase,
            "Content-Type": "application/json"
        }

        if self.simulated:
            request.headers["x-simulated-trading"] = "1"

        return request
Beispiel #3
0
 def sign(self, request: Request):
     request.headers = {"Content-Type": "application/json"}
     if request.method == "POST":
         if request.data:
             request.json_data = request.data
             request.data = json.dumps(request.data)
     return request
Beispiel #4
0
    def closeAll(self, symbol, standard_token=None):
        """以市价单的方式全平某个合约的当前仓位,若交易所支持批量下单,使用批量下单接口

        Parameters
        ----------
        symbols : str
            所要平仓的合约代码,多个合约代码用逗号分隔开。
        direction : str, optional
            账户统一到某个币本位上

        Return
        ------
        vtOrderIDs: list of str
        包含平仓操作发送的所有订单ID的列表
        """
        if not standard_token:
            return []
        vtOrderIDs = []
        base_currency, quote_currency = symbol.split("-")
        if base_currency == standard_token:
            path = f'/api/spot/v3/accounts/{str.lower(quote_currency)}'
            side = 'buy'
        elif quote_currency == standard_token:
            path = f'/api/spot/v3/accounts/{str.lower(base_currency)}'
            side = 'sell'
        else:
            return []  # 币对双方都不是指定的本位
        request = Request('GET',
                          path,
                          params=None,
                          callback=None,
                          data=None,
                          headers=None)

        request = self.sign2(request)
        request.extra = {"instrument_id": symbol, "side": side}
        url = self.makeFullUrl(request.path)
        response = requests.get(url,
                                headers=request.headers,
                                params=request.params)
        data = response.json()
        rsp = self.onCloseAll(data, request)
        # rsp: [{'client_oid': '', 'order_id': '2433076975049728', 'result': True}]
        # failed: [{'code': 30024, 'message': 'Parameter value filling error'}]
        for result in rsp:
            if "code" in result.keys():
                self.gateway.writeLog(f'换币失败:{result}', logging.ERROR)
            elif "result" in result.keys():
                if result['result']:
                    vtOrderIDs.append(result['order_id'])
                    self.gateway.writeLog(f'换币成功:{result}')

        return vtOrderIDs
Beispiel #5
0
    def cancelAll(self, symbol=None, orders=None):
        """撤销所有挂单,若交易所支持批量撤单,使用批量撤单接口

        Parameters
        ----------
        symbol : str, optional
            用逗号隔开的多个合约代码,表示只撤销这些合约的挂单(默认为None,表示撤销所有合约的所有挂单)
        orders : str, optional
            用逗号隔开的多个vtOrderID.
            若为None,先从交易所先查询所有未完成订单作为待撤销订单列表进行撤单;
            若不为None,则对给出的对应订单中和symbol参数相匹配的订单作为待撤销订单列表进行撤单。
        Return
        ------
        vtOrderIDs: list of str
        包含本次所有撤销的订单ID的列表
        """
        vtOrderIDs = []
        # 未完成(未成交和部分成交)
        req = {
            'instrument_id': symbol,
        }
        path = f'/api/spot/v3/orders_pending'
        request = Request('GET',
                          path,
                          params=req,
                          callback=None,
                          data=None,
                          headers=None)
        request = self.sign2(request)
        request.extra = orders
        url = self.makeFullUrl(request.path)
        response = requests.get(url,
                                headers=request.headers,
                                params=request.params)
        data = response.json()

        if data:
            rsp = self.onCancelAll(data, request)
            # failed rsp: {'code': 33027, 'message': 'Order has been revoked or revoked'}
            if "code" in rsp.keys():
                self.gateway.writeLog(f"交易所返回{symbol}撤单失败:{rsp['message']}",
                                      logging.ERROR)
                return []
            # rsp: {'eth-usdt':
            # {'result': True, 'client_oid': '',
            # 'order_id': ['2432470701654016', '2432470087389184', '2432469715472384']}}
            for sym, result in rsp.items():
                if result['result']:
                    vtOrderIDs += result['order_id']
                    self.gateway.writeLog(
                        f"交易所返回{sym}撤单成功: ids: {result['order_id']}")
        return vtOrderIDs
Beispiel #6
0
    def onCancelAll(self, data, request):
        orderids = [
            str(order['order_id']) for order in data
            if str(order['state']) in ['0', '1', '3']
        ]
        if request.extra:
            orderids = list(
                set(orderids).intersection(set(request.extra.split(","))))
        for i in range(len(orderids) // 10 + 1):
            orderid = orderids[i * 10:(i + 1) * 10]

            req = {
                'instrument_id': request.params['instrument_id'],
                'order_ids': orderid
            }
            path = f"/api/futures/v3/cancel_batch_orders/{request.params['instrument_id']}"
            # self.addRequest('POST', path, data=req, callback=self.onCancelAll)
            request = Request('POST',
                              path,
                              params=None,
                              callback=None,
                              data=req,
                              headers=None)

            request = self.sign(request)
            url = self.makeFullUrl(request.path)
            response = requests.post(url,
                                     headers=request.headers,
                                     data=request.data)
            return response.json()
Beispiel #7
0
    def onCloseAll(self, data, request):
        l = []

        def _response(request, l):
            request = self.sign(request)
            url = self.makeFullUrl(request.path)
            response = requests.post(url,
                                     headers=request.headers,
                                     data=request.data)
            l.append(response.json())
            return l

        for holding in data['holding']:
            path = '/api/swap/v3/order'
            closeDirectionMap = {"long": 3, "short": 4}

            req = {
                'client_oid': None,
                'instrument_id': holding['instrument_id'],
                'type': closeDirectionMap[holding['side']],
                'price': holding['avg_cost'],
                'size': holding['avail_position'],
                'match_price': '1'
            }

            request = Request('POST',
                              path,
                              params=None,
                              callback=None,
                              data=req,
                              headers=None)
            l = _response(request, l)
        return l
Beispiel #8
0
    def sign(self, request: Request):
        """
        Generate ByBit signature.
        """
        request.headers = {"Referer": "vn.py"}

        if request.method == "GET":
            api_params = request.params
            if api_params is None:
                api_params = request.params = {}
        else:
            api_params = request.data
            if api_params is None:
                api_params = request.data = {}

        api_params["api_key"] = self.key
        api_params["recv_window"] = 30 * 1000
        api_params["timestamp"] = generate_timestamp(-5)

        data2sign = "&".join(
            [f"{k}={v}" for k, v in sorted(api_params.items())])
        signature = sign(self.secret, data2sign.encode())
        api_params["sign"] = signature

        return request
Beispiel #9
0
    def onCloseAll(self, data, request):
        l = []

        def _response(request, l):
            request = self.sign(request)
            url = self.makeFullUrl(request.path)
            response = requests.post(url,
                                     headers=request.headers,
                                     data=request.data)
            l.append(response.json())
            return l

        req = {
            'client_oid': None,
            'instrument_id': request.extra['instrument_id'],
            'type': "market",
            'side': request.extra['side'],
            'notional': data['available'],  # buy amount
            'size': data['available']  # sell quantity
        }

        if self.leverage > 0:
            req["margin_trading"] = 2
        else:
            req["margin_trading"] = 1
        path = '/api/spot/v3/orders'
        request = Request('POST',
                          path,
                          params=None,
                          callback=None,
                          data=req,
                          headers=None)
        l = _response(request, l)
        return l
Beispiel #10
0
    def onCancelAll(self, data, request):
        orderids = [
            str(order['order_id']) for order in data
            if order['status'] == 'open' or order['status'] == 'part_filled'
        ]
        if request.extra:
            orderids = list(
                set(orderids).intersection(set(request.extra.split(","))))
        for i in range(len(orderids) // 10 + 1):
            orderid = orderids[i * 10:(i + 1) * 10]

            req = [{
                'instrument_id': str.lower(request.params['instrument_id']),
                'order_ids': orderid
            }]
            path = "/api/spot/v3/cancel_batch_orders"
            # self.addRequest('POST', path, data=req, callback=self.onCancelAll)
            request = Request('POST',
                              path,
                              params=None,
                              callback=None,
                              data=req,
                              headers=None)

            request = self.sign(request)
            url = self.makeFullUrl(request.path)
            response = requests.post(url,
                                     headers=request.headers,
                                     data=request.data)
            return response.json()
Beispiel #11
0
    def closeAll(self, symbol, direction=None):
        """以市价单的方式全平某个合约的当前仓位,若交易所支持批量下单,使用批量下单接口

        Parameters
        ----------
        symbols : str
            所要平仓的合约代码,多个合约代码用逗号分隔开。
        direction : str, optional
            所要平仓的方向,()
默认为None,即在两个方向上都进行平仓,否则只在给出的方向上进行平仓
        Return
        ------
        vtOrderIDs: list of str
        包含平仓操作发送的所有订单ID的列表
        """
        vtOrderIDs = []
        req = {
            'instrument_id': symbol,
        }
        path = f'/api/swap/v3/{symbol}/position/'
        request = Request('GET',
                          path,
                          params=req,
                          callback=None,
                          data=None,
                          headers=None)

        request = self.sign2(request)
        request.extra = direction
        url = self.makeFullUrl(request.path)
        response = requests.get(url,
                                headers=request.headers,
                                params=request.params)
        data = response.json()
        if data['holding']:
            rsp = self.onCloseAll(data, request)
            # failed:{'error_message': 'Incorrect order size', 'result': 'true',
            #      'error_code': '35012', 'order_id': '-1'}
            # rsp: {'error_message': '', 'result': 'true', 'error_code': '0',
            #  'order_id': '66-a-4ec048f15-0'}
            for result in rsp:
                if not result['error_message']:
                    vtOrderIDs.append(result['order_id'])
                    self.gateway.writeLog(f'平仓成功:{result}')
                else:
                    self.gateway.writeLog(f'平仓失败:{result}', logging.ERROR)
        return vtOrderIDs
Beispiel #12
0
    def sign(self, request: Request):
        """
        Sign Bitstamp request.
        """
        if request.method == "GET":
            return request

        timestamp = str(int(round(time.time() * 1000)))
        nonce = str(uuid.uuid4())
        content_type = "application/x-www-form-urlencoded"

        # Empty post data leads to API0020 error,
        # so use this offset dict instead.
        if not request.data:
            request.data = {"offset": "1"}

        payload_str = urlencode(request.data)

        message = "BITSTAMP " + self.key + \
            request.method + \
            "www.bitstamp.net/api/v2" + \
            request.path + \
            "" + \
            content_type + \
            nonce + \
            timestamp + \
            "v2" + \
            payload_str
        message = message.encode("utf-8")

        signature = hmac.new(
            self.secret,
            msg=message,
            digestmod=hashlib.sha256
        ).hexdigest().upper()

        request.headers = {
            "X-Auth": "BITSTAMP " + self.key,
            "X-Auth-Signature": signature,
            "X-Auth-Nonce": nonce,
            "X-Auth-Timestamp": timestamp,
            "X-Auth-Version": "v2",
            "Content-Type": content_type
        }
        request.data = payload_str

        return request
Beispiel #13
0
    def _process_request(
        self, request: Request
    ):
        """
        Bistamp API server does not support keep-alive connection.
        So when using session.request will cause header related error.
        Reimplement this method to use requests.request instead.
        """
        try:
            request = self.sign(request)

            url = self.make_full_url(request.path)

            response = requests.request(
                request.method,
                url,
                headers=request.headers,
                params=request.params,
                data=request.data,
                proxies=self.proxies,
            )
            request.response = response
            status_code = response.status_code
            if status_code // 100 == 2:  # 2xx codes are all successful
                if status_code == 204:
                    json_body = None
                else:
                    json_body = response.json()

                request.callback(json_body, request)
                request.status = RequestStatus.success
            else:
                request.status = RequestStatus.failed

                if request.on_failed:
                    request.on_failed(status_code, request)
                else:
                    self.on_failed(status_code, request)
        except Exception:
            request.status = RequestStatus.error
            t, v, tb = sys.exc_info()
            if request.on_error:
                request.on_error(t, v, tb, request)
            else:
                self.on_error(t, v, tb, request)
Beispiel #14
0
 def cancelAll(self, symbol=None, orders=None):
     """撤销所有挂单,若交易所支持批量撤单,使用批量撤单接口
     Parameters
     ----------
     symbol : str, optional
         用逗号隔开的多个合约代码,表示只撤销这些合约的挂单(默认为None,表示撤销所有合约的所有挂单)
     orders : str, optional
         用逗号隔开的多个vtOrderID.
         若为None,先从交易所先查询所有未完成订单作为待撤销订单列表进行撤单;
         若不为None,则对给出的对应订单中和symbol参数相匹配的订单作为待撤销订单列表进行撤单。
     Return
     ------
     vtOrderIDs: list of str
     包含本次所有撤销的订单ID的列表
     """
     vtOrderIDs = []
     symbol = self.contractMapReverse[symbol]
     # 未完成(包含未成交和部分成交)
     req = {'instrument_id': symbol, 'state': 6}
     path = f'/api/futures/v3/orders/{symbol}'
     request = Request('GET',
                       path,
                       params=req,
                       callback=None,
                       data=None,
                       headers=None)
     request = self.sign2(request)
     request.extra = orders
     url = self.makeFullUrl(request.path)
     response = requests.get(url,
                             headers=request.headers,
                             params=request.params)
     data = response.json()
     if data['result'] and data['order_info']:
         data = self.onCancelAll(data['order_info'], request)
         #{'result': True,
         # 'order_ids': ['2432685818596352', '2432686510479360'],
         # 'instrument_id': 'ETH-USD-190329'}
         if data['result']:
             vtOrderIDs += str(data['order_ids'])
             self.gateway.writeLog(
                 f"交易所返回{str(data['instrument_id'])} 撤单成功: ids: {str(data['order_ids'])}"
             )
     return vtOrderIDs
Beispiel #15
0
    def cancelAll(self, symbol=None, orders=None):
        """撤销所有挂单,若交易所支持批量撤单,使用批量撤单接口

        Parameters
        ----------
        symbol : str, optional
            用逗号隔开的多个合约代码,表示只撤销这些合约的挂单(默认为None,表示撤销所有合约的所有挂单)
        orders : str, optional
            用逗号隔开的多个vtOrderID.
            若为None,先从交易所先查询所有未完成订单作为待撤销订单列表进行撤单;
            若不为None,则对给出的对应订单中和symbol参数相匹配的订单作为待撤销订单列表进行撤单。
        Return
        ------
        vtOrderIDs: list of str
        包含本次所有撤销的订单ID的列表
        """
        vtOrderIDs = []
        # 未完成(包含未成交和部分成交)
        req = {'state': 6}
        path = f'/api/swap/v3/orders/{symbol}'
        request = Request('GET',
                          path,
                          params=req,
                          callback=None,
                          data=None,
                          headers=None)
        request = self.sign2(request)
        request.extra = orders
        url = self.makeFullUrl(request.path)
        response = requests.get(url,
                                headers=request.headers,
                                params=request.params)
        data = response.json()
        if data['order_info']:
            data = self.onCancelAll(data['order_info'], request)
            # {'client_oids': [],
            # 'ids': ['66-7-4ebc9281f-0', '66-8-4ebc91cfa-0'],
            # 'instrument_id': 'ETH-USD-SWAP', 'result': 'true'}
            if data['result'] == 'true':
                vtOrderIDs += data['ids']
                self.gateway.writeLog(f"交易所返回{symbol}撤单成功: ids: {data['ids']}")
        return vtOrderIDs
Beispiel #16
0
    def sign(self, request: Request) -> Request:
        """
        Generate HUOBI signature.
        """
        request.headers = {
            "User-Agent":
            "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36"
        }
        params_with_signature = create_signature(self.key, request.method,
                                                 self.host, request.path,
                                                 self.secret, request.params)
        request.params = params_with_signature

        if request.method == "POST":
            request.headers["Content-Type"] = "application/json"

            if request.data:
                request.data = json.dumps(request.data)

        return request
Beispiel #17
0
    def closeAll(self, symbol, direction=None):
        """以市价单的方式全平某个合约的当前仓位,若交易所支持批量下单,使用批量下单接口
        Parameters
        ----------
        symbols : str
            所要平仓的合约代码,多个合约代码用逗号分隔开。
        direction : str, optional
            所要平仓的方向,(默认为None,即在两个方向上都进行平仓,否则只在给出的方向上进行平仓)
        Return
        ------
        vtOrderIDs: list of str
        包含平仓操作发送的所有订单ID的列表
        """
        vtOrderIDs = []
        symbol = self.contractMapReverse[symbol]
        req = {
            'instrument_id': symbol,
        }
        path = f'/api/futures/v3/{symbol}/position/'
        request = Request('GET',
                          path,
                          params=req,
                          callback=None,
                          data=None,
                          headers=None)

        request = self.sign2(request)
        request.extra = direction
        url = self.makeFullUrl(request.path)
        response = requests.get(url,
                                headers=request.headers,
                                params=request.params)
        data = response.json()
        if data['result'] and data['holding']:
            data = self.onCloseAll(data, request)
            for result in data:
                if result['result']:
                    vtOrderIDs.append(result['order_id'])
                    self.gateway.writeLog(f'平仓成功:{result}')
        return vtOrderIDs
Beispiel #18
0
    def sign(self, request: Request) -> Request:
        """
        Generate SUGAR signature.
        """
        signature = self.create_signature(request.data)
        request_time = datetime.strftime(datetime.now(),"%Y-%m-%d %H:%M:%S.%f")

        request_data = {
            "requestHeader":{
                "token": self.token,
                "sign": signature,
                "yqMemberId": self.open_account,
                "merRequestNo": request_time,
                "merRequestTime": request_time[:-7]
            },
            "requestBody": request.data
        }

        request.headers = {"Content-Type": "application/json"}
        request.data = json.dumps(request_data)

        return request
Beispiel #19
0
    def sign(self, request: Request) -> Request:
        """
        Generate BINANCE signature.
        """
        security = request.data["security"]
        if security == Security.NONE:
            request.data = None
            return request

        if request.params:
            path = request.path + "?" + urllib.parse.urlencode(request.params)
        else:
            request.params = dict()
            path = request.path

        if security == Security.SIGNED:
            timestamp = int(time.time() * 1000)

            if self.time_offset > 0:
                timestamp -= abs(self.time_offset)
            elif self.time_offset < 0:
                timestamp += abs(self.time_offset)

            request.params["timestamp"] = timestamp

            query = urllib.parse.urlencode(sorted(request.params.items()))
            signature = hmac.new(self.secret, query.encode("utf-8"),
                                 hashlib.sha256).hexdigest()

            query += "&signature={}".format(signature)
            path = request.path + "?" + query

        request.path = path
        request.params = {}
        request.data = {}

        # Add headers
        headers = {
            "Content-Type": "application/x-www-form-urlencoded",
            "Accept": "application/json",
            "X-MBX-APIKEY": self.key,
            "Connection": "close"
        }

        if security in [Security.SIGNED, Security.API_KEY]:
            request.headers = headers

        return request
Beispiel #20
0
    def onCloseAll(self, data, request):
        l = []

        def _response(request, l):
            request = self.sign(request)
            url = self.makeFullUrl(request.path)
            response = requests.post(url,
                                     headers=request.headers,
                                     data=request.data)
            l.append(response.json())
            return l

        for holding in data['holding']:
            path = '/api/futures/v3/order'
            req_long = {
                'client_oid': None,
                'instrument_id': holding['instrument_id'],
                'type': '3',
                'price': holding['long_avg_cost'],
                'size': str(holding['long_avail_qty']),
                'match_price': '1',
                'leverage': self.leverage,
            }
            req_short = {
                'client_oid': None,
                'instrument_id': holding['instrument_id'],
                'type': '4',
                'price': holding['short_avg_cost'],
                'size': str(holding['short_avail_qty']),
                'match_price': '1',
                'leverage': self.leverage,
            }
            if request.extra and request.extra == constant.DIRECTION_LONG and int(
                    holding['long_avail_qty']) > 0:
                # 多仓可平
                request = Request('POST',
                                  path,
                                  params=None,
                                  callback=None,
                                  data=req_long,
                                  headers=None)
                l = _response(request, l)
            elif request.extra and request.extra == constant.DIRECTION_SHORT and int(
                    holding['short_avail_qty']) > 0:
                # 空仓可平
                request = Request('POST',
                                  path,
                                  params=None,
                                  callback=None,
                                  data=req_short,
                                  headers=None)
                l = _response(request, l)
            elif request.extra is None:
                if int(holding['long_avail_qty']) > 0:
                    # 多仓可平
                    request = Request('POST',
                                      path,
                                      params=None,
                                      callback=None,
                                      data=req_long,
                                      headers=None)
                    l = _response(request, l)
                if int(holding['short_avail_qty']) > 0:
                    # 空仓可平
                    request = Request('POST',
                                      path,
                                      params=None,
                                      callback=None,
                                      data=req_short,
                                      headers=None)
                    l = _response(request, l)
        return l