Ejemplo n.º 1
0
 def __fallback_thread__(self):
     if self.proxies is None:
         test_clt = MarketClient(url=self.url, timeout=5)
     else:
         test_clt = MarketClient(url=self.url,
                                 timeout=5,
                                 proxies=self.proxies)
     testing = True
     while testing:
         if not self.live:
             return
         try:
             test_clt.get_candlestick("btcusdt", CandlestickInterval.MIN1,
                                      2)
             testing = False
         except:
             time.sleep(0.1)
             continue
     ECHO.print(
         "[watchdog] [fallbacker] [{}] the original api url {} has recovered"
         .format(
             time.strftime("%y-%m-%d %H:%M:%S",
                           time.localtime(self.get_timestamp() / 1000)),
             self.url))
     self.fallbacked = False
Ejemplo n.º 2
0
def getTrainData(symbol, interval):
    market_client = MarketClient(init_log=True)
    list_obj = market_client.get_candlestick(symbol, interval, 2000)
    Id = []
    High = []
    Low = []
    Open = []
    Close = []
    Count = []
    Amount = []
    Volume = []
    if list_obj and len(list_obj):
        for obj in list_obj:
            Id.append(obj.id)
            High.append(obj.high)
            Low.append(obj.low)
            Open.append(obj.open)
            Close.append(obj.close)
            Count.append(obj.count)
            Amount.append(obj.amount)
            Volume.append(obj.vol)
        # print(obj.id)
    # 字典中的key值即为csv中列名
    dataframe = pd.DataFrame(
        {'Id': Id, 'High': High, 'Low': Low, 'Open': Open, 'Close': Close, 'Count': Count, 'Amount': Amount,
         'Volume': Volume})

    # 将DataFrame存储为csv,index表示是否显示行名,default=True
    dataframe.to_csv(interval + symbol + ".csv", index=False, sep=',')
Ejemplo n.º 3
0
def update_graph_live(n):
    market_client = MarketClient(url="https://api.hbdm.com")
    list_obj = market_client.get_candlestick("ETH_CQ",
                                             CandlestickInterval.MIN1, 1)
    live_data['price'].append(list_obj[-1].close)
    if len(live_data['price']) >= 1000:
        live_data['price'] = live_data['price'][-1000:]
    live_data['time'].append(datetime.datetime.now().strftime('%c'))
    fig = plotly.tools.make_subplots(rows=1, cols=1, vertical_spacing=0.2)
    fig['layout']['margin'] = {'l': 30, 'r': 10, 'b': 30, 't': 10}
    fig['layout']['legend'] = {'x': 0, 'y': 1, 'xanchor': 'left'}

    fig.append_trace(
        {
            'x': live_data['time'],
            'y': live_data['price'],
            'name': 'Price',
            'mode': 'lines+markers',
            'type': 'scatter'
        }, 1, 1)
    return fig
Ejemplo n.º 4
0
def update_graph(n):
    data = {'time': [], 'price': []}
    market_client = MarketClient(url="https://api.hbdm.com")
    list_obj = market_client.get_candlestick("ETH_CQ",
                                             CandlestickInterval.MIN1, 200)
    for item in list_obj:
        data['price'].append(item.close)
        data['time'].append(
            datetime.datetime.fromtimestamp(item.id).strftime('%c'))
    fig = plotly.tools.make_subplots(rows=1, cols=1, vertical_spacing=0.2)
    fig['layout']['margin'] = {'l': 30, 'r': 10, 'b': 30, 't': 10}
    fig['layout']['legend'] = {'x': 0, 'y': 1, 'xanchor': 'left'}

    fig.append_trace(
        {
            'x': data['time'],
            'y': data['price'],
            'name': 'Price',
            'mode': 'lines+markers',
            'type': 'scatter'
        }, 1, 1)
    return fig
Ejemplo n.º 5
0
from huobi.client.trade import TradeClient

generic_client = GenericClient()
list_symbol = generic_client.get_exchange_symbols()
list_currency = generic_client.get_reference_currencies()
print(list_symbol[0])
print(list_currency[0].print_object())

a = c
access_key = " "
secret_key = " "

# Create generic client instance and get the timestamp
generic_client = GenericClient()
timestamp = generic_client.get_exchange_timestamp()
print(timestamp)

# Create the market client instance and get the latest btcusdt‘s candlestick
market_client = MarketClient()
list_obj = market_client.get_candlestick("btcusdt", CandlestickInterval.MIN5,
                                         10)
LogInfo.output_list(list_obj)

# // Create an AccountClient instance with APIKey
account_client = AccountClient(api_key=access_key, secret_key=secret_key)

# // Create a TradeClient instance with API Key and customized host
trade_client = TradeClient(api_key=access_key,
                           secret_key=secret_key,
                           url="https://api-aws.huobi.pro")
Ejemplo n.º 6
0
from huobi.client.market import MarketClient
from huobi.constant import *
from huobi.utils import *

market_client = MarketClient(init_log=True)
interval = CandlestickInterval.MIN5
symbol = "ethusdt"
list_obj = market_client.get_candlestick(symbol, interval, 10)
LogInfo.output("---- {interval} candlestick for {symbol} ----".format(
    interval=interval, symbol=symbol))
LogInfo.output_list(list_obj)
Ejemplo n.º 7
0
class DataHandler:
    def __init__(self, symbol):
        self.symbol = symbol
        self.market_client = MarketClient()
        self.candle_tick = pd.DataFrame(columns=[
            'id', 'open', 'close', 'high', 'low', 'amount', 'count', 'vol'
        ])
        self.mbp_tick = pd.DataFrame(columns=[
            "id", "prevSeqNum", "bids_0_price", "bids_1_price", "bids_2_price",
            "bids_3_price", "bids_4_price", "asks_0_price", "asks_1_price",
            "asks_2_price", "asks_3_price", "asks_4_price", "asks_0_amount",
            "asks_1_amount", "asks_2_amount", "asks_3_amount", "asks_4_amount",
            "bids_0_amount", "bids_1_amount", "bids_2_amount", "bids_3_amount",
            "bids_4_amount"
        ])
        self.trade_tick = pd.DataFrame(
            columns=['id', 'price', 'amount', 'direction'])
        self.conn = sqlite3.connect('market.db', timeout=10)
        self.s = sched.scheduler(time.time, time.sleep)

    def get_candle_list(self, interval, length):
        list_obj = self.market_client.get_candlestick(self.symbol, interval,
                                                      length)
        return list_obj

    def get_trade_list(self, length):
        list_obj = self.market_client.get_history_trade(self.symbol, length)
        return list_obj

    def get_candle(self, interval, length):
        list_obj = self.get_candle_list(interval, length)
        data = parse_candle_list(list_obj)
        return data

    def get_trade(self, length):
        list_obj = self.get_trade_list(length)
        data = parse_trade_list(list_obj)
        return data

    def update_database(self, table, data):
        c = self.conn.cursor()
        # get the count of tables with the name
        c.execute(
            "SELECT count(name) FROM sqlite_master WHERE type='table' AND name='"
            + table + "'")
        # #if the count is 1, then table exists
        if c.fetchone()[0] == 1:
            last_data = pd.read_sql('select * from ' + table, self.conn)
            last_data = last_data.append(data).drop_duplicates().sort_values(
                by='id', ascending=True)
            last_data.sort_values(by='id',
                                  ascending=True).to_sql(table,
                                                         self.conn,
                                                         if_exists='replace',
                                                         index=False)
        else:
            data.sort_values(by='id',
                             ascending=True).to_sql(table,
                                                    self.conn,
                                                    if_exists='replace',
                                                    index=False)

    def update_candle(self, interval, freq):
        candle = self.get_candle(interval, freq)
        self.update_database(self.symbol + '_' + interval + '_' + 'candle',
                             candle)

    def update_trade(self, freq):
        trade = self.get_trade(freq)
        self.update_database(self.symbol + '_' + 'trade', trade)

    def candle_callback(self, candlestick_event: 'CandlestickEvent'):
        candle = candlestick_event.return_object()
        self.candle_tick = self.candle_tick.append(candle, ignore_index=True)
        # print(self.candle_tick)

    def mbp_callback(self, mbp_event: 'MbpFullEvent'):
        mbp = mbp_event.return_object()
        self.mbp_tick = self.mbp_tick.append(mbp, ignore_index=True)
        # print(self.mbp_tick)

    def trade_callback(self, trade_event: 'TradeDetailEvent'):
        obj_list = trade_event.return_object()
        for trade in obj_list:
            self.trade_tick = self.trade_tick.append(trade_to_dict(trade),
                                                     ignore_index=True)
        # print(self.trade_tick)

    def candle_subscribe(self, interval):
        self.market_client.sub_candlestick(self.symbol, interval,
                                           self.candle_callback, error)

    def mbp_subscribe(self):
        self.market_client.sub_mbp_full(self.symbol, MbpLevel.MBP5,
                                        self.mbp_callback, error)

    def trade_subscribe(self):
        self.market_client.sub_trade_detail(self.symbol, self.trade_callback,
                                            error)

    def save_tick_data(self):
        self.update_database(self.symbol + "_tick_trade", self.trade_tick)
        self.update_database(self.symbol + "_tick_mbp", self.mbp_tick)
        self.update_database(self.symbol + "_tick_candle", self.candle_tick)
        print("saved tick data")
        self.s.enter(60, 1, self.save_tick_data, ())

    def save_1min_candle(self):
        try:
            self.update_candle("1min", 10)
        except:
            print("connection error")
        to_sleep_1min = 60 - time.time() % 60
        print(to_sleep_1min)
        self.s.enter(to_sleep_1min + 1, 1, self.save_1min_candle, ())

    def save_5min_candle(self):
        try:
            self.update_candle("5min", 10)
            print("saved 5min candle")
        except:
            print("connection error")
        to_sleep_5min = 300 - time.time() % 300
        self.s.enter(to_sleep_5min + 1, 1, self.save_5min_candle, ())

    def save_15min_candle(self):
        try:
            self.update_candle("15min", 10)
            print("saved 15min candle")
        except:
            print("connection error")
        to_sleep_15min = 900 - time.time() % 900
        self.s.enter(to_sleep_15min + 1, 1, self.save_15min_candle, ())

    def save_30min_candle(self):
        try:
            self.update_candle("30min", 10)
            print("saved 30min candle")
        except:
            print("connection error")
        to_sleep_30min = 1800 - time.time() % 1800
        self.s.enter(to_sleep_30min + 1, 1, self.save_30min_candle, ())

    def save_60min_candle(self):
        try:
            self.update_candle("60min", 10)
            self.update_candle("1day", 10)
            print("saved 60min candle")
            print("saved 1day candle")
        except:
            print("connection error")
        to_sleep_60min = 3600 - time.time() % 3600
        self.s.enter(to_sleep_60min + 1, 1, self.save_60min_candle, ())

    # def save_1day_candle(self):
    #     try:
    #         self.update_candle("1day", 10)
    #         print("saved 1day candle")
    #     except:
    #         print("connection error")
    #     self.s.enter(86400, 1, self.save_1day_candle, ())

    def save_trade_data(self):
        try:
            self.update_trade(100)
            print("saved trade data")
        except:
            print("connection error")
        self.s.enter(10, 1, self.save_trade_data, ())

    def update_candle_data(self):
        self.update_trade(2000)
        self.s.enter(0, 1, self.save_trade_data, ())
        self.s.enter(0, 1, self.save_1min_candle, ())
        self.s.enter(0, 1, self.save_5min_candle, ())
        self.s.enter(0, 1, self.save_15min_candle, ())
        self.s.enter(0, 1, self.save_30min_candle, ())
        self.s.enter(0, 1, self.save_60min_candle, ())
        self.s.run()

    def update_tick_data(self):
        self.trade_subscribe()
        self.candle_subscribe("1min")
        self.mbp_subscribe()
        self.s.enter(60, 1, self.save_tick_data, ())
Ejemplo n.º 8
0
class Trader(BaseTrader):
    def __init__(self, api_key, secret_key, account_id, verbose=False):
        super().__init__()
        self.account_id = account_id
        self.trade_client = TradeClient(api_key=api_key, secret_key=secret_key)
        self.account_client = AccountClient(api_key=api_key,
                                            secret_key=secret_key)
        self.algo_client = AlgoClient(api_key=api_key, secret_key=secret_key)
        self.market_client = MarketClient()
        self.holds = {}
        self.total_fee = 0
        self.stop_loss_threads = []
        self.long_order_threads = []
        self.latest_timestamp = 0
        self.client_id_counter = 0
        self.verbose = verbose
        self.subscription = None

    def add_trade_clearing_subscription(self,
                                        symbol,
                                        callback,
                                        error_handler=None):
        self.subscription = self.trade_client.sub_trade_clearing(
            symbol, callback, error_handler)
        return self.subscription

    def remove_trade_clearing_subscription(self, subscription):
        self.subscription.unsubscribe_all()

    def get_balance(self, symbol='usdt'):
        balances = self.account_client.get_balance(self.account_id)
        for balance in balances:
            if balance.currency == symbol:
                return float(balance.balance)

    def get_balance_pair(self, symbol):
        pair = transaction_pairs[symbol]
        target, base = pair.target, pair.base
        balances = self.account_client.get_balance(self.account_id)
        target_balance, base_balance = None, None
        for balance in balances:
            if balance.currency == target and target_balance is None:
                target_balance = float(balance.balance)
            elif balance.currency == base and base_balance is None:
                base_balance = float(balance.balance)
        return target_balance, base_balance

    def get_newest_price(self, symbol):
        newest_trade = self.market_client.get_market_trade(symbol=symbol)[0]
        return newest_trade.price

    def submit_orders(self, symbol, prices, amounts, order_type):
        """Submit a series of orders to the trader and return their ids.

        symbol -- symbol of trading pair
        prices -- list of prices of limit orders
        amounts -- list of amounts of limit orders
        order_type -- OrderType.BUY_LIMIT or OrderType.SELL_LIMIT
        """
        client_order_id_header = str(int(time.time()))
        order_ids = [
            f'{client_order_id_header}{symbol}{i:02d}'
            for i in range(len(prices))
        ]
        pair = transaction_pairs[symbol]
        price_scale, amount_scale = pair.price_scale, pair.amount_scale
        orders = [{
            'account_id': self.account_id,
            'symbol': symbol,
            'order_type': order_type,
            'source': OrderSource.API,
            'amount':
            f'{self.correct_amount(amount, symbol):.{amount_scale}f}',
            'price': f'{price:.{price_scale}f}',
            'client_order_id': order_id
        } for amount, price, order_id in zip(amounts, prices, order_ids)]
        results = []
        for i in range(0, len(orders), MAX_ORDER_NUM):
            create_results = self.trade_client.batch_create_order(
                order_config_list=orders[i:i + MAX_ORDER_NUM])
            results += create_results
        LogInfo.output_list(results)
        return results

    @staticmethod
    def get_normalized_amounts_with_eagerness(num_orders, eagerness=1.0):
        amounts = np.geomspace(eagerness**num_orders, 1, num_orders)
        return amounts / np.sum(amounts)

    @staticmethod
    def get_normalized_amounts_with_normal_distr(num_orders, skewness=1.0):
        amounts = np.linspace(-skewness, skewness, num_orders)
        amounts = stats.norm.pdf(amounts, 0, 1)
        amounts += amounts.min()
        return amounts / np.sum(amounts)

    @staticmethod
    def get_normalized_amounts_with_distr(num_orders, distr):
        if distr is None:
            return Trader.get_normalized_amounts_with_eagerness(
                num_orders, 1.0)
        elif distr['distr'] == 'geometry':
            return Trader.get_normalized_amounts_with_eagerness(
                num_orders, distr.get('eagerness', 1.0))
        elif distr['distr'] == 'normal':
            return Trader.get_normalized_amounts_with_normal_distr(
                num_orders, distr.get('skewness', 1.0))

    @staticmethod
    def get_price_interval(lower_price, upper_price, num_orders, order_type):
        if order_type == OrderType.BUY_LIMIT:
            prices = np.linspace(upper_price, lower_price, num_orders)
        elif order_type == OrderType.SELL_LIMIT:
            prices = np.linspace(lower_price, upper_price, num_orders)
        else:
            raise ValueError(f'Unknown order type {order_type}')
        return prices

    def generate_buy_queue_orders(self,
                                  symbol,
                                  lower_price,
                                  upper_price,
                                  num_orders,
                                  total_amount=None,
                                  total_amount_fraction=None,
                                  distr=None):
        prices = self.get_price_interval(lower_price, upper_price, num_orders,
                                         OrderType.BUY_LIMIT)
        normalized_amounts = self.get_normalized_amounts_with_distr(
            num_orders, distr)
        if total_amount is not None:
            amounts = normalized_amounts * total_amount
        elif total_amount_fraction is not None:
            balance = self.get_balance(
                transaction_pairs[symbol].base) * total_amount_fraction
            amounts = normalized_amounts * (balance / prices *
                                            normalized_amounts).sum()
        else:
            raise ValueError(
                'One of total_amount or total_amount_fraction should be given')
        return self.submit_orders(symbol, prices, amounts, OrderType.BUY_LIMIT)

    def create_smart_buy_queue(self,
                               symbol,
                               lower_price,
                               upper_price,
                               num_orders,
                               profit=1.05,
                               total_amount=None,
                               total_amount_fraction=None,
                               distr=None):
        orders = self.generate_buy_queue_orders(symbol, lower_price,
                                                upper_price, num_orders,
                                                total_amount,
                                                total_amount_fraction, distr)
        client_order_id_header = str(int(time.time()))
        price_scale = transaction_pairs[symbol].price_scale
        algo_order_ids = []
        for i, order in enumerate(orders):
            client_order_id = f'{client_order_id_header}{symbol}{i:02d}'
            order_price = float(order['price']) * profit
            stop_price = order_price * 0.999
            self.algo_client.create_order(
                account_id=self.account_id,
                symbol=symbol,
                order_side=OrderSide.SELL,
                order_type=AlgoOrderType.LIMIT,
                order_size=order['amount'],
                order_price=f'{order_price:.{price_scale}f}',
                stop_price=f'{stop_price:.{price_scale}f}',
                client_order_id=client_order_id)
            algo_order_ids.append(client_order_id)
        return results, orders, algo_order_ids

    def cancel_all_algo_orders(self, order_ids):
        results = [
            self.algo_client.cancel_orders(order_id) for order_id in order_ids
        ]
        return results

    def update_timestamp(self):
        now = int(time.time())
        if now == self.latest_timestamp:
            self.client_id_counter += 1
        else:
            self.latest_timestamp = now
            self.client_id_counter = 0

    def get_order(self, order_id):
        return self.trade_client.get_order(order_id)

    def create_order(self,
                     symbol,
                     price,
                     order_type,
                     amount=None,
                     amount_fraction=None):
        pair = transaction_pairs[symbol]
        if amount is None:
            if order_type is OrderType.SELL_LIMIT or order_type is OrderType.SELL_MARKET:
                amount = self.get_balance(pair.target) * amount_fraction
            else:
                amount = self.get_balance(pair.base) * amount_fraction
        amount = f'{float(amount):.{pair.amount_scale}f}'
        if price is not None:
            price = f'{float(price):.{pair.price_scale}f}'
        self.update_timestamp()
        client_order_id = f'{self.latest_timestamp}{symbol}{self.client_id_counter:02d}'
        order_id = self.trade_client.create_order(
            symbol=symbol,
            account_id=self.account_id,
            order_type=order_type,
            price=price,
            amount=amount,
            source=OrderSource.API,
            client_order_id=client_order_id)
        return order_id

    @staticmethod
    def get_time():
        return int(time.time())

    def get_previous_prices(self, symbol, window_type, window_size):
        candlesticks = self.market_client.get_candlestick(
            symbol, window_type, window_size)
        return [(cs.id, (cs.open + cs.close) / 2)
                for cs in sorted(candlesticks, key=lambda cs: cs.id)]

    def create_buy_queue(self,
                         symbol,
                         lower_price,
                         upper_price,
                         num_orders,
                         total_amount=None,
                         total_amount_fraction=None,
                         distr=None):
        newest_price = self.get_newest_price(symbol)
        if upper_price > newest_price:
            raise ValueError(
                'Unable to buy at a price higher the the market price')
        if lower_price >= upper_price:
            raise ValueError('lower_price should be less than upper_price')
        orders = self.generate_buy_queue_orders(symbol, lower_price,
                                                upper_price, num_orders,
                                                total_amount,
                                                total_amount_fraction, distr)
        return orders

    def create_sell_queue(self,
                          symbol,
                          lower_price,
                          upper_price,
                          num_orders,
                          total_amount=None,
                          total_amount_fraction=None,
                          distr=None):
        newest_price = self.get_newest_price(symbol)
        if lower_price < newest_price:
            raise ValueError(
                'Unable to sell at a price lower the the market price')
        if lower_price >= upper_price:
            raise ValueError('lower_price should be less than upper_price')
        prices = self.get_price_interval(lower_price, upper_price, num_orders,
                                         OrderType.SELL_LIMIT)
        normalized_amounts = self.get_normalized_amounts_with_distr(
            num_orders, distr)
        if total_amount is not None:
            amounts = normalized_amounts * total_amount
        elif total_amount_fraction is not None:
            balance = self.get_balance(
                transaction_pairs[symbol].target) * total_amount_fraction
            amounts = normalized_amounts * balance
        else:
            raise ValueError(
                'One of total_amount or total_amount_fraction should be given')
        return self.submit_orders(symbol, prices, amounts,
                                  OrderType.SELL_LIMIT)

    def cancel_orders(self, symbol, order_ids):
        cancel_results = []
        for i in range(0, len(order_ids), MAX_CANCEL_ORDER_NUM):
            cancel_result = self.trade_client.cancel_orders(
                symbol, order_ids[i:i + MAX_CANCEL_ORDER_NUM])
            cancel_results.append(cancel_result)
        return cancel_results

    def cancel_all_orders_with_type(self, symbol, order_type):
        account_spot = self.account_client.get_account_by_type_and_symbol(
            AccountType.SPOT, symbol=None)
        orders = self.trade_client.get_open_orders(symbol=symbol,
                                                   account_id=account_spot.id,
                                                   direct=QueryDirection.NEXT)
        sell_order_ids = [
            str(order.id) for order in orders if order.type == order_type
        ]
        if len(sell_order_ids) == 0:
            return
        return self.cancel_orders(symbol, sell_order_ids)

    def cancel_all_buy_orders(self, symbol):
        return self.cancel_all_orders_with_type(symbol, OrderType.BUY_LIMIT)

    def cancel_all_sell_orders(self, symbol):
        return self.cancel_all_orders_with_type(symbol, OrderType.SELL_LIMIT)

    def sell_all_at_market_price(self, symbol):
        return self.create_order(symbol=symbol,
                                 price=None,
                                 order_type=OrderType.SELL_MARKET,
                                 amount_fraction=0.999)

    def start_new_stop_loss_thread(self,
                                   symbol,
                                   stop_loss_price,
                                   interval=10,
                                   trailing_order=None):
        from stop_loss import StopLoss
        thread = StopLoss(symbol, self, stop_loss_price, interval,
                          trailing_order)
        self.stop_loss_threads.append(thread)

    def start_long_order_thread(self,
                                symbol,
                                buy_price,
                                profit,
                                amount=None,
                                amount_fraction=None,
                                stop_loss=0.9,
                                interval=10):
        from long_order import LongOrder
        thread = LongOrder(symbol, self, buy_price, profit, amount,
                           amount_fraction, stop_loss, interval)
        self.long_order_threads.append(thread)