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
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=',')
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
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
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")
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)
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, ())
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)