def run(self): logger = self.logger prefix = self.prefix pair = self.pair mode = self.mode session_id = self.session_id capi = self.capi storage = self.storage limit = self.limit min_profit = self.min_profit #print mode, pair, session_id #return logger.info('-' * 40, prefix) logger.info( 'Run strategy %s, pair: %s mode: %i hold_currency %s' % (self.name, pair, mode, str(self.hold_currency)), prefix) #удаляем неактуальные записи об ордерах Lib.delete_orders_not_actual(self) #удаляем ордера по валютной паре, поставленные в своей сессии logger.info( 'Remove orders for pair %s in session %s' % (pair, session_id), prefix) Lib.delete_own_orders(self) time.sleep(3) #удаляем все ордера по паре #capi.orders_cancel([pair]) #получаем существующие ордера по валютной паре orders = capi.orders([pair]) #print orders #получаем лучшие цены покупки и продажи try: ask = orders[pair]['ask'][0][0] bid = orders[pair]['bid'][0][0] except KeyError: ask = orders['_'.join([pair.split('_')[1], pair.split('_')[0]])]['ask'][0][0] bid = orders['_'.join([pair.split('_')[1], pair.split('_')[0]])]['bid'][0][0] logger.info('pair %s: ask=%f bid=%f' % (pair, ask, bid), prefix) #получаем наличие своих средств balance = capi.balance() primary_balance = min(balance[pair.split('_')[0]], limit / ask) secondary_balance = min(balance[pair.split('_')[1]], limit) #сохраняем в базу последние сделки Lib.save_last_user_trades(self) logger.info( 'Balance: %s = %f; %s = %f' % (pair.split('_')[0], balance[pair.split('_')[0]], pair.split('_')[1], balance[pair.split('_')[1]]), prefix) logger.info( 'Balance with limit: %s = %f; %s = %f' % (pair.split('_')[0], primary_balance, pair.split('_')[1], secondary_balance), prefix) #комиссия try: fee = capi.fee[pair] except KeyError: fee = capi.fee['_'.join([pair.split('_')[1], pair.split('_')[0]])] logger.info('fee=%f' % fee, prefix) #минимальный шаг try: if 'decimal_places' in capi.pair_settings[pair]: min_price_step = 1.0 / (10**( capi.pair_settings[pair]['decimal_places'])) else: min_price_step = 0.000001 except KeyError: if 'decimal_places' in capi.pair_settings['_'.join( [pair.split('_')[1], pair.split('_')[0]])]: min_price_step = 1.0 / (10**(capi.pair_settings['_'.join([ pair.split('_')[1], pair.split('_')[0] ])]['decimal_places'])) else: min_price_step = 0.000001 #logger.info(min_price_step) #минимальный баланс первой и второй валют в паре для создания ордера min_primary_balance, min_secondary_balance = capi.get_min_balance(pair) #logger.info(min_primary_balance) #logger.info(min_secondary_balance) #биржа с нормальным названием пар if self.capi.name not in ['poloniex']: #если есть на балансе первая валюта if primary_balance > min_primary_balance: #новые цены продажи и покупки new_ask = ask - min_price_step new_bid = bid + min_price_step #вычисляем профит на основе верхней цены и нижней цены profit = new_ask / new_bid * (1 - fee) * (1 - fee) - 1 if profit <= min_profit: #вычисляем цену продажи исходя из текущей цены покупки и небольшого профита new_ask = new_bid * (1 + (2 * fee + min_profit)) #если первая валюта не является hold if (self.hold_currency is not None) and (self.pair.split('_')[0] in self.hold_currency): self.logger.info( 'Currency %s is hold!' % self.pair.split('_')[0], self.prefix) else: #ставим ордер на продажу Lib.order_create(self, 'sell', new_ask, primary_balance) time.sleep(2) #если есть на балансе вторая валюта if secondary_balance > min_secondary_balance: #новые цены продажи и покупки new_ask = ask - min_price_step new_bid = bid + min_price_step #вычисляем профит на основе верхней цены и нижней цены profit = new_ask / new_bid * (1 - fee) * (1 - fee) - 1 if profit <= min_profit: #если профита нет выставляем цену покупки ниже, на основе цены продажи и профита new_bid = new_ask * (1 - (2 * fee + min_profit)) #если вторая валюта не является hold if (self.hold_currency is not None) and (self.pair.split('_')[1] in self.hold_currency): self.logger.info( 'Currency %s is hold!' % self.pair.split('_')[1], self.prefix) else: #выставляем ордер на покупку Lib.order_create(self, 'buy', new_bid, secondary_balance / new_bid) #биржа с обратным название пар elif self.capi.name in ['poloniex']: #если есть на балансе вторая валюта if primary_balance > min_primary_balance: #новые цены продажи и покупки new_ask = ask - min_price_step new_bid = bid + min_price_step #вычисляем профит на основе верхней цены и нижней цены profit = new_ask / new_bid * (1 - fee) * (1 - fee) - 1 if profit <= min_profit: #вычисляем цену покупки исходя из текущей цены продажи и небольшого профита new_bid = new_ask * (1 - (2 * fee + min_profit)) # если первая валюта не является hold if (self.hold_currency is not None) and (self.pair.split('_')[0] in self.hold_currency): self.logger.info( 'Currency %s is hold!' % self.pair.split('_')[0], self.prefix) else: #выставляем ордер на покупку Lib.order_create(self, 'buy', new_bid, primary_balance / new_bid) time.sleep(2) #если есть на балансе первая валюта if secondary_balance > min_secondary_balance: #новые цены продажи и покупки new_ask = ask - min_price_step new_bid = bid + min_price_step #вычисляем профит на основе лучшей цены продажи и покупки profit = new_ask / new_bid * (1 - fee) * (1 - fee) - 1 if profit <= min_profit: #если профита нет выставляем цену продажи выше, на основе цены покупки и профита new_ask = new_bid * (1 + (2 * fee + min_profit)) #если вторая валюта не является hold if (self.hold_currency is not None) and (self.pair.split('_')[1] in self.hold_currency): self.logger.info( 'Currency %s is hold!' % self.pair.split('_')[1], self.prefix) else: #ставим ордер на продажу Lib.order_create(self, 'sell', new_ask, secondary_balance) else: #если неправильно задан mode raise Exception('incorrect capi.name value!')
def run(self): logger = self.logger prefix = self.prefix pair = self.pair mode = self.mode session_id = self.session_id capi = self.capi storage = self.storage limit = self.limit min_profit = self.min_profit #print mode, pair, session_id #return logger.info('-'*40, prefix) logger.info('Run strategy %s, pair: %s mode: %i' % (self.name, pair, mode), prefix) #удаляем неактуальные записи об ордерах Lib.delete_orders_not_actual(self) #удаляем ордера по валютной паре, поставленные в своей сессии logger.info('Удаляем ордера по %s в сессии %s' % (pair, session_id), prefix) Lib.delete_own_orders(self) time.sleep(3) #удаляем все ордера по паре #capi.orders_cancel([pair]) #получаем существующие ордера по валютной паре orders = capi.orders([pair]) #print orders #получаем лучшие цены покупки и продажи try: ask = orders[pair]['ask'][0][0] bid = orders[pair]['bid'][0][0] except KeyError: ask = orders['_'.join([pair.split('_')[1], pair.split('_')[0]])]['ask'][0][0] bid = orders['_'.join([pair.split('_')[1], pair.split('_')[0]])]['bid'][0][0] logger.info('pair %s: ask=%f bid=%f' % (pair, ask, bid), prefix) #получаем наличие своих средств balance = capi.balance() primary_balance = min(balance[pair.split('_')[0]], limit/ask) secondary_balance = min(balance[pair.split('_')[1]], limit) #сохраняем в базу последние сделки Lib.save_last_user_trades(self) logger.info('Balance: %s = %f; %s = %f' % (pair.split('_')[0], balance[pair.split('_')[0]], pair.split('_')[1], balance[pair.split('_')[1]]), prefix) logger.info('Balance with limit: %s = %f; %s = %f' % (pair.split('_')[0], primary_balance, pair.split('_')[1], secondary_balance), prefix) #комиссия try: fee = capi.fee[pair] except KeyError: fee = capi.fee['_'.join([pair.split('_')[1], pair.split('_')[0]])] #минимальный шаг try: if 'decimal_places' in capi.pair_settings[pair]: min_price_step = 1.0/(10**(capi.pair_settings[pair]['decimal_places'])) else: min_price_step = 0.000001 except KeyError: if 'decimal_places' in capi.pair_settings['_'.join([pair.split('_')[1], pair.split('_')[0]])]: min_price_step = 1.0/(10**(capi.pair_settings['_'.join([pair.split('_')[1], pair.split('_')[0]])]['decimal_places'])) else: min_price_step = 0.000001 #logger.info(min_price_step) #минимальный баланс первой и второй валют в паре для создания ордера min_primary_balance, min_secondary_balance = capi.get_min_balance(pair) #logger.info(min_primary_balance) #logger.info(min_secondary_balance) #сохраняем балансы в базу для сбора статистики if primary_balance < min_primary_balance: Lib.save_change_balance(self, pair.split('_')[1], balance[pair.split('_')[1]]) if secondary_balance < min_secondary_balance: Lib.save_change_balance(self, pair.split('_')[0], balance[pair.split('_')[0]]) #вычисляем цены покупки и продажи prices = Lib.calc_prices(self, orders, min_price_step, fee) new_ask = prices['ask'] new_bid = prices['bid'] logger.info('new_ask=%f new_bid=%f' % (new_ask, new_bid), prefix) #если наращиваем вторую валюту в паре(игра на повышении) if mode == 0: #если есть на балансе первая валюта if primary_balance > min_primary_balance: #ставим ордер на продажу Lib.order_create(self, 'sell', new_ask, primary_balance) time.sleep(2) #если есть на балансе вторая валюта if secondary_balance > min_secondary_balance: #выставляем ордер на покупку Lib.order_create(self, 'buy', new_bid, secondary_balance/new_bid) #если наращиваем первую валюту в паре (игра на понижении) elif mode == 1: #если есть на балансе вторая валюта if secondary_balance > min_secondary_balance: #выставляем ордер на покупку Lib.order_create(self, 'buy', new_bid, secondary_balance/new_bid) time.sleep(2) #если есть на балансе первая валюта if primary_balance > min_primary_balance: #ставим ордер на продажу Lib.order_create(self, 'sell', new_ask, primary_balance) else: #если неправильно задан mode raise Exception('incorrect mode value: expected 0 or 1!')
def run(self): #print mode, pair, session_id #return self.logger.info('-' * 40, self.prefix) self.logger.info( 'Run strategy %s, pairs: %s, sell_order_ttl: %i hours' % (self.name, str(self.pairs), self.sell_order_ttl), self.prefix) self.logger.info( 'Order_limits: %s, Limits: %s' % (str(self.order_limits), str(self.limits)), self.prefix) #получаем свои ордера user_orders = self.capi.user_orders() #удаляем неактуальные записи об ордерах в базе Lib.delete_orders_not_actual(self, user_orders) #получаем ticker ticker = self.capi.ticker() #удаляем ордера "BUY" и ордера "SELL" с истекшим временем жизни now = int(time.time()) max_delta_time = self.sell_order_ttl * 3600 sum_in_orders = {} for pair, user_orders_for_pair in user_orders.items(): for user_order_for_pair in user_orders_for_pair: if user_order_for_pair['type'] == 'buy': order_id = int(user_order_for_pair['order_id']) res = self.capi.order_cancel(order_id) if 'result' in res and res['result'] == True: self.logger.info( 'order "BUY" id=%i removed succesfully' % order_id, self.prefix) else: self.logger.error( 'ERROR while removing order "BUY" id=%i' % order_id, self.prefix) elif user_order_for_pair['type'] == 'sell': created = int(user_order_for_pair['created']) if ( now - created ) > max_delta_time: #если ордер слишком старый удаляем его order_id = int(user_order_for_pair['order_id']) res = self.capi.order_cancel(order_id) if 'result' in res and res['result'] == True: self.logger.info( 'order "SELL" id=%i expired and removed succesfully' % order_id, self.prefix) self.storage.delete(pair + '_ask') else: self.logger.error( 'ERROR while removing order "SELL" id=%i' % order_id, self.prefix) else: #иначе учитываем сумму в ордере как вложенную в торги по данной паре if pair not in sum_in_orders: sum_in_orders[pair] = 0.0 sum_in_orders[pair] += user_order_for_pair['amount'] if self.stop_trade > 0: self.logger.info('Stopping trade...') return #перебираем пары с которыми работаем for pair in self.pairs: self.pair = pair # получаем наличие своих средств balance = self.capi.balance() ask = max(ticker[pair]['sell_price'], ticker[pair]['buy_price']) bid = min(ticker[pair]['sell_price'], ticker[pair]['buy_price']) order_limit = self.order_limits[pair] if pair in sum_in_orders: limit = self.limits[pair] - sum_in_orders[pair] else: limit = self.limits[pair] secondary_balance = min(balance[pair.split('_')[1]], limit, order_limit) primary_balance = balance[pair.split('_')[0]] self.logger.info('pair %s, ask = %f, bid = %f' % (pair, ask, bid), self.prefix) self.logger.info( 'Balance: %s = %f; %s = %f' % (pair.split('_')[0], balance[pair.split('_')[0]], pair.split('_')[1], balance[pair.split('_')[1]]), self.prefix) self.logger.info( 'Balance with limit: %s = %f; %s = %f' % (pair.split('_')[0], primary_balance, pair.split('_')[1], secondary_balance), self.prefix) #комиссия try: fee = self.capi.fee[pair] except KeyError: fee = self.capi.fee['_'.join( [pair.split('_')[1], pair.split('_')[0]])] self.logger.info('fee=%f' % fee, self.prefix) #минимальный шаг try: if 'decimal_places' in self.capi.pair_settings[pair]: min_price_step = 1.0 / (10**( self.capi.pair_settings[pair]['decimal_places'])) else: min_price_step = 0.000001 except KeyError: if 'decimal_places' in self.capi.pair_settings['_'.join( [pair.split('_')[1], pair.split('_')[0]])]: min_price_step = 1.0 / (10**(self.capi.pair_settings[ '_'.join([pair.split('_')[1], pair.split('_')[0]])]['decimal_places'])) else: min_price_step = 0.000001 #logger.info(min_price_step) #минимальный баланс первой и второй валют в паре для создания ордера min_primary_balance, min_secondary_balance = self.capi.get_min_balance( pair, ticker) profit = (ask - min_price_step) / (bid + min_price_step) * ( 1 - fee) * (1 - fee) - 1.0 self.logger.info('Profit on pair %s = %f' % (pair, profit), self.prefix) #logger.info(min_primary_balance) #logger.info(min_secondary_balance) #биржа с нормальным названием пар if self.capi.name not in ['poloniex']: # если разбег цен обеспечивает профит и вторая валюта есть if secondary_balance >= min_secondary_balance and profit >= self.min_profit: #новые цены продажи и покупки new_ask = ask - min_price_step new_bid = bid + min_price_step # выставляем ордер на покупку Lib.order_create(self, 'buy', new_bid, secondary_balance / new_bid) #сохраняем данные по цене self.storage.save(pair + '_ask', new_ask, 'float') self.storage.save(pair + '_bid', new_bid, 'float') else: self.logger.info( 'No profit or no balance, no action required...', self.prefix) time.sleep(2) # если есть на балансе первая валюта if primary_balance >= min_primary_balance: saved_ask = self.storage.load(pair + '_ask') if saved_ask is None: saved_ask = 0.0 sell_price = max(saved_ask, ask - min_price_step) # ставим ордер на продажу Lib.order_create(self, 'sell', sell_price, primary_balance) #биржа с обратным названием пар elif self.capi.name in ['poloniex']: # если есть на балансе первая валюта if primary_balance >= min_primary_balance and profit >= self.min_profit: # новые цены продажи и покупки new_ask = ask - min_price_step new_bid = bid + min_price_step # выставляем ордер на покупку Lib.order_create(self, 'buy', new_bid, primary_balance / new_bid) # сохраняем данные по цене self.storage.save(pair + '_ask', new_ask, 'float') self.storage.save(pair + '_bid', new_bid, 'float') else: self.logger.info( 'No profit or no balance, no action required...', self.prefix) time.sleep(2) if secondary_balance >= min_secondary_balance: saved_ask = self.storage.load(pair + '_ask') if saved_ask is None: saved_ask = 0.0 sell_price = max(saved_ask, ask - min_price_step) # ставим ордер на продажу Lib.order_create(self, 'sell', sell_price, secondary_balance) #сохраняем последние сделки Lib.save_last_user_trades2(self) #сохраняем балансы для статистики balance_full = self.capi.balance_full() full_usd_balance = self.capi.balance_full_usd(balance_full, ticker) full_btc_balance = self.capi.balance_full_btc(balance_full, ticker) Lib.save_change_balance2(self, 'USD', full_usd_balance) Lib.save_change_balance2(self, 'BTC', full_btc_balance)
def run(self): logger = self.logger prefix = self.prefix pair = self.pair capi = self.capi #print mode, pair, session_id #return logger.info('-' * 40, prefix) logger.info('Run strategy %s, pair: %s' % (self.name, pair), prefix) user_trades = self.capi.user_trades([self.pair]) # минимальный баланс первой и второй валют в паре для создания ордера min_primary_balance, min_secondary_balance = capi.get_min_balance(pair) #получаем наличие своих средств balance = capi.balance() primary_balance = balance[pair.split('_')[0]] secondary_balance = balance[pair.split('_')[1]] logger.info( 'Balance with limit: %s = %f; %s = %f' % (pair.split('_')[0], primary_balance, pair.split('_')[1], secondary_balance), prefix) #комиссия try: self.fee = capi.fee[pair] except KeyError: self.fee = capi.fee['_'.join( [pair.split('_')[1], pair.split('_')[0]])] logger.info('fee=%f' % self.fee, prefix) #logger.info(min_price_step) #logger.info(min_primary_balance) #logger.info(min_secondary_balance) #биржа с нормальным названием пар if self.capi.name not in ['poloniex']: #если есть на балансе первая валюта if primary_balance > min_primary_balance: new_ask = Lib.calc_price_sell(self, primary_balance, user_trades) if new_ask is None: return False #ставим ордер на продажу Lib.order_create(self, 'sell', new_ask, primary_balance) #биржа с обратным название пар elif self.capi.name in ['poloniex']: #если есть на балансе первая валюта if secondary_balance > min_secondary_balance: new_ask = Lib.calc_price_sell(self, secondary_balance, user_trades) if new_ask is None: return False #ставим ордер на продажу Lib.order_create(self, 'sell', new_ask, secondary_balance) else: #если неправильно задан mode raise Exception('incorrect capi.name value!')
def run(self): logger = self.logger prefix = self.prefix pair = self.pair session_id = self.session_id capi = self.capi storage = self.storage limit = self.limit min_profit = self.min_profit #print mode, pair, session_id #return logger.info('-' * 40, prefix) logger.info( 'Run strategy %s, pair: %s hold_currency %s' % (self.name, pair, str(self.hold_currency)), prefix) #удаляем неактуальные записи об ордерах Lib.delete_orders_not_actual(self) #удаляем ордера по валютной паре, поставленные в своей сессии logger.info( 'Remove orders for pair %s in session %s' % (pair, session_id), prefix) Lib.delete_own_orders(self) time.sleep(3) #удаляем все ордера по паре #capi.orders_cancel([pair]) #получаем существующие ордера по валютной паре orders = capi.orders([pair]) #print orders #получаем историю торгов trades = capi.trades([pair]) #получаем лучшие цены покупки и продажи try: ask = orders[pair]['ask'][0][0] bid = orders[pair]['bid'][0][0] except KeyError: ask = orders['_'.join([pair.split('_')[1], pair.split('_')[0]])]['ask'][0][0] bid = orders['_'.join([pair.split('_')[1], pair.split('_')[0]])]['bid'][0][0] logger.info('pair %s: ask=%f bid=%f' % (pair, ask, bid), prefix) #получаем наличие своих средств balance = capi.balance() primary_balance = min(balance[pair.split('_')[0]], limit / ask) secondary_balance = min(balance[pair.split('_')[1]], limit) #сохраняем в базу последние сделки Lib.save_last_user_trades(self) logger.info( 'Balance: %s = %f; %s = %f' % (pair.split('_')[0], balance[pair.split('_')[0]], pair.split('_')[1], balance[pair.split('_')[1]]), prefix) logger.info( 'Balance with limit: %s = %f; %s = %f' % (pair.split('_')[0], primary_balance, pair.split('_')[1], secondary_balance), prefix) #комиссия try: fee = capi.fee[pair] except KeyError: fee = capi.fee['_'.join([pair.split('_')[1], pair.split('_')[0]])] logger.info('fee=%f' % fee, prefix) #минимальный шаг try: if 'decimal_places' in capi.pair_settings[pair]: min_price_step = 1.0 / (10**( capi.pair_settings[pair]['decimal_places'])) else: min_price_step = 0.000001 except KeyError: if 'decimal_places' in capi.pair_settings['_'.join( [pair.split('_')[1], pair.split('_')[0]])]: min_price_step = 1.0 / (10**(capi.pair_settings['_'.join([ pair.split('_')[1], pair.split('_')[0] ])]['decimal_places'])) else: min_price_step = 0.000001 logger.info('min_price_step %f' % min_price_step, prefix) ticker = capi.ticker() #минимальный баланс первой и второй валют в паре для создания ордера min_primary_balance, min_secondary_balance = capi.get_min_balance( pair, ticker) logger.info('min_primary_balance %f' % min_primary_balance, prefix) logger.info('min_secondary_balance %f' % min_secondary_balance, prefix) #сохраняем балансы в базу для сбора статистики if primary_balance < min_primary_balance: Lib.save_change_balance(self, pair.split('_')[1], balance[pair.split('_')[1]]) if secondary_balance < min_secondary_balance: Lib.save_change_balance(self, pair.split('_')[0], balance[pair.split('_')[0]]) full_equal_usd = capi.balance_full_usd(ticker) full_equal_btc = capi.balance_full_btc(ticker) Lib.save_change_balance(self, 'FULL_EQUAL_USD', full_equal_usd) Lib.save_change_balance(self, 'FULL_EQUAL_BTC', full_equal_btc) Lib.save_statistic_data(self, orders=orders, trades=trades, store_time=5) price_trend = Lib.detect_marker_direct(self, pair=pair, time_interval=30) if price_trend is not None and price_trend >= 0: #тренд восходящий logger.info('trend is bull(up)', prefix) #биржа с нормальным названием пар if self.capi.name not in ['poloniex']: #если есть на балансе первая валюта if primary_balance > min_primary_balance: #новые цены продажи и покупки new_ask = ask - min_price_step new_bid = bid + min_price_step #вычисляем профит на основе верхней цены и нижней цены profit = new_ask / new_bid * (1 - fee) * (1 - fee) - 1 if profit < min_profit: #вычисляем цену продажи исходя из текущей цены покупки и небольшого профита new_ask = new_bid * (1 + (2 * fee + min_profit)) #если первая валюта не является hold if (self.hold_currency is not None) and (self.pair.split('_')[0] in self.hold_currency): self.logger.info( 'Currency %s is hold!' % self.pair.split('_')[0], self.prefix) else: #ставим ордер на продажу Lib.order_create(self, 'sell', new_ask, primary_balance) time.sleep(2) #если есть на балансе вторая валюта if secondary_balance > min_secondary_balance: #новые цены продажи и покупки new_ask = ask - min_price_step new_bid = bid + min_price_step #вычисляем профит на основе верхней цены и нижней цены profit = new_ask / new_bid * (1 - fee) * (1 - fee) - 1 # выставляем цену покупки по верху стакана #если вторая валюта не является hold if (self.hold_currency is not None) and (self.pair.split('_')[1] in self.hold_currency): self.logger.info( 'Currency %s is hold!' % self.pair.split('_')[1], self.prefix) else: #выставляем ордер на покупку Lib.order_create(self, 'buy', new_bid, secondary_balance / new_bid) #биржа с обратным название пар else: #если есть на балансе вторая валюта if primary_balance > min_primary_balance: #новые цены продажи и покупки new_ask = ask - min_price_step new_bid = bid + min_price_step #вычисляем профит на основе верхней цены и нижней цены profit = new_ask / new_bid * (1 - fee) * (1 - fee) - 1 #ставим цену покупки по верху стакана # если первая валюта не является hold if (self.hold_currency is not None) and (self.pair.split('_')[0] in self.hold_currency): self.logger.info( 'Currency %s is hold!' % self.pair.split('_')[0], self.prefix) else: #выставляем ордер на покупку Lib.order_create(self, 'buy', new_bid, primary_balance / new_bid) time.sleep(2) #если есть на балансе первая валюта if secondary_balance > min_secondary_balance: #новые цены продажи и покупки new_ask = ask - min_price_step new_bid = bid + min_price_step #вычисляем профит на основе лучшей цены продажи и покупки profit = new_ask / new_bid * (1 - fee) * (1 - fee) - 1 if profit < min_profit: #если профита нет выставляем цену продажи выше, на основе цены покупки и профита new_ask = new_bid * (1 + (2 * fee + min_profit)) #если вторая валюта не является hold if (self.hold_currency is not None) and (self.pair.split('_')[1] in self.hold_currency): self.logger.info( 'Currency %s is hold!' % self.pair.split('_')[1], self.prefix) else: #ставим ордер на продажу Lib.order_create(self, 'sell', new_ask, secondary_balance) elif price_trend is not None and price_trend < 0: #тренд нисходящий logger.info('trend is bear(down)', prefix) # биржа с нормальным названием пар if self.capi.name not in ['poloniex']: # если есть на балансе первая валюта if primary_balance > min_primary_balance: # новые цены продажи и покупки new_ask = ask - min_price_step new_bid = bid + min_price_step # вычисляем профит на основе верхней цены и нижней цены profit = new_ask / new_bid * (1 - fee) * (1 - fee) - 1 #ставим цену продажи по верху стакана # если первая валюта не является hold if (self.hold_currency is not None) and (self.pair.split('_')[0] in self.hold_currency): self.logger.info( 'Currency %s is hold!' % self.pair.split('_')[0], self.prefix) else: # ставим ордер на продажу Lib.order_create(self, 'sell', new_ask, primary_balance) time.sleep(2) # если есть на балансе вторая валюта if secondary_balance > min_secondary_balance: # новые цены продажи и покупки new_ask = ask - min_price_step new_bid = bid + min_price_step # вычисляем профит на основе верхней цены и нижней цены profit = new_ask / new_bid * (1 - fee) * (1 - fee) - 1 if profit <= min_profit: # если профита нет выставляем цену покупки ниже, на основе цены продажи и профита new_bid = new_ask * (1 - (2 * fee + min_profit)) # если вторая валюта не является hold if (self.hold_currency is not None) and (self.pair.split('_')[1] in self.hold_currency): self.logger.info( 'Currency %s is hold!' % self.pair.split('_')[1], self.prefix) else: # выставляем ордер на покупку Lib.order_create(self, 'buy', new_bid, secondary_balance / new_bid) # биржа с обратным название пар else: # если есть на балансе вторая валюта if primary_balance > min_primary_balance: # новые цены продажи и покупки new_ask = ask - min_price_step new_bid = bid + min_price_step # вычисляем профит на основе верхней цены и нижней цены profit = new_ask / new_bid * (1 - fee) * (1 - fee) - 1 if profit <= min_profit: # вычисляем цену покупки исходя из текущей цены продажи и небольшого профита new_bid = new_ask * (1 - (2 * fee + min_profit)) # если первая валюта не является hold if (self.hold_currency is not None) and (self.pair.split('_')[0] in self.hold_currency): self.logger.info( 'Currency %s is hold!' % self.pair.split('_')[0], self.prefix) else: # выставляем ордер на покупку Lib.order_create(self, 'buy', new_bid, primary_balance / new_bid) time.sleep(2) # если есть на балансе первая валюта if secondary_balance > min_secondary_balance: # новые цены продажи и покупки new_ask = ask - min_price_step new_bid = bid + min_price_step # вычисляем профит на основе лучшей цены продажи и покупки profit = new_ask / new_bid * (1 - fee) * (1 - fee) - 1 #ставим цену продажи по верху стакана # если вторая валюта не является hold if (self.hold_currency is not None) and (self.pair.split('_')[1] in self.hold_currency): self.logger.info( 'Currency %s is hold!' % self.pair.split('_')[1], self.prefix) else: # ставим ордер на продажу Lib.order_create(self, 'sell', new_ask, secondary_balance) else: #тренд не определен logger.info('trend not defined', prefix) #вычисляем цены покупки и продажи prices = Lib.calc_prices(self, orders, min_price_step, fee) new_ask = prices['ask'] new_bid = prices['bid'] logger.info('new_ask=%f new_bid=%f' % (new_ask, new_bid), prefix) #если есть на балансе первая валюта if primary_balance > min_primary_balance: #ставим ордер на продажу Lib.order_create(self, 'sell', new_ask, primary_balance) time.sleep(2) #если есть на балансе вторая валюта if secondary_balance > min_secondary_balance: #выставляем ордер на покупку Lib.order_create(self, 'buy', new_bid, secondary_balance / new_bid)
def run(self): logger = self.logger prefix = self.prefix pair = self.pair mode = self.mode session_id = self.session_id capi = self.capi storage = self.storage limit = self.limit min_profit = self.min_profit #print mode, pair, session_id #return logger.info('-' * 40, prefix) logger.info( 'Run strategy %s, pair: %s mode: %i hold_currency %s' % (self.name, pair, mode, str(self.hold_currency)), prefix) #удаляем неактуальные записи об ордерах Lib.delete_orders_not_actual(self) #удаляем ордера по валютной паре, поставленные в своей сессии logger.info('Удаляем ордера по %s в сессии %s' % (pair, session_id), prefix) Lib.delete_own_orders(self) #удаляем все ордера по паре #capi.orders_cancel([pair]) #получаем существующие ордера по валютной паре orders = capi.orders([pair]) #print orders #получаем лучшие цены покупки и продажи ask = orders[pair]['ask'][0][0] bid = orders[pair]['bid'][0][0] logger.info('pair %s: ask=%f bid=%f' % (pair, ask, bid), prefix) #получаем наличие своих средств balance = capi.balance() primary_balance = min(balance[pair.split('_')[0]], limit / ask) secondary_balance = min(balance[pair.split('_')[1]], limit) #сохраняем в базу последние сделки Lib.save_last_user_trades(self) logger.info( 'Balance: %s = %f; %s = %f' % (pair.split('_')[0], balance[pair.split('_')[0]], pair.split('_')[1], balance[pair.split('_')[1]]), prefix) logger.info( 'Balance with limit: %s = %f; %s = %f' % (pair.split('_')[0], primary_balance, pair.split('_')[1], secondary_balance), prefix) #комиссия fee = capi.fee[pair] #минимальный шаг if 'decimal_places' in capi.pair_settings[pair]: min_price_step = 1.0 / (10**( capi.pair_settings[pair]['decimal_places'])) else: min_price_step = 0.000001 #logger.info(min_price_step) #минимальный баланс первой и второй валют в паре для создания ордера min_primary_balance, min_secondary_balance = capi.get_min_balance(pair) #logger.info(min_primary_balance) #logger.info(min_secondary_balance) #если наращиваем вторую валюту в паре(игра на повышении) if mode == 0: #получаем цену предыдущей покупки prev_price = storage.load( pair.split('_')[0] + '_buy_price', session_id) #logger.info('prev_price=%s' % str(prev_price), prefix) #если есть на балансе первая валюта if primary_balance > min_primary_balance: #новые цены продажи и покупки new_ask = ask - min_price_step new_bid = bid + min_price_step if prev_price is not None: #если монеты уже покупались #вычисляем профит на основе верхней цены продажи и цены покупки profit = new_ask / prev_price * (1 - fee) * (1 - fee) - 1 if profit <= min_profit: #если профита нет, то цену ставим побольше (пониже по стакану) но с профитом new_ask = prev_price * (1 + (2 * fee + min_profit)) else: #если монеты не покупались #вычисляем профит на основе верхней цены и нижней цены profit = new_ask / new_bid * (1 - fee) * (1 - fee) - 1 if profit <= min_profit: #вычисляем цену продажи исходя из текущей цены покупки и небольшого профита new_ask = new_bid * (1 + (2 * fee + min_profit)) #ставим ордер на продажу Lib.order_create(self, 'sell', new_ask, primary_balance) else: #если первой валюты на балансе нет удаляем цену покупки storage.delete(pair.split('_')[0] + '_buy_price', session_id) #сохраняем баланс по второй валюте в базу Lib.save_change_balance(self, pair.split('_')[1], balance[pair.split('_')[1]]) time.sleep(2) #если есть на балансе вторая валюта if secondary_balance > min_secondary_balance: #новые цены продажи и покупки new_ask = ask - min_price_step new_bid = bid + min_price_step #вычисляем профит на основе верхней цены и нижней цены profit = new_ask / new_bid * (1 - fee) * (1 - fee) - 1 if profit <= min_profit: #если профита нет выставляем цену покупки ниже, на основе цены продажи и профита new_bid = new_ask * (1 - (2 * fee + min_profit)) #выставляем ордер на покупку и запоминаем цену покупки if Lib.order_create(self, 'buy', new_bid, secondary_balance / new_bid): storage.save( pair.split('_')[0] + '_buy_price', new_bid, 'float', session_id) else: #сохраняем баланс по первой валюте в базу Lib.save_change_balance(self, pair.split('_')[0], balance[pair.split('_')[0]]) #если наращиваем первую валюту в паре (игра на понижении) elif mode == 1: #если есть на балансе вторая валюта if secondary_balance > min_secondary_balance: #получаем цену предыдущей продажи prev_price = storage.load( pair.split('_')[0] + '_sell_price', session_id) #logger.info('prev_price=%s' % str(prev_price), prefix) #новые цены продажи и покупки new_ask = ask - min_price_step new_bid = bid + min_price_step if prev_price is not None: #если монеты уже продавались #вычисляем профит на основе верхней цены покупки и цены продажи profit = prev_price / new_bid * (1 - fee) * (1 - fee) - 1 if profit <= min_profit: #если профита нет, то цену ставим поменьше (пониже по стакану) но с профитом new_bid = prev_price * (1 - (2 * fee + min_profit)) else: #если монеты не продавались #вычисляем профит на основе верхней цены и нижней цены profit = new_ask / new_bid * (1 - fee) * (1 - fee) - 1 if profit <= min_profit: #вычисляем цену покупки исходя из текущей цены продажи и небольшого профита new_bid = new_ask * (1 - (2 * fee + min_profit)) #выставляем ордер на покупку Lib.order_create(self, 'buy', new_bid, secondary_balance / new_bid) else: #если второй валюты на балансе нет, то удаляем цену продажи storage.delete(pair.split('_')[0] + '_sell_price', session_id) #сохраняем баланс по первой валюте в базу Lib.save_change_balance(self, pair.split('_')[0], balance[pair.split('_')[0]]) time.sleep(2) #если есть на балансе первая валюта if primary_balance > min_primary_balance: #новые цены продажи и покупки new_ask = ask - min_price_step new_bid = bid + min_price_step #вычисляем профит на основе лучшей цены продажи и покупки profit = new_ask / new_bid * (1 - fee) * (1 - fee) - 1 if profit <= min_profit: #если профита нет выставляем цену продажи выше, на основе цены покупки и профита new_ask = new_bid * (1 + (2 * fee + min_profit)) #ставим ордер на продажу и запоминаем цену продажи if Lib.order_create(self, 'sell', new_ask, primary_balance): storage.save( pair.split('_')[0] + '_sell_price', new_ask, 'float', session_id) else: #сохраняем баланс по второй валюте в базу Lib.save_change_balance(self, pair.split('_')[1], balance[pair.split('_')[1]]) else: #если неправильно задан mode raise Exception('incorrect mode value: expected 0 or 1!')
def run(self): self.logger.info('-' * 40, self.prefix) self.logger.info('Run strategy %s, pair: %s' % (self.name, self.pair), self.prefix) #Получаем ордера на покупку orders = self.capi.orders([self.pair]) try: buy_orders = orders[self.pair]['bid'] except KeyError: buy_orders = orders[Lib.reverse_pair(self.pair)]['bid'] #минимальный баланс первой и второй валют в паре для создания ордера ticker = self.capi.ticker() min_primary_balance, min_secondary_balance = self.capi.get_min_balance( self.pair, ticker) #получаем комиссию self.fee = self.capi.fee[self.capi.check_pair(self.pair)] #удаляем все ордера по паре self.capi.orders_cancel([self.pair]) #удаляем неактуальные записи об ордерах Lib.delete_orders_not_actual(self) #получаем наличие своих средств balance = self.capi.balance() primary_balance = balance[self.pair.split('_')[0]] secondary_balance = min(balance[self.pair.split('_')[1]], self.limit) #сохраняем в базу последние сделки Lib.save_last_user_trades(self) # сохраняем балансы в базу для сбора статистики if primary_balance < min_primary_balance: Lib.save_change_balance(self, self.pair.split('_')[1], balance[self.pair.split('_')[1]]) if secondary_balance < min_secondary_balance: Lib.save_change_balance(self, self.pair.split('_')[0], balance[self.pair.split('_')[0]]) self.logger.info( 'balance: %s=%f; %s=%f' % (self.pair.split('_')[0], primary_balance, self.pair.split('_')[1], secondary_balance), self.prefix) #если баланс по 2 валюте достаточен if secondary_balance >= min_secondary_balance: self.logger.info('buing %s' % self.pair.split('_')[0], self.prefix) #цена покупки по процентам buy_price_percent = buy_orders[0][0] * ( 1 - self.margin_down_percent / 100.0) #цена покупки по сумме temp_amount = 0.0 for row in buy_orders: order_price = row[0] order_quantity = row[1] order_amount = row[2] temp_amount += order_amount if temp_amount >= self.margin_down_volume: buy_price_amount = order_price break buy_price = min(buy_price_percent, buy_price_amount) self.logger.info( 'top_buy_price=%f; buy_price_percent=%f; buy_price_amount=%f' % (buy_orders[0][0], buy_price_percent, buy_price_amount), self.prefix) Lib.order_create(self, 'buy', buy_price, secondary_balance / buy_price) self.storage.save(self.session_id + 'buy_price', buy_price, 'float', self.session_id) #сохраняем закупочную цену #если баланс по первой валюте достаточен if primary_balance >= min_primary_balance: self.logger.info( 'checking selling %s profitness' % self.pair.split('_')[0], self.prefix) #получаем историю торгов по паре и сортируем по времени user_trades = self.capi.user_trades([self.pair]) user_trades = sorted(user_trades[self.capi.check_pair(self.pair)], key=lambda row: -row['date']) #вычисляем сколько мы потратили второй валюты на покупку имеющегося количества первой валюты (amount1) curr_quantity = 0.0 amount1 = 0.0 trades_data_valid = False for trade in user_trades: if trade['type'] == 'sell' or trade[ 'pair'] != self.capi.check_pair(self.pair): continue print 'quantity=%f; amount=%f' % (trade['quantity'], trade['amount']) curr_quantity += trade['quantity'] amount1 += trade['amount'] #print 'q=%f a=%f time=%s' % (trade['quantity'], trade['amount'], time.ctime(trade['date'])) if Lib._round(curr_quantity * (1 - self.fee), 5) >= Lib._round( primary_balance, 5): trades_data_valid = True break #обрабатываем когда нет данных о сделках if not trades_data_valid: amount1 = primary_balance / self.storage.load( self.session_id + 'buy_price', self.session_id) #вычисляем из ордеров на покупку за сколько можно продать по рынку имеющееся количество первой валюты (amount2) amount2 = self.capi.possable_amount( self.pair.split('_')[0], self.pair.split('_')[1], primary_balance, orders) self.logger.info('amount1=%f; amount2=%f' % (amount1, amount2), self.prefix) if amount2 * (1 - self.fee) > amount1: #если цена восстановилась self.logger.info( 'selling %s by market' % self.pair.split('_')[0], self.prefix) #продаем по рынку первую валюту pair = self.capi.check_pair(self.pair) chain = { 'chain': [{ 'pair': pair, 'currency': self.pair.split('_')[0], 'order_type': 'sell' }] } res = self.capi.execute_exchange_chain(chain, primary_balance) self.logger.info(str(res), self.prefix)