forked from NicoleQiujuan/simple-grid
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsimple_grid_kucoin.py
executable file
·179 lines (155 loc) · 6.62 KB
/
simple_grid_kucoin.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import json
import logging
import time
from concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETED
from decimal import Decimal
from kucoin.client import Trade
from kucoin.client import Market
def log_setting():
logging.basicConfig(filename='log.log',
format='%(asctime)s - %(levelname)s - %(module)s - %(lineno)d: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',
level=logging.INFO)
class Grid(object):
def __init__(self):
# read configuration from json file
with open('config.json', 'r') as file:
config = json.load(file)
self.api_key = config['api_key']
self.api_secret = config['api_secret']
self.api_passphrase = config['api_passphrase']
self.sandbox = config['is_sandbox']
self.symbol = config['symbol']
self.leverage = config['leverage']
self.size = config['size']
self.depth = config['depth']
self.market = Market(self.api_key, self.api_secret, self.api_passphrase, is_sandbox=self.sandbox)
self.trade = Trade(self.api_key, self.api_secret, self.api_passphrase, is_sandbox=self.sandbox)
self.tick_size = 0
self.best_ask = 0
self.best_bid = 0
self.diff = 0
self.max_ask = 0
self.max_bid = 0
self.precision = 0
self.ask_list = {}
self.bid_list = {}
def get_symbol(self):
symbols = self.market.get_symbol_list()
ks = {}
for s in symbols:
if s.get('symbol') and s.get('symbol') == self.symbol:
ks = s
if ks:
self.tick_size = Decimal(ks['priceIncrement'])
self.diff = Decimal(self.tick_size * self.depth)
self.precision = int(1 / Decimal(ks['baseIncrement']))
logging.debug('tick_size = %s, precision = %s', self.tick_size, self.precision)
def get_market_price(self):
try:
r = self.market.get_ticker(self.symbol)
if 'bestAsk' in r.keys():
self.best_ask = Decimal(r['bestAsk'])
self.max_ask = Decimal(self.best_ask + self.diff).quantize(Decimal("0.00"))
else:
return
if 'bestBid' in r.keys():
self.best_bid = Decimal(r['bestBid'])
self.max_bid = Decimal(self.best_bid - self.diff).quantize(Decimal("0.00"))
else:
return
logging.debug('最新卖价格 = %s' % self.best_ask)
logging.debug('最新买价格 = %s' % self.best_bid)
except Exception as e:
logging.error(e)
time.sleep(5)
def cancel_order(self, order_id, side):
try:
oi = self.trade.get_order_details(order_id)
if oi['isActive']:
self.trade.cancel_order(order_id)
if side == 'sell':
del self.ask_list[order_id]
elif side == 'buy':
del self.bid_list[order_id]
except Exception as e:
logging.error('该订单状态不可撤回 side = %s, order_id = %s' % (side, order_id))
logging.error(e)
def ask_maker(self, p):
try:
price = int(p * 100) / 100
ask = self.trade.create_limit_order(self.symbol, 'sell', self.size, float(price))
logging.debug('当前盘口价格 = %s,在交易对 %s 以数量= %s,价格= %s,创建了卖单,卖单ID = %s' %
(self.best_ask, self.symbol, self.size, float(price), ask['orderId']))
self.ask_list[ask['orderId']] = {
'price': p
}
except Exception as e:
logging.error(e)
def bid_maker(self, p):
try:
price = int(p * 100) / 100
bid = self.trade.create_limit_order(self.symbol, 'buy', self.size, float(price))
logging.debug('当前盘口价格 = %s,在交易对 %s 以数量= %s,价格= %s,创建了买单,卖单ID = %s' %
(self.best_ask, self.symbol, self.size, float(price), bid['orderId']))
self.bid_list[bid['orderId']] = {
'price': p
}
except Exception as e:
logging.error(e)
if __name__ == '__main__':
log_setting()
grid = Grid()
grid.get_symbol()
executor = ThreadPoolExecutor(max_workers=5)
all_task = []
while grid.tick_size > 0:
grid.get_market_price()
if grid.best_bid <= 0 or grid.best_ask <= 0:
logging.error('best_bid or best_ask error')
time.sleep(5)
continue
logging.info('len(grid.ask_list) = %s' % len(grid.ask_list))
logging.info('len(grid.bid_list) = %s' % len(grid.bid_list))
for k, v in (grid.ask_list.items()):
if v['price'] < grid.best_ask or v['price'] >= grid.max_ask:
task = executor.submit(grid.cancel_order, k, 'sell')
all_task.append(task)
wait(all_task, return_when=ALL_COMPLETED)
all_task.clear()
for k, v in (grid.bid_list.items()):
if v['price'] > grid.best_bid or v['price'] <= grid.max_bid:
task = executor.submit(grid.cancel_order, k, 'buy')
all_task.append(task)
wait(all_task, return_when=ALL_COMPLETED)
all_task.clear()
logging.info('len(grid.ask_list) = %s' % len(grid.ask_list))
logging.info('len(grid.bid_list) = %s' % len(grid.bid_list))
ask_price = grid.best_ask
bid_price = grid.best_bid
for i in range(0, grid.depth):
ask_price = Decimal(grid.best_ask + grid.tick_size * Decimal(i)).quantize(Decimal("0.00"))
flag = 0
for k, v in (grid.ask_list.items()):
if ask_price == v['price']:
flag = 1
if flag == 0:
task = executor.submit(grid.ask_maker, ask_price)
all_task.append(task)
wait(all_task, return_when=ALL_COMPLETED)
all_task.clear()
for i in range(0, grid.depth):
bid_price = Decimal(grid.best_bid - grid.tick_size * Decimal(i)).quantize(Decimal("0.00"))
flag = 0
for k, v in (grid.bid_list.items()):
if bid_price == v['price']:
flag = 1
if flag == 0:
task = executor.submit(grid.bid_maker, bid_price)
all_task.append(task)
wait(all_task, return_when=ALL_COMPLETED)
all_task.clear()
logging.info('len(grid.ask_list) = %s' % len(grid.ask_list))
logging.info('len(grid.bid_list) = %s' % len(grid.bid_list))