Beispiel #1
0
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']
Beispiel #2
0
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('Информации не найдено')
Beispiel #3
0
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))
Beispiel #4
0
class Market:
    def __init__(self):
        self.bittrex = Bittrex()
        self.update_currencies_raw()

    def update_currencies_raw(self):
        self.currencies_raw = self.get_crypto_currencies()
        self.currencies_list = sorted(
            [c["MarketName"] for c in self.currencies_raw])

    def get_crypto_currencies(self):
        try:
            return self.bittrex.get_markets()["result"]
        except Exception:
            return self.currencies_raw
Beispiel #5
0
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'])
Beispiel #6
0
def get_inactive_markets():
    """
    Used to obtain the set of markets that are not currently active on Bittrex
    :return: list of Market objects
    """
    b = Bittrex(None, None)
    response = b.get_markets()
    if response['success']:
        markets = response['result']
        inactive_markets = []
        for market in markets:
            if not market['IsActive']:
                inactive_markets.append(Market(market['MarketName']))
                print "{:s}\t{:s}".format(market['MarketName'],
                                          market['Notice'])
        return inactive_markets
    else:
        raise Exception(response['message'])
Beispiel #7
0
class TestBittrexPublicAPI(unittest.TestCase):
    """
        Integration tests for Bittrex Public API
    """
    def setUp(self):
        self.bittrex = Bittrex()

    def test_get_markets(self):
        actual = self.bittrex.get_markets()
        test_basic_response(self, actual, 'get_markets')

    def test_get_currencies(self):
        actual = self.bittrex.get_currencies()
        test_basic_response(self, actual, 'get_currencies')

    def test_get_ticker(self):
        self.assertRaises(TypeError, self.bittrex.get_ticker)
        actual = self.bittrex.get_ticker('BTC-LTC')
        test_basic_response(self, actual, 'get_ticker')
        false_actual = self.bittrex.get_ticker('BTC')
        test_failed_response(self, false_actual, 'get_ticker')

    def test_get_market_summaries(self):
        actual = self.bittrex.get_market_summaries()
        test_basic_response(self, actual, 'get_market_summaries')

    def test_get_market_summary(self):
        self.assertRaises(TypeError, self.bittrex.get_market_summary)
        actual = self.bittrex.get_ticker('BTC-LTC')
        test_basic_response(self, actual, 'get_market_summar')
        false_actual = self.bittrex.get_ticker('BTC')
        test_failed_response(self, false_actual, 'get_market_summar')

    def test_get_order_book(self):
        self.assertRaises(TypeError, self.bittrex.get_order_book)
        self.assertRaises(TypeError, self.bittrex.get_order_book, 'BTC-LTC')
        actual = self.bittrex.get_order_book('BTC-LTC', 'buy')
        test_basic_response(self, actual, 'get_order_book')

    def test_get_market_history(self):
        self.assertRaises(TypeError, self.bittrex.get_market_history)
        actual = self.bittrex.get_market_history('BTC-LTC')
        test_basic_response(self, actual, 'get_market_history')
Beispiel #8
0
def get_data():

    db_name = 'BB_coins'
    trader = get_arg(1, 'VIVEK')  # 'LANDON', 'CHRISTIAN' OR 'VIVEK.
    collection = '{}_coinigy_account'.format(trader)
    try:
        db_user = '******'
        db_password = os.environ['MONGO-WRITE-PASSWORD']
        host = 'mongodb://{}:{}@127.0.0.1'.format(db_user, db_password)
    except KeyError:
        host = 'localhost'
    db = MyMongoClient(db_name, collection_name=collection,
                       host=host)

    json_data = []
    market_history_total_data = []
    balance_curr_codes = []
    market_names = []

    key, secret = "54680684a8cb481c9f99a5f0ccaa1841", "4009a8a233114ab8a16f03c856d03752"
    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 = ({
                      'balance_curr_code': balance_curr_code,
                      'last_price': market_history_data['Price'],
                      'TimeStamp': market_history_data['TimeStamp']})

        db.insert_one(json_data)
Beispiel #9
0
import pandas as pd
from cis.lib import capping
from coinmarketcap import Market
from bittrex import Bittrex, API_V2_0, API_V1_1

# get coinmarketcap top 50
coinmarketcap = Market()
data = coinmarketcap.ticker(limit=50)

# get all bittrex markets
my_bittrex = Bittrex(None, None, api_version=API_V1_1)  # or defaulting to v1.1 as Bittrex(None, None)
bittrex_markets = pd.DataFrame(my_bittrex.get_markets()['result'])

# get coins traded in BTC in bittrex
bittrex_coins = bittrex_markets.loc[bittrex_markets['BaseCurrency'] == 'BTC']['MarketCurrency']
bittrex_coins = bittrex_coins.append(pd.Series('BTC'))

# create blacklist
blacklist = pd.Series(['BCC', 'USDT'])

# create dataframe from coinmarketcap data
df = pd.DataFrame(data)

# remove blacklist coins and coins not in bittrex from dataframe
df = df.loc[df['symbol'].isin(bittrex_coins) & ~df['symbol'].isin(blacklist), :]

# get top 20
df = df.head(20)

# compute market weights
df['market_cap_usd'] = df['market_cap_usd'].astype(float)
Beispiel #10
0
		"""
		buy_rule_boolean,buy_rule_dict=self.check_buy_rule(market,threshold)
		if buy_rule_boolean:
			print("The there is a chance of scoring on market {market}. Proceeding to bite algorithm.".format(market=market['MarketName']))
			self.bite_and_let_go(market,buy_rule_dict)
		else:
			print("The there is nothing going on on market {market}.)".format(market=market['MarketName']))
			pass

# init bittrex client
br = Bittrex(API_key, API_secret)
# get market names
markets={market['MarketName']:{'MarketName':market['MarketName'],
							   'MarketCurrency':market['MarketCurrency'], 
							   'MinTradeSize':market['MinTradeSize']
							  } for market in br.get_markets()['result'] if market['MarketName'].startswith('BTC')}

def get_fertile_markets(): 
	# /GET FERTILE MARKETS
	print("Getting 0.9 quantile markets with respect to its base volume. This takes few minutes, please wait...")
	# assign base_volume to markets
	for market,market_dict in markets.items():
		market_name=market_dict['MarketName']
		markets[market_name]['base_volume']=get_market_base_volume(market_dict['MarketName'])

	sum_base_volume=sum([market_dict['base_volume'] for market,market_dict in markets.items()])

	# assign proxy for liquidity as a fraction of base_volume to markets
	for market,market_dict in markets.items():
		market_name=market_dict['MarketName']
		markets[market_name]['liquidity']=markets[market_name]['base_volume']/sum_base_volume
Beispiel #11
0
class TradeBot():
    def __init__(self, key=None, secret=None, **kwargs):
        self.exchange = Bittrex(key, secret)
        self.orders = []
        # Default config
        config = {
            'base_currency': 'ETH',
            'min_order': 0.001,
            'max_order': 0.05,
            'sleep_time': 60,
            'profit': 2,
            'min_volume': 75,
            'max_units': 100
        }
        # Update config from object constructor
        config.update(kwargs)
        # Set attributes based on config
        for attr in config.keys():
            setattr(self, attr, config[attr])

    def get_markets(self):
        logging.info(f'Getting markets for {self.base_currency}')
        all_markets = self.exchange.get_markets()['result']
        markets = set()
        for mkt in all_markets:
            if mkt['BaseCurrency'] == self.base_currency:
                markets.add(mkt['MarketName'])
        return markets

    def get_coins_with_open_orders(self):
        open_orders = self.exchange.get_open_orders()['result']
        if len(open_orders) == 0:
            return []
        else:
            return [x['Exchange'] for x in open_orders]

    def get_market_data(self):
        mkt_data = []
        for mkt in self.markets:
            logging.info(f'Getting market data for {mkt}')
            data = self.exchange.get_marketsummary(mkt)['result'][0]
            data['Change'] = calculate_change(data['Last'], data['Low'])
            mkt_data.append(data)
        return mkt_data

    def has_balance_to_buy(self):
        logging.info('checking if we have some balance to buy')
        q = self.exchange.get_balance(self.base_currency)
        # balance_adjustment to avoid INSUFFICIENT FUNDS MESSAGE
        balance_adjustment = 0.0005
        self.balance = q['result']['Available'] - balance_adjustment
        logging.debug(f'{self.balance}{self.base_currency} available')
        if self.balance >= self.min_order:
            return True
        else:
            return False

    def get_market_to_buy(self):
        self.update()
        mkt = [
            m for m in self.market_data if m['BaseVolume'] >= self.min_volume
        ]
        sorted_mkt = sorted(mkt, key=lambda x: x['BaseVolume'], reverse=True)
        while sorted_mkt[0]['MarketName'] in self.coins_with_open_orders:
            sorted_mkt.pop(0)
        return sorted_mkt[0]

    def buy(self, mkt):
        coin = mkt['MarketName']
        # get a price between ask and bid
        price = (mkt['Ask'] + mkt['Bid']) / 2
        if self.balance > self.max_order:
            qnt = self.max_order / price
        else:
            qnt = self.balance / price
        if qnt > self.max_units:
            qnt = self.max_units
        if (qnt * price) < self.min_order:
            qnt = self.min_order / price
        logging.info(f'BUY {qnt} {coin} - price {price}, total {price * qnt}')
        order = self.exchange.buy_limit(coin, qnt, price)
        if order['success']:
            self.orders.append(order['result']['uuid'])
        else:
            logging.error(f'BUY FAIL - {order}')
        return (order)

    def sell(self):
        for order in self.orders:
            order_info = self.exchange.get_order(order)['result']
            if order_info['Closed']:
                coin = order_info['Exchange']
                qnt = order_info['Quantity']
                price = profit(order_info['PricePerUnit'], self.profit)
                sell_order = self.exchange.sell_limit(coin, qnt, price)
                self.orders.remove(order)
                logging.info(f'SELL {order} {sell_order}')

    def update(self):
        logging.info('Updating data')
        self.markets = self.get_markets()
        self.market_data = self.get_market_data()
        self.coins_with_open_orders = self.get_coins_with_open_orders()

    def do_trade(self):
        if self.has_balance_to_buy():
            self.buy(self.get_market_to_buy())
        if len(self.orders) > 0:
            self.sell()
        logging.info(f'Sleeping for {self.sleep_time} seconds')
        sleep(self.sleep_time)

    def run(self):
        logging.info('Starting Bot')
        while True:
            self.do_trade()
Beispiel #12
0
    "BTC",
    "DASH",
    "ETC",
    "ETH",
    "LTC",
    "NEO",
    "XMR",
    "XRP",
    "ZEC",
]

EXCHANGE_RATE = 0.9975

print key, secret
api = Bittrex(key, secret)
data = api.get_markets()

money = 100


def lineno():
    """Returns the current line number in our program."""
    return inspect.currentframe().f_back.f_lineno


def get_new_round():
    ''' Need return buying path . Currently only use static path
	meaning keep going this path regarding the current price
	'''
    marketsummaries = api.get_market_summaries().get("result")
    #print marketsummaries[0].get("TimeStamp")
Beispiel #13
0
Load Libraries

import pandas as pd
from bittrex import Bittrex

my_bittrex = Bittrex("99f9f179b8e84a43a1204903a5c242eb", "0994a3ebc9aa4d0fa44d0c9d94d272bc")
my_bittrex.get_markets()
# Key = 99f9f179b8e84a43a1204903a5c242eb
# Secret = 0994a3ebc9aa4d0fa44d0c9d94d272bc
# Function to extract required data from the bittrex API - Symbol, time frame, frequency


# Additional data cleaning ?


# Backtester


# Trend following


# Momentum

Beispiel #14
0
class CryptoCommander:
    def __init__(self, poloapicreds=['', ''], bittrexapicreds=['', '']):
        print(
            "Initializing Crypto Commander, Intelligent and Responsive Crypto-Currency Platform..."
        )
        print(
            "Disclaimer!! You have launched this via command line, great caution is advised and the developers are NOT responsible for proper usage or lost coins!"
        )
        print(
            "Notice - :: :: Bitcoin & Crypto-Currencies are largely untested and come with no assurances! Trade with care. :: ::"
        )
        if poloapicreds == ['', '']:
            print(
                "No poloniex credentials found, skipping initialization. This may cause instability!"
            )
        else:
            try:
                self.poloniexBot = poloniex(poloapicreds[0], poloapicreds[1])
                self.btcBalance, self.btsBalance, self.clamBalance, self.dashBalance, self.dogeBalance, self.ethBalance, self.fctBalance, self.ltcBalance, self.maidBalance, self.strBalance, self.xmrBalance, self.xrpBalance, = Decimal(
                    0.0), Decimal(0.0), Decimal(0.0), Decimal(0.0), Decimal(
                        0.0), Decimal(0.0), Decimal(0.0), Decimal(
                            0.0), Decimal(0.0), Decimal(0.0), Decimal(
                                0.0), Decimal(0.0)
            except AttributeError:
                print(
                    "An error occurred trying to initialize Poloniex functionality."
                )
        if bittrexapicreds == ['', '']:
            print(
                "No bittrex credentials detected, skipping initialization. This may cause instability!"
            )
        else:
            try:
                self.bittrexBot = Bittrex(bittrexapicreds[0],
                                          bittrexapicreds[1])
            except AttributeError:
                print(
                    "An error occurred trying to initialized Bittrex functionality."
                )

    def convert_coinpair_poloniex(self, coinpair):
        return coinpair.replace('-', '_')

    def get_tickers_raw(self, market):
        # A clone of the bittrex get_markets() & poloniex returnTicker commands, in a unified stream.
        if market == 'poloniex':
            return self.poloniexBot.returnTicker()
        elif market == 'bittrex':
            return self.bittrexBot.get_markets()

    def get_coinpair_ticker_raw(self, market, coinpair):
        # Returns raw market information on coin pair  on market
        if market == 'poloniex':
            coinpair = self.convert_coinpair_poloniex(coinpair)
            rawtickerdata = self.get_tickers_raw(market)
            for coinpairdata in rawtickerdata:
                if coinpairdata == coinpair:
                    return rawtickerdata[coinpairdata]
        if market == 'bittrex':
            return self.bittrexBot.get_ticker(coinpair.capitalize())

    def getTickerData(self,
                      market,
                      bitcoinMarketsOnly=True,
                      activeOnly=True,
                      printFriendly=False,
                      decimalTypes=True):
        #if market == 'poloniex:

        if market == 'bittrex':
            cryptoCommandTickers = {'BTC': [], 'Other': []}
            btcMarketsList = cryptoCommandTickers['BTC']
            otherMarketsList = cryptoCommandTickers['Other']
            stagingList = []
            if printFriendly == True:
                decimalTypes = False
            for ticker in self.bittrexBot.get_markets()['result']:
                if ticker != None:
                    stagingList.append([
                        str(ticker['MarketName']),
                        str(ticker['BaseCurrency']),
                        bool(str(ticker['IsActive']))
                    ])
            for ticker in self.bittrexBot.get_market_summaries()['result']:
                if ticker != None:
                    for list in stagingList:
                        if list[0] == str(ticker['MarketName']):
                            list.extend([
                                ticker['High'], ticker['Low'], ticker['Ask'],
                                ticker['Bid'], ticker['Last'],
                                ticker['PrevDay'], ticker['Volume'],
                                ticker['BaseVolume'],
                                (ticker['High'] + ticker['Low'] / 2.0)
                            ])
            for list in stagingList:
                if list[1] == 'BTC':
                    btcMarketsList.append(list)
                else:
                    otherMarketsList.append(list)
            if printFriendly == True:
                for dictobject in cryptoCommandTickers:
                    for list in cryptoCommandTickers[dictobject]:
                        for n, listobject in enumerate(list):
                            if type(listobject) == float:
                                list[n] = format(listobject, '.8f')
            elif decimalTypes == True:
                for dictobject in cryptoCommandTickers:
                    for list in cryptoCommandTickers[dictobject]:
                        for n, listobject in enumerate(list):
                            if type(listobject) == float:
                                list[n] = Decimal(format(listobject, '.8f'))
            return cryptoCommandTickers

    def getActiveMarketCurrencies(self, market, appendString=''):
        currentMarketList = []
        if market == 'poloniex':
            rawCoinPairData = self.poloniexBot.api_query('returnTicker')
            for coinPairData in rawCoinPairData:
                if str(rawCoinPairData[coinPairData]['isFrozen']) == '0':
                    currentMarketList.append(
                        str(coinPairData).split('_', 1)[1])
        if market == 'bittrex':
            for coinData in self.bittrexBot.get_currencies()['result']:
                if coinData['IsActive'] == True:
                    currentMarketList.append(appendString +
                                             str(coinData['Currency']))
        return set(currentMarketList)

    def getCurrentBalance(self, market, coin):
        if market == 'poloniex':
            return self.poloniexBot.returnBalances()[coin.upper()]
        elif market == 'bittrex':
            return self.bittrexBot.get_balance(coin)['result']['Balance']

    def getTopOrder(self, market, coinPair, buyOrders):
        if buyOrders == True:
            if market == 'poloniex':
                for i in self.poloniexBot.returnOrderBook(
                        coinPair.replace('-', '_'))['bids']:
                    return i
            elif market == 'bittrex':
                for i in self.bittrexBot.get_orderbook(coinPair,
                                                       'buy')['result']:
                    return i
            else:
                print('Not a valid market: ' + str(market))
        else:
            if market == 'poloniex':
                for i in self.poloniexBot.returnOrderBook(
                        coinPair.replace('-', '_'))['asks']:
                    return i
            elif market == 'bittrex':
                for i in self.bittrexBot.get_orderbook(coinPair,
                                                       'sell')['results']:
                    return i
            else:
                print('Not a valid market: ' + str(market))

    def getWalletAddress(self, market, coin):
        if market == "poloniex" or market == "Poloniex":
            return self.poloniexBot.api_query('returnDepositAddresses')[coin]
        elif market == "bittrex" or market == "Bittrex":
            return self.bittrexBot.get_balance(coin)['result']['CryptoAddress']

    def compareMarkets(self, market1, market2):
        currentActiveMarketsLists = [
            self.getActiveMarketCurrencies(market1),
            self.getActiveMarketCurrencies(market2)
        ]
        comparisonList = []
        for i in currentActiveMarketsLists[0]:
            for y in currentActiveMarketsLists[1]:
                if i == y: comparisonList.append(i)
                else: continue
        return comparisonList

    def getCoinPairPriceDifferencePercent(self, buyPrice, sellPrice):
        return (((float(buyPrice) - float(sellPrice)) / float(buyPrice)) *
                100.00)

    def arbitrageScan(self, market1, market2, minPercent=0.45):
        try:
            arbOpportunitiesList = []
            for coinpair in self.doMarketComparison(market1, market2):
                print("Scanning Coin Pair : " + str(coinpair))
                differenceBetweenMarket1and2 = format(
                    self.getCoinPairPriceDifferencePercent(
                        float(self.getTopOrder(market1, coinpair, False, 1)),
                        float(self.getTopOrder(market2, coinpair, True, 1))))
                differenceBetweenMarket2and1 = format(
                    self.getCoinPairPriceDifferencePercent(
                        float(self.getTopOrder(market2, coinpair, False, 1)),
                        float(self.getTopOrder(market1, coinpair, True, 1))))
                if float(differenceBetweenMarket2and1) < (-.525 - minPercent):
                    if (float(self.getTopOrder(market1, coinpair, True)[0]) *
                            float(
                                self.getTopOrder(market1, coinpair, True)[1])
                        ) >= float(self.getCurrentBalance(market1, "BTC")):
                        print("Arb Op: " + str(differenceBetweenMarket2and1) +
                              " for coin pair ")
                        print("Info: Bittrex: Buy:: ")
                        print(self.getTopOrder('bittrex', coinpair, True))
                        print("- Sell:: ")
                        print(self.getTopOrder('bittrex', coinpair, False))
                        arbOpportunity = (coinpair, "Market2to1",
                                          differenceBetweenMarket2and1, 1)
                        arbOpportunitiesList.append(arbOpportunity)
                    else:
                        continue
                elif float(differenceBetweenMarket1and2) < (-.525 -
                                                            minPercent):
                    if float(
                            self.getTopOrder('bittrex', coinpair, True, 3)[0]
                    ) * float(self.getTopOrder(
                            'bittrex', coinpair, True)[1]) >= float(
                                self.getCurrentBalance(market2, "BTC")):
                        print("Arb Op: ")
                        print(str(differenceBetweenMarket1and2))
                        print("Info: Bittrex: Buy:: ")
                        print(self.getTopOrder('poloniex', coinpair, True))
                        print("- Sell:: ")
                        print(self.getTopOrder('poloniex', coinpair, False))
                        print("Info: Poloniex: Buy:: ")
                        print(self.getTopOrder('bittrex', coinpair, True))
                        print("- Sell:: ")
                        print(self.getTopOrder('bittrex', coinpair, False))
                        arbOpportunity = (coinpair, "Market1to2",
                                          differenceBetweenMarket1and2, 1)
                        arbOpportunitiesList.append(arbOpportunity)
                    else:
                        continue
                else:
                    print(differenceBetweenMarket1and2 + " or " +
                          differenceBetweenMarket2and1 + " is more than -.7")
                    continue
            return arbOpportunitiesList
        except AttributeError:
            print("Attribute Error")

    def selectBestOpportunity(self, market1, market2, minPercent=0.45):
        opportunitiesList = []
        while opportunitiesList == []:
            opportunitiesList = self.arbitrageScan(market1, market2,
                                                   minPercent)
        if len(opportunitiesList) != 0:
            bestOpportunity = opportunitiesList[0]
            for opportunity in opportunitiesList:
                if bestOpportunity[2] < opportunity[2]:
                    bestOpportunity = opportunity
        else:
            print("No Opportunities Found")
            bestOpportunity = ("", "", 0.0, 0)
        return bestOpportunity

    def activateArbitrage(self, market1, market2, minPercent=0.45):
        bestArbitrageOpportunity = self.selectBestOpportunity(
            market1, market2, minPercent)
        coinName = str(bestArbitrageOpportunity[0]).replace("BTC-", "")
        if bestArbitrageOpportunity[1] == 'Market1to2':
            fullTopBuyOrder = self.getTopOrder(market1,
                                               bestArbitrageOpportunity[0],
                                               False)
            btcBuyOrderAvailable = (float(fullTopBuyOrder[0]) *
                                    float(fullTopBuyOrder[1]))
            btcBalanceOnMarket = float(
                self.getCurrentBalance('poloniex', "BTC"))
            if float(btcBuyOrderAvailable) > float(btcBalanceOnMarket):
                btcBuyOrderAvailable = float(btcBalanceOnMarket)
            coinAvailable = float(btcBuyOrderAvailable) / float(
                fullTopBuyOrder[0])
            if market1 == "poloniex" or market1 == "Poloniex":
                try:
                    if float(
                            self.getTopOrder(
                                market1, bestArbitrageOpportunity[0], False,
                                0)[0]) * float(
                                    self.getTopOrder(
                                        market1, bestArbitrageOpportunity[0],
                                        False, 0)[1]) < float(
                                            self.getBalance('poloniex',
                                                            'BTC')):
                        self.poloniexBot.buy(
                            bestArbitrageOpportunity[0].replace("-", "_"),
                            fullTopBuyOrder[0], coinAvailable)
                        print(
                            "Successfully Bought on Poloniex, Attempting to Send to Bittrex Now..."
                        )
                        time.sleep(3)
                        self.poloniexBot.withdraw(
                            coinName,
                            (self.getCurrentBalance('poloniex', coinName)),
                            self.getWalletAddress('bittrex', coinName))
                        tempCounter = 0
                        print(self.getCurrentBalance('bittrex', coinName))
                        while float(self.getCurrentBalance(
                                'bittrex', coinName)) < 0.0005:
                            time.sleep(5)
                            tempCounter = tempCounter + 1
                            if tempCounter > 15:
                                print("Still Awaiting Deposit...")
                                tempCounter = 0
                        print(
                            "Deposit Confirmed & Active! Preparing to Dump in 5 Seconds"
                        )
                        time.sleep(5)
                        while float(self.getCurrentBalance(market2, coinName)
                                    ) > 0.00050055 or self.getCurrentBalance(
                                        market2, coinName) == None:
                            time.sleep(3)
                            self.bittrexBot.sell_limit(
                                bestArbitrageOpportunity[0],
                                self.getCurrentBalance('bittrex', coinName),
                                self.getTopOrder(market2,
                                                 bestArbitrageOpportunity[0],
                                                 True, 1))
                        print(
                            "Finished Selling All the Coins that Could be Sold. Cycle Complete."
                        )
                    else:
                        print(
                            "The order didnt stay high enough, starting over")
                        self.activateArbitrage(market1, market2, minPercent)
                except MemoryError:
                    print("Error")
        if bestArbitrageOpportunity[1] == 'Market2to1':
            fullTopBuyOrder = self.getTopOrder(market2,
                                               bestArbitrageOpportunity[0],
                                               False, 0)
            btcBuyOrderAvailable = (float(fullTopBuyOrder[0]) *
                                    float(fullTopBuyOrder[1]))
            btcBalanceOnMarket = float(self.getCurrentBalance(market2, "BTC"))
            if btcBuyOrderAvailable > btcBalanceOnMarket:
                btcBuyOrderAvailable = btcBalanceOnMarket
            coinAvailable = float(btcBuyOrderAvailable) / float(
                fullTopBuyOrder[0])
            if market2 == "bittrex" or market2 == "Bittrex":
                try:
                    if float(
                            self.getTopOrder(
                                market1, bestArbitrageOpportunity[0], False,
                                0)[0]) * float(
                                    self.getTopOrder(
                                        market1, bestArbitrageOpportunity[0],
                                        False, 0)[1]) < float(
                                            self.getCurrentBalance(
                                                'bittrex', 'BTC')):
                        print("Buying " + str(bestArbitrageOpportunity[0]) +
                              " " + str(coinAvailable))
                        buy = self.bittrexBot.buy_limit(
                            bestArbitrageOpportunity[0], coinAvailable,
                            fullTopBuyOrder[0])
                        print(buy)
                        time.sleep(5)
                        if buy['success'] == True:
                            print(
                                "Successfully Bought on Bittrex, Attempting to Send to Poloniex Now..."
                            )
                            time.sleep(5)
                            self.bittrexBot.withdraw(
                                coinName,
                                self.getCurrentBalance(market2, coinName),
                                self.getWalletAddress(market1, coinName))
                            tempCounter = 0
                            print(self.getCurrentBalance(market1, coinName))
                            while float(
                                    self.getCurrentBalance(market1, coinName)
                            ) < 0.00050055 or self.getCurrentBalance(
                                    market1, coinName) == None:
                                time.sleep(5)
                                tempCounter = tempCounter + 1
                                if tempCounter > 15:
                                    print("Still Awaiting Deposit...")
                                    tempCounter = 0
                            print(
                                "Deposit Confirmed and Active! Preparing to Dump in 5 Seconds"
                            )
                            time.sleep(5)
                            while float(
                                    self.getCurrentBalance(
                                        market1, coinName)) > 0.00010055:
                                time.sleep(5)
                                self.poloniexBot.sell(
                                    str(bestArbitrageOpportunity[0]).replace(
                                        "-", "_"),
                                    float(
                                        self.getTopOrder(
                                            market1,
                                            bestArbitrageOpportunity[0].
                                            replace("-", "_"), True, 1)),
                                    self.getCurrentBalance(market1, coinName))
                                print(
                                    "Attempting to Sell Maximum Amount of Coins that Could be Sold."
                                )
                            print("Finished Selling all coins. Cycle Complete")
                        else:
                            print("Failed to Buy")
                            return "Failed to Buy"
                    else:
                        print(
                            "The order didn't stay high enough, starting over")
                        self.activateArbitrage(market1, market2, minPercent)
                except AttributeError:
                    print("Attribute Error, sorry")

    def getLendingBalances(self):
        #Only works with Poloniex
        try:
            return cryptoCommander.poloniexBot.api_query(
                'returnAvailableAccountBalances')['lending']
        except KeyError:
            return []

    def getCurrentLoanOffers(self, coin):
        #Only works with Poloniex
        ret = urllib2.request.urlopen('http://poloniex.com/public?command=' +
                                      'returnLoanOrders' + '&currency=' +
                                      str(coin))
        return json.loads(ret.read())

    def getPrimeLendingRate(self, coin, minWeight=Decimal('25.0')):
        #Only works with Poloniex
        accumulatedWeight, bestRate = Decimal('0.0'), Decimal('0.0')
        print(accumulatedWeight)
        for offer in self.getCurrentLoanOffers(coin)['offers']:
            if accumulatedWeight < minWeight:
                print('Accumulated weight is less than 25: ' +
                      str(accumulatedWeight))
                accumulatedWeight = accumulatedWeight + Decimal(
                    str(offer['amount']))
            else:
                print('Best rate is: ' + str(offer['rate']))
                bestRate = Decimal(str(offer['rate'])) - Decimal('0.000001')
                break
        if bestRate < Decimal('0.000001'): bestRate = Decimal('0.000001')
        return bestRate

    def getActiveLoans(self):
        #Only works with Poloniex
        return self.poloniexBot.api_query('returnActiveLoans')

    def getOpenLoanOffers(self):
        #Only works with Poloniex
        try:
            return self.poloniexBot.api_query('returnOpenLoanOffers')
        except KeyError:
            return []

    def cancelLoanOffer(self, currency, orderNumber):
        #Only works with Poloniex
        return self.poloniexBot.api_query('cancelLoanOffer', {
            "currency": currency,
            "orderNumber": orderNumber
        })

    def cancelAllLoanOffers(self):
        openLoansDict = self.getOpenLoanOffers()
        for openLoanCoin in openLoansDict:
            for dataObject in openLoansDict[openLoanCoin]:
                self.cancelLoanOffer(openLoanCoin, dataObject[id])

    def createLoanOffer(self, currency, amount, duration, autoRenew,
                        lendingRate):
        return self.poloniexBot.api_query(
            'createLoanOffer', {
                "currency": currency,
                "amount": amount,
                "duration": duration,
                "autoRenew": autoRenew,
                "lendingRate": lendingRate,
            })

    def checkLendingStagnation(self):
        openLoansDict = self.getOpenLoanOffers()
        for openLoanCoin in openLoansDict:
            for data in openLoansDict[openLoanCoin]:
                if (datetime.datetime.utcnow() - datetime.datetime.strptime(
                        str(data['date']), '%Y-%m-%d %X') >
                        datetime.timedelta(minutes=2)):
                    print('Cancelling Loan Orders that are stagnant.')
                    self.cancelLoanOffer(openLoanCoin, data['id'])

    def placeAllLoans(self):
        balances = self.getLendingBalances()
        for coin in balances:
            try:
                print(balances[coin])
                if type(balances[coin]
                        ) != Decimal and balances[coin] > Decimal('0.0'):
                    balances[coin] = Decimal(str(balances[coin]))
                if type(balances[coin]
                        ) == Decimal and balances[coin] >= Decimal('0.01'):
                    #print "Print currency available is: " + str(balances[coin]) + str(coin) + ", Lending Now."
                    while Decimal(str(balances[coin])) >= Decimal('0.01'):
                        if Decimal(str(balances[coin])) <= Decimal(
                                '0.02') and Decimal(str(
                                    balances[coin])) >= Decimal('0.01'):
                            print('lending between 0.01 and 0.02')
                            print(
                                self.createLoanOffer(
                                    coin, float(balances[coin]), 2, 0,
                                    self.getPrimeLendingRate(coin)))
                        else:
                            primeRate = self.getPrimeLendingRate(coin)
                            print("Prime Rate is: " + str(primeRate))
                            if primeRate <= Decimal('0.000025') or Decimal(
                                    balances[coin]) > Decimal('0.1'):
                                if Decimal(balances[coin]) >= Decimal('10.0'):
                                    if Decimal(
                                            balances[coin]
                                    ) < Decimal('20.0') and Decimal(
                                            balances[coin]) > Decimal('10.0'):
                                        print('lending between 10 and 20')
                                        print(
                                            self.createLoanOffer(
                                                coin, float(balances[coin]), 2,
                                                0, primeRate))
                                    else:
                                        print('lending 10')
                                        print(
                                            self.createLoanOffer(
                                                coin, 10.0, 2, 0, primeRate))
                                else:
                                    if Decimal(
                                            balances[coin]) > Decimal('0.1'):
                                        if Decimal(balances[coin]) < Decimal(
                                                '0.2') and Decimal(
                                                    balances[coin]) > Decimal(
                                                        '0.1'):
                                            print(
                                                'lending between 0.1 and 0.2')
                                            print(
                                                self.createLoanOffer(
                                                    coin,
                                                    float(balances[coin]), 2,
                                                    0, primeRate))
                                        else:
                                            print('lending 0.1')
                                            print(
                                                self.createLoanOffer(
                                                    coin, 0.1, 2, 0,
                                                    primeRate))
                                    else:
                                        print('lending 0.01')
                                        print(
                                            self.createLoanOffer(
                                                coin, 0.01, 2, 0, primeRate))
                            else:
                                print('lending 0.01')
                                print(
                                    self.createLoanOffer(
                                        coin, 0.01, 2, 0, primeRate))
                        time.sleep(.2)
                        balances = self.getLendingBalances()
                else:
                    print('No coins available to lend, sorry!')
            except KeyError:
                print('All loans for ' + str(coin) + ' actively being lent.')

    def startLendingAutomation(self):
        while True:
            try:
                while self.getLendingBalances(
                ) != None and self.getOpenLoanOffers() != None:
                    while any(self.getLendingBalances()) > Decimal(
                            '0.001') or any(self.getOpenLoanOffers()):
                        self.placeAllLoans()
                        time.sleep(150)
                        self.checkLendingStagnation()
                print('All Done.')
            except TypeError:
                print("NOT done")
Beispiel #15
0
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.send_buy_email(buy_order_data["result"], stats)
        self.Messenger.print_buy(coin_pair, price, stats["rsi"],
                                 stats["24HrVolume"])
        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.send_sell_email(sell_order_data["result"], stats)
        self.Messenger.print_sell(coin_pair, price, stats["rsi"],
                                  stats["profitMargin"])
        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
Beispiel #16
0
    #bidPrice = float('%.8f' % bittrex.get_ticker('BTC-'+coinName)['result']['Bid']) * rate
    bidPrice = '%.8f' % (float(bidPrice) * rate)
    print(bidPrice)
    buyResult = bittrex.sell_limit('BTC-' + coinName, coinAvail, bidPrice)['result']
    myOrderHistory = bittrex.get_order_history(coinName, 1)
    openOrders = bittrex.get_open_orders(coinName)
    return buyResult, myOrderHistory, openOrders

#coinName = sys.argv[1].upper()
#print(coinName)
#askPrice, buyResult, myOrderHistory, openOrders = buyCoin(coinName,1.2)
#print(str(buyResult))

#sellResult, myOrderHistory, openOrders = sellCoin(coinName,askPrice, 2.5)
#print(str(sellResult))
result = bittrex.get_markets()
for coin in result['result']:
    MarketName = coin['MarketName']
    if 'BTC-' in MarketName:
        try:
            #ticker = bittrex.get_ticker(MarketName)
            #currency =  float('%.8f' % ticker['result']['Ask'])
            #print(ticker)
            #print(MarketName + ' : ' + str(currency))
            ThreadGetTiker(MarketName).start()
        except:
            print('error : ' + MarketName)
            #print(MarketName + ' : ' + str(currency))
#print(result)
#print(str(myOrderHistory))
#print(str(openOrders))
Beispiel #17
0
        return [
            self.minutes, self.price, self.trans_amount, self.coin_amount,
            self.change_sm, self.change_md, self.change_lg, self.t0_price
        ]


#settings
CHANGE_SM = 5 * 60  #seconds
CHANGE_MD = 15 * 60  #seconds
CHANGE_LG = 30 * 60  #seconds
HISTORY = 60 * 60  #size of history store in seconds
OFFSET = 30 * 60  #time for future prediction
#vars + init
my_bitterx = Bittrex(None, None)
markets = []
bit_markets = my_bitterx.get_markets()["result"]
for market in bit_markets:
    markets.append(market["BaseCurrency"] + "-" + market["MarketCurrency"])
print(markets)
history_store = []  #storage for history
#markets = json.load(open("markets.json",'r'))
for market in markets:
    history_store.append({"flag": False, "market": market, "history": []})
lock = allocate_lock()


#extract markethistory
def hist_fetch(a):
    global my_bitterx, history_store, markets
    print("Thread 1 started")
    while True:
Beispiel #18
0
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
import time
from bittrex import Bittrex
import pandas as pd

apikey = 'fd25ef6daf6c4d5cb8507878781df312'
secret = '5f00769f175141be861bf199f089f9fd'
my_bittrex = Bittrex(apikey, secret)
my_bittrex.get_currencies()
my_bittrex.get_marketsummary('BTC-LTC')

coinList = [{
    'CoinName': x['MarketCurrency'],
    'CoinName_Full': x['MarketCurrencyLong'],
    'MarketName': x['MarketName'],
    'BaseCurrency': x['BaseCurrency']
} for x in my_bittrex.get_markets()['result']]
coinList = pd.DataFrame(coinList)
coinList

BTC - LTC,

col = [
    'MarketName', 'High', 'Low', 'Volume', 'Last', 'BaseVolume', 'TimeStamp',
    'Bid', 'Ask', 'OpenBuyOrders', 'OpenSellOrders', 'PrevDay', 'Created'
]
market_price = pd.DataFrame(columns=col)
i = 0

while 1:
    market_price = pd.DataFrame(columns=col)
    time = time.asctime()
class TestBittrexV11PublicAPI(unittest.TestCase):
    """
    Integration tests for the Bittrex public API.
    These will fail in the absence of an internet connection or if bittrex API goes down
    """
    def setUp(self):
        self.bittrex = Bittrex(None, None, api_version=API_V1_1)

    def test_handles_none_key_or_secret(self):
        self.bittrex = Bittrex(None, None)
        # could call any public method here
        actual = self.bittrex.get_markets()
        self.assertTrue(actual['success'],
                        "failed with None key and None secret")

        self.bittrex = Bittrex("123", None)
        actual = self.bittrex.get_markets()
        self.assertTrue(actual['success'], "failed with None secret")

        self.bittrex = Bittrex(None, "123")
        actual = self.bittrex.get_markets()
        self.assertTrue(actual['success'], "failed with None key")

    def test_get_markets(self):
        actual = self.bittrex.get_markets()
        test_basic_response(self, actual, "get_markets")
        self.assertTrue(isinstance(actual['result'], list),
                        "result is not a list")
        self.assertTrue(len(actual['result']) > 0, "result list is 0-length")

    def test_get_currencies(self):
        actual = self.bittrex.get_currencies()
        test_basic_response(self, actual, "get_currencies")

    def test_get_ticker(self):
        actual = self.bittrex.get_ticker(market='BTC-LTC')
        test_basic_response(self, actual, "get_ticker")

    def test_get_market_summaries(self):
        actual = self.bittrex.get_market_summaries()
        test_basic_response(self, actual, "get_market_summaries")

    def test_get_orderbook(self):
        actual = self.bittrex.get_orderbook('BTC-LTC',
                                            depth_type=BUY_ORDERBOOK)
        test_basic_response(self, actual, "get_orderbook")

    def test_get_market_history(self):
        actual = self.bittrex.get_market_history('BTC-LTC')
        test_basic_response(self, actual, "get_market_history")

    def test_list_markets_by_currency(self):
        actual = self.bittrex.list_markets_by_currency('LTC')
        self.assertListEqual(['BTC-LTC', 'ETH-LTC', 'USDT-LTC'], actual)

    def test_get_wallet_health(self):
        self.assertRaisesRegexp(Exception, 'method call not available',
                                self.bittrex.get_wallet_health)

    def test_get_balance_distribution(self):
        self.assertRaisesRegexp(Exception, 'method call not available',
                                self.bittrex.get_balance_distribution)

    def test_get_candles(self):
        self.assertRaisesRegexp(Exception,
                                'method call not available',
                                self.bittrex.get_candles,
                                market='BTC-LTC',
                                tick_interval=TICKINTERVAL_ONEMIN)

    def test_get_latest_candle(self):
        self.assertRaisesRegexp(Exception,
                                'method call not available',
                                self.bittrex.get_latest_candle,
                                market='BTC-LTC',
                                tick_interval=TICKINTERVAL_ONEMIN)
Beispiel #21
0
# for terminal output -- sorry Windows users!
class colors:
    HEADER = '\033[95m'
    BLUE = '\033[94m'
    GREEN = '\033[92m'
    YELLOW = '\033[93m'
    RED = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'


# fetch markets
print("fetching markets...")
markets = api.get_markets()
print(" - done")

# read config
print("reading config...")
c = open("marketmusic.conf", "r").readlines()
currency = []
for i in range(0, len(c)):
    t = c[i].replace("\n", "")
    currency.append(t)
    print(" - currency added: " + t)
print(" - done")

# get current market values
i = 1
s = ""