· 8 years ago · Jun 01, 2018, 08:34 AM
1"""
2 ÐŸÐ¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ боте на Ñайте bablofil.ru/bot-dlya-binance
3"""
4import sqlite3
5import logging
6import time
7import os
8
9from datetime import datetime
10
11from binance_api import Binance
12bot = Binance(
13 API_KEY='',
14 API_SECRET=''
15)
16
17"""
18 Пропишите пары, на которые будет идти торговлÑ.
19 base - Ñто Ð±Ð°Ð·Ð¾Ð²Ð°Ñ Ð¿Ð°Ñ€Ð° (BTC, ETH, BNB, USDT) - то, что на бинанÑе пишетÑÑ Ð² табличке Ñверху
20 quote - Ñто ÐºÐ²Ð¾Ñ‚Ð¸Ñ€ÑƒÐµÐ¼Ð°Ñ Ð²Ð°Ð»ÑŽÑ‚Ð°. Ðапример, Ð´Ð»Ñ Ñ‚Ð¾Ñ€Ð³Ð¾Ð² по паре NEO/USDT Ð±Ð°Ð·Ð¾Ð²Ð°Ñ Ð²Ð°Ð»ÑŽÑ‚Ð° USDT, NEO - квотируемаÑ
21"""
22pairs = [
23{
24 'base': 'BTC',
25 'quote': 'XVG',
26 'offers_amount': 5, # Сколько предложений из Ñтакана берем Ð´Ð»Ñ Ñ€Ð°Ñчета Ñредней цены
27 # МакÑимум 1000. ДопуÑкаютÑÑ Ñледующие значениÑ:[5, 10, 20, 50, 100, 500, 1000]
28 'spend_sum': 0.0015, # Сколько тратить base каждый раз при покупке quote
29 'profit_markup': 0.005, # Какой навар нужен Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ Ñделки? (0.001 = 0.1%)
30 'max_sell_orders': 0,
31
32 }, {
33 'base': 'USDT',
34 'quote': 'NEO',
35 'offers_amount': 5, # Сколько предложений из Ñтакана берем Ð´Ð»Ñ Ñ€Ð°Ñчета Ñредней цены
36 # МакÑимум 1000. ДопуÑкаютÑÑ Ñледующие значениÑ:[5, 10, 20, 50, 100, 500, 1000]
37 'spend_sum': 11, # Сколько тратить base каждый раз при покупке quote
38 'profit_markup': 0.005, # Какой навар нужен Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ Ñделки? (0.001 = 0.1%)
39 'max_sell_orders': 0,
40
41 }
42
43]
44
45BUY_LIFE_TIME_SEC = 180 # Сколько (в Ñекундах) держать ордер на продажу открытым
46
47STOCK_FEE = 0.001 # КомиÑÑиÑ, которую берет биржа (0.001 = 0.1%)
48
49# ЕÑли вы решите не платить комиÑÑию в BNB, то уÑтановите в False. Обычно делать Ñтого не надо
50USE_BNB_FEES = True
51
52# Получаем Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ñ‚Ð¾Ñ€Ð³Ð¾Ð² по вÑем парам Ñ Ð±Ð¸Ñ€Ð¶Ð¸
53local_time = int(time.time())
54limits = bot.exchangeInfo()
55server_time = int(limits['serverTime'])//1000
56
57# Ф-циÑ, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ñ€Ð¸Ð²Ð¾Ð´Ð¸Ñ‚ любое чиÑло к чиÑлу, кратному шагу, указанному биржей
58# ЕÑли передать параметр increase=True то округление произойдет к Ñледующему шагу
59def adjust_to_step(value, step, increase=False):
60 return ((int(value * 100000000) - int(value * 100000000) % int(
61 float(step) * 100000000)) / 100000000)+(float(step) if increase else 0)
62
63# Подключаем логирование
64logging.basicConfig(
65 format="%(asctime)s [%(levelname)-5.5s] %(message)s",
66 level=logging.DEBUG,
67 handlers=[
68 logging.FileHandler("{path}/logs/{fname}.log".format(path=os.path.dirname(os.path.abspath(__file__)), fname="binance")),
69 logging.StreamHandler()
70 ])
71
72log = logging.getLogger('')
73
74# БеÑконечный цикл программы
75
76shift_seconds = server_time-local_time
77bot.set_shift_seconds(shift_seconds)
78
79log.debug("""
80 Текущее времÑ: {local_time_d} {local_time_u}
81 Ð’Ñ€ÐµÐ¼Ñ Ñервера: {server_time_d} {server_time_u}
82 Разница: {diff:0.8f} {warn}
83 Бот будет работать, как будто ÑейчаÑ: {fake_time_d} {fake_time_u}
84""".format(
85 local_time_d = datetime.fromtimestamp(local_time), local_time_u=local_time,
86 server_time_d=datetime.fromtimestamp(server_time), server_time_u=server_time,
87 diff=abs(local_time-server_time),
88 warn="ТЕКУЩЕЕ ВРЕМЯ ВЫШЕ" if local_time > server_time else '',
89 fake_time_d=datetime.fromtimestamp(local_time+shift_seconds), fake_time_u=local_time+shift_seconds
90))
91
92while True:
93 try:
94 # УÑтанавливаем Ñоединение Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ð¾Ð¹ базой данных
95 conn = sqlite3.connect('binance.db')
96 cursor = conn.cursor()
97
98 # ЕÑли не ÑущеÑтвует таблиц, их нужно Ñоздать (первый запуÑк)
99 orders_q = """
100 create table if not exists
101 orders (
102 order_type TEXT,
103 order_pair TEXT,
104
105 buy_order_id NUMERIC,
106 buy_amount REAL,
107 buy_price REAL,
108 buy_created DATETIME,
109 buy_finished DATETIME NULL,
110 buy_cancelled DATETIME NULL,
111
112 sell_order_id NUMERIC NULL,
113 sell_amount REAL NULL,
114 sell_price REAL NULL,
115 sell_created DATETIME NULL,
116 sell_finished DATETIME NULL
117 );
118 """
119 cursor.execute(orders_q)
120
121 log.debug("Получаем вÑе неиÑполненные ордера по БД")
122
123 orders_q = """
124 SELECT
125 CASE WHEN order_type='buy' THEN buy_order_id ELSE sell_order_id END order_id
126 , order_type
127 , order_pair
128 , sell_amount
129 , sell_price
130 , strftime('%s',buy_created)
131 , buy_amount
132 , buy_price
133 FROM
134 orders
135 WHERE
136 buy_cancelled IS NULL AND CASE WHEN order_type='buy' THEN buy_finished IS NULL ELSE sell_finished IS NULL END
137 """
138 orders_info = {}
139
140
141 for row in cursor.execute(orders_q):
142 orders_info[str(row[0])] = {'order_type': row[1], 'order_pair': row[2], 'sell_amount': row[3], 'sell_price': row[4],
143 'buy_created': row[5], 'buy_amount': row[6], 'buy_price': row[7] }
144 # формируем Ñловарь из указанных пар, Ð´Ð»Ñ ÑƒÐ´Ð¾Ð±Ð½Ð¾Ð³Ð¾ доÑтупа
145 all_pairs = {pair['quote'].upper() + pair['base'].upper():pair for pair in pairs}
146
147 if orders_info:
148 log.debug("Получены неиÑполненные ордера из БД: {orders}".format(orders=[order for order in orders_info]))
149
150 # ПроверÑем каждый неиÑполненный по базе ордер
151 for order in orders_info:
152 # Получаем по ордеру поÑледнюю информацию по бирже
153 stock_order_data = bot.orderInfo(symbol=orders_info[order]['order_pair'], orderId=order)
154
155 order_status = stock_order_data['status']
156 if order_status == 'NEW':
157 log.debug('Ордер {order} вÑÑ‘ еще не выполнен'.format(order=order))
158
159 # ЕÑли ордер на покупку
160 if orders_info[order]['order_type'] == 'buy':
161 # ЕÑли ордер уже иÑполнен
162 if order_status == 'FILLED':
163 log.info("""
164 Ордер {order} выполнен, получено {exec_qty:0.8f}.
165 Создаем ордер на продажу
166 """.format(
167 order=order, exec_qty=float(stock_order_data['executedQty'])
168 ))
169
170 # Ñмотрим, какие Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ ÐµÑть Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¾Ñ€Ð´ÐµÑ€Ð° на продажу
171 for elem in limits['symbols']:
172 if elem['symbol'] == orders_info[order]['order_pair']:
173 CURR_LIMITS = elem
174 break
175 else:
176 raise Exception("Ðе удалоÑÑŒ найти наÑтройки выбранной пары " + pair_name)
177
178 # РаÑÑчитываем данные Ð´Ð»Ñ Ð¾Ñ€Ð´ÐµÑ€Ð° на продажу
179
180 # ИмеющееÑÑ ÐºÐ¾Ð»-во на продажу
181 has_amount = orders_info[order]['buy_amount']*((1-STOCK_FEE) if not USE_BNB_FEES else 1)
182 # Приводим количеÑтво на продажу к чиÑлу, кратному по ограничению
183 sell_amount = adjust_to_step(has_amount, CURR_LIMITS['filters'][1]['stepSize'])
184 # РаÑÑчитываем минимальную Ñумму, которую нужно получить, что бы оÑтатьÑÑ Ð² плюÑе
185 need_to_earn = orders_info[order]['buy_amount']*orders_info[order]['buy_price']*(1+all_pairs[stock_order_data['symbol']]['profit_markup'])
186 # РаÑÑчитываем минимальную цену Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð°Ð¶Ð¸
187 min_price = (need_to_earn/sell_amount)/((1-STOCK_FEE) if not USE_BNB_FEES else 1)
188 # Приводим к нужному виду, еÑли цена поÑле Ñрезки лишних Ñимволов меньше нужной, увеличиваем на шаг
189 cut_price = max(
190 adjust_to_step(min_price, CURR_LIMITS['filters'][0]['tickSize'], increase=True),
191 adjust_to_step(min_price, CURR_LIMITS['filters'][0]['tickSize'])
192 )
193 # Получаем текущие курÑÑ‹ Ñ Ð±Ð¸Ñ€Ð¶Ð¸
194 curr_rate = float(bot.tickerPrice(symbol=orders_info[order]['order_pair'])['price'])
195 # ЕÑли Ñ‚ÐµÐºÑƒÑ‰Ð°Ñ Ñ†ÐµÐ½Ð° выше нужной, продаем по текущей
196 need_price = max(cut_price, curr_rate)
197
198 log.info("""
199 Изначально было куплено {buy_initial:0.8f}, за вычетом комиÑÑии {has_amount:0.8f},
200 ПолучитÑÑ Ð¿Ñ€Ð¾Ð´Ð°Ñ‚ÑŒ только {sell_amount:0.8f}
201 Ðужно получить как минимум {need_to_earn:0.8f} {curr}
202 Мин. цена (Ñ ÐºÐ¾Ð¼Ð¸ÑÑией) ÑоÑтавит {min_price}, поÑле Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ {cut_price:0.8f}
203 Ð¢ÐµÐºÑƒÑ‰Ð°Ñ Ñ†ÐµÐ½Ð° рынка {curr_rate:0.8f}
204 Ð˜Ñ‚Ð¾Ð³Ð¾Ð²Ð°Ñ Ñ†ÐµÐ½Ð° продажи: {need_price:0.8f}
205 """.format(
206 buy_initial=orders_info[order]['buy_amount'], has_amount=has_amount,sell_amount=sell_amount,
207 need_to_earn=need_to_earn, curr=all_pairs[orders_info[order]['order_pair']]['base'],
208 min_price=min_price, cut_price=cut_price, need_price=need_price,
209 curr_rate=curr_rate
210 ))
211
212 # ЕÑли Ð¸Ñ‚Ð¾Ð³Ð¾Ð²Ð°Ñ Ñумма продажи меньше минимума, ругаемÑÑ Ð¸ не продаем
213 if (need_price*has_amount) <float(CURR_LIMITS['filters'][2]['minNotional']):
214 raise Exception("""
215 Итоговый размер Ñделки {trade_am:0.8f} меньше допуÑтимого по паре {min_am:0.8f}. """.format(
216 trade_am=(need_price*has_amount), min_am=float(CURR_LIMITS['filters'][2]['minNotional'])
217 ))
218
219 log.debug(
220 'РаÑÑчитан ордер на продажу: кол-во {amount:0.8f}, курÑ: {rate:0.8f}'.format(
221 amount=sell_amount, rate=need_price)
222 )
223
224 # ОтправлÑем команду на Ñоздание ордера Ñ Ñ€Ð°ÑÑчитанными параметрами
225 new_order = bot.createOrder(
226 symbol=orders_info[order]['order_pair'],
227 recvWindow=5000,
228 side='SELL',
229 type='LIMIT',
230 timeInForce='GTC', # Good Till Cancel
231 quantity="{quantity:0.{precision}f}".format(
232 quantity=sell_amount, precision=CURR_LIMITS['baseAssetPrecision']
233 ),
234 price="{price:0.{precision}f}".format(
235 price=need_price, precision=CURR_LIMITS['baseAssetPrecision']
236 ),
237 newOrderRespType='FULL'
238 )
239 # ЕÑли ордер ÑоздалÑÑ Ð±ÐµÐ· ошибок, запиÑываем данные в базу данных
240 if 'orderId' in new_order:
241 log.info("Создан ордер на продажу {new_order}".format(new_order=new_order))
242 cursor.execute(
243 """
244 UPDATE orders
245 SET
246 order_type = 'sell',
247 buy_finished = datetime(),
248 sell_order_id = :sell_order_id,
249 sell_created = datetime(),
250 sell_amount = :sell_amount,
251 sell_price = :sell_initial_price
252 WHERE
253 buy_order_id = :buy_order_id
254
255 """, {
256 'buy_order_id': order,
257 'sell_order_id': new_order['orderId'],
258 'sell_amount': sell_amount,
259 'sell_initial_price': need_price
260 }
261 )
262 conn.commit()
263 # ЕÑли были ошибки при Ñоздании, выводим Ñообщение
264 else:
265 log.warning("Ðе удалоÑÑŒ Ñоздать ордер на продажу {new_order}".format(new_order=new_order))
266
267 # Ордер еще не иÑполнен, чаÑтичного иÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð½ÐµÑ‚, проверÑем возможноÑть отмены
268 elif order_status == 'NEW':
269 order_created = int(orders_info[order]['buy_created'])
270 time_passed = int(time.time()) - order_created
271 log.info("passed {passed:0.2f}".format(passed=time_passed))
272 # Прошло больше времени, чем разрешено держать ордер
273 if time_passed > BUY_LIFE_TIME_SEC:
274 log.info("""Ордер {order} пора отменÑть, прошло {passed:0.1f} Ñек.""".format(
275 order=order, passed=time_passed
276 ))
277 # ОтменÑем ордер на бирже
278 cancel = bot.cancelOrder(
279 symbol=orders_info[order]['order_pair'],
280 orderId=order
281 )
282 # ЕÑли удалоÑÑŒ отменить ордер, Ñкидываем информацию в БД
283 if 'orderId' in cancel:
284 log.info("Ордер {order} был уÑпешно отменен".format(order=order))
285 cursor.execute(
286 """
287 UPDATE orders
288 SET
289 buy_cancelled = datetime()
290 WHERE
291 buy_order_id = :buy_order_id
292 """, {
293 'buy_order_id': order
294 }
295 )
296 conn.commit()
297 else:
298 log.warning("Ðе удалоÑÑŒ отменить ордер: {cancel}".format(cancel=cancel))
299 elif order_status == 'PARTIALLY_FILLED':
300 log.debug("Ордер {order} чаÑтично иÑполнен, ждем завершениÑ".format(order=order))
301
302 # ЕÑли Ñто ордер на продажу, и он иÑполнен
303 if order_status == 'FILLED' and orders_info[order]['order_type'] == 'sell':
304 log.debug("Ордер {order} на продажу иÑполнен".format(
305 order=order
306 ))
307 # ОбновлÑем информацию в БД
308 cursor.execute(
309 """
310 UPDATE orders
311 SET
312 sell_finished = datetime()
313 WHERE
314 sell_order_id = :sell_order_id
315
316 """, {
317 'sell_order_id': order
318 }
319 )
320 conn.commit()
321
322 for i, d in enumerate(pairs):
323 if d['quote'].upper() + d['base'] == orders_info[order]['order_pair']:
324 pairs[i]['max_sell_orders'] = pairs[i]['max_sell_orders'] - 1
325
326 else:
327 log.debug("ÐеиÑполненных ордеров в БД нет")
328
329 log.debug('Получаем из наÑтроек вÑе пары, по которым нет неиÑполненных ордеров')
330
331 orders_q = """
332 SELECT
333 distinct(order_pair) pair
334 FROM
335 orders
336 WHERE
337 buy_cancelled IS NULL AND CASE WHEN order_type='buy' THEN buy_finished IS NULL ELSE sell_finished IS NULL END
338 """
339 # Получаем из базы вÑе ордера, по которым еÑть торги, и иÑключаем их из ÑпиÑка, по которому будем Ñоздавать новые ордера
340 for row in cursor.execute(orders_q):
341 del all_pairs[row[0]]
342
343 all_pairs = {pair['quote'].upper() + pair['base'].upper():pair for pair in pairs if pair['max_sell_orders'] > 0}
344 # ЕÑли оÑталиÑÑŒ пары, по которым нет текущих торгов
345 if all_pairs:
346 log.debug('Ðайдены пары, по которым нет неиÑполненных ордеров: {pairs}'.format(pairs=list(all_pairs.keys())))
347 # for pair_name, pair_obj in all_pairs.items():
348 for pair_name, pair_obj in all_pairs.items():
349 log.debug("Работаем Ñ Ð¿Ð°Ñ€Ð¾Ð¹ {pair}".format(pair=pair_name))
350
351 # Получаем лимиты пары Ñ Ð±Ð¸Ñ€Ð¶Ð¸
352 for elem in limits['symbols']:
353 if elem['symbol'] == pair_name:
354 CURR_LIMITS = elem
355 break
356 else:
357 raise Exception("Ðе удалоÑÑŒ найти наÑтройки выбранной пары " + pair_name)
358
359 # Получаем баланÑÑ‹ Ñ Ð±Ð¸Ñ€Ð¶Ð¸ по указанным валютам
360 balances = {
361 balance['asset']: float(balance['free']) for balance in bot.account()['balances']
362 if balance['asset'] in [pair_obj['base'], pair_obj['quote']]
363 }
364 log.debug("Ð‘Ð°Ð»Ð°Ð½Ñ {balance}".format(balance=["{k}:{bal:0.8f}".format(k=k, bal=balances[k]) for k in balances]))
365 # ЕÑли Ð±Ð°Ð»Ð°Ð½Ñ Ð¿Ð¾Ð·Ð²Ð¾Ð»Ñет торговать - выше лимитов биржи и выше указанной Ñуммы в наÑтройках
366 if balances[pair_obj['base']] >= pair_obj['spend_sum']:
367 # Получаем информацию по предложениÑм из Ñтакана, в кол-ве указанном в наÑтройках
368 offers = bot.depth(
369 symbol=pair_name,
370 limit=pair_obj['offers_amount']
371 )
372
373 # Берем цены покупок (Ð´Ð»Ñ Ñ†ÐµÐ½ продаж замените bids на asks)
374 prices = [float(bid[0]) for bid in offers['bids']]
375
376 try:
377 # РаÑÑчитываем Ñреднюю цену из полученных цен
378 avg_price = sum(prices) / len(prices)
379 # Среднюю цену приводим к требованиÑм биржи о кратноÑти
380 my_need_price = adjust_to_step(avg_price, CURR_LIMITS['filters'][0]['tickSize'])
381 # РаÑÑчитываем кол-во, которое можно купить, и тоже приводим его к кратному значению
382 my_amount = adjust_to_step(pair_obj['spend_sum']/ my_need_price, CURR_LIMITS['filters'][1]['stepSize'])
383 # ЕÑли в итоге получаетÑÑ Ð¾Ð±ÑŠÐµÐ¼ торгов меньше минимально разрешенного, то ругаемÑÑ Ð¸ не Ñоздаем ордер
384 if my_amount < float(CURR_LIMITS['filters'][1]['stepSize']) or my_amount < float(CURR_LIMITS['filters'][1]['minQty']):
385 log.warning("""
386 ÐœÐ¸Ð½Ð¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ñумма лота: {min_lot:0.8f}
387 Минимальный шаг лота: {min_lot_step:0.8f}
388 Ðа Ñвои деньги мы могли бы купить {wanted_amount:0.8f}
389 ПоÑле Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ðº минимальному шагу мы можем купить {my_amount:0.8f}
390 Покупка невозможна, выход. Увеличьте размер Ñтавки
391 """.format(
392 wanted_amount=pair_obj['spend_sum']/ my_need_price,
393 my_amount=my_amount,
394 min_lot=float(CURR_LIMITS['filters'][1]['minQty']),
395 min_lot_step=float(CURR_LIMITS['filters'][1]['stepSize'])
396 ))
397 continue
398
399 # Итоговый размер лота
400 trade_am = my_need_price*my_amount
401 log.debug("""
402 СреднÑÑ Ñ†ÐµÐ½Ð° {av_price:0.8f},
403 поÑле Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ {need_price:0.8f},
404 объем поÑле Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ {my_amount:0.8f},
405 итоговый размер Ñделки {trade_am:0.8f}
406 """.format(
407 av_price=avg_price, need_price=my_need_price, my_amount=my_amount, trade_am=trade_am
408 ))
409 # ЕÑли итоговый размер лота меньше минимального разрешенного, то ругаемÑÑ Ð¸ не Ñоздаем ордер
410 if trade_am < float(CURR_LIMITS['filters'][2]['minNotional']):
411 raise Exception("""
412 Итоговый размер Ñделки {trade_am:0.8f} меньше допуÑтимого по паре {min_am:0.8f}.
413 Увеличьте Ñумму торгов (в {incr} раз(а))""".format(
414 trade_am=trade_am, min_am=float(CURR_LIMITS['filters'][2]['minNotional']),
415 incr=float(CURR_LIMITS['filters'][2]['minNotional'])/trade_am
416 ))
417 log.debug(
418 'РаÑÑчитан ордер на покупку: кол-во {amount:0.8f}, курÑ: {rate:0.8f}'.format(amount=my_amount, rate=my_need_price)
419 )
420 # ОтправлÑем команду на бирже о Ñоздании ордера на покупку Ñ Ñ€Ð°ÑÑчитанными параметрами
421 new_order = bot.createOrder(
422 symbol=pair_name,
423 recvWindow=5000,
424 side='BUY',
425 type='LIMIT',
426 timeInForce='GTC', # Good Till Cancel
427 quantity="{quantity:0.{precision}f}".format(
428 quantity=my_amount, precision=CURR_LIMITS['baseAssetPrecision']
429 ),
430 price="{price:0.{precision}f}".format(
431 price=my_need_price, precision=CURR_LIMITS['baseAssetPrecision']
432 ),
433 newOrderRespType='FULL'
434 )
435 # ЕÑли удалоÑÑŒ Ñоздать ордер на покупку, запиÑываем информацию в БД
436 if 'orderId' in new_order:
437 log.info("Создан ордер на покупку {new_order}".format(new_order=new_order))
438 cursor.execute(
439 """
440 INSERT INTO orders(
441 order_type,
442 order_pair,
443 buy_order_id,
444 buy_amount,
445 buy_price,
446 buy_created
447
448 ) Values (
449 'buy',
450 :order_pair,
451 :order_id,
452 :buy_order_amount,
453 :buy_initial_price,
454 datetime()
455 )
456 """, {
457 'order_pair': pair_name,
458 'order_id': new_order['orderId'],
459 'buy_order_amount': my_amount,
460 'buy_initial_price': my_need_price
461 }
462 )
463 conn.commit()
464 else:
465 log.warning("Ðе удалоÑÑŒ Ñоздать ордер на покупку! {new_order}".format(new_order=str(new_order)))
466
467 except ZeroDivisionError:
468 log.debug('Ðе удаетÑÑ Ð²Ñ‹Ñ‡Ð¸Ñлить Ñреднюю цену: {prices}'.format(prices=str(prices)))
469 else:
470 log.warning('Ð”Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¾Ñ€Ð´ÐµÑ€Ð° на покупку нужно минимум {min_qty:0.8f} {curr}, выход'.format(
471 min_qty=pair_obj['spend_sum'], curr=pair_obj['base']
472 ))
473
474 else:
475 log.debug('По вÑем парам еÑть неиÑполненные ордера')
476
477 except Exception as e:
478 log.exception(e)
479 finally:
480 conn.close()