简体   繁体   English

如何使用 python 在币安上做空资产

[英]How to short an asset on binance with python

Is there a way with python to open a short position and to close it for a certain asset? python 有没有办法打开一个空头 position 并为某个资产关闭它?

I found this for normal orders, but it is not to short a position.我发现这是正常订单,但不是做空 position。 Just to buy normally:正常购买:

order = client.create_test_order(
symbol='BNBBTC',
side=Client.SIDE_BUY,
type=Client.ORDER_TYPE_MARKET,
quantity=100)
print("order", order)

Method 1: Using ccxt library:方法一:使用ccxt库:

# -*- coding: utf-8 -*-

import os
import sys
from pprint import pprint

root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.path.append(root + '/python')

import ccxt  # noqa: E402

print('CCXT Version:', ccxt.__version__)

# Must read before your start:
#
#     - https://github.com/ccxt/ccxt/wiki/Manual
#     - https://github.com/ccxt/ccxt/wiki/Manual#implicit-api-methods
#     - https://github.com/ccxt/ccxt/wiki/Manual#unified-api
#
# In short, Binance's API is structured as follows and you should understand
# the meaning and the difference between ISOLATED vs CROSSED margin mode and
# the difference between Hedged positions vs One-way positions.
#
#     - wapi: funding for withdrawals and deposits (wapi)
#     - api: spot (api)
#     - sapi: spot margin
#     - CROSSED margin mode
#         - Hedged positions
#         - One-way positions
#     - ISOLATED margin mode
#         - Hedged positions
#         - One-way positions
#     - fapi: swap/perpetual futures margin
#     - CROSSED margin mode
#         - Hedged positions
#         - One-way positions
#     - ISOLATED margin mode
#         - Hedged positions
#         - One-way positions
#     - dapi: classic delivery futures margin
#     - CROSSED margin mode
#         - Hedged positions
#         - One-way positions
#     - ISOLATED margin mode
#         - Hedged positions
#         - One-way positions
#
# You should pick the following:
#
#     1. which API you want to trade (fapi, i believe)
#     2. which specific margin mode you want (CROSSED or ISOLATED)
#     3. which specific position mode you want (Hedged or One-way)
#
# Differences in margin modes:
#
#     - CROSSED margin mode = you have one futures-margin account for all your positions,
#       if some position requires too much margin, your entire account is affected,
#       leaving less margin for the other positions,
#       thus you share the same margin _"across"_ all your positions
#
#     - ISOLATED margin mode = you have separate futures-margin for each of your positions,
#       if some position runs out of margin the other positions are not affected,
#       thus your positions are _"isolated"_ from one another
#
# Difference in position modes:
#
#     - One-way position mode - when you're in this mode
#       there's no such things as LONG or SHORT positions.
#       You just buy or sell a number of contracts, and
#       if the price goes down, your PnL goes negative,
#       if the price goes up, your PnL is positive.
#       Thus, the position operates `BOTH` ways, both long and short at the same time,
#       the notion of "long" and "short" is abstracted away from you,
#       so there's only one way the position can go and that way is called "BOTH".
#
#     - Hedge mode - you either enter a `LONG` position or a `SHORT` position and
#       your PnL calculation rules depend on that
#       so there's a number of ways a position can go
#
# Which specific mode of trading (margin mode + position mode) do you want?


def table(values):
    first = values[0]
    keys = list(first.keys()) if isinstance(first, dict) else range(0, len(first))
    widths = [max([len(str(v[k])) for v in values]) for k in keys]
    string = ' | '.join(['{:<' + str(w) + '}' for w in widths])
    return "\n".join([string.format(*[str(v[k]) for k in keys]) for v in values])


exchange = ccxt.binance({
    'apiKey': 'YOUR_API_KEY',
    'secret': 'YOUR_SECRET',
    'options': {
        'defaultType': 'future',
    },
})

markets = exchange.load_markets()

symbol = 'BTC/USDT'  # YOUR SYMBOL HERE
market = exchange.market(symbol)

exchange.verbose = True  # UNCOMMENT THIS AFTER LOADING THE MARKETS FOR DEBUGGING

print('----------------------------------------------------------------------')

print('Fetching your balance:')
response = exchange.fetch_balance()
pprint(response['total'])  # make sure you have enough futures margin...
# pprint(response['info'])  # more details

print('----------------------------------------------------------------------')

# https://binance-docs.github.io/apidocs/futures/en/#position-information-v2-user_data

print('Getting your positions:')
response = exchange.fapiPrivateV2_get_positionrisk()
print(table(response))

print('----------------------------------------------------------------------')

# https://binance-docs.github.io/apidocs/futures/en/#change-position-mode-trade

print('Getting your current position mode (One-way or Hedge Mode):')
response = exchange.fapiPrivate_get_positionside_dual()
if response['dualSidePosition']:
    print('You are in Hedge Mode')
else:
    print('You are in One-way Mode')

print('----------------------------------------------------------------------')

# print('Setting your position mode to One-way:')
# response = exchange.fapiPrivate_post_positionside_dual({
#     'dualSidePosition': False,
# })
# print(response)

# print('Setting your positions to Hedge mode:')
# response = exchange.fapiPrivate_post_positionside_dual({
#     'dualSidePosition': True,
# })
# print(response)

# print('----------------------------------------------------------------------')

# # https://binance-docs.github.io/apidocs/futures/en/#change-margin-type-trade

# print('Changing your', symbol, 'position margin mode to CROSSED:')
# response = exchange.fapiPrivate_post_margintype({
#     'symbol': market['id'],
#     'marginType': 'CROSSED',
# })
# print(response)

# print('Changing your', symbol, 'position margin mode to ISOLATED:')
# response = exchange.fapiPrivate_post_margintype({
#     'symbol': market['id'],
#     'marginType': 'ISOLATED',
# })
# print(response)

# print('----------------------------------------------------------------------')

# # https://binance-docs.github.io/apidocs/spot/en/#new-future-account-transfer-futures

# code = 'USDT'
# amount = 123.45
# currency = exchange.currency(code)

# print('Moving', code, 'funds from your spot account to your futures account:')

# response = exchange.sapi_post_futures_transfer({
#     'asset': currency['id'],
#     'amount': exchange.currency_to_precision(code, amount),
#     # 1: transfer from spot account to USDT-Ⓜ futures account.
#     # 2: transfer from USDT-Ⓜ futures account to spot account.
#     # 3: transfer from spot account to COIN-Ⓜ futures account.
#     # 4: transfer from COIN-Ⓜ futures account to spot account.
#     'type': 1,
# })

# print('----------------------------------------------------------------------')

# # for ISOLATED positions only
# print('Modifying your ISOLATED', symbol, 'position margin:')
# response = exchange.fapiPrivate_post_positionmargin({
#     'symbol': market['id'],
#     'amount': 123.45,  # ←-------------- YOUR AMOUNT HERE
#     'positionSide': 'BOTH',  # use BOTH for One-way positions, LONG or SHORT for Hedge Mode
#     'type': 1,  # 1 = add position margin, 2 = reduce position margin
# })

# print('----------------------------------------------------------------------')

for see more examples of this library on binance different markets see here .要查看更多关于币安不同市场的库示例,请参见此处

Method 2: Custom Base Class方法二:自定义基础 Class

I've a base class for this purpose base on main Binance API document you can use this class or customize it for yourself:我有一个基础 class 用于此目的,基于主要的 Binance API 文档,您可以使用此 class 或自己定制:

# -*- coding: utf-8 -*-


import requests
import hashlib
import time
from uuid import uuid4
import urllib
import hmac

class BinanceFutures:
    base = "https://fapi.binance.com"

    def __init__(self, public=None, secret=None):
        self.public = public
        self.secret = secret

    def sign(self, params):
        params['timestamp'] = (int(time.time()) * 1000)
        params['recvWindow'] = 30000
        params_str = urllib.parse.urlencode(params).encode('utf-8')
        sign = hmac.new(
            key=str.encode(self.secret),
            msg=params_str,
            digestmod=hashlib.sha256
        ).hexdigest()
        return params_str.decode("utf-8") + "&signature=" + str(sign)

    def get_header(self):
        return {"X-MBX-APIKEY": self.public, "Content-Type": "application/json"}

    def send_request(self, method, endpoint, params):
        url = BinanceFutures.base + endpoint + "?" + self.sign(params=params)
        response = requests.request(method=method.upper(), url=url, headers=self.get_header()).json()
        return response

    def get_listenKey(self):
        response = self.send_request(method="post", endpoint="/fapi/v1/listenKey", params={})
        return response["listenKey"]

    def get_ticker(self, symbol):
        response = requests.get(BinanceFutures.base + f"/fapi/v1/ticker/price?symbol={symbol}").json()
        return float(response["price"])

    def set_leverage(self, symbol, leverage, trade_mode=False):
        if trade_mode:
            response = self.send_request(method="post", endpoint="/fapi/v1/leverage",
                                         params={"symbol": symbol, "leverage": leverage})
            return response
        else:
            return True

    def get_funding_fees_sum(self, symbol, start):
        params = {
            "symbol": symbol,
            "incomeType": "FUNDING_FEE",
            "startTime": start
        }
        response = self.send_request(method="get", endpoint="/fapi/v1/income", params=params)
        funding_fee = 0
        for income in response:
            if income['incomeType'] == 'FUNDING_FEE':
                if income['time'] >= start:
                    funding_fee += float(income['income'])
        return funding_fee

    def get_balance(self):
        return self.send_request(method="get", endpoint="/fapi/v2/balance", params={})

    def account_info(self):
        return self.send_request(method="get", endpoint="/fapi/v2/account", params={})

    def send_order(self, order, trade_mode=False):
        if trade_mode:
            response = self.send_request(method="post", endpoint="/fapi/v1/order", params=order)
        else:
            response = {
                "orderId": str(uuid4()),
                "symbol": order["symbol"],
                "side": order["side"],
                "origQty": float(order["quantity"]),
            }
        avg_price = self.get_ticker(symbol=order['symbol'])
        response["avgPrice"] = avg_price
        response["cumQuote"] = avg_price * float(order.get('quantity', 0))
        return response

    def open_positions(self, symbols=None, trade_mode=True):
        if not trade_mode:
            return [], 100_000
        response = self.send_request(method="get", endpoint="/fapi/v2/account", params={})
        positions = response.get("positions", None)
        positions = [p for p in positions if float(p['entryPrice']) > 0]
        free_usdt = float(response.get("availableBalance", 0))
        if symbols:
            positions = [p for p in positions if p["symbol"] in symbols]
        return positions, free_usdt

    def params_filter_futures(self, symbol_, quantity, price=0):
        info = requests.get(self.base + '/fapi/v1/exchangeInfo').json()
        params = {
            'quantity': 0,
            'price': 0
        }
        for symbol in info['symbols']:
            if symbol['symbol'] == symbol_:
                for f in symbol['filters']:
                    if f['filterType'] == 'LOT_SIZE':
                        minQty = float(f['minQty'])
                        maxQty = float(f['maxQty'])
                        step = float(f['stepSize'])
                        quantity = max(quantity, minQty)
                        quantity = min(quantity, maxQty)
                        k = round(int(quantity / step))
                        # quantity = ((k-1) * step) + minQty
                        quantity = k * step
                        quantity = round(quantity, symbol['baseAssetPrecision'] - 1)
                        params['quantity'] = quantity
                    elif f['filterType'] == 'PRICE_FILTER' and price:
                        minPrice = float(f['minPrice'])
                        maxPrice = float(f['maxPrice'])
                        step = float(f['tickSize'])
                        price = max(price, minPrice)
                        price = min(price, maxPrice)
                        k = round(int(price / step))
                        price = k * step
                        price = round(price, symbol['quotePrecision'] - 1)
                        params['price'] = price
        return params

    def value2quantity(self, value, symbol):
        price = self.get_ticker(symbol=symbol)
        quantity = value / price
        params = self.params_filter_futures(symbol_=symbol, quantity=quantity, price=0)
        return params["quantity"]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Python 币安 Api 保证金空单 - Python Binance Api Margin Short Order Binance API:如何获取美元作为报价资产 - Binance API: how to get the USD as the quote asset binance python api:出售任何资产的整个余额功能 - binance python api: sell entire balance function for any asset 精度超过为此资产定义的最大值。 python-binance 模块 - Precision is over the maximum defined for this asset. python-binance module 如何使用 python-binance 下期货市场订单:APIError(code=-1111): Precision is over the maximum defined for this assets - How to place a futures market order using python-binance: APIError(code=-1111): Precision is over the maximum defined for this asset Binance API:如何使用python在binance中获取订单ID - Binance API: How to get an Order ID in binance using python 获取期货资产余额 Binance - Get Futures Asset Balance Binance 币安 API:APIError(code=-1111):精度超过为该资产定义的最大值。 Python - Binance API: APIError(code=-1111): Precision is over the maximum defined for this asset. Python Binance API:APIError(code=-1111):精度超过了为该资产定义的最大值。 || Python - Binance API: APIError(code=-1111): Precision is over the maximum defined for this asset. || Python 如何在 python 中使用 ccxt 制作币安期货订单? - How to make a binance futures order with ccxt in python?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM