# Настройки на период 110 минут
# 1200 c задержки покупки продажи
# порог curr -1 1
import time
import json
import requests
import urllib, http.client
import hmac, hashlib
import mysql.connector
import pandas as pd
import openpyxl
# Если нет нужных пакетов - читаем тут: https://bablofil.ru/python-indicators/
import numpy
import talib
from datetime import datetime
PERIOD = 4*60 #4*60 # Период в минутах для построения свечей краткосрочного MACD
#BUY=True #True разрешено покупать
BUY=True
TRADE=True #используем для долгосрочного MCAD сейчас отсутствует
SELL=True #True разрешено продавать
GROWLAST = False
FIRST = False
# ключи API, которые предоставила exmo
#API_KEY = 'K- кей'
# обратите внимание, что добавлена 'b' перед строкой
#API_SECRET = b'S-секрет'
# аккаунт 1
# ключи API, которые предоставила exmo
#API_KEY = 'K-'
API_KEY = ''
# обратите внимание, что добавлена 'b' перед строкой
#API_SECRET = b'S-'
API_SECRET = b''
# Список пар, на которые торгуем
MARKETS = [
'BTC_USD'
]
CAN_SPEND = 20 # Сколько USD готовы вложить в бай
MARKUP = 0.001 # 0.001 = 0.1% - Какой навар со сделки хотим получать
STOCK_FEE = 0.002 # Какую комиссию берет биржа
#PERIOD = 4 # Период в минутах для построения свечей
ORDER_LIFE_TIME = 0.5 # Через сколько минут отменять неисполненный ордер на покупку 0.5 = 30 сек.
USE_MACD = True # True - оценивать тренд по MACD, False - покупать и продавать невзирая ни на что
API_URL = 'api.exmo.me'
API_VERSION = 'v1'
#USE_LOG = False
USE_LOG = True
DEBUG = False # True - выводить отладочную информацию, False - писать как можно меньше
MM = False
SS = False
SS_last = False
numpy.seterr(all='ignore')
curr_pair = None
# Свой класс исключений
class ScriptError(Exception):
pass
class ScriptQuitCondition(Exception):
pass
# все обращения к API проходят через эту функцию
def call_api(api_method, http_method="POST", **kwargs):
payload = {'nonce': int(round(time.time()*1000))}
if kwargs:
payload.update(kwargs)
payload = urllib.parse.urlencode(payload)
H = hmac.new(key=API_SECRET, digestmod=hashlib.sha512)
H.update(payload.encode('utf-8'))
sign = H.hexdigest()
headers = {"Content-type": "application/x-www-form-urlencoded",
"Key":API_KEY,
"Sign":sign}
conn = http.client.HTTPSConnection(API_URL, timeout=90)
conn.request(http_method, "/"+API_VERSION + "/" + api_method, payload, headers)
response = conn.getresponse().read()
conn.close()
try:
obj = json.loads(response.decode('utf-8'))
if 'error' in obj and obj['error']:
raise ScriptError(obj['error'])
return obj
except json.decoder.JSONDecodeError:
raise ScriptError('Ошибка анализа возвращаемых данных, получена строка', response)
def AO(ohlc, slow_period=34, fast_period=5):
"""
Awesome Oscillator is an indicator used to measure market momentum. AO calculates the difference of a 34 Period and 5 Peri$
The Simple Moving Averages that are used are not calculated using closing price but rather each bar's midpoints.
AO is generally used to affirm trends or to anticipate possible reversals. """
ohlc['medean'] = (ohlc['high'] + ohlc['low']) / 2
ohlc['ao_slow'] = pd.Series(ohlc['medean']).rolling(window=slow_period).mean()
ohlc['ao_fast'] = pd.Series(ohlc['medean']).rolling(window=fast_period).mean()
ohlc['ao'] = ohlc['ao_fast'] - ohlc['ao_slow']
#ohlc['ac'] = ohlc['ao'] - pd.Series(ohlc['ao']).rolling(window=5).mean()
#ohlc['jaw'] = pd.Series(ohlc['medean']).rolling(window=13).mean().shift(8)
#ohlc['teeth'] = pd.Series(ohlc['medean']).rolling(window=8).mean().shift(5)
#ohlc['lips'] = pd.Series(ohlc['medean']).rolling(window=5).mean().shift(3)
def close_chk(data):
#global PERIOD
#global SS #доступ к сигналу стоплосса
df = pd.DataFrame(data, columns=['date', 'open', 'high', 'low', 'close'])
df['Date'] = df['date']
df['Date'] = df['Date'].astype(int)
df['Date'] = pd.to_datetime(df['Date'], unit='s')
df['dat'] = None
AO(df, slow_period=34, fast_period=5)
df['B1'] = None
df['B2'] = None
df['B3'] = None
df['S1'] = None
df['S2'] = None
df['S3'] = None
df['SS'] = None
df['Trand'] = None
df['BUY'] = None
df['TRADE'] = None
df['PRICE'] = None
df['PRICE2'] = None
df = df.iloc[34:]
#print(df)
dict = df.to_dict('records')
Lesszero = True
min1 = []
max1 = []
#pmin = 1 # относительное падение цены от начала работы бота
#pmin1 = 1 # относительное падение цены от закупки
#MM = False
for index, elems in enumerate(dict):
# Здесь для индикаторов B1, B2, B3, S1, S2, S3
# определим выше нуля или нет и обнулим списки
if dict[index-1]['ao'] >= 0 and dict[index]['ao'] < 0 :
Lesszero = True # Сигнал нам нужно сохранить пока не пересечем нуль
min1 = []
max1 = []
if dict[index-1]['ao'] < 0 and dict[index]['ao'] >= 0 :
Lesszero = False
min1 = []
max1 = []
# B1 сигнал на покупку блюдце выше нуля
#if dict[index-1]['ao'] < 0 and dict[index]['ao'] >= 0 :
if not Lesszero:
if (
(dict[index-1]['ao'] < dict[index]['ao']
and dict[index-2]['ao'] > dict[index-1]['ao']
and dict[index-2]['ao'] > 0)
):
elems['B1'] = True
# B2 сигнал на покупку пересечение нуля снизу вверх
if (
dict[index]['ao'] > 0 and dict[index-1]['ao'] <=0
):
elems['B2'] = True
# B3 сигнал на покупку два пика ниже нуля
#if dict[index-1]['ao'] >= 0 and dict[index]['ao'] < 0 :
if Lesszero:
#print(dict[index]['Date'])
#min1.append(dict[index-1]['ao'])
# мы ловим второй пик, если он больше (ближе к нулю) чем первый
# формируем сигнал на покупку
# если он меньше (дальше от нуля)
# удаляем первый пик
if (
dict[index-1]['ao'] < dict[index]['ao']
and dict[index-2]['ao'] > dict[index-1]['ao']
):
min1.append(dict[index]['ao'])
if len(min1) == 2 and min1[0] >= min1[1]: # второй пик ниже
#print('delete')
#print(min1)
min1.pop(0) #удаляем первый пик
#print(min1)
#print(dict[index]['Date'])
#print(min1)
if len(min1) == 2 and min1[0] < min1[1]:
#S1_sell = True
#print('buy')
#print(min1)
elems['B3'] = True
min1.pop()
min1.pop()
#S1 сигнал на продажу блюдце ниже нуля
if (
dict[index-1]['ao'] > dict[index]['ao']
and dict[index-2]['ao'] < dict[index-1]['ao']
and dict[index]['ao'] < 0
):
elems['S1'] = True
#S2 сигнал на продажу пересечение нуля сверху вниз
if (
dict[index]['ao'] < 0 and dict[index-1]['ao'] >=0
):
elems['S2'] = True
# S3 сигнал на продажу два пика выше нуля
#if dict[index-1]['ao'] < 0 and dict[index]['ao'] >= 0 :
if not Lesszero: # выше нуля
# мы ловим третий пик, если он ниже (ближе ок нулю) чем средний
# формируем сигнал на продажу блюдце
# если он выше (дальше от нуля)
# удаляем первый пик
if (
dict[index-1]['ao'] > dict[index]['ao']
and dict[index-2]['ao'] < dict[index-1]['ao']
):
max1.append(dict[index-1]['ao'])
if len(max1) == 2 and max1[0] <= max1[1]: # второй пик выше
#print('S3')
#print(max1)
max1.pop(0) #удаляем первый пик
#print(max1)
#print(dict[index]['Date'])
#print(min1)
if len(max1) == 2 and max1[1] < max1[0]:
#print('buy')
#print(min1)
elems['S3'] = True
max1.pop()
max1.pop()
# SS сигнал стоплосса (справочно)
#if SS: # сработал стоплосс
#elems['SS'] = True
#else:
#SS = False # снимаем сигнал
# Для транда MM опишем покупку
#if (
#elems['B1'] or elems['B2'] or elems['B3']
#(elems['B1'] or elems['B2'] or elems['B3']) and elems['lips'] > elems['teeth'] and elems['lips'] > elems['jaw']
#elems['AB1'] or elems['AB2'] or elems['AB3']
# or elems['B2'] or elems['B3']
#):
#MM = True
# Для транда MM опишем продажу
#if (
#elems['S1'] or elems['S2'] or elems['S3'] or elems['SS']
#elems['AS1'] or elems['AS2'] or elems['AS3']
#):
#MM = False
#Trand = MM
#elems['Trand'] = Trand
#print(dict)
Debug = True
#Debug = False
if Debug:
col = (
['Date', 'open', 'high', 'low', 'close',
'B1','B2','B3','S1','S2','S3','SS','ao', 'Trand'
#,'Signal','pmin','pmin1','Profit','Prof']
]
)
df = pd.DataFrame(dict, columns=col)
print(df.tail(20))
return dict[-1]
def get_close(data):
global PERIOD
close=numpy.asarray([float(item['close']) for item in data])
return (close[-1])
# Получаем с биржи данные, необходимые для построения индикаторов
#def get_ticks(pair):
def get_sql(PER):
print('PER =', PER)
#resource = requests.get('https://api.exmo.me/v1/trades/?pair=%s&limit=10000' % pair)
#data = json.loads(resource.text)
#_SQL = """select * from trade"""
dt = datetime.utcnow()
dtt = dt.timetuple()
#print(dtt)
x = time.mktime(dtt)
#print(x)
#print(datetime.fromtimestamp(x))
#x=int(time.time())
#print(x)
#print(datetime.fromtimestamp(x))
pr = PER * 60
#x= x - pr*110
x= x - pr*70 # 70 свечей
#_SQL = """select * from trade where date between 1519318790 and 1519318800; """
_SQL = """SELECT
FLOOR(MIN(`date`)/%s)*%s AS date,
SUBSTRING_INDEX(MIN(CONCAT(`date`, '_', id, '_', price)), '_', -1) AS `open`,
MAX(price) AS high,
MIN(price) AS low,
SUBSTRING_INDEX(MAX(CONCAT(`date`, '_', id, '_', price)), '_', -1) AS `close`
FROM trade
WHERE date >= %s
GROUP BY FLOOR(`date`/%s)
ORDER BY date"""
#print(_SQL)
#cur.execute(_SQL,(pr,pr,x,pr))
db = mysql.connector.connect(host="localhost", user="u", passwd="secret", db="exmo")
cur = db.cursor()
try:
cur.execute(_SQL,(pr,pr,x,pr))
except Exception as e:
log(e)
sdata=[]
for item in cur.fetchall():
#sdata.append({'time':datetime.utcfromtimestamp(int(item[0])),'date':int(item[0]),'open':float(item[1]),'high':float(item[2]),'low':float(item[3]),'close':float(item[4])})
sdata.append({'date':int(item[0]),'open':float(item[1]),'high':float(item[2]),'low':float(item[3]),'close':float(item[4])})
cur.close()
db.close()
return sdata
def get_ticks ():
global PERIOD
global MACD
flg = False
data=[]
# d текщее время на которое расчитывается свеча
# data список предварительно рассчитанные свечи
DEBUG = False
#DEBUG = True
if flg: #flg = True для ускорения используем кэш предрасчитанные свечи в списке data
data1=[] #перегрузим сюда свечи до времени d с учетом запаса для расчета MACD
for offset, elem in enumerate(data):
#if True:
if (data[offset]['date'] <=d) and (data[offset]['date'] >= (d - PERIOD*MACD*2*60)):
data1.append(data[offset]) #не пропускаем последнюю свечу!
cand2_st = data1[-1]['date'] # из последней свечи возьмем возьмем начала периода для расчета неполной свечи
cand2_end = d # время UTC
data2=get_sql(cand2_st, cand2_end, PERIOD) #расчет неполной свечи на момент d
data1.pop() #удалим последнюю, полную закрытую свечу
if len(data2)>0: # при расчете свечи на момент d может вернуться пустой список (если сделок не было)
data1.append(data2[-1])
if DEBUG: #отладка
print()
print('Расчет свечей из кэша :')
print('data1 =', data1)
print('cand2_st = ', cand2_st)
print('cand2_end = ', cand2_end)
print()
print('data2=',data2)
print()
print("Удаляем последнюю свечу")
print('data1 =', data1)
print()
print('Добавим последню свечу')
print('Если data2 не пустой')
print('Список в работу целиком :')
print('data1 =', data1)
return data1
else: #flg = False свечи рассчитываются напрямую запросом sql
#cand2_st = d - PERIOD*MACD*2*60 # время UTC
#cand2_end = d # время UTC
#data2=get_sql(cand2_st, cand2_end, PERIOD)
data2=get_sql(PERIOD)
if DEBUG:# отладка
print()
print('Тоже напрямую через SQL :')
#print('cand2_st = ', cand2_st)
#print('cand2_end = ', cand2_end)
print()
print('data2 =', data2)
return data2
# Выводит всякую информацию на экран, самое важное скидывает в Файл log.txt
def log(*args):
global USE_LOG
if USE_LOG:
# аккаунт 1
l = open("./log1.txt", 'a', encoding='utf-8')
# аккаунт 2
#l = open("./log2.txt", 'a', encoding='utf-8')
print(datetime.utcnow(), *args, file=l)
l.close()
print(datetime.utcnow(),' ', *args)
# Ф-ция для создания ордера на покупку
def create_buy(pair):
#global USE_LOG
#USE_LOG = True
log(pair, "Создаем ордер на покупку")
log(pair, 'Получаем текущие курсы')
offers = call_api('order_book', pair=pair)[pair]
try:
#current_rate = float(offers['ask'][0][0]) # покупка по лучшей цене
#current_rate = sum([float(item[0]) for item in offers['ask'][:3]])/3 # покупка по средней цене из трех лучших в стакане
#current_rate = sum([float(item[0]) for item in offers['bid'][:1]])+0.0000001 # покупка по самой выгодной цене в стакане
current_rate = float(offers['ask'][0][0]) # покупка по лучшей цене
#can_buy = CAN_SPEND/current_rate
can_buy = float(balances[pair[-3:]])/current_rate
print('buy', can_buy, current_rate)
log(pair, """
Текущая цена - %0.8f
На сумму %0.8f %s можно купить %0.8f %s
Создаю ордер на покупку
""" % (current_rate, CAN_SPEND, pair[0], can_buy, pair[1])
)
new_order = call_api(
'order_create',
pair = pair,
quantity = can_buy,
price = current_rate,
type = 'buy'
)
log("Создан ордер на покупку %s" % new_order['order_id'] )
except ZeroDivisionError:
print('Не удается вычислить цену', prices)
#USE_LOG = False
# Ф-ция для создания ордера на продажу
def create_sell(pair):
#global USE_LOG
#USE_LOG = True
balances = call_api('user_info')['balances']
#if float(balances[pair[:-4]]) >= CURRENCY_1_MIN_QUANTITY: # Есть ли в наличии CURRENCY_1, которую можно продать?
wanna_get = CAN_SPEND + CAN_SPEND * (STOCK_FEE + MARKUP)
order_amount = float(balances[pair[:-4]])
new_rate = wanna_get/order_amount
new_rate_fee = new_rate/(1-STOCK_FEE)
offers = call_api('order_book', pair=pair)[pair]
current_rate = float(offers['bid'][0][0]) # Берем верхнюю цену, по которой кто-то покупает
#choosen_rate = current_rate if current_rate > new_rate_fee else new_rate_fee
choosen_rate = float(offers['bid'][0][0]) # Берем верхнюю цену, по которой кто-то покупает
print('sell', balances[pair[:-4]], wanna_get, choosen_rate)
log(pair, "Создаем ордер на продажу")
log(pair, """
Итого на этот ордер было потрачено %0.8f %s, получено %0.8f %s
Что бы выйти в плюс, необходимо продать купленную валюту по курсу %0.8f
Тогда, после вычета комиссии %0.4f останется сумма %0.8f %s
Итоговая прибыль составит %0.8f %s
Текущий курс продажи %0.8f
Создаю ордер на продажу по курсу %0.8f
"""
% (
wanna_get, pair[0], order_amount, pair[1],
new_rate_fee,
STOCK_FEE, (new_rate_fee*order_amount - new_rate_fee * order_amount * STOCK_FEE), pair[0],
(new_rate_fee*order_amount - new_rate_fee*order_amount * STOCK_FEE)-wanna_get, pair[0],
current_rate,
choosen_rate,
)
)
new_order = call_api(
'order_create',
pair=pair,
quantity = balances[pair[:-4]],
price= choosen_rate,
type='sell'
)
log(pair, "Создан ордер на продажу %s" % new_order['order_id'])
print('Создан ордер на продажу', pair[:-4], new_order['order_id'])
if DEBUG:
print('Создан ордер на продажу', pair[:-4], new_order['order_id'])
#USE_LOG = False
# Ф-ция для определения падения цены покупки
def price_buy(): # Возвращает цену покупки
traders_orders = call_api('user_trades', pair=pair, limit=10)[pair]
buy_orders = []
for order in traders_orders:
if order['type'] == 'buy':
buy_orders.append(order)
price_buy = float(buy_orders[0]['price']) # Цена покупки по последнему ордеру
return (price_buy)
def get_grow(macdhist, last, porog):
if macdhist >= porog:
grow = True
if macdhist <= -porog:
grow = False
if macdhist < porog and macdhist > -porog:
grow = last
return grow
# Программа
date_last= 0 # предыдущая дата
date_last1 = 0
#trand = False
Trand_last = False
rows_list = []
# Бесконечный цикл процесса - основная логика
while True:
try:
print('Аккаунт 1')
#log('eue')
for pair in MARKETS: # Проходим по каждой паре из списка в начале\
try:
# Получаем список активных ордеров
try:
opened_orders = call_api('user_open_orders')[pair]
except KeyError:
if DEBUG:
print('Открытых ордеров нет')
log(pair, "Открытых ордеров нет")
opened_orders = []
sell_orders = []
# Есть ли неисполненные ордера на продажу CURRENCY_1?
#log(pair, " Обработка...")
for order in opened_orders:
if order['type'] == 'sell':
# Есть неисполненные ордера на продажу CURRENCY_1, выход
raise ScriptQuitCondition('Выход, ждем пока не исполнятся/закроются все ордера на продажу (один ордер может быть разбит биржей на несколько и исполняться частями)')
# пропуск продажи
# pass
else:
# Запоминаем ордера на покупку CURRENCY_1
sell_orders.append(order)
# Проверяем, есть ли открытые ордера на покупку CURRENCY_1
if sell_orders: # открытые ордера есть
for order in sell_orders:
# Проверяем, есть ли частично исполненные
if DEBUG:
print('Проверяем, что происходит с отложенным ордером', order['order_id'])
try:
order_history = call_api('order_trades', order_id=order['order_id'])
# по ордеру уже есть частичное выполнение, выход
#raise ScriptQuitCondition('Выход, продолжаем надеяться докупить валюту по тому курсу, по которому уже купили часть')
#LK
time_passed = time.time() - int(order['created'])
if time_passed > ORDER_LIFE_TIME * 60:
log('Пора отменять ордер %s' % order)
# Ордер уже давно висит, никому не нужен, отменяем
call_api('order_cancel', order_id=order['order_id'])
log('Ордер %s отменен' % order)
raise ScriptQuitCondition('Отменяем ордер -за ' + str(ORDER_LIFE_TIME) + ' минут не удалось купить ')
except ScriptError as e:
if 'Error 50304' in str(e):
if DEBUG:
print('Частично исполненных ордеров нет')
time_passed = time.time() - int(order['created'])
if time_passed > ORDER_LIFE_TIME * 60:
log('Пора отменять ордер %s' % order)
# Ордер уже давно висит, никому не нужен, отменяем
call_api('order_cancel', order_id=order['order_id'])
log('Ордер %s отменен' % order)
raise ScriptQuitCondition('Отменяем ордер -за ' + str(ORDER_LIFE_TIME) + ' минут не удалось купить ')
else:
raise ScriptQuitCondition('Выход, продолжаем надеяться купить валюту по указанному ранее курсу, со времени создания ордера прошло %s секунд' % str(time_passed))
else:
raise ScriptQuitCondition(str(e))
else: # Открытых ордеров нет
# Начинаем нашу торговлю
data1 = get_ticks()
PRICE2 = get_close(data1) # Текущая close по незакрытой свече
print('Текущая цена для стоплосса = ', PRICE2)
#print('последняя цена = ', get_close(data1))
ind = close_chk(data1[:-1]) # удаляем последнюю свечу
#print(ind)
# логгируем при смене свечи
if ind['date'] != date_last1: # логгируем при смене свечи
log(ind)
date_last1 = ind['date']
SS = False
ind['dat'] = datetime.utcnow()
#Trand = ind['Trand']
# Для транда MM опишем покупку
if (
ind['B1'] or ind['B2'] or ind['B3']
):
MM = True
# Для транда MM опишем продажу
if (
ind['S1'] or ind['S2'] or ind['S3'] or SS
):
MM = False
Trand = MM
ind['Trand'] = Trand
ind['SS'] = SS
ind['BUY'] = BUY
ind['TRADE'] = TRADE
print('Trand = ', Trand)
print('SS = ', SS)
print(ind)
#if Trand != Trand_last and Trand: #Если Trand и сменился
#BUY = True #
#macd_advice = close_chk(data1) #открытые свечи
#macdhist = macd_advice['macdhist']
#low = macd_advice['low']
#print('low = ',low)
#high = macd_advice['high']
#lowerband = macd_advice['lowerband']
#upperband = macd_advice['upperband']
#fastd = macd_advice['fastd']
#macdh_2 = macd_advice['macdhist-2']
#PRICE2 = macd_advice['close']
# ниже сделано для стоплосса:
#PRICE2 = get_close(data1) # Текущая close по незакрытой свече
#print('Текущая цена для стоплосса = ', PRICE2)
#GROW = get_grow(macdh_1, GROWLAST, 12)
#aro14 = macd_advice['aro14-1']
#aro14_1 = macd_advice['aro14-2']
#aro7 = macd_advice['aro7-1']
#aro7_1 = macd_advice['aro7-2']
#print(macd_advice)
# Определение смены тренда
# при торговле по тренду если продадим в цикле покупок до смены тренда
# нужно запретить повторные закупки TRADE = False
#if ( #условие смены тренда тоже что и после продажи
#not GROW
#GROW and not GROWLAST
#or (macd_advice['aro7-1'] < 0 and GROW)# Если пошел слив
#) :
#print('Сменился тренд торгуем')
#TRADE = True
#print('TRADE = ', TRADE)
#print(call_api('user_info'))
balances = call_api('user_info')['balances']
#print('balances', balances)
reserved = call_api('user_info')['reserved']
min_quantityy = call_api('pair_settings',pair=pair)[pair]
CURRENCY_1_MIN_QUANTITY = float(min_quantityy['min_quantity'])
# Покупка
if True:
#if BUY and TRADE :
#if TRADE: #Если TRADE = False значит сработал стоплосс ждем окончания свечи
if float(balances[pair[-3:]]) >= 20: # Если есть больше 20 USD
#if mm[2][-1]>=data1[-2]['high'] and macd_advice['k'] >= 1.001 : #покупаем
#if macd_advice['k'] >= 1.001 : #покупаем
#if macd_advice['ksma7'] >= 1.001 and mm[2][-1]>=data1[-2]['high']: #покупаем
#if GROW and not GROWLAST: # После смены тренда будем покупать при aro(7) < 0
#FIRST = True #
#print("Ждем покупки")
if ( # Условие покупки
#FIRST # После смены тренда будем покупать при aro(7) < 0
#or GROW and aro7 > 0 # Повторная закупка при aro(7) > 0
BUY and Trand
#and fastd > 22
):
log(ind)
log('Создаем ордер на покупку')
BUY = False # указываем цикл продаж
TRADE = True
create_buy(pair=pair)
else:
print('Ждем покупки')
else:
order = str(' В ордере :' + str(float(reserved[pair[:-4]])) + '. ' + str(pair[:-4])) if float(reserved[pair[:-4]]) > 0.0 else ''
#raise ScriptQuitCondition('Не хватает денег для торговли: баланс ' + str(round(float(balances[pair[-3:]]))) + ' ' + str(pair[-3:]) + order)
#else:
#print('Ожидание окончания свечи')
# Продажа
if TRADE:
print('торгуем!!!')
#if not BUY and TRADE:
#print(call_api('user_info'))
#balances = call_api('user_info')['balances']
#print('balances', balances)
#reserved = call_api('user_info')['reserved']
#min_quantityy = call_api('pair_settings',pair=pair)[pair]
#CURRENCY_1_MIN_QUANTITY = float(min_quantityy['min_quantity'])
#print('Баланс: '+str(float(balances[pair[:-4]]))+' '+str(pair[:-4]))
#if True:
if float(balances[pair[:-4]]) >= CURRENCY_1_MIN_QUANTITY: # Есть ли в наличии CURRENCY_1, которую можно продать?
print('Баланс: '+str(float(balances[pair[:-4]]))+' '+str(pair[:-4]))
PRICE = price_buy() # Цена покупки последнего ордера
ind['PRICE'] = PRICE
ind['PRICE2'] = PRICE2
if PRICE2 < PRICE * 0.99: #условие стоплосса
# SS будем держать пока не смениться свеча
SS = True # сигнал стоплосса сработает в следующем цикле
log('Это был стоплосс!!!')
#print('Цена последнего ордера = ',PRICE)
#if aro7 > 0: # когда стал положительным
#FIRST = False # отменяем
if ( # Условие продажи
not Trand
#or PRICE2 < PRICE * 0.99 #условие стоплосса
#or PRICE2 < 8415 #условие стоплосса
#not GROW
#or aro14_1 == 100 and aro14 < 100 and GROW and BUY100 and not FIRST # при aro14 = 100 январь 2018
#or aro7 < 0 and GROW and not FIRST # Для января 2018 жесткое условие
) :#Продаем
TRADE = False # Блокируем до конца тренда
#TRADE = True
#BUY = True
BUY = True
log('Сработал сигнал sell')
log('Создаем ордер на продажу')
log('PRICE = ', PRICE)
log('PRICE2 = ', PRICE2)
log(ind)
create_sell(pair=pair)
else:
print('Ожидаем продажу !!!')
else:
#print('Баланс: '+str(float(balances[pair[:-4]]))+' '+str(pair[:-4]))
print('Нет BTC для продажи')
else:
print('TRADE = ', TRADE)
if ind['date'] != date_last: # логгируем при смене свечи
date_last = ind['date']
rows_list.append(ind)
if ind['SS'] != SS_last: # логгируем при изменении сигнала SS
SS_last = ind['SS']
rows_list.append(ind)
except ScriptError as e:
print(e)
except ScriptQuitCondition as e:
print(e)
except Exception as e:
print("!!!!",e)
#except (KeyboardInterrupt, SystemExit):
#print("Exiting...")
#col = (
#['Date', 'Date_int', 'open', 'high', 'low', 'close', 'ao'
#]
#)
#df = pd.DataFrame(rows_list, columns=col)
#df = pd.DataFrame(df, columns=col)
#filename = 'backup-'+ datetime.utcnow().strftime("%Y%m%d-%H%M%S")+'.xlsx'
#writer = pd.ExcelWriter(filename)
#df.to_excel(writer,'Sheet1')
#writer.save()
#print('Файл ' + filename + ' сохранен!')
#break
time.sleep(1)
#GROWLAST = GROW
except Exception as e:
print(e)
except (KeyboardInterrupt, SystemExit):
print("Exiting...")
col = (
[
'dat','Date',
#'open', 'high', 'low',
'close',
'B1','B2','B3','S1','S2','S3','SS','ao',
'Trand','BUY','TRADE','PRICE','PRICE2'
]
)
df = pd.DataFrame(rows_list, columns=col)
#df = pd.DataFrame(df, columns=col)
filename = 'backup-'+ datetime.utcnow().strftime("%Y%m%d-%H%M%S")+'.xlsx'
writer = pd.ExcelWriter(filename)
df.to_excel(writer,'Sheet1')
writer.save()
print('Файл ' + filename + ' сохранен!')
break