-
Notifications
You must be signed in to change notification settings - Fork 115
/
Copy pathfutures.py
112 lines (94 loc) · 4.38 KB
/
futures.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# !/usr/bin/env python
# coding: utf-8
import logging
import time
from decimal import Decimal as D, ROUND_UP, getcontext
from gate_api import ApiClient, Configuration, FuturesApi, FuturesOrder, Transfer, WalletApi
from gate_api.exceptions import GateApiException
from config import RunConfig
logger = logging.getLogger(__name__)
def futures_demo(run_config):
# type: (RunConfig) -> None
settle = "usdt"
contract = "BTC_USDT"
# Initialize API client
# Setting host is optional. It defaults to https://api.gateio.ws/api/v4
config = Configuration(key=run_config.api_key, secret=run_config.api_secret, host=run_config.host_used)
futures_api = FuturesApi(ApiClient(config))
# update position leverage
leverage = "3"
futures_api.update_position_leverage(settle, contract, leverage)
# retrieve position size
position_size = 0
try:
position = futures_api.get_position(settle, contract)
position_size = position.size
except GateApiException as ex:
if ex.label != "POSITION_NOT_FOUND":
raise ex
# set order size
futures_contract = futures_api.get_futures_contract(settle, contract)
order_size = 10
if futures_contract.order_size_min and futures_contract.order_size_min > order_size:
order_size = futures_contract.order_size_min
if position_size < 0:
order_size = 0 - order_size
# example to update risk limit
assert futures_contract.risk_limit_base
assert futures_contract.risk_limit_step
risk_limit = D(futures_contract.risk_limit_base) + D(futures_contract.risk_limit_step)
futures_api.update_position_risk_limit(settle, contract, str(risk_limit))
# retrieve last price to calculate margin needed
tickers = futures_api.list_futures_tickers(settle, contract=contract)
assert len(tickers) == 1
last_price = tickers[0].last
logger.info("last price of contract %s: %s", contract, last_price)
getcontext().prec = 8
getcontext().rounding = ROUND_UP
assert futures_contract.quanto_multiplier
margin = order_size * D(last_price) * D(futures_contract.quanto_multiplier) / D(leverage) * D("1.1")
logger.info("needs margin amount: %s", str(margin))
# if balance is not enough, transfer from spot account
available = "0"
try:
futures_account = futures_api.list_futures_accounts(settle)
available = futures_account.available
except GateApiException as ex:
if ex.label != "USER_NOT_FOUND":
raise ex
logger.info("futures account available: %s %s", available, settle.upper())
if D(available) < margin:
if run_config.use_test:
logger.warning("testnet account balance not enough. make a transferal on web")
return
transfer = Transfer(amount=str(margin), currency=settle.upper(), _from='spot', to='futures')
wallet_api = WalletApi(ApiClient(config))
wallet_api.transfer(transfer)
# example to cancel all open orders in contract
futures_api.cancel_futures_orders(settle, contract)
# order using market price
order = FuturesOrder(contract=contract, size=order_size, price="0", tif='ioc')
try:
order_response = futures_api.create_futures_order(settle, order)
except GateApiException as ex:
logger.error("error encountered creating futures order: %s", ex)
return
logger.info("order %s created with status: %s", order_response.id, order_response.status)
if order_response.status == 'open':
futures_order = futures_api.get_futures_order(settle, str(order_response.id))
logger.info("order %s status %s, total size %s, left %s", futures_order.id, futures_order.status,
futures_order.size, futures_order.left)
futures_api.cancel_futures_order(settle, str(futures_order.id))
logger.info("order %s cancelled", futures_order.id)
else:
time.sleep(0.2)
order_trades = futures_api.get_my_trades(settle, contract=contract, order=order_response.id)
assert len(order_trades) > 0
trade_size = 0
for t in order_trades:
assert t.order_id == str(order_response.id)
trade_size += t.size
logger.info("order %s filled size %s with price %s", t.order_id, t.size, t.price)
assert trade_size == order_size
# example to update position margin
futures_api.update_position_margin(settle, contract, "0.01")