# 使用Hummingbot Script移植韭菜收割机策略(2)

By [Dolm](https://paragraph.com/@dolm) · 2023-03-24

---

根据我们在[上一节](https://zhuanlan.zhihu.com/p/599238623)的设计流程图可以看出，我们需要写几个主要函数来实现功能：

1.  更新交易量
    
2.  更新订单簿
    
3.  平衡资产
    
4.  判断市场状况并下单
    

### 更新交易量

万事开头难，第一步我们就遇到了问题，因为Hummingbot Script并没有提供直接获取历史交易的方法，

我们只能直接用交易所的API去获取这个数据，不过据说Hummingbot的开发人员已经在着手写一个和Trade相关的模块，以便让用户更方便地调用：

        def update_vols(self):
            trades = pd.DataFrame(self.fetch_historical_trades(self.trading_pair, 15))
            self.vol = 0.7*self.vol+0.3*trades.size.sum()
            if len(self.prices) == 0:
                self.prices = list(trades['price'].astype('float'))    
        def fetch_historical_trades(self, trading_pair: str, limit) -> List[Decimal]:
            url = "https://api.binance.com/api/v3/trades"
            params = {
                "symbol": trading_pair.replace("-", ""),
                "limit": f"{limit}"
            }
            trades = requests.get(url=url, params=params).json()
            return trades
    

> _这段程序实现了以下功能：update\_vols()函数中，使用pd.DataFrame(self.fetch\_historical\_trades(self.trading\_pair, 15))获取近15条交易的信息，存储在trades变量中。使用trades.size.sum()获取trades中交易数量的总和，并使用0.7self.vol+0.3trades.size.sum()更新self.vol的值。判断self.prices列表是否为空，如果为空，将trades中price列转化为浮点数后存储在self.prices中。fetch\_historical\_trades()函数中，使用requests.get(url=url, params=params).json()获取最近15条交易的信息。其中url是API的URL，params是请求参数，包括交易对和交易数量。最后返回获取到的交易信息。注意：这段代码与Binance交易所相关，需要确保你有Binance的API访问权限。_

### 更新订单薄

Hummingbot有一个获取订单薄的方法，我们可以直接使用：

        def update_orderBooks(self):
    
            orderBook = self.connectors[self.connector_name].get_order_book(self.trading_pair)
            ask_entries = orderBook.ask_entries()
            bid_entries = orderBook.bid_entries()
    
            Asks1 = float(next(ask_entries).price)
            Asks2 = float(next(ask_entries).price)
            Asks3 = float(next(ask_entries).price)
    
            Bids1 = float(next(bid_entries).price)
            Bids2 = float(next(bid_entries).price)
            Bids3 = float(next(bid_entries).price)
    
            Asks = Bids1*0.618 + Asks1*0.382 + 0.01
            Bids = Bids1*0.382 + Asks1*0.618 - 0.01
    
            PriceGetIn = (Bids1+Asks1)*0.35 + (Bids2+Asks2)*0.1 + (Bids3+Asks3)*0.05
            self.prices.pop(0)
            self.prices.append(PriceGetIn)
    
            return Asks,Bids,Asks1,Bids1
    

> _这段程序实现了以下功能：使用self.connectors\[self.connector\_name\].get\_order\_book(self.trading\_pair)获取交易对的订单簿。使用ask\_entries()和bid\_entries()方法分别获取卖盘和买盘的订单。使用next(ask\_entries).price和next(bid\_entries).price获取卖盘和买盘的价格。其中Asks1, Asks2, Asks3, Bids1, Bids2, Bids3分别表示第一第二第三档卖盘和买盘的价格。使用Asks1和Bids1算出Asks和Bids的值。使用Bids1, Asks1, Bids2, Asks2, Bids3, Asks3算出PriceGetIn的值。将PriceGetIn的值加入self.prices列表中。最后返回Asks, Bids, Asks1, Bids1四个值。注意：程序中的0.618，0.382，0.01和0.35，0.1，0.05是预先设定的常量，他们对于程序的结果有影响。_

### 平衡资产

        def get_balance(self):
    
            df = self.get_balance_df()
            self.base_asset = float(df.loc[df['Asset'] == self.base, 'Total Balance'])
            self.price = float(self.connectors[self.connector_name].get_mid_price(self.trading_pair))
            self.base_value = self.base_asset * self.price
            self.quote_asset = float(df.loc[df['Asset'] == self.quote, 'Total Balance'])
            total_value = self.quote_asset + self.base_value
    
            if self.base_value >= total_value * 0.52:
                self.sell(self.connector_name, self.trading_pair, Decimal(total_value/self.price * self.threshold),
                          OrderType.LIMIT, Decimal(self.price * 1.0001))
            elif self.base_value < total_value * 0.48:
                self.buy(self.connector_name, self.trading_pair, Decimal(total_value/self.price * self.threshold),
                         OrderType.LIMIT, Decimal(self.price * 0.9999))
    

> _这段程序实现了以下功能：1.使用self.get\_balance\_df()获取账户资产信息并存储在df中。2.使用df.loc\[df\['Asset'\] == self.base, 'Total Balance'\]获取基准资产的余额并存储在self.base\_asset中。3.使用self.connectors\[self.connector\_name\].get\_mid\_price(self.trading\_pair)获取基准资产和报价资产的中间价格，并存储在self.price中。使用self.base\_asset \* self.price计算基准资产的总价值并存储在self.base\_value中。使用df.loc\[df\['Asset'\] == self.quote, 'Total Balance'\]获取报价资产的余额并存储在self.quote\_asset中。使用self.quote\_asset + self.base\_value计算总价值并存储在total\_value中。判断基准资产的总价值是否大于等于总价值的52%，如果是，调用self.sell()函数卖出指定比例的资产；如果基准资产的总价值小于总价值的48%，调用self.buy()函数买入指定比例的资产。注意：程序中使用了self.connector\_name，self.trading\_pair，self.threshold，self.base，self.quote等变量，需要确保这些变量已经被正确赋值。_

### 判断市场状况并下单

这一部分的代码比较长，就不贴出来了，简单说就是通过定义好的爆发阈值判断当前市场是牛市或者是熊市，并根据交易量、价格波动、盘口价差等因素进行下单力度调整，具体可以原始代码。

最后我们在on\_tick函数中调用上面几个函数，程序就基本完成了。

下一节，我们将展示实际的机器人绩效，并提出一些优化改进的想法。

### 本文参考了以下内容：

[Script入门指南 - Hummingbot Docs](https://link.zhihu.com/?target=https%3A//docs.hummingbot.org/scripts/getting-started/)

[Hummingbot Script速查表](https://link.zhihu.com/?target=https%3A//drive.google.com/file/d/1_qqQ8jnd1IpiaCHWOMLaLAT4Y6WGWyeW/view%3Fusp%3Dsharing)

[ChatGPT](https://link.zhihu.com/?target=https%3A//chat.openai.com/)

[Binance API Documentation](https://link.zhihu.com/?target=https%3A//binance-docs.github.io/apidocs)

* * *

### 如有任何问题获想参与讨论，请加入我们的社区

我们的社区有众多的做市商和套利者，他们愿意互相帮助，充分利用 Hummingbot。 您可以加入我们的 [Discord 中文频道](https://link.zhihu.com/?target=https%3A//discord.gg/hYFEz3rY5f)

，讨论 Hummingbot、策略、流动性挖坑以及与加密货币世界有关的任何其他内容，并获得我们团队的直接支持。

加入中文微信群，请添加ID：amtf202004

---

*Originally published on [Dolm](https://paragraph.com/@dolm/hummingbot-script-2)*
