Esempio n. 1
0
def get_account_balance(symbol=CoinSymbol.Btcusdt):
    try:
        request_client = RequestClient(api_key=g_api_key,
                                       secret_key=g_secret_key)
        account_balance_list = request_client.get_account_balance()
        if account_balance_list and len(account_balance_list):
            for account in account_balance_list:
                if account.account_type == AccountType.MARGIN and account.subtype == symbol.symbol:
                    if account.balances and len(account.balances):
                        for balance in account.balances:
                            if balance.currency == CoinSymbol.Btcusdt.coin and balance.balance_type == "trade":
                                balance_info.coin = balance.balance
                            if balance.currency == CoinSymbol.Btcusdt.cash and balance.balance_type == "trade":
                                balance_info.cash = balance.balance
    except Exception as e:
        print(e)
        print("retrying in 1s")
        time.sleep(1)
        return get_account_balance()
Esempio n. 2
0
from huobi import RequestClient
from huobi.constant.test import *
from huobi.base.printobject import *
from huobi.model import Account

request_client = RequestClient(api_key=g_api_key, secret_key=g_secret_key)
account_balance_list = request_client.get_account_balance()
if account_balance_list and len(account_balance_list):
    for account in account_balance_list:
        print("======= ID", account.id, "=======")
        print("Account Status", account.account_state)
        print("Account Type", account.account_type)
        print("Subtype", account.subtype)
        if account.balances and len(account.balances):
            for balance in account.balances:
                print("\tBalance Currency", balance.currency)
                print("\tBalance Type", balance.balance_type)
                print("\tBalance", balance.balance)
                print()
        print()
Esempio n. 3
0
class KeepBalanceStrategy(BaseStrategy, MailHandler):
    """
    动态平衡策略
    """
    def __init__(self):
        BaseStrategy.__init__(self)
        self.request_client = RequestClient(
            api_key=self.get_config_value("huobi", "api_key"),
            secret_key=self.get_config_value("huobi", "secret_key"))
        self.strategy = 'KeepBalance'

    def signal(self):
        balance_dict = self.get_account_balance()
        for key, value in enumerate(balance_dict):
            if float(balance_dict[value]["amount"]) * 1.03 < float(
                    balance_dict[value]["dollar"]):
                self.buy(value,
                         amount=balance_dict[value]["amount"],
                         dollar=balance_dict[value]["dollar"])
            elif float(balance_dict[value]["dollar"]) * 1.03 < float(
                    balance_dict[value]["amount"]):
                self.sell(value,
                          amount=balance_dict[value]["amount"],
                          dollar=balance_dict[value]["dollar"],
                          price=balance_dict[value]["price"])
            else:
                self.logger.info(
                    f"当前持有{value}合计金额: {balance_dict[value]['amount']}, 对标美元: "
                    f"{balance_dict[value]['dollar']}, 小于阈值不触发交易, "
                    f"买入阈值: {retain_decimals(float(balance_dict[value]['dollar']) / 1.05, 2)}, "
                    f"卖出阈值: {retain_decimals(float(balance_dict[value]['dollar']) * 1.05, 2)}"
                )

    def buy(self, symbol_name, **kwargs):
        self.trade_lock(symbol_name, self.strategy)
        try:
            assert kwargs['dollar'] >= kwargs['amount']
            buy_dollar = retain_decimals(
                (float(kwargs['dollar']) - float(kwargs['amount'])) / 2, 2)
            if float(buy_dollar) >= TradeLimit.USDT:
                # 买入
                order_id = self.request_client.create_order(
                    symbol_name + 'usdt', AccountType.SPOT,
                    OrderType.BUY_MARKET, buy_dollar, None)
                self.update_balance_and_dollar(order_id,
                                               Action.BUY,
                                               symbol_name,
                                               buy_dollar=buy_dollar)
                self.send_mail("触发买入信号",
                               f"动态平衡策略触发买入{buy_dollar}的{symbol_name}")
            else:
                self.logger.warning(
                    f"当前欲买入{buy_dollar}美金的{symbol_name}, 不满足最低交易限制")
        except AssertionError:
            self.logger.error(
                f"AssertionError, symbol={symbol_name}, amount={kwargs['amount']}, "
                f"dollar={kwargs['dollar']}")
        finally:
            self.trade_unlock(symbol_name, self.strategy)

    def sell(self, symbol_name, **kwargs):
        self.trade_lock(symbol_name, self.strategy)
        try:
            assert kwargs['amount'] > kwargs['dollar']

            # 获取交易数目精度
            precision = self.precision_collection.find_one(
                {"symbol": symbol_name + "usdt"}, {"amount_precision": 1})
            amount_precision = float(precision['amount_precision'])

            # 计算欲卖出的数目
            sell_currency = retain_decimals(
                (float(kwargs['amount']) - float(kwargs['dollar'])) / 2 /
                float(kwargs['price']), amount_precision)

            if float(sell_currency) > TradeLimit.BTC:
                order_id = self.request_client.create_order(
                    symbol_name + 'usdt', AccountType.SPOT,
                    OrderType.SELL_MARKET, sell_currency, None)
                self.update_balance_and_dollar(order_id, Action.SELL,
                                               symbol_name)
                self.send_mail("触发卖出信号",
                               f"动态平衡策略触发卖出{sell_currency}的{symbol_name}")
            else:
                self.logger.warning(
                    f"当前欲卖出{sell_currency}美金的{symbol_name}, 不满足最低交易限制")
        except AssertionError:
            self.logger.error(
                f"AssertionError, symbol={symbol_name}, amount={kwargs['amount']}, "
                f"dollar={kwargs['dollar']}")
        finally:
            self.trade_unlock(symbol_name, self.strategy)

    def update_balance_and_dollar(self, order_id, action, symbol_name,
                                  **kwargs):
        order_detail = self.request_client.get_order("symbol", order_id)

        # 验证订单是否执行完成
        while not order_detail.state == OrderState.FILLED:
            time.sleep(1)
            self.logger.info(f"{order_id}还未执行完成, 休眠1秒等待执行完成")
            order_detail = self.request_client.get_order("symbol", order_id)

        # mongodb中减去已使用的美金
        result = self.keep_balance_collection.find_one({"symbol": symbol_name})
        dollar = float(result['amount'])
        if action == 'BUY':
            dollar -= float(kwargs['buy_dollar'])
        # mongodb中加上卖出获得的美金
        elif action == 'SELL':
            dollar += float(order_detail.filled_cash_amount)

        # 格式化美金数
        dollar = retain_decimals(dollar, 2)

        # mongodb更新操作
        self.keep_balance_collection.update_one({"symbol": symbol_name},
                                                {"$set": {
                                                    "amount": dollar
                                                }})
        self.logger.info(f"{symbol_name}美金数置为: {dollar}")

    def get_account_balance(self):
        """
        获取余额大于0的交易对
        :return:
        """
        balances = self.request_client.get_account_balance()
        balance_dict = {}
        for key, value in enumerate(balances[0].balances):
            if value.balance > 0 and value.currency != 'usdt':
                if not self.check_trade_lock_exist(value.currency,
                                                   self.strategy):
                    price, amount = self.get_account_amount(
                        value.currency, value.balance)
                    if float(amount) >= 1:
                        dollar = self.get_mongodb_dollar(
                            value.currency, amount)
                        balance_dict[value.currency] = {
                            "balance": str(value.balance),
                            "price": str(price),
                            "amount": str(amount),
                            "dollar": dollar
                        }
        self.logger.debug(balance_dict)
        return balance_dict

    def get_account_amount(self, symbol_name, symbol_balance):
        price = self.get_price(symbol_name + "usdt")
        amount = str(float(symbol_balance) * float(price))
        amount = retain_decimals(amount, 2)
        return price, amount

    def get_mongodb_dollar(self, symbol_name, symbol_amount):
        result = self.keep_balance_collection.find_one({"symbol": symbol_name})
        if result is None:
            self.keep_balance_collection.insert_one({
                "symbol":
                symbol_name,
                "amount":
                str(symbol_amount)
            })
            return symbol_amount
        else:
            return result['amount']

    def get_price(self, symbol_name):
        """
        获取当前交易对价格
        :param symbol_name:
        :return:
        """
        current_prices = self.request_client.get_latest_candlestick(
            symbol=symbol_name, interval=CandlestickInterval.DAY1, size=1)
        return current_prices[0].close
Esempio n. 4
0
class Trader():
    def __init__(self, logger):
        self.logger = logger
        self.api = RequestClient(url="https://api-aws.huobi.pro",
                                 api_key=g_api_key,
                                 secret_key=g_secret_key)
        self.buy_price = 7314
        self.profit = 100
        self.avg_price = 0
        self.open_price = 0
        self.ask = 0
        self.bid = 0
        self.second_max = 0
        self.second_min = 0
        self.max = 0
        self.min = 0

    def trade(self):
        self.init_candles()
        result = self.desicion()
        self.do_trade(result)

    def get_current_price(self, symbol="btcusdt"):
        return self.api.get_best_quote(symbol)

    def update_second(self, high, low):
        if high > self.max:
            self.second_max = self.max
            self.max = high
        if low < self.min:
            self.second_min = self.min
            self.min = low

    def init_candles(self):
        candles = self.api.get_candlestick("btcusdt",
                                           CandlestickInterval.MIN60, 7)
        for candle in candles:
            high = candle.high
            low = candle.low
            if self.max == 0:
                self.max = high
                self.min = low
            self.update_second(high, low)

    def desicion(self, symbol="btcusdt"):
        current = self.get_current_price(symbol)
        self.ask = current.ask_price  #卖1
        self.bid = current.bid_price  #买1
        self.logger.info("买1:" + str(self.bid))
        self.logger.info("卖1:" + str(self.ask))

        self.update_second(self.bid, self.ask)
        print(self.second_max)
        print(self.second_min)

        if self.ask >= self.second_max and self.ask - self.buy_price > self.profit:
            return TradeOpt.Sell
        elif self.bid <= self.second_min:
            return TradeOpt.Buy
        return TradeOpt.Hold

    def do_trade(self, opt, symbol="btcusdt"):
        if opt == TradeOpt.Hold:
            return
        if opt == TradeOpt.Sell:
            position = self.get_position(symbol)
            if position <= 0.01:
                return
            order = self.api.create_order(symbol=symbol,
                                          account_type=AccountType.SPOT,
                                          order_type=OrderType.SELL_LIMIT,
                                          amount=position,
                                          price=self.ask)
            # cancel if failed
        else:
            # get cash
            cash = self.get_cash()
            amount = cash / self.bid
            order = self.api.create_order(symbol=symbol,
                                          account_type=AccountType.SPOT,
                                          order_type=OrderType.BUY_LIMIT,
                                          amount=amount,
                                          price=self.bid)
            self.buy_price = self.bid

    def get_position(self, symbol="btcusdt"):
        account_balance_list = self.api.get_account_balance()
        if account_balance_list and len(account_balance_list):
            for account in account_balance_list:
                if account.account_type == "spot" or account.account_type == "SPOT":
                    if account.balances and len(account.balances):
                        for balance in account.balances:
                            if balance.balance > 0.0 and balance.currency == symbol:
                                print("\tBalance Currency", balance.currency)
                                print("\tBalance Type", balance.balance_type)
                                print("\tBalance", balance.balance)
                                return balance.balance
        return 0

    def get_cash(self):
        return self.get_position("usdt")
Esempio n. 5
0
import logging
from huobi import SubscriptionClient, RequestClient
from huobi.constant.test import *
from huobi.model import *
from huobi.base.printobject import PrintMix, PrintBasic

logger = logging.getLogger("huobi-client")
logger.setLevel(level=logging.INFO)
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
logger.addHandler(handler)

def callback(order_req_obj: 'OrderListRequest'):
    print("---- order list:  ----")
    order_req_obj.print_object()
    print()

request_client = RequestClient(api_key=g_api_key, secret_key=g_secret_key, url = "https://api.huobi.vn")
sub_client = SubscriptionClient(api_key=g_api_key, secret_key=g_secret_key, uri = "https://api.huobi.vn")
data = request_client.get_account_balance()
if len(data):
    for account in data:
        print("============= account info =============")
        PrintBasic.print_basic(account.id, "Account ID")
        sub_client.request_order_list_event(symbol="nodeusdt", account_id=account.id, callback=callback, order_states = OrderState.FILLED, client_req_id = None, auto_close = True)
        break # for frequence limit


class KeepBalanceStrategySocket(BaseStrategy, FileReadAndWrite):
    """
    动态平衡策略
    """

    def __init__(self):
        BaseStrategy.__init__(self)
        FileReadAndWrite.__init__(self)
        self.request_client = RequestClient(api_key=self.get_config_value("huobi", "api_key"),
                                            secret_key=self.get_config_value("huobi", "secret_key"))
        self.strategy = 'KeepBalance'
        self.timeout = float(self.get_config_value("strategy", "timeout"))

    def signal(self):
        balance_dict = self.get_account_balance()
        for key, value in enumerate(balance_dict):
            if float(balance_dict[value]["amount"]) * 1.03 < float(balance_dict[value]["dollar"]):
                self.buy(value, amount=balance_dict[value]["amount"], dollar=balance_dict[value]["dollar"])
            elif float(balance_dict[value]["dollar"]) * 1.03 < float(balance_dict[value]["amount"]):
                self.sell(value, amount=balance_dict[value]["amount"], dollar=balance_dict[value]["dollar"],
                          price=balance_dict[value]["price"])
            else:
                self.logger.info(f"当前{value}价格为{balance_dict[value]['price']}, 持有{value}合计金额: "
                                 f"{balance_dict[value]['amount']}, 对标美元: {balance_dict[value]['dollar']}, "
                                 f"小于阈值不触发交易, "
                                 f"买入阈值: {retain_decimals(str(float(balance_dict[value]['dollar']) / 1.03), '2')}, "
                                 f"卖出阈值: {retain_decimals(str(float(balance_dict[value]['dollar']) * 1.03), '2')}")

    def buy(self, symbol_name, **kwargs):
        self.trade_lock(symbol_name, self.strategy)
        try:
            assert kwargs['dollar'] >= kwargs['amount']
            buy_dollar = retain_decimals(str((float(kwargs['dollar']) - float(kwargs['amount'])) / 2), '2')
            if float(buy_dollar) >= TradeLimit.trade_limit_dict['usdt']:
                # 买入
                order_id = self.request_client.create_order(symbol_name + 'usdt', AccountType.SPOT,
                                                            OrderType.BUY_MARKET, buy_dollar, None)
                self.update_balance_and_dollar(order_id, Action.BUY, symbol_name, buy_dollar=buy_dollar)
                # self.send_mail("触发买入信号", f"动态平衡策略触发买入{buy_dollar}的{symbol_name}")
                WeChatRobot.send_message(f"动态平衡策略触发买入{buy_dollar}的{symbol_name}")
            else:
                self.logger.warning(f"当前欲买入{buy_dollar}美金的{symbol_name}, 不满足最低交易限制")
        except AssertionError:
            self.logger.error(f"AssertionError, symbol={symbol_name}, amount={kwargs['amount']}, "
                              f"dollar={kwargs['dollar']}")
        except Exception as E:
            self.logger.error(E)
        finally:
            self.trade_unlock(symbol_name, self.strategy)

    def sell(self, symbol_name, **kwargs):
        self.trade_lock(symbol_name, self.strategy)
        try:
            assert kwargs['amount'] > kwargs['dollar']

            # 获取交易数目精度
            precision = self.precision_collection.find_one({"symbol": symbol_name + "usdt"}, {"amount_precision": 1})
            amount_precision = float(precision['amount_precision'])

            # 计算欲卖出的数目
            sell_currency = retain_decimals(
                str((float(kwargs['amount']) - float(kwargs['dollar'])) / 2 / float(kwargs['price'])),
                str(amount_precision))

            if float(sell_currency) > TradeLimit.trade_limit_dict[symbol_name]:
                order_id = self.request_client.create_order(symbol_name + 'usdt', AccountType.SPOT,
                                                            OrderType.SELL_MARKET, sell_currency, None)
                self.update_balance_and_dollar(order_id, Action.SELL, symbol_name)
                # self.send_mail("触发卖出信号", f"动态平衡策略触发卖出{sell_currency}的{symbol_name}")
                WeChatRobot.send_message(f"动态平衡策略触发卖出{sell_currency}的{symbol_name}")
            else:
                self.logger.warning(f"当前欲卖出{sell_currency}美金的{symbol_name}, 不满足最低交易限制")
        except AssertionError:
            self.logger.error(f"AssertionError, symbol={symbol_name}, amount={kwargs['amount']}, "
                              f"dollar={kwargs['dollar']}")
        except Exception as E:
            self.logger.error(E)
        finally:
            self.trade_unlock(symbol_name, self.strategy)

    def update_balance_and_dollar(self, order_id, action, symbol_name, **kwargs):
        order_detail = self.request_client.get_order("symbol", order_id)

        # 验证订单是否执行完成
        while not order_detail.state == OrderState.FILLED:
            time.sleep(1)
            self.logger.info(f"{order_id}还未执行完成, 休眠1秒等待执行完成")
            order_detail = self.request_client.get_order("symbol", order_id)

        # mongodb中减去已使用的美金
        result = self.keep_balance_collection.find_one({"symbol": symbol_name})
        dollar = float(result['amount'])
        if action == 'BUY':
            dollar -= float(kwargs['buy_dollar'])
        # mongodb中加上卖出获得的美金
        elif action == 'SELL':
            dollar += float(order_detail.filled_cash_amount)

        # 格式化美金数
        dollar = retain_decimals(str(dollar), '2')

        # mongodb更新操作
        self.keep_balance_collection.update_one({"symbol": symbol_name}, {"$set": {"amount": dollar}})
        self.logger.info(f"{symbol_name}美金数置为: {dollar}")

    def get_account_balance(self):
        """
        获取余额大于0的交易对
        :return:
        """
        balances = self.request_client.get_account_balance()
        balance_dict = {}
        for key, value in enumerate(balances[0].balances):
            if value.balance > 0 and value.currency != 'usdt':
                price, amount = self.get_account_amount(value.currency, value.balance)
                if float(amount) >= 1:
                    if not self.check_trade_lock_exist(value.currency, self.strategy):
                        dollar = self.get_mongodb_dollar(value.currency, amount)
                        balance_dict[value.currency] = {"balance": str(value.balance), "price": str(price),
                                                        "amount": str(amount), "dollar": dollar}
        self.logger.debug(balance_dict)
        return balance_dict

    def get_account_amount(self, symbol_name, symbol_balance):
        price = self.get_price(symbol_name + "usdt")
        amount: str = str(float(symbol_balance) * float(price))
        amount: str = retain_decimals(str(amount), '2')
        return price, amount

    def get_mongodb_dollar(self, symbol_name, symbol_amount):
        result = self.keep_balance_collection.find_one({"symbol": symbol_name})
        if result is None:
            self.keep_balance_collection.insert_one({"symbol": symbol_name, "amount": str(symbol_amount)})
            return symbol_amount
        else:
            return result['amount']

    def get_price(self, symbol_name: str) -> str:
        """
        获取当前交易对价格
        :param symbol_name:
        :return:
        """
        try:
            file = FileReadAndWrite.read(f"{self.get_config_value('strategy', 'price_file_locate')}{symbol_name}.txt")
            time_stamp, price = file.split(",")
            # time.time()获取的时间为0时区时间, 火币为东8区时间, 因此减去28800秒
            current_time = time.time() - 28800
            if abs(current_time - float(time_stamp) / 1000) < self.timeout:
                return price
            else:
                self.logger.error("动态平衡策略获取时间戳出错, 价格超时")
                os.system("/root/miniconda3/bin/supervisorctl -u gator -p zhangpei529\!\@ -c "
                          "/usr/supervisor/supervisord.conf restart collect_price_data")
                self.logger.info("重启价格获取程序")
                raise TimeoutError
        except FileNotFoundError:
            self.logger.error(f"{self.get_config_value('strategy', 'price_file_locate')}{symbol_name}.txt文件不存在")
            raise FileNotFoundError