-
Notifications
You must be signed in to change notification settings - Fork 95
/
margin.py
103 lines (88 loc) · 4.78 KB
/
margin.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
# !/usr/bin/env python
# coding: utf-8
import logging
import random
from decimal import Decimal as D, ROUND_UP, getcontext
from gate_api import ApiClient, Configuration, Loan, MarginApi, Order, RepayRequest, SpotApi, Transfer, WalletApi
from gate_api.exceptions import GateApiException
from config import RunConfig
logger = logging.getLogger(__name__)
def margin_demo(run_config):
# type: (RunConfig) -> None
currency_pair = 'BTC_USDT'
currency = currency_pair.split("_")[1]
# 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)
spot_api = SpotApi(ApiClient(config))
margin_api = MarginApi(ApiClient(config))
wallet_api = WalletApi(ApiClient(config))
# retrieve currency pair last price
tickers = spot_api.list_tickers(currency_pair=currency_pair)
assert len(tickers) == 1
last_price = tickers[0].last
logger.info("currency pair %s last price %s", currency_pair, last_price)
pairs = margin_api.list_margin_currency_pairs()
pair = next(p for p in pairs if p.id == currency_pair)
loan_amount = D("0") if not pair.min_quote_amount else D(pair.min_quote_amount)
if pair.min_base_amount:
min_loan_amount = D(pair.min_base_amount) * D(last_price)
if loan_amount < min_loan_amount:
loan_amount = min_loan_amount
logger.info("minimum loan amount in currency pair %s: %s %s", currency_pair, str(loan_amount), currency)
getcontext().prec = 8
getcontext().rounding = ROUND_UP
# example to lend
funding_accounts = margin_api.list_funding_accounts(currency=currency)
lend_amount = loan_amount + D(random.random())
if len(funding_accounts) == 1 and D(funding_accounts[0].available) >= lend_amount:
lending_loan = Loan(amount=str(lend_amount), auto_renew=False, days=10, currency=currency, rate="0.002",
side='lend')
created_loan = margin_api.create_loan(lending_loan)
logger.info("place a lending loan %s with currency %s, rate %s, amount %s", created_loan.id,
created_loan.currency, created_loan.rate, created_loan.amount)
loan_result = margin_api.get_loan(created_loan.id, 'lend')
if loan_result.status == 'loaned':
records = margin_api.list_loan_records(loan_result.id)
for r in records:
logger.info("loan %s is borrowed with record id %s, amount %s, status: %s", r.loan_id, r.id, r.amount,
r.status)
else:
margin_api.cancel_loan(created_loan.id, currency)
assert pair.leverage
margin = loan_amount / (pair.leverage - 1)
accounts = margin_api.list_margin_accounts(currency_pair=currency_pair)
assert len(accounts) == 1
available = D(accounts[0].quote.available)
logger.info("available margin balance of currency %s in currency pair %s: %s", currency, currency_pair,
str(available))
if margin > available:
transfer = Transfer(currency_pair=currency_pair, currency=currency, amount=str(margin - available),
_from='spot', to='margin')
wallet_api.transfer(transfer)
logger.info("transferred %s %s to margin account", transfer.amount, transfer.currency)
# borrow with minimum rate
borrow_amount = loan_amount + D(random.random())
min_rate_item = min(
filter(lambda x: x.rate and D(x.amount) > borrow_amount, margin_api.list_funding_book(currency)),
key=lambda x: D(x.rate)
)
loan = Loan(side='borrow', currency=currency, rate=min_rate_item.rate, amount=str(borrow_amount),
days=min_rate_item.days, currency_pair=currency_pair)
borrowed = margin_api.create_loan(loan)
logger.info("borrowed %s %s in currency pair %s with rate %s, id %s", borrowed.amount, borrowed.currency,
borrowed.currency_pair, borrowed.rate, borrowed.id)
assert borrowed.status == 'loaned'
# create margin order
order_amount = spot_api.get_currency_pair(currency_pair).min_quote_amount
order = Order(account='margin', currency_pair=currency_pair, price=last_price, amount=order_amount or "1",
side='sell')
try:
created_order = spot_api.create_order(order)
logger.info("margin order created with id %s, status %s", created_order.id, created_order.status)
except GateApiException as ex:
logger.error("failed to create margin order: %s", ex)
repay_request = RepayRequest(mode='all', currency=currency, currency_pair=currency_pair)
margin_api.repay_loan(borrowed.id, repay_request)
for r in margin_api.list_loan_repayments(borrowed.id):
logger.info("loan %s repaid %s with interest %s", borrowed.id, r.principal, r.interest)