Advertisement
namile

Untitled

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