예제 #1
0
 def __init__(self, key, secret):
     super(Trader, self).__init__()
     self.symbols = []
     self.symbols_gen = get_symbols_as_updated()
     self.wss = BtfxWss(key=key, secret=secret, log_level='CRITICAL')
     self._disconnect_event = Event()
     self._receiver = None
예제 #2
0
파일: trade_hbot.py 프로젝트: aitjcize/alec
    def __init__(self, symbols=None, callbacks=None):
        """
        Args:
            symbols: A list used to subscribe tickers.
            callbacks: A list of functions to handle events:
                'reset',
                'process_wallet',
                'process_order',
                'process_tick',
                'process_notification'
        """
        required_callbacks = [
            'reset',
            'process_wallet',
            'process_order',
            'process_tick',
            'process_notification'
        ]
        if not symbols or not callbacks:
            log(LOG_ERROR, 'Require parameters symbols and callbacks')
            return
        for callback in required_callbacks:
            if callback not in callbacks:
                log(LOG_ERROR, 'Require %s callback function' % callback)
                return

        self._tick_symbols = symbols
        self._callbacks = callbacks

        self._received_order_snapshot = False
        self._received_wallet_snapshot = False
        self._wss = BtfxWss(
            key=config.BFX_API_KEY, secret=config.BFX_API_SECRET)
        self._wss.start()
예제 #3
0
 def __init__(self):
     self.bids = dict()
     self.asks = dict()
     self.bid_depth = 0
     self.bid_ma_slow = 0
     self.bid_ma_fast = 0
     self.ask_depth = 0
     self.ask_ma_slow = 0
     self.ask_ma_fast = 0
     self.wss = BtfxWss()
class Connection:
    #     def __init__(self, key=None, secret=None, log_level=None, **wss_kwargs):
    def __init__(self, symbol):
        self.wss = BtfxWss(key=None,
                           secret=None,
                           addr='wss://api.bitfinex.com/ws/2')
        self.wss.start()
        self.symbol = symbol
        while not self.wss.conn.connected.is_set():
            time.sleep(1)
    
        self.wss.subscribe_to_ticker(symbol)
        self.wss.subscribe_to_order_book(symbol)

    def stop(self):
        # Unsubscribing from channels:
        # self.wss.unsubscribe_from_ticker('BTCUSD')
        # self.wss.unsubscribe_from_order_book('BTCUSD')

        # Shutting down the client:
        self.wss.stop()

    def get_bitfinex_price(self):
        ticker_q = self.wss.tickers(self.symbol)  # returns a Queue object for the pair.
        return ticker_q
예제 #5
0
 def __init__(self, symbols):
     self.DEBUG = True
     self._rest_client = bitfinex_v1_rest.FullApi()
     self._wss = None
     self._symbols = symbols
     self._funding = {}
     self._credits = {}
     self._offers = {}
     self._wss = BtfxWss(key=config.BFX_API_KEY,
                         secret=config.BFX_API_SECRET)
     self._wss.start()
 def __init__(self, symbol):
     self.wss = BtfxWss(key=None,
                        secret=None,
                        addr='wss://api.bitfinex.com/ws/2')
     self.wss.start()
     self.symbol = symbol
     while not self.wss.conn.connected.is_set():
         time.sleep(1)
 
     self.wss.subscribe_to_ticker(symbol)
     self.wss.subscribe_to_order_book(symbol)
예제 #7
0
 def test_is_connected_decorator_works_as_expected(self):
     wss = BtfxWss(log_level=logging.CRITICAL)
     time.sleep(1)
     wss.start()
     try:
         wss.subscribe_to_candles('BTCUSD')
     except WebSocketConnectionClosedException:
         self.fail("Decorator did not work!")
     wss.stop()
예제 #8
0
    def getBalances(self):
        bf = BtfxWss(key=self.key, secret=self.secret)
        bf.start()

        while not bf.conn.connected.is_set():
            time.sleep(1)

        bf.authenticate()
        time.sleep(1)

        resp = bf.wallets
        timeout = time.time() + 10
        while resp.qsize == 0 or time.time() <= timeout:
            time.sleep(1)

        bf.stop()

        l = list()
        while resp.qsize() > 0:
            l.append(resp.get())

        logging.debug(l)
        #logging.info(l[0][0][1])

        balance = dict()
        if len(l) == 0:
            return balance

        for entry in l[0][0][1]:
            #[['funding', 'IOT', 0.00471435, 0, None], ['exchange', 'ETH', 0, 0, None], ['exchange', 'IOT', 408.54209381, 0, None], ['exchange', 'BTC', 0, 0, None]]
            cur = entry[1]
            value = entry[2]

            if cur not in balance:
                balance[cur] = 0.0
            balance[cur] += value

        return balance
예제 #9
0
def get_candle_q(symbol):
    """
        candle_format: ([[1515066900000, 3.1354, 3.1457, 3.1459, 3.1261, 41373.42748331]], 1515066939.756591)
                        ([[candle_time, O, H, L, C]], timestamp)
    """
    wss = BtfxWss()
    wss.start()

    while not wss.conn.connected.is_set():
        time.sleep(1)

    valid_candles = [
        '1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D', '7D', '14D',
        '1M'
    ]
    wss.subscribe_to_candles(symbol, '1m')

    time.sleep(15)
    candles_q = wss.candles(symbol, '1m')
    return candles_q
예제 #10
0
def run():
    bq = BigQuery(table="BTCUSD_trade_data", dataset="bitfinex", schema=schema)
    logger = setup_logger()

    wss = BtfxWss()
    wss.start()

    while not wss.conn.connected.is_set():
        sleep(1)

    wss.subscribe_to_trades('BTCUSD')

    t = time.time()
    while time.time() - t < 10:
        pass

    # access queue object
    books_q = wss.trades('BTCUSD')
    while wss.conn.connected.is_set():
        rows_to_insert = books_q.get()
        rows = []

        if depth(rows_to_insert[0]) == 3:
            continue
        if rows_to_insert[0][0] == 'te':
            continue

        side = "Sell" if rows_to_insert[0][1][2] < 0 else "Buy"
        r = {
            "ts": rows_to_insert[1],
            "price": rows_to_insert[0][1][3],
            "id": rows_to_insert[0][1][1],
            "side": side,
            "size": abs(rows_to_insert[0][1][2])
        }
        rows.append(r)

        errors = bq.client.insert_rows(bq.tbl, rows)
        if errors != []:
            print(errors)
예제 #11
0
def store_data(symbol):
    file_dir = TRADE_FILE_LOCATION.format(symbol=symbol)
    if not os.path.exists(file_dir):
        os.makedirs(file_dir)
    wss = BtfxWss()
    wss.start()
    while not wss.conn.connected.is_set():
        time.sleep(1)
    wss.subscribe_to_trades(symbol)
    time.sleep(15)
    trade_q = wss.trades(symbol)
    while 1:
        if trade_q.empty():
            time.sleep(1)
        else:
            trade = trade_q.get()
            with open(
                    file_dir + datetime.datetime.now().strftime("%Y%m%d") +
                    '.txt', 'a') as outfile:
                outfile.write(str(trade))
                outfile.write('\n')
            print(trade)
예제 #12
0
def main():
    wss = BtfxWss()
    wss.start()
    macd_obj = macd.MACD()
    rsi_obj = rsi.RSI()
    long_position = LongPosition()

    while not wss.conn.connected.is_set():
        time.sleep(1)

    # wss.subscribe_to_ticker('XRPUSD')
    wss.subscribe_to_trades('XRPUSD')

    time.sleep(15)

    # ticker_q = wss.tickers('XRPUSD')  # returns a Queue object for the pair.
    ticker_q = wss.trades('XRPUSD')
    while 1:
        if ticker_q.empty():
            time.sleep(1)
        else:
            ticker = ticker_q.get()
            print(ticker)
            # price = ticker[0][-1][6]
            # timestamp = ticker[1]
            timestamp = ticker[1]
            price = ticker[0][-1][-1]
            if isinstance(price, list):
                continue
            macd_obj.update_macd(timestamp, price)
            # print(macd_obj.macds)
            rsi_obj.update_rsi(timestamp, price)
            # print(rsi_obj.rsi)
            long_position.update_position(macd_obj.macds['present_macd'],
                                          macd_obj.macds['present_signal'],
                                          rsi_obj.rsi['rsi'], price, timestamp)
예제 #13
0
    'https://api.bitfinex.com/v1/symbols').text.upper().replace(
        '"', '')[1:-1].split(',')

# Setting the BtfxWss Library
log = logging.getLogger(__name__)

fh = logging.FileHandler('test.log')
fh.setLevel(logging.DEBUG)
sh = logging.StreamHandler(sys.stdout)
sh.setLevel(logging.DEBUG)

log.addHandler(sh)
log.addHandler(fh)
logging.basicConfig(level=logging.DEBUG, handlers=[fh, sh])

wss = BtfxWss()
wss.start()

while not wss.conn.connected.is_set():
    time.sleep(1)

for ticket in tickets:
    wss.subscribe_to_ticker(ticket)

    t = time.time()
    while time.time() - t < 0.5:
        pass

    try:
        ticker = wss.tickers(ticket).get()
    except KeyError:
예제 #14
0
# -*- coding: utf-8 -*-
"""
Created on Tue Sep 26 16:00:36 2017

@author: vince
"""

from btfxwss import BtfxWss
wss = BtfxWss()

예제 #15
0

def replace_value_with_definition(current_dict, key_to_find, definition):
    for key in current_dict.keys():
        if key == key_to_find:
            current_dict[key] = definition
            break
    return current_dict


secStr = btfAccount()

loginName = str(secStr['APIK'])
passName = str(secStr['APIS'])

wss = BtfxWss(key=loginName, secret=passName)
wss.start()

while not wss.conn.connected.is_set():
    time.sleep(1)
wss.authenticate()  #Success
##############################################################################
# Subscribe to some channels
wss.subscribe_to_ticker('BTCUSD')
wss.subscribe_to_order_book('BTCUSD')
wss.subscribe_to_trades('BTCUSD')

time.sleep(5)
#Accessing data stored in BtfxWss:
ticker_q = wss.tickers('BTCUSD')
while not ticker_q.empty():
예제 #16
0
class BitfinexBookWatcher:
    def __init__(self):
        self.bids = dict()
        self.asks = dict()
        self.bid_depth = 0
        self.bid_ma_slow = 0
        self.bid_ma_fast = 0
        self.ask_depth = 0
        self.ask_ma_slow = 0
        self.ask_ma_fast = 0
        self.wss = BtfxWss()

    def start(self):
        if not self.wss.conn.connected.is_set():
            logger.info("Starting Bitfinex websocket client")
            self.wss.start()
        while not self.wss.conn.connected.is_set():
            time.sleep(1)
        # for P1 precision usual width of order book is ~100 USD (for BTC/USD price ~6500)
        # for wider range (about 1500 USD) use P2 precision. But the price will be rounded to tens
        self.wss.subscribe_to_order_book('BTCUSD', prec="P1", len=100)
        logger.info("Subscribed to Order Book WSS channel")
        # waiting for a bit to receive the book snapshot
        time.sleep(2)

    # call get_updates regularly to clear the queue!! Otherwise you may get OutOfMemory errors
    def get_updates(self):
        book_q = self.wss.books(
            'BTCUSD')  # returns a Queue object for the pair.
        # result = []
        while not book_q.empty():
            get = book_q.get()
            # print(get)
            # result.append(get)
            book_item, tag = get
            self.fill_the_book(book_item)
        self.bid_depth = sum(self.bids.values())
        self.bid_ma_fast = update_ma(self.bid_depth, self.bid_ma_fast, 5)
        self.bid_ma_slow = update_ma(self.bid_depth, self.bid_ma_slow, 90)
        self.ask_depth = sum(self.asks.values())
        self.ask_ma_fast = update_ma(self.ask_depth, self.ask_ma_fast, 5)
        self.ask_ma_slow = update_ma(self.ask_depth, self.ask_ma_slow, 90)
        # logger.debug("Market depth: bids: {0}, ma5: {1} ma90: {2} |  asks: {3}, ma5: {4} ma90: {5}".format(
        #     round(self.bid_depth),
        #     round(self.bid_ma_fast),
        #     round(self.bid_ma_slow),
        #     round(self.ask_depth),
        #     round(self.ask_ma_fast),
        #     round(self.ask_ma_slow)
        # ))
        # return result

    # better call stop() at the end of the program (and on TERM signal)
    def stop(self):
        if self.wss.conn.connected.is_set() and self.wss.channel_configs:
            logger.debug("unsubscribe")
            self.wss.unsubscribe_from_order_book('BTCUSD')
        if self.wss.conn.connected.is_set():
            logger.debug("stopping the socket")
            self.wss.stop()
            logger.debug("stopped.")

    def fill_the_book(self, input_list):
        for row in input_list:
            if isinstance(row[0], list):
                self.fill_the_book(row)
            else:
                price = str(row[0])
                count = row[1]
                amt = row[2]
                if count != 0:
                    if amt > 0:
                        self.bids[price] = amt
                    else:
                        self.asks[price] = abs(amt)
                else:
                    if amt > 0:
                        if price in self.bids.keys():
                            del (self.bids[price])
                    elif amt < 0:
                        if price in self.asks.keys():
                            del (self.asks[price])
예제 #17
0
#!/usr/bin/env python

import time
import uuid
import ujson
from btfxwss import BtfxWss
from classes.tasks import save_ticker, save_trade
from classes.utils import get_time, get_timestamp, get_hour, get_date

if __name__ == '__main__':
    wss = BtfxWss()
    wss.start()

    while not wss.conn.connected.is_set():
        time.sleep(1)

    cryptos = []
    with open('config.json', 'r') as handler:
        cryptos = ujson.load(handler)

    if cryptos:
        for crypto in cryptos:
            currency = crypto['symbol'].upper()
            # Subscribe to some channels
            wss.subscribe_to_ticker(currency)
            wss.subscribe_to_trades(currency)
            time.sleep(1)

        try:
            print("Starting...")
            while True:
예제 #18
0
def worker_function(quit_flag, launch_flag, globalz):
    counter = 0
    established = False
    wss = None
    qq = None
    first = True
    order = False
    OCHLVlast = 0
    OCHLVcur = 0

    while not quit_flag.value:

        if launch_flag.value == 5:

            if established == False:
                wss = BtfxWss(key=API_KEY, secret=API_SECRET)
                wss.start()

                while not wss.conn.connected.is_set():
                    time.sleep(1)
                    established = True
                    wss.authenticate()
                # Subscribe to some channels
                wss.subscribe_to_ticker('BTCUSD')
                wss.subscribe_to_candles('BTCUSD', '15m')
                wss.subscribe_to_candles('BTCUSD', '1m')
                wss.subscribe_to_order_book('BTCUSD')

            # Do something else
            t = time.time()
            while time.time() - t < 2:
                pass

            # Accessing data stored in BtfxWss:
            ticker_q = wss.candles(
                'BTCUSD', '1m')  # returns a Queue object for the pair.
            wallet = wss.wallets

            while not ticker_q.empty():
                qq = np.asarray(ticker_q.get())
                #globalz[0] = int(np.asarray(qq)[1])
                if type(qq[0][0][0]) == list:
                    first = True
                if first:
                    globalz[0] = int(((qq)[0][0][0][0]) / 1000)
                    #globalz[1] =
                    logging.debug(((qq)[0][0][0][0]) / 1000)
                    #loggin.debug()
                    #logging.debug(type((qq)[0][0][0][0]))
                    #logging.debug(type((qq)[0][0][0]))
                    #logging.debug(type((qq)[0][0]))
                    #logging.debug(type((qq)[0]))
                    #logging.debug(type((qq)))

                    with open('my.ts', 'w') as file:

                        for i in range(len(qq[0][0])):
                            stri = (str(qq[0][0][i]))
                            file.write((stri))
                            file.write("\n")

                    first = False
                else:
                    globalz[30] = int(((qq)[1]))
                    globalz[0] = int(((qq)[0][0][0]) / 1000)
                    globalz[5] = int(((qq)[0][0][5]) * 1000)
                    globalz[6] = int(((qq)[0][0][5]) * 1000)

                    #globalz[0] =

                    for i in range(1, 5):
                        globalz[i] = int((np.asarray(qq)[0][0][i]))

                    #logging.debug(counter)
                    logging.debug((np.asarray(qq)[0][0]))
                    #logging.debug((np.asarray(qq)[0][0][1]))

            if wallet.empty() == False:
                logging.debug(wallet.get())

            #ticker_q = wss.candles('BTCUSD')  # returns a Queue object for the pair.

            counter += 1
            logging.debug("Tick # %s" % counter)

            #var.set()
            #time.sleep(0.01)

        elif launch_flag.value == -1:
            if established == True:
                logging.info("Stopping kekush at # %s" % counter)
                time.sleep(0.01)

                wss.unsubscribe_from_ticker('BTCUSD')
                wss.unsubscribe_from_candles('BTCUSD')
                wss.unsubscribe_from_order_book('BTCUSD')

                # Shutting down the client:
                wss.stop()
                wss = None
                counter = 0
                established = False
                first = True

        elif launch_flag.value == 6:
            if order == False:
                logging.info("Ordering some shit at # %s" % counter)

                order = {
                    "cid": 373617,  #change to the API_Key Number
                    "type": "LIMIT",
                    "symbol": "tEOSUSD",
                    "amount": "2",
                    "price": "14",
                    "hidden": 0,
                    "postonly": 1
                }

                wss.new_order(**order)

                launch_flag.value = 7
                order = True

                time.sleep(3)
                logging.info(wss.orders.get())
예제 #19
0
class RateMonitor(object):
    def __init__(self, symbols):
        self.DEBUG = True
        self._rest_client = bitfinex_v1_rest.FullApi()
        self._wss = None
        self._symbols = symbols
        self._funding = {}
        self._credits = {}
        self._offers = {}
        self._wss = BtfxWss(key=config.BFX_API_KEY,
                            secret=config.BFX_API_SECRET)
        self._wss.start()

    def reset(self):
        self._funding = {}
        self._credits = {}
        self._offers = {}

    def connect(self):
        log("Server connected")
        self._wss.authenticate()
        for symbol in self._symbols:
            self._wss.subscribe_to_trades(symbol)
            self._funding['latest_ts'] = 0
            self._funding['latest_rate'] = 0.0

    def run(self):
        while True:
            self.check_system()
            self.check_account_info()
            self.check_trades()
            time.sleep(0.5)

    def check_system(self):
        try:
            server_q = self._wss.opened
            while not server_q.empty():
                server_q.get()
                self.reset()
                self.connect()
        except KeyError:
            # KeyError means Btfxwss doesn't get related information yet.
            # It's fine to pass and check in the next time.
            pass

    def check_account_info(self):
        try:
            wallets_q = self._wss.wallets
            while not wallets_q.empty():
                self.received_wallets(wallets_q.get())

            wallet_update_q = self._wss.wallet_update
            while not wallet_update_q.empty():
                self.received_wallet_update(wallet_update_q.get())

            credits_q = self._wss.credits
            while not credits_q.empty():
                self.received_credits(credits_q.get())

            offer_new_q = self._wss.offer_new
            while not offer_new_q.empty():
                self.received_offer_new(offer_new_q.get())

            offer_cancel_q = self._wss.offer_cancel
            while not offer_cancel_q.empty():
                self.received_offer_cancel(offer_cancel_q.get())

            credit_close_q = self._wss.credit_close
            while not credit_close_q.empty():
                self.received_credit_close(credit_close_q.get())

            credit_update_q = self._wss.credit_update
            while not credit_update_q.empty():
                self.received_credit_update(credit_update_q.get())

            q = self._wss.offer_update
            while not q.empty():
                print(q.get())
        except KeyError:
            # KeyError means Btfxwss doesn't get related information yet.
            # It's fine to pass and check in the next time.
            pass

    def check_trades(self):
        for symbol in self._symbols:
            try:
                trades_q = self._wss.trades(symbol)
                while not trades_q.empty():
                    self.received_trades(symbol, trades_q.get())
            except KeyError:
                # KeyError means Btfxwss doesn't get related information yet.
                # It's fine to pass and check in the next time.
                pass

    def received_wallets(self, message):
        # pylint: disable=W0612
        data, ts = message
        for wallet in data[1]:
            self.process_wallet(wallet)

    def received_wallet_update(self, message):
        # pylint: disable=W0612
        data, ts = message
        self.process_wallet(data[1])

    def received_credits(self, message):
        # pylint: disable=W0612
        data, ts = message
        self._funding['lent'] = 0
        for credit in data[1]:
            self._funding['lent'] += self.process_credit(credit)
        log("Funding usd lent: %f" % self._funding['lent'])

    def received_offer_new(self, message):
        # pylint: disable=W0612
        data, ts = message
        self.process_offer(data[1])

    def received_offer_cancel(self, message):
        # pylint: disable=W0612
        data, ts = message
        self.process_offer(data[1])

    def received_credit_close(self, message):
        # pylint: disable=W0612
        data, ts = message
        self.process_credit(data[1])

    def received_credit_update(self, message):
        # pylint: disable=W0612
        data, ts = message
        self.process_credit(data[1])

    def received_trades(self, symbol, message):
        # pylint: disable=W0612
        data, ts = message
        if isinstance(data[0], list):
            for transaction in data[0]:
                self.process_public_trade(symbol, transaction)
        elif data[0] == 'fte':
            self.process_public_trade(symbol, data[1])
            self.lend_strategy()

    def process_wallet(self, data):
        if self.DEBUG:
            print(data)
        wallet = bitfinex_v2_rest.Wallet(data)
        if wallet.wallet_type == 'funding' and wallet.currency == 'USD':
            self._funding['total'] = wallet.balance
            log("Funding usd: %f" % self._funding['total'])

    def process_credit(self, data):
        if self.DEBUG:
            print(data)
        credit = bitfinex_v2_rest.Credit(data)
        if credit.symbol == 'fUSD':
            if credit.status == 'ACTIVE':
                self._credits[credit.id] = credit.amount
                return credit.amount
            elif credit.status.startswith('CLOSED'):
                del self._credits[credit.id]
                self._funding['lent'] -= credit.amount
                log('Close a credit, amount: %f' % credit.amount)
                self.lend_strategy()
        return 0

    def process_offer(self, data):
        if self.DEBUG:
            print(data)
        offer = bitfinex_v2_rest.FundingOffer(data)
        if offer.symbol == 'fUSD':
            if offer.status == 'ACTIVE':
                if offer.id not in self._offers:
                    self._offers[offer.id] = offer.amount_orig
                    self._funding['lent'] += offer.amount_orig
                    log('Create an offer, amount: %f' % offer.amount_orig)
            elif offer.status == 'CANCEL':
                self._funding['lent'] -= offer.amount
                log('Cancel an offer, amount: %f' % offer.amount)
                del self._offers[offer.id]
            elif offer.status.startswith('EXECUTED'):
                if offer.id not in self._offers:
                    self._funding['lent'] += offer.amount_orig
                    log('Create an offer, amount: %f' % offer.amount_orig)
                else:
                    del self._offers[offer.id]

    def process_public_trade(self, symbol, data):
        trade = bitfinex_v2_rest.Trade(data)
        log("%s: Timestamp: %s, Rate: %f, Period: %d, Amount: %f" %
            (symbol, time.strftime("%H:%M:%S", time.localtime(trade.time)),
             trade.rate * 100, trade.period, abs(trade.amount)))

        if trade.time > self._funding['latest_ts']:
            self._funding['latest_ts'] = trade.time
            self._funding['latest_rate'] = trade.rate

    def lend_strategy(self):
        if 'total' in self._funding and 'lent' in self._funding:
            available = self._funding['total'] - self._funding['lent']
        else:
            return
        if 'available' not in self._funding or (available !=
                                                self._funding['available']):
            log('total: %f, lent: %f, available: %f' %
                (self._funding['total'], self._funding['lent'], available))
            self._funding['available'] = available

        # Re-write the strategy by yourself
        if available > 50:
            # rate 0 means FRR
            self.new_offer('USD', available - Decimal(0.000001), 0, 2)

    def new_offer(self, currency, amount, rate, period):
        """Create an new offer
        :param rate: Rate per day
        """
        try:
            result = self._rest_client.new_offer(currency, amount, rate,
                                                 period)
        except BitfinexClientError as e:
            log(e.value)
            raise

        log('Create an new %s offer with amount: %f, rate: %f, ' %
            (currency, amount, rate) + 'period: %d' % period)
        self._offers[result['offer_id']] = amount
        self._funding['lent'] += amount
        return result['offer_id']

    def cancel_offer(self, offer_id):
        """Cancel an offer"""
        try:
            self._rest_client.cancel_offer(offer_id)
        except BitfinexClientError as e:
            log(e.value)
            raise
        log('Cancel an offer with id: %d' % offer_id)
예제 #20
0
from btfxwss import BtfxWss
import time

# config
log = logging.getLogger(__name__)
fh = logging.FileHandler('../test.log')
fh.setLevel(logging.DEBUG)
sh = logging.StreamHandler(sys.stdout)
sh.setLevel(logging.DEBUG)

log.addHandler(sh)
log.addHandler(fh)
logging.basicConfig(level=logging.DEBUG, handlers=[fh, sh])

# 国内设置代理
wss = BtfxWss(http_proxy_host='127.0.0.1', http_proxy_port='1080')

# wss = BtfxWss()


# 订阅websocket
def subscribe():
    while not wss.conn.connected.is_set():
        time.sleep(1)
    # Subscribe to some channels
    wss.subscribe_to_ticker('BTCUSD')
    wss.subscribe_to_order_book('BTCUSD')
    wss.subscribe_to_candles('BTCUSD', '1h')
    wss.subscribe_to_candles('BTCUSD', '1D')
    wss.subscribe_to_trades('BTCUSD')
    wss.subscribe_to_raw_order_book('BTCUSD')
예제 #21
0
import sys

from btfxwss import BtfxWss

log = logging.getLogger(__name__)

fh = logging.FileHandler('test.log')
fh.setLevel(logging.DEBUG)
sh = logging.StreamHandler(sys.stdout)
sh.setLevel(logging.DEBUG)

log.addHandler(sh)
log.addHandler(fh)
logging.basicConfig(level=logging.DEBUG, handlers=[fh, sh])

wss = BtfxWss()
wss.start()

while not wss.conn.connected.is_set():
    time.sleep(1)

wss.subscribe_to_ticker('BTCUSD')
wss.subscribe_to_ticker('ETHUSD')
wss.subscribe_to_ticker('EOSUSD')
wss.subscribe_to_ticker('ETHBTC')
wss.subscribe_to_ticker('EOSBTC')
wss.subscribe_to_ticker('EOSETH')

while (1):
    q1 = wss.tickers('BTCUSD')
    q2 = wss.tickers('ETHBTC')
예제 #22
0
    def __init__(self, **kwargs):
        self.exchange = 'Bitfinex'
        self.pair_btc = 'BTCUSD'
        self.pair_eth = 'ETHUSD'
        self.pair_etc = 'ETCUSD'
        self.pair_ltc = 'LTCUSD'
        self.pair_dsh = 'DSHUSD'
        self.pair_bch = 'BCHUSD'
        self.pair_btg = 'BTGUSD'
        self.pair_eos = 'EOSUSD'
        self.pair_trx = 'TRXUSD'
        self.pair_xmr = 'XMRUSD'
        self.pair_vet = 'VETUSD'
        self.pair_iot = 'IOTUSD'
        self.pair_zec = 'ZECUSD'
        self.pair_neo = 'NEOUSD'
        self.cnx = mysql.connector.connect(**kwargs)
        self.cursor = self.cnx.cursor()

        wss = BtfxWss()
        wss.start()

        while not wss.conn.connected.is_set():
            time.sleep(1)

        wss.subscribe_to_trades(self.pair_btc)
        wss.subscribe_to_trades(self.pair_eth)
        wss.subscribe_to_trades(self.pair_etc)
        wss.subscribe_to_trades(self.pair_ltc)
        wss.subscribe_to_trades(self.pair_dsh)
        wss.subscribe_to_trades(self.pair_bch)
        wss.subscribe_to_trades(self.pair_btg)
        wss.subscribe_to_trades(self.pair_eos)
        wss.subscribe_to_trades(self.pair_trx)
        wss.subscribe_to_trades(self.pair_xmr)
        wss.subscribe_to_trades(self.pair_vet)
        wss.subscribe_to_trades(self.pair_iot)
        wss.subscribe_to_trades(self.pair_zec)
        wss.subscribe_to_trades(self.pair_neo)

        t = time.time()
        while time.time() - t < 10:
            pass

        self.ticker_btc = wss.trades(self.pair_btc)
        self.ticker_eth = wss.trades(self.pair_eth)
        self.ticker_etc = wss.trades(self.pair_etc)
        self.ticker_ltc = wss.trades(self.pair_ltc)
        self.ticker_dsh = wss.trades(self.pair_dsh)
        self.ticker_bch = wss.trades(self.pair_bch)
        self.ticker_btg = wss.trades(self.pair_btg)
        self.ticker_eos = wss.trades(self.pair_eos)
        self.ticker_trx = wss.trades(self.pair_trx)
        self.ticker_xmr = wss.trades(self.pair_xmr)
        self.ticker_vet = wss.trades(self.pair_vet)
        self.ticker_iot = wss.trades(self.pair_iot)
        self.ticker_zec = wss.trades(self.pair_zec)
        self.ticker_neo = wss.trades(self.pair_neo)
예제 #23
0
    def test_subscribing_to_data_works(self):
        wss = BtfxWss(log_level=logging.DEBUG)
        wss.start()
        time.sleep(1)
        wss.subscribe_to_ticker('BTCUSD')
        wss.subscribe_to_candles('BTCUSD')
        wss.subscribe_to_order_book('BTCUSD')
        wss.subscribe_to_raw_order_book('BTCUSD')
        wss.subscribe_to_trades('BTCUSD')
        time.sleep(10)

        try:
            wss.tickers('BTCUSD').get(block=False)
        except Empty:
            self.fail("No ticker data arrived!")

        try:
            wss.candles('BTCUSD', '1m').get(block=False)
        except Empty:
            self.fail("No candles data arrived!")
        except KeyError:
            self.fail("No candles data arrived, key not found! %s" %
                      list(wss.queue_processor.candles.keys()))

        try:
            wss.books('BTCUSD').get(block=False)
        except Empty:
            self.fail("No book data arrived!")

        try:
            wss.raw_books('BTCUSD').get(block=False)
        except Empty:
            self.fail("No war book data arrived!")

        try:
            wss.trades('BTCUSD').get(block=False)
        except Empty:
            self.fail("No trades data arrived!")

        wss.stop()
예제 #24
0
class Market(object):
    """
    This is the market of the cryptocurrency given symbol.
    Data source is Bitfinex Websocket API.
    """
    def __init__(self, symbol='BTCUSD'):
        self.symbol = symbol
        self.wss = BtfxWss()

        self.wss.start()


    def check_connection(self, pat=60):
        """
        Check connection with Bitfinex API. If consecutively failing to connect,
        the program will send an alert message
        :param pat:
            the maximum patience time before sending an alert notification of
            disrupted connection.
        """
        init = time.time()

        # Wait until either connected or exceeding patience
        while not self.wss.conn.connected.is_set() or time.time() > init + pat:
            time.sleep(1)

        # If connection is not set, send a note
        if self.wss.conn.connected.is_set():
            pass
        else:
            message(txt_msg='The connection is disrupted.')
            logger.error('Connection failed.')
            exit()

    def initialize_api(self):
        """
        Initialize the API for the crypto market and subscribe to trades and order
        books. Data is stored as Queues.
        """

        self.check_connection()

        # Subscribe to some channels
        self.wss.subscribe_to_trades(self.symbol)
        self.wss.subscribe_to_order_book(pair=self.symbol, len=100)

        # Initialize a DataBase object
        self.db = DataBase(symbol=self.symbol)

        logger.info('API connection initialized.')

    def create_database(self):
        """
        This function will build connection with Bitfinex Websocket API and AWS
        MySQL DB. Then initialize the csv files and sql databases
        for trades and orderbook.
        """
        # Check connection
        self.check_connection()

        # Prepare csv databases for trades and quotes
        self.db.initialize_trade_csv()
        self.db.initialize_quote_csv()

        # Prepare sql database and tables
        self.db.initialize_sql_db()
        self.db.initialize_trade_sql()
        self.db.initialize_quote_sql()

        # Access data from BtfxWss and return a Queue object for the pair:
        self.trade_q = self.wss.trades(self.symbol)
        self.quote_q = self.wss.books(self.symbol)

        # Take a snapshot of the orderbook
        quote_snapshot = self.quote_q.get()

        # Input the snapshot to database
        self.db.create_order_book(quote_snapshot)
        self.db.create_quote_csv(quote_snapshot)
        self.db.create_quote_sql(quote_snapshot)

        logger.info('Databases created.')

    def stream_data(self):
        """
        This function access the live data with established Bitfinex API, and
        keep streaming new trade and quote data. Then update the csv files and
        sql databases accordingly.
        """
        # Check connection
        self.check_connection()

        # Update trade info
        new_trade = self.trade_q.get()
        self.db.update_trade_csv(new_trade)
        self.db.update_trade_sql(new_trade)

        # Update order book
        quote_change = self.quote_q.get()
        self.db.update_quote_csv(quote_change)
        self.db.update_quote_sql(quote_change)

        logger.info('New trade and quote updated.')
예제 #25
0
                self.state = "unavailable"
                time.sleep(self.reconnect_interval)
                self.log.debug("_connect():  ReConnection..")
                self.socket = websocket.WebSocketApp(
                    self.url,
                    on_open=self._on_open,
                    on_message=self._on_message,
                    on_error=self._on_error,
                    on_close=self._on_close)

                # We need to set this flag since closing the socket will
                # set it to False
                self.socket.keep_running = True
                self.socket.run_forever(sslopt=self.sslopt)

    wss = BtfxWss()
    wss.conn._connect = types.MethodType(_connect, wss.conn)
    wss.start()

    while not wss.conn.connected.is_set():
        time.sleep(1)

    # Subscribe to some channels
    wss.subscribe_to_ticker(coin_type)
    # wss.subscribe_to_order_book('BTCUSD')

    # Do something else
    t = time.time()
    while time.time() - t < 10:
        pass
예제 #26
0
    def __init__(self, symbol='BTCUSD'):
        self.symbol = symbol
        self.wss = BtfxWss()

        self.wss.start()
예제 #27
0
class Trader(_Account):
    """
    Class interface for trading on the Bitfinex Exchange
    :param key: str: Bitfinex api-key
    :param secret:  str: Bitfinex api-secret
    """
    _sleep_time = 0.01
    _min_order_value = 35.
    _max_order_history = 100
    _trade_types = {'market', 'limit'}
    _sources = ('Orders', 'Order New', 'Order Update', 'Order Cancel',
                'Wallets')

    def __init__(self, key, secret):
        super(Trader, self).__init__()
        self.symbols = []
        self.symbols_gen = get_symbols_as_updated()
        self.wss = BtfxWss(key=key, secret=secret, log_level='CRITICAL')
        self._disconnect_event = Event()
        self._receiver = None

    def cancel(self, _id):
        """
        Cancel an order
        :param _id: int: order id
        :return: None
        """
        self.wss.cancel_order(multi=False, id=_id)

    def cancel_all(self, older_than=0):
        """
        Cancel all orders older than a certain time
        :param older_than: int/float:
            age of order that should be cancelled (in seconds)
        :return: None
        """
        now = time.time()
        for _id, order in self._orders.copy().items():
            if now - order['timestamp'] > older_than:
                self.cancel(_id)

    def connect(self):
        """Open a connection to a Bitfinex websocket"""
        self.wss.start()
        while not self.wss.conn.connected.is_set():
            time.sleep(1e-4)
        self.wss.authenticate()
        # This thread will wait for 99.999% of its life
        subscriber_thread = Thread(target=self._subscribe)
        subscriber_thread.setDaemon(True)
        subscriber_thread.start()
        # This thread should be working and is therefore joined
        self._receiver = Thread(target=self._receive)
        self._receiver.start()

    def close(self):
        """Close the connection to the Bitfinex websocket"""
        self._disconnect_event.set()
        for symbol in self.symbols:
            self.wss.unsubscribe_from_ticker(symbol)
        self.wss.stop()
        self._receiver.join()

    def order(self,
              symbol,
              price,
              *,
              dollar_amount=None,
              ratio=None,
              value_ratio=None,
              trade_type='limit',
              pad_price=None,
              return_id=True):
        """
        Make an exchange order
        :param symbol: str:
            ticker symbol to order (e.g. 'BTCUSD', 'ETHUSD'...)

        :param price: float:
            Price at which to submit order
            You can also pass "market" as an argument for price
            to order at current market value
            e.g. Trader.order('BTCUSD', 'market', dollar_amount=5)

        :param dollar_amount: float:
            Dollar equivalent value of trade amount (negative for selling)
            e.g. ordering 10 BTCUSD at $5 per coin
                -> Trader.order('BTCUSD', 5, dollar_amount=50)

        :param ratio: float:
            Ratio of available balance for requested symbol (negative for sell)
            e.g. With $1000 USD in wallet, ordering 100 BTCUSD at $5 per coin
                -> Trader.order('BTCUSD', 5, ratio=0.5)

        :param value_ratio: float:
            Ratio of Trader.value (negative for selling)
            e.g. With $500 in USD and $500 in BTCUSD (at $5) in wallet,
                 ordering 100 BTCUSD at $5 per coin
                -> Trader.order('BTCUSD', 5, value_ratio=0.5)

        :param trade_type: str: (optional)
            Bitfinex api trade type - one of {'market', 'limit'}
            see https://www.bitfinex.com/features for details

        :param pad_price: float: (optional)
            Ratio based price padding - used to undercut or overshoot price
            If buying then pad_price * price is added to submitted price
            If selling then pad_price * price is subtracted from price

        :param return_id: bool: (optional)
            If true, Trader.order blocks until order_id is returned
            from Bitfinex, otherwise returns immediately

        :return: int:
            If return_id is True, then order id is returned, otherwise None

        :raises: AssertionError:
            If values passed are non-consistent
        """

        assert dollar_amount or ratio or value_ratio, \
            'Must provide either `dollar_amount`, `ratio` or `value_ratio`'
        assert sum(bool(i) for i in [dollar_amount, ratio, value_ratio]) == 1,\
            'Must provide only 1 of `dollar_amount`, `ratio` or `value_ratio`'
        assert trade_type.lower() in self._trade_types, \
            'Unknown trade type, try one of these: %s' % str(self._trade_types)

        symbol_lower = symbol.lower().replace('usd', '')
        symbol = symbol.upper().split('USD')[0] + 'USD'
        buying = (dollar_amount or ratio or value_ratio) > 0

        if price == 'market' or trade_type == 'market':
            trade_type = 'market'
            price = self._prices[symbol]

        if pad_price:
            delta = price * pad_price
            price += max(delta, 0.01) if buying else min(-delta, -0.01)
        assert price >= 0.01, 'Price cannot be less than $0.01'

        if buying:
            max_amount = self.available_balances['usd'] / price
        else:
            max_amount = self.available_balances[symbol_lower]

        if dollar_amount:
            amount = dollar_amount / price
        elif ratio:
            amount = max_amount * ratio
        else:
            amount = min(max(-max_amount, self.value * value_ratio / price),
                         max_amount)
        amount, max_amount = round(amount, 8), round(max_amount, 8)

        assertion_msg = 'Trade value (${:.2f}) is %s available trade value ' \
                        '($%.2f)'.format(abs(amount * price))
        assert abs(amount) >= self._min_order_value / price, \
            assertion_msg % ('below minimum', self._min_order_value)
        assert abs(amount) <= max_amount, \
            assertion_msg % ('above maximum', max_amount * price)

        current_order_ids = set(self._orders.keys())
        if len(self._executed_orders) == 0:
            last_executed_id = None
        else:
            last_executed_id = self._executed_orders[-1][0]

        self.wss.new_order(
            cid=int(time.time()),
            type="EXCHANGE %s" % trade_type.upper(),
            symbol="t%s" % symbol,
            amount="%.8f" % amount,
            price="%.2f" % price,
        )

        while return_id:
            for _id in self._orders.copy().keys():
                # new order arrives in _orders
                if _id not in current_order_ids:
                    return _id
            else:
                # new order is executed immediately
                if len(self._executed_orders) > 0 \
                 and self._executed_orders[-1][0] != last_executed_id:
                    return self._executed_orders[-1][0]
                time.sleep(self._sleep_time)

    def subscribe(self, symbol):
        """
        Subscribe to a symbol for price watching
        :param symbol: str: symbol to subscribe to (e.g. 'BTCUSD', 'ETHUSD'...)
        """
        self.symbols.append(symbol)
        self.wss.subscribe_to_ticker(symbol)

    def wait_execution(self, _id, seconds=1e9):
        """
        Waits for an order to execute
        :param _id: int: id of order to wait for
        :param seconds: int/float: time to wait before raising error
        :return: dict: order in json format
        :raises: TimeoutError (if order is not executed in given time)
        """
        start_time = time.time()
        while time.time() - start_time < seconds:
            try:
                ids, trades = tuple(zip(*self._executed_orders))
                return trades[ids.index(_id)]
            except ValueError:
                time.sleep(self._sleep_time)
        raise TimeoutError('Waiting for execution of order '
                           '%d timed out after %d seconds' % (_id, seconds))

    def _receive(self):
        while not self._disconnect_event.is_set():
            for source in self._sources:
                with suppress(Empty):
                    q = self.wss.queue_processor.account[source]
                    cmd, data = q.get_nowait()[0]
                    self._update(cmd, data)

            for symbol in self.symbols:
                with suppress(Empty):
                    q = self.wss.queue_processor.tickers[('ticker', symbol)]
                    data = q.get_nowait()[0]
                    self._update('t' + symbol, data)

    def _subscribe(self):
        for symbol in self.symbols_gen:
            self.subscribe(symbol)
예제 #28
0
def main(logger):

    # Fetch available pairs & timeframes from DB
    pairs_timeframes = Pair_Timeframe.objects.all()

    if pairs_timeframes.exists() is False:
        logger.error("No pairs in a database.")
        return None

    wss = BtfxWss()
    wss.start()
    time.sleep(1)  # give the client some prep time to set itself up

    last_mts = dict()

    pairs_timeframes_tuples = pairs_timeframes.values_list(
        "id", "pair", "timeframe")
    for pairs_timeframes_id, pair, timeframe in pairs_timeframes_tuples:
        wss.subscribe_to_candles(pair, timeframe=timeframe)
        last_mts.update({pairs_timeframes_id: None})
    time.sleep(5)
    candles_queue = {}
    for pairs_timeframes_id, pair, timeframe in pairs_timeframes_tuples:
        candles_queue.update(
            {pair + timeframe: wss.candles(pair=pair, timeframe=timeframe)})
        logger.info(
            "Collecting CANDLES of pair '%s' with timeframe '%s' has been started"
            % (pair, timeframe))

    try:
        while True:

            for pairs_timeframes_id, pair, timeframe in pairs_timeframes_tuples:
                if not candles_queue[pair + timeframe].empty():

                    q_candles = candles_queue[pair + timeframe].get()
                    """
                    ([  [4345.5, 16.7770791, 4345.6, 12.74414776, 77.6, 0.0182, 4345.6, 15220.55529737, 4397.5, 4248.4] ], 1503992628.42302)

                    # MTS     int     millisecond time stamp
                    # OPEN    float   First execution during the time frame
                    # CLOSE   float   Last execution during the time frame
                    # HIGH    integer     Highest execution during the time frame
                    # LOW     float   Lowest execution during the timeframe
                    # VOLUME  float   Quantity of symbol traded within the timeframe
                    """

                    data = []

                    if isinstance(q_candles[0][0][0], list):
                        mass = sorted(q_candles[0][0], key=lambda x: x[0])
                        for c in mass:
                            mts = datetime.datetime.utcfromtimestamp(
                                float(str(c[0])[:-3]))
                            if should_update(mts, last_mts,
                                             pairs_timeframes_id):
                                data.append({
                                    "mts": mts,
                                    "open": c[1],
                                    "close": c[2],
                                    "high": c[3],
                                    "low": c[4],
                                    "volume": c[5]
                                })
                    else:
                        mts = datetime.datetime.utcfromtimestamp(
                            float(str(q_candles[0][0][0])[:-3]))
                        if should_update(mts, last_mts, pairs_timeframes_id):
                            data.append({
                                "mts": mts,
                                "open": q_candles[0][0][1],
                                "close": q_candles[0][0][2],
                                "high": q_candles[0][0][3],
                                "low": q_candles[0][0][4],
                                "volume": q_candles[0][0][5]
                            })

                    # Important:
                    # UPSERT works well.
                    # If you have missed rows -> check volume
                    upsert(data=data, pairs_timeframes_id=pairs_timeframes_id)

    except Exception:
        logger.error(str(traceback.format_exc()))

    for pairs_timeframes_id, pair, timeframe in pairs_timeframes_tuples:
        wss.unsubscribe_from_candles(pair, timeframe=timeframe)

    # Shutting down the client
    wss.stop()
    logger.info("Process terminated")
예제 #29
0
import sys

from btfxwss import BtfxWss

log = logging.getLogger(__name__)

fh = logging.FileHandler('test.log')
fh.setLevel(logging.DEBUG)
sh = logging.StreamHandler(sys.stdout)
sh.setLevel(logging.DEBUG)

log.addHandler(sh)
log.addHandler(fh)
logging.basicConfig(level=logging.DEBUG, handlers=[fh, sh])

wss = BtfxWss()
wss.start()

while not wss.conn.connected.is_set():
    time.sleep(1)

# Subscribe to some channels
wss.subscribe_to_ticker('BTCUSD')
wss.subscribe_to_order_book('BTCUSD')

# Do something else
t = time.time()
while time.time() - t < 10:
    pass

# Accessing data stored in BtfxWss:
예제 #30
0
log = logging.getLogger(__name__)

fh = logging.FileHandler('test.log')
fh.setLevel(logging.DEBUG)
sh = logging.StreamHandler(sys.stdout)
sh.setLevel(logging.DEBUG)

log.addHandler(sh)
log.addHandler(fh)
logging.basicConfig(level=logging.DEBUG, handlers=[fh, sh])

client = MongoClient('mongodb://localhost:27017/iotatracker')
db = client.iotatracker
collection = db['trades']

wss = BtfxWss()
wss.start()

while not wss.conn.connected.is_set():
    time.sleep(1)

# Subscribe to some channels
wss.subscribe_to_trades('IOTUSD')

# Do something else
t = time.time()
while time.time() - t < 10:
    pass

# Accessing data stored in BtfxWss:
while True: