def handle(self, *args, **options): email = options.get('email') exchange = options.get('exchange') if not email: raise CommandError( "Please provide --account_email. See details --help" ) accounts = Account.objects.filter( user__email=email, exchange__name=exchange ) if not accounts.exists(): raise CommandError( f"Could not find account for {exchange} with {email} email" ) for account in accounts: if not all([account.api_key, account.api_secret]): raise CommandError( "Wrong account, check that API_KEY and API_SECRET were provided for this account, and they correct." ) bittrex = Bittrex( account.api_key, account.api_secret, # api_version=API_V2_0 api_version=API_V1_1 ) response = bittrex.get_order_history() orders = response.get('result') if orders is None: self.stdout.write(f'There no new orders: API response - {response}') self.save_orders(account, orders) self.stdout.write('Done')
def __init__(self): self.log = logging.getLogger('crypto') #a list of all active investments self.holdings = [] #a record of all active trades self.trades = [] self.budget = 0 #a list of indicators used validate trade positions self.indicators = ["macd", "bbands"] #in memory data store for each market's analysis self.datastore = {} self.exchange = Bittrex() #candlestick chart data self.cs = None self.framesize = "5m" self.timeframe = "24h" self.settings = {"limit": 0.02, "profit": 0.03, "trailing_stop": 0.01}
def __init__(self, secrets): self.trade_params = secrets["tradeParameters"] self.pause_params = secrets["pauseParameters"] self.Bittrex = Bittrex(secrets) self.Messenger = Messenger(secrets) self.Database = Database()
class bittrex_public: def __init__(self): self.bittrex_public = Bittrex(None, None) # 公開情報を扱うBittrexオブジェクト # 取引可能通貨サマリ一覧をList型で返す def get_coin_summery_list(self): coin_summery_list = [] response = self.bittrex_public.get_markets() for item in response['result']: coin_summery = str(item['MarketCurrencyLong']) coin_summery_list.append(coin_summery) return coin_summery_list # 通貨の最小取引単位取得 def get_min_trade_size(self, market): response = self.bittrex_public.get_markets() for item in response['result']: if item['MarketCurrency'] == market: return item['MinTradeSize'] return False # 通貨の終値取得 def get_last_price(self, market): response = self.bittrex_public.get_marketsummary(market) return response['result'][0]['Last']
def __init__(self, file_path, market="USDT-BTC", tickInterval="oneMin"): """ Chargement ou création de la base de donnée :param file_path: fichier où socker la base de donnée :param market: marché de la base de donnée, par défault : USDT-BTC :param tickInterval: interval de temps entre deux valeurs demandées à l'API bittrex avec ces valeurs possibles : oneMin, fiveMin, hour, thirtyMin,Day """ self.bittrex = Bittrex(None, None, api_version='v2.0') self.file_path = file_path self.market = market self.tickInterval = tickInterval try: with open(file_path, "r") as file: self.data = pd.read_csv(file) format = '%Y-%m-%d %H:%M:%S' self.data['date'] = pd.to_datetime(self.data['date'], format=format) self.data = self.data.set_index(pd.DatetimeIndex( self.data['date'])) del self.data['date'] print("[+] Valeurs chargées") except: self.data = None print("[-] Valeurs non chargées") self.init()
def get_bitr(coin): my_bittrex = Bittrex(None, None, api_version=API_V1_1) l = [] p = [] markets = my_bittrex.get_markets() tick = my_bittrex.get_ticker('NEO-USDT') i=0 eth = get_eth() while i<289: l.append(markets['result'][i]['MarketName']) i=i+1 for i in l: if i[:3]=='ETH': p.append(i) i=0 tr=False while i<len(p): if coin==p[i][4:]: tick = my_bittrex.get_ticker(p[i]) tr=True try: highlow = get_histor(p[i]) except: print('Cant') break i=i+1 if tr==True: try: tests = check_coin(coin) link = 'https://coinmarketcap.com/currencies/{}/'.format(tests[2]) return('1 ' + coin +' = ' + str(round(tick['result']['Bid']*eth,2)) + " USD\nСамая высокая цена: {} USD,\nСамая низкая цена: {} USD".format(round(highlow[0]*eth,2),round(highlow[1]*eth,2))+'\nИзменение за 24 часа: {} USD'.format(str(tests[0]))+'\nИзменение за 7 дней: {} USD\nСсылка на токен: '.format(str(tests[1]))+link) except: return('1 ' + coin +' = ' + str(tick['result']['Bid']*eth) + ' USD') else: return('Информации не найдено')
def setUp(self): with open("secrets.json") as secrets_file: self.secrets = json.load(secrets_file) secrets_file.close() self.bittrex = Bittrex(self.secrets['key'], self.secrets['secret'], api_version=API_V2_0)
def main(argv): call = Bittrex(api_key,api_secret) url = urllib2.urlopen call.api_query('getbalances')
def test_handles_invalid_key_or_secret(self): self.bittrex = Bittrex('invalidkey', self.secrets['secret'], api_version=API_V2_0) actual = self.bittrex.get_balance('BTC') test_auth_basic_failures(self, actual, 'Invalid key, valid secret') self.bittrex = Bittrex(None, self.secrets['secret'], api_version=API_V2_0) actual = self.bittrex.get_balance('BTC') test_auth_basic_failures(self, actual, 'None key, valid secret') self.bittrex = Bittrex(self.secrets['key'], 'invalidsecret', api_version=API_V2_0) actual = self.bittrex.get_balance('BTC') test_auth_basic_failures(self, actual, 'valid key, invalid secret') self.bittrex = Bittrex(self.secrets['key'], None, api_version=API_V2_0) actual = self.bittrex.get_balance('BTC') test_auth_basic_failures(self, actual, 'valid key, None secret') self.bittrex = Bittrex('invalidkey', 'invalidsecret', api_version=API_V2_0) actual = self.bittrex.get_balance('BTC') test_auth_basic_failures(self, actual, 'invalid key, invalid secret')
def __init__(self, trader, **kwargs): Bittrex.__init__(self, None, None) self.__dict__.update(kwargs) self.trader = trader self.market = None self.busy = False self.price_tweet = None self.price_buy = None
def getPredictions(): f = open('predictor.txt', 'r+') x = f.read() y = ast.literal_eval(x) p = open('profits.txt', 'r+') profits = float(p.read()) new_data = [] for z in y: my_bittrex = Bittrex('******', '####') market = "BTC-" + z['coin'] price_btc = my_bittrex.get_ticker(market)['result']['Ask'] new_prices = z['data']['prices'] new_prices.pop(0) new_prices.append(price_btc) if z['data']['tracing'] == True: if ((price_btc / new_prices[4]) + (new_prices[4] / new_prices[3])) / 2 >= 1: finace = finances.Finances() amount = finace.getBuyAmount() #trader = trader.Trader() # trader.buyCoin(z['coin']) print('BUY,', z['coin']) buyCoin(z['coin']) # for i in range(1,len(new_prices)-3): # running_average = running_average + (new_prices[i]/new_prices[i-1] #print("% 5s ....... % 4.3f" % (z['coin'],running_average)) running_average = ((new_prices[1] / new_prices[0]) + (new_prices[2] / new_prices[1]) + (new_prices[1] / new_prices[0]) + (new_prices[3] / new_prices[2])) / 4 #print("% 5s ....... % 4.3f" % (z['coin'], running_average)) new_price_length = len(new_prices) if ((price_btc / new_prices[new_price_length - 2]) + (new_prices[new_price_length - 2] / new_prices[new_price_length - 3])) / 2 > 1: tracing_bool = False elif (running_average) < 0.995: print("STARTED TRACING", z['coin']) tracing_bool = True else: tracing_bool = False data = { 'coin': z['coin'], 'data': { 'prices': new_prices, 'slope': new_prices[1] / new_prices[0], 'tracing': tracing_bool } } new_data.append(data) # print(new_data) f = open('predictor.txt', 'w+') f.write(str(new_data)) f.close()
def __init__(self, secrets, settings): self.trade_params = settings["tradeParameters"] self.pause_params = settings["pauseParameters"] self.Bittrex = Bittrex(secrets) self.Messenger = Messenger(secrets, settings) self.Database = Database() self.Messenger.send_balance_slack(self.get_non_zero_balances())
def __init__(self, config={}): self.influxdb_measurement = config.get("influxdb_measurement", "market_ohlc") self.market = config.get("market", "USDT-BTC") self.exchange = config.get("exchange", "bittrex") self.currency = self.market.split("-")[1] self.influx = InfluxDbWrapper.getInstance() self.bittrex = Bittrex() self.cryptocompare = CryptoCompare()
def __init__(self, market, amount, stopLoss=0): self.market = market self.amount = amount self.analyzer = BotAnalysis(self.market) self.bittrex = Bittrex('', '') if stopLoss: self.stopLoss = stopLoss self.tradePlaced = False self.data = [] self.prices = [] self.typeOfTrade = False
def show_balances(bot, update): if update.message.chat_id in auth.masters_chat_idx: my_b = Bittrex(auth.api_key, auth.api_secret) balances = my_b.get_balances() for currency in balances['result']: if currency['Available'] > 0: curr = str(currency['Currency']) bal = str(currency['Available']) update.message.reply_text(curr + ' ' + bal) else: update.message.reply_text("Не хватает прав. Попробуй другую команду")
def get_data(number): db_name = 'BB_coins' trader = get_arg(1) # 'LANDON', 'CHRISTIAN' OR 'VIVEK. # with open('accountkey.json') as data_file: # data = json.load(data_file) # print(data) collection_name = '{}_bittrex_account'.format(trader) try: mongoserver_uri = "mongodb://*****:*****@10.8.0.2:27017/admin" # mongoserver_uri = "mongodb://*****:*****@127.0.0:1" connection = MongoClient(host=mongoserver_uri) db = connection['BB_coins'] db_collection = db[collection_name] except KeyError: host = 'localhost' db_collection = MyMongoClient(db_name, collection_name=collection_name, host=host) balance_curr_codes = [] market_names = [] # key, secret = "141172172c12458f8d0051d4c2618559", "2d944113b64844f2b3ad33030f99101a" key = get_arg(2) secret = get_arg(3) api = Bittrex(api_key=key, api_secret=secret) markets_data = api.get_markets()["result"] for markets_datum in markets_data: if markets_datum["BaseCurrency"] == 'BTC': balance_curr_codes.append(markets_datum["MarketCurrency"]) market_names.append(markets_datum["MarketName"]) for market_name in market_names: market_history_data = api.get_market_history(market_name, count=1)["result"][0] balance_curr_code = market_name.split('-')[1] json_data = ({ 'Number': number, 'balance_curr_code': balance_curr_code, 'last_price': market_history_data['Price'], 'TimeStamp': market_history_data['TimeStamp'] }) db_collection.insert_one(json_data) print('------table name-----') print(collection_name) print('Inserted: \n{}'.format(json_data))
def __init__(self, name, bittrex=None): """ :param name: String literal for the market (e.g. BTC-LTC) :type name: str :param bittrex: Instance of Bittrex, potentially with API_KEY and SECRET :type bittrex: Bittrex """ self.name = name self.basis, self.coin = self.name.split("-") if bittrex: self.bittrex = bittrex else: self.bittrex = Bittrex(None, None)
class BittrexWrapper(object): def __init__(self, apiKey, apiSecret): self.apiKey = apiKey self.apiSecret = apiSecret self.api = Bittrex(self.apiKey, self.apiSecret) self.failure = (False, 0, 0) def get_price(self, market_code, base_code='BTC'): self.currency_code = '%s-%s' % (base_code, market_code) price_ticker = bittrex_api.get_ticker(currency_code) if price_ticker['success']: return price_ticker else: return {} def get_address(self): deposit_address_query = self.api.get_deposit_address(base_code) if deposit_address_query['success'] == False and deposit_address_query['message'] == 'ADDRESS_GENERATING': time.sleep(10) deposit_address_query = self.api.get_deposit_address(base_code) def buy_coins(self, market_code, price, base_code='BTC'): currency_code = '%s-%s' % (base_code, market_code) price_ticker = self.api.get_ticker(currency_code) if price_ticker['success']: ask_price = price_ticker['result']['Ask'] else: return self.failure quantity = price / ask_price sell_market_query = self.api.buy_limit(currency_code, quantity, ask_price) if sell_market_query['success']: order_uuid = sell_market_query['result']['uuid'] elif not sell_market_query['success']: return self.Failure # Sleep for long enough for bittrex to process the order time.sleep(30) # 4) Check the Order order_status_query = bittrex_api.get_order(order_uuid) if order_status_query['success']: aOrder = dict() aOrder['price'] = order_status_query['result']['Price'] aOrder['Quantity'] = order_status_query['result']['Quantity'] aOrder['Exchange'] = order_status_query['result']['Exchange'] aOrder['completed'] = True return aOrder['completed'], aOrder['price'], aOrder['Quantity'] else: return self.Failure
def create(): keys = open('key.json') data = json.load(keys) for cu in data: if cu == 'key': api_key = data[cu] if cu == 'secret': secret_key = data[cu] if api_key and secret_key: walets = Bittrex(api_key, secret_key, api_version=API_V2_0) else: walets = Bittrex(None, None, api_version=API_V2_0) keys.close() return (walets)
def __init__(self, exchanges): '''exchanges = comma separated list of exchanges you want to monitor''' self.exchanges = [e.lower() for e in exchanges] # Depending on which exchanges got included, connect to APIs if 'kraken' in self.exchanges: self.kraken_api = krakenex.API() self.kraken = KrakenAPI(self.kraken_api) if 'gdax' in self.exchanges: self.gdax = gdax_api.PublicClient() if 'bittrex' in self.exchanges: self.bittrex = Bittrex(None, None) if 'coinmarketcap' in self.exchanges: self.coinmarketcap = Market()
def buyCoin(coin): my_bittrex = Bittrex('******', '####') market = 'BTC-' + coin price_btc = my_bittrex.get_ticker(market)['result']['Ask'] finance = finances.Finances() size = (finance.getBuyAmount() / price_btc) #size = ((profits*0.92)/(price_btc)) my_bittrex.buy_limit(market, size, price_btc) print('BOUGHT', coin) ledger_list.append({'coin': coin, 'price': price_btc, 'size': size}) print(ledger_list) f = open('ledger.txt', 'w+') f.write(str(ledger_list)) # updateProfitsSpent(profits*0.92) f.close()
def __init__(self, key=None, secret=None, token=None): self.EXCHANGE_RATE = 0.9975 # 0.25% for each trading transaction self.api = Bittrex(key, secret) self.token = token try: m = self.api.get_market_summaries() #print m market_list = [] for market in m.get("result"): market_list.append(market.get("MarketName")) #print marketlist except: print "Error: Cannot get market summaries" exit(1) self.market_list = market_list
class Bittrex: def __init__(self, key, secret): self.client = Client(key, secret) self.logger = Logger(__name__) def getBalances(self): try: result = self.client.get_balances() balances = {} if not result['success']: raise ExchangeException(self.__class__.__name__, result['message']) for currency in result["result"]: name = currency["Currency"].encode('utf-8').upper() value = currency["Balance"] if value > 0.0: balances[name] = value return balances except Exception as e: self.logger.log(e) raise ExchangeException(self.__class__.__name__, e.message)
class Bittrex: def __init__(self, key, secret): self.logger = Logger(__name__) try: self.client = Client(key, secret, api_version="v2.0") except Exception as e: self.logger.log(e) raise ExchangeException(self.__class__.__name__, e) def getBalances(self): try: result = self.client.get_balances() balances = {} if not result['success']: raise Exception(result['message']) for currency in result["result"]: name = currency["Currency"]["Currency"] value = currency["Balance"]["Balance"] if value >= Config.BALANCE_ZERO: balances[name] = value return balances except Exception as e: self.logger.log(e) raise ExchangeException(self.__class__.__name__, e)
def __init__(self, credentials, coins): self.credentials = credentials self.coins = coins self.exchanges = {} self.last_market_update = 0 for i, exch in enumerate(self.credentials): self.exchanges[exch] = {} processed = False if (exch == "cryptsy"): self.exchanges[exch]["connection"] = PyCryptsy( str(self.credentials[exch]["pubkey"]), str(self.credentials[exch]["privkey"])) processed = True if (exch == "bittrex"): self.exchanges[exch]["connection"] = Bittrex( str(self.credentials[exch]["pubkey"]), str(self.credentials[exch]["privkey"])) processed = True if (exch == "coins-e"): self.exchanges[exch]["connection"] = PyCoinsE( str(self.credentials[exch]["pubkey"]), str(self.credentials[exch]["privkey"])) processed = True if (exch == "c-cex"): self.exchanges[exch]["connection"] = PyCCEX( str(self.credentials[exch]["key"])) processed = True if (processed == False): raise ValueError("unknown exchange") self.update_markets()
def refresh(self, scrape=False): # print("market={},exchange={}".format(self.market, self.exchange)) scraper = Scraper({'market': self.market, 'exchange': self.exchange}) self.candle_remaining = self.trader.getCandleRemaining() if self.candle_remaining is None: csdata = None if scrape: try: if self.candlesize == "1d" or self.candlesize == "1h": cs = self.candlesize else: cs = "1m" # print('scraping:{}'.format(cs)) csdata = scraper.cc_scrapeCandle(cs) self.scrapeDate = datetime.datetime.utcnow().strftime( '%Y-%m-%dT%H:%M:%S') self.rticks += 1 except Exception as ex: print(ex) if self.candlesize not in ("1m", "1d", "1h"): csdata = None self.loadCandlesticks(csdata) try: if self.exchange == "bittrex": self.market_summary = Bittrex().public_get_market_summary( self.market).data["result"][0] else: last = scraper.cc_lastprice() self.market_summary = {"Last": last, "Ask": 0, "Bid": 0} except Exception as ex: self.market_summary = { "Last": self.csdata["closed"][-1], "Ask": 0, "Bid": 0 } self.last = self.market_summary['Last'] self.csdata['closed'][-1] = self.last if self.candle_remaining is not None: if self.last > self.refresh_high: self.refresh_high == self.last if self.last < self.refresh_low: self.refresh_low = self.last else: self.refresh_high = self.csdata["high"][-1] self.refresh_low = self.csdata["low"][-1] #self.candle_remaining = self.trader.candle_remaining self.csdata["high"][-1] = self.refresh_high self.csdata["low"][-1] = self.refresh_low self.calculate_ta()
def get_active_trades(self): if self.last_active_trade_query + self.bittrex_min_poll > time.time(): return self.trades self.last_active_trade_query = time.time() conn = self.getPgDb().db.getconn() cur = conn.cursor(cursor_factory= psycopg2.extras.DictCursor ) cur.execute("""select * from markets.trades WHERE active=true and status NOT IN ('closed','cancelled','sold') """) res = cur.fetchall() self.trades = res for trade in self.trades: uuid = trade["trade_uuid"] if len(uuid) >= 32 and trade["status"] in ["open","selling"]: self.log.info("getting order details from bittrex") trade_details = Bittrex().account_get_order(uuid).getData() if trade_details["result"]["IsOpen"] == False: if trade["status"] == "open": new_status = "active" elif trade["status"] == "selling": new_status = "sold" cur.execute("""UPDATE markets.trades SET status=%s WHERE id=%s""",[new_status,trade["id"],]) res = conn.commit() self.log.info(res) self.getPgDb().db.putconn(conn) cur.close() return self.trades
def process_trade(self, signal ): precision = 2 marketfee = 0.0025 trade_amount = signal["trade_amount"] trade_total = round(signal["price_entry"] * trade_amount ,precision) trade_fee = round(trade_total * marketfee ,precision) uuid = None if not self.demo: res = Bittrex().market_buylimit(signal["market"],trade_amount,signal["price_entry"]).getData() self.log.info(res) if res["success"]: uuid = res["result"]["uuid"] else: uuid = "DEMO" if uuid is not None: data = { "exchange": signal["exchange"], "market": signal["market"], "price_entry": signal["price_entry"], "trade_amount": trade_amount, "trade_entry_total": trade_total, "price_entry_date": time.strftime("%c"), "trade_fee": trade_fee, "market_fee": marketfee, "trade_uuid": uuid, "status": "open" } self.log.info("saving to db") self.log.info(data) res = self.new_trade(data) else: self.log.error("failed to add trade")
def get_active_markets(): """ Used to obtain the set of markets that are currently active on Bittrex :return: list of Market objects """ b = Bittrex(None, None) response = b.get_markets() if response['success']: markets = response['result'] active_markets = [] for market in markets: if market['IsActive']: active_markets.append(Market(market['MarketName'])) return active_markets else: raise Exception(response['message'])
def __init__(self, secrets): self.trade_params = secrets["tradeParameters"] self.pause_params = secrets["pauseParameters"] self.Bittrex = Bittrex(secrets) self.Messenger = Messenger(secrets) self.Database = Database()
def __init__(self, key, secret): self.logger = Logger(__name__) try: self.client = Client(key, secret, api_version="v2.0") except Exception as e: self.logger.log(e) raise ExchangeException(self.__class__.__name__, e)
class Trader(object): """ Used for handling all trade functionality """ def __init__(self, secrets): self.trade_params = secrets["tradeParameters"] self.pause_params = secrets["pauseParameters"] self.Bittrex = Bittrex(secrets) self.Messenger = Messenger(secrets) self.Database = Database() def initialise(self): """ Fetch the initial coin pairs to track and to print the header line """ try: if len(self.Database.app_data["coinPairs"]) < 1: self.Database.store_coin_pairs(self.get_markets("BTC")) self.Messenger.print_header(len(self.Database.app_data["coinPairs"])) except ConnectionError as exception: self.Messenger.print_exception_error("connection") logger.exception(exception) exit() def analyse_pauses(self): """ Check all the paused buy and sell pairs and reactivate the necessary ones """ if self.Database.check_resume(self.pause_params["buy"]["pauseTime"], "buy"): self.Database.store_coin_pairs(self.get_markets("BTC")) self.Messenger.print_resume_pause(len(self.Database.app_data["coinPairs"]), "buy") if self.Database.check_resume(self.pause_params["sell"]["pauseTime"], "sell"): self.Messenger.print_resume_pause(self.Database.app_data["pausedTrackedCoinPairs"], "sell") self.Database.resume_sells() def analyse_buys(self): """ Analyse all the un-paused coin pairs for buy signals and apply buys """ trade_len = len(self.Database.trades["trackedCoinPairs"]) pause_trade_len = len(self.Database.app_data["pausedTrackedCoinPairs"]) if (trade_len < 1 or pause_trade_len == trade_len) and trade_len < self.trade_params["buy"]["maxOpenTrades"]: for coin_pair in self.Database.app_data["coinPairs"]: self.buy_strategy(coin_pair) def analyse_sells(self): """ Analyse all the un-paused tracked coin pairs for sell signals and apply sells """ for coin_pair in self.Database.trades["trackedCoinPairs"]: if coin_pair not in self.Database.app_data["pausedTrackedCoinPairs"]: self.sell_strategy(coin_pair) def buy_strategy(self, coin_pair): """ Applies the buy checks on the coin pair and handles the results appropriately :param coin_pair: Coin pair market to check (ex: BTC-ETH, BTC-FCT) :type coin_pair: str """ if (len(self.Database.trades["trackedCoinPairs"]) >= self.trade_params["buy"]["maxOpenTrades"] or coin_pair in self.Database.trades["trackedCoinPairs"]): return rsi = self.calculate_RSI(coin_pair=coin_pair, period=14, unit=self.trade_params["tickerInterval"]) day_volume = self.get_current_24hr_volume(coin_pair) current_buy_price = self.get_current_price(coin_pair, "ask") if self.check_buy_parameters(rsi, day_volume, current_buy_price): buy_stats = { "rsi": rsi, "24HrVolume": day_volume } self.buy(coin_pair, self.trade_params["buy"]["btcAmount"], current_buy_price, buy_stats) elif rsi is not None and rsi <= self.pause_params["buy"]["rsiThreshold"]: self.Messenger.print_no_buy(coin_pair, rsi, day_volume, current_buy_price) elif rsi is not None: self.Messenger.print_pause(coin_pair, rsi, self.pause_params["buy"]["pauseTime"], "buy") self.Database.pause_buy(coin_pair) def sell_strategy(self, coin_pair): """ Applies the sell checks on the coin pair and handles the results appropriately :param coin_pair: Coin pair market to check (ex: BTC-ETH, BTC-FCT) :type coin_pair: str """ if (coin_pair in self.Database.app_data["pausedTrackedCoinPairs"] or coin_pair not in self.Database.trades["trackedCoinPairs"]): return rsi = self.calculate_RSI(coin_pair=coin_pair, period=14, unit=self.trade_params["tickerInterval"]) current_sell_price = self.get_current_price(coin_pair, "bid") profit_margin = self.Database.get_profit_margin(coin_pair, current_sell_price) if self.check_sell_parameters(rsi, profit_margin): sell_stats = { "rsi": rsi, "profitMargin": profit_margin } self.sell(coin_pair, current_sell_price, sell_stats) elif rsi is not None and profit_margin >= self.pause_params["sell"]["profitMarginThreshold"]: self.Messenger.print_no_sell(coin_pair, rsi, profit_margin, current_sell_price) elif rsi is not None: self.Messenger.print_pause(coin_pair, profit_margin, self.pause_params["sell"]["pauseTime"], "sell") self.Database.pause_sell(coin_pair) def check_buy_parameters(self, rsi, day_volume, current_buy_price): """ Used to check if the buy conditions have been met :param rsi: The coin pair's current RSI :type rsi: float :param day_volume: The coin pair's current 24 hour volume :type day_volume: float :param current_buy_price: The coin pair's current price :type current_buy_price: float :return: Boolean indicating if the buy conditions have been met :rtype : bool """ return (rsi is not None and rsi <= self.trade_params["buy"]["rsiThreshold"] and day_volume >= self.trade_params["buy"]["24HourVolumeThreshold"] and current_buy_price > self.trade_params["buy"]["minimumUnitPrice"]) def check_sell_parameters(self, rsi, profit_margin): """ Used to check if the sell conditions have been met :param rsi: The coin pair's current RSI :type rsi: float :param profit_margin: The coin pair's current profit margin :type profit_margin: float :return: Boolean indicating if the sell conditions have been met :rtype : bool """ return ((rsi is not None and rsi >= self.trade_params["sell"]["rsiThreshold"] and profit_margin > self.trade_params["sell"]["minProfitMarginThreshold"]) or profit_margin > self.trade_params["sell"]["profitMarginThreshold"]) def buy(self, coin_pair, btc_quantity, price, stats, trade_time_limit=2): """ Used to place a buy order to Bittrex. Wait until the order is completed. If the order is not filled within trade_time_limit minutes cancel it. :param coin_pair: String literal for the market (ex: BTC-LTC) :type coin_pair: str :param btc_quantity: The amount of BTC to buy with :type btc_quantity: float :param price: The price at which to buy :type price: float :param stats: The buy stats object :type stats: dict :param trade_time_limit: The time in minutes to wait fot the order before cancelling it :type trade_time_limit: float """ buy_data = self.Bittrex.buy_limit(coin_pair, btc_quantity / price, price) if not buy_data["success"]: return logger.error("Failed to buy on {} market.".format(coin_pair)) self.Database.store_initial_buy(coin_pair, buy_data["result"]["uuid"]) buy_order_data = self.get_order(buy_data["result"]["uuid"], trade_time_limit * 60) self.Database.store_buy(buy_order_data["result"], stats) self.Messenger.print_buy(coin_pair, price, stats["rsi"], stats["24HrVolume"]) self.Messenger.send_buy_slack(coin_pair, stats["rsi"], stats["24HrVolume"]) self.Messenger.send_buy_gmail(buy_order_data["result"], stats) self.Messenger.play_sw_imperial_march() def sell(self, coin_pair, price, stats, trade_time_limit=2): """ Used to place a sell order to Bittrex. Wait until the order is completed. If the order is not filled within trade_time_limit minutes cancel it. :param coin_pair: String literal for the market (ex: BTC-LTC) :type coin_pair: str :param price: The price at which to buy :type price: float :param stats: The buy stats object :type stats: dict :param trade_time_limit: The time in minutes to wait fot the order before cancelling it :type trade_time_limit: float """ trade = self.Database.get_open_trade(coin_pair) sell_data = self.Bittrex.sell_limit(coin_pair, trade["quantity"], price) if not sell_data["success"]: return logger.error( "Failed to sell on {} market. Bittrex error message: {}".format(coin_pair, sell_data["message"]) ) sell_order_data = self.get_order(sell_data["result"]["uuid"], trade_time_limit * 60) # TODO: Handle partial/incomplete sales. self.Database.store_sell(sell_order_data["result"], stats) self.Messenger.print_sell(coin_pair, price, stats["rsi"], stats["profitMargin"]) self.Messenger.send_sell_slack(coin_pair, stats["rsi"], stats["profitMargin"]) self.Messenger.send_sell_gmail(sell_order_data["result"], stats) self.Messenger.play_sw_theme() def get_markets(self, main_market_filter=None): """ Gets all the Bittrex markets and filters them based on the main market filter :param main_market_filter: Main market to filter on (ex: BTC, ETH, USDT) :type main_market_filter: str :return: All Bittrex markets (with filter applied, if any) :rtype : list """ markets = self.Bittrex.get_markets() if not markets["success"]: logger.error("Failed to fetch Bittrex markets") exit() markets = markets["result"] if main_market_filter is not None: market_check = main_market_filter + "-" markets = py_.filter_(markets, lambda market: market_check in market["MarketName"]) markets = py_.map_(markets, lambda market: market["MarketName"]) return markets def get_current_price(self, coin_pair, price_type): """ Gets current market price for a coin pair :param coin_pair: Coin pair market to check (ex: BTC-ETH, BTC-FCT) :type coin_pair: str :param price_type: The type of price to get (one of: 'ask', 'bid') :type price_type: str :return: Coin pair's current market price :rtype : float """ coin_summary = self.Bittrex.get_market_summary(coin_pair) if not coin_summary["success"]: logger.error("Failed to fetch Bittrex market summary for the {} market".format(coin_pair)) return None if price_type == "ask": return coin_summary["result"][0]["Ask"] if price_type == "bid": return coin_summary["result"][0]["Bid"] return coin_summary["result"][0]["Last"] def get_current_24hr_volume(self, coin_pair): """ Gets current 24 hour market volume for a coin pair :param coin_pair: Coin pair market to check (ex: BTC-ETH, BTC-FCT) :type coin_pair: str :return: Coin pair's current 24 hour market volume :rtype : float """ coin_summary = self.Bittrex.get_market_summary(coin_pair) if not coin_summary["success"]: logger.error("Failed to fetch Bittrex market summary for the {} market".format(coin_pair)) return None return coin_summary["result"][0]["BaseVolume"] def get_closing_prices(self, coin_pair, period, unit): """ Returns closing prices within a specified time frame for a coin pair :param coin_pair: String literal for the market (ex: BTC-LTC) :type coin_pair: str :param period: Number of periods to query :type period: int :param unit: Ticker interval (one of: 'oneMin', 'fiveMin', 'thirtyMin', 'hour', 'week', 'day', and 'month') :type unit: str :return: Array of closing prices :rtype : list """ historical_data = self.Bittrex.get_historical_data(coin_pair, period, unit) closing_prices = [] for i in historical_data: closing_prices.append(i["C"]) return closing_prices def get_order(self, order_uuid, trade_time_limit): """ Used to get an order from Bittrex by it's UUID. First wait until the order is completed before retrieving it. If the order is not completed within trade_time_limit seconds, cancel it. :param order_uuid: The order's UUID :type order_uuid: str :param trade_time_limit: The time in seconds to wait fot the order before cancelling it :type trade_time_limit: float :return: Order object :rtype : dict """ start_time = time.time() order_data = self.Bittrex.get_order(order_uuid) while time.time() - start_time <= trade_time_limit and order_data["result"]["IsOpen"]: time.sleep(10) order_data = self.Bittrex.get_order(order_uuid) if order_data["result"]["IsOpen"]: error_str = self.Messenger.print_order_error(order_uuid, trade_time_limit, order_data["result"]["Exchange"]) logger.error(error_str) if order_data["result"]["Type"] == "LIMIT_BUY": self.Bittrex.cancel(order_uuid) return order_data return order_data def calculate_RSI(self, coin_pair, period, unit): """ Calculates the Relative Strength Index for a coin_pair If the returned value is above 75, it's overbought (SELL IT!) If the returned value is below 25, it's oversold (BUY IT!) :param coin_pair: String literal for the market (ex: BTC-LTC) :type coin_pair: str :param period: Number of periods to query :type period: int :param unit: Ticker interval (one of: 'oneMin', 'fiveMin', 'thirtyMin', 'hour', 'week', 'day', and 'month') :type unit: str :return: RSI :rtype : float """ closing_prices = self.get_closing_prices(coin_pair, period * 3, unit) count = 0 change = [] # Calculating price changes for i in closing_prices: if count != 0: change.append(i - closing_prices[count - 1]) count += 1 if count == 15: break # Calculating gains and losses advances = [] declines = [] for i in change: if i > 0: advances.append(i) if i < 0: declines.append(abs(i)) average_gain = (sum(advances) / 14) average_loss = (sum(declines) / 14) new_avg_gain = average_gain new_avg_loss = average_loss for _ in closing_prices: if 14 < count < len(closing_prices): close = closing_prices[count] new_change = close - closing_prices[count - 1] add_loss = 0 add_gain = 0 if new_change > 0: add_gain = new_change if new_change < 0: add_loss = abs(new_change) new_avg_gain = (new_avg_gain * 13 + add_gain) / 14 new_avg_loss = (new_avg_loss * 13 + add_loss) / 14 count += 1 if new_avg_loss == 0: return None rs = new_avg_gain / new_avg_loss new_rs = 100 - 100 / (1 + rs) return new_rs
def __init__(self, apiKey, apiSecret): self.apiKey = apiKey self.apiSecret = apiSecret self.api = Bittrex(self.apiKey, self.apiSecret) self.failure = (False, 0, 0)