Hummingbot Architecture Part 2

Blog»Hummingbot Architecture Part 2
cover

Martin Kou

2021-05-03 · 7 min read

Introduction

In the last article of this series, we've discussed the design motivations behind Hummingbot, the clock and the market connectors. Today, we'll be discussing the architecture behind trading strategies - the very component that decides Hummingbot trades with your money. We will also discuss how you can diagnose problems and debug Hummingbot in live trading.

Strategies

chess

If market connectors are the hands and eyes of Hummingbot, then strategy is the brain of Hummingbot. Strategy objects process market signals, and decide when and what orders to create or remove on markets.

We will use the Avellaneda & Stoikov market making strategy as an example for our discussions.

Watching the Market Like A Movie

Every strategy class is a subclass of the TimeIterator class - which means, in normal live trading, its c_tick() function gets called once every second. Each time c_tick() is called, the strategy object should be making observations on the latest market information, and decide what it should do.

You can imagine strategy objects are watching the markets like a movie, where each second is one frame of the movie - and it's constantly trying to decide what to do about any new developments from the movie.

Let's take a look at the c_tick() function of the Avellaneda & Stoikov market making strategy in Hummingbot, below:

avellaneda

Here is an overview of what the strategy is doing every second - after it's been properly initialized.

  1. Line 412 - perform market observations and update indicators

    This function performs observations on both price actions on the market, and also the current inventory on the trader's account. Specifically, it updates the price volatility trailing indicator _avg_vol, and periodically updates the _gamma_kappa, and _eta parameters as specified from the Avellaneda & Stoikov paper.

  2. Line 415 - checking timestamps for creating new orders

    This line looks at the current wall clock time and determines whether it's time to create new orders on the market.

  3. Line 424 - decide on the order prices, if creating order

    This line calculates the prices for creating market making orders, from the indicators and parameters just calculated above.

  4. Line 426 to 433 - create an intermediate order proposal for creating orders later

    The intermediate order proposal specifies the price, amount and side of the orders to be created. However, they do not consider whether there are already similar active orders on the market.

  5. Line 435 - cancel expired active orders, or if the new order proposal has different prices to the existing orders

  6. Line 438 to 443 - execute order proposals

    These lines executes the order proposals generated from the logic above - sending orders to the exchange and tracking them.

Reading Prices and Order Book

If you do a manual trace of the get_price() or get_mid_price() functions in the Avellaneda & Stoikov strategy code, you'll find it leads to OrderBook.c_get_price() in the module hummingbot.core.data_type.order_book.

getprice

The OrderBook class tracks the real-time order book, including depth on both sides, trades and prices, on live exchanges. Each market pair in an exchange market will have one order book. Since trailing indicators often depend on price and order book depths as their fundamental inputs, order book information is often among first inputs to be read by a strategy in every c_tick() iteration.

Trailing Indicators

Sophisticated strategies often need some trailing indicators from the market, in addition to the current prices or order book depth information, to make trading decisions. This includes most of the technical analysis indicators such as EMA, MACD and Bollinger Bands. In Avellaneda & Stoikov strategy example, the object self._avg_vol, which is an instance of AverageVolatilityIndicator, is a trailing indicator for recent price volatility.

Let's take a look at how it collects new samples from the strategy code. For every call to c_tick()c_collect_market_variables() would send the newest price to self._avg_vol via self._avg_vol.add_sample(price).

avi

When you look into the relevant code for calculating the values of the trailing indicator, you'll find that AverageVolatilityIndicator stores a fixed number of samples of prices and outputs a smoothed standard deviation statistic of the prices in the window.

avi2
avi3

If you want to write your own custom indicators, you can do so by inheriting from BaseTrailingIndicator just like the above, and writing your own sampling and calculation logic.

High Performance Backtesting / Hummingbot Pro Preview

If you have looked behind the hood of the Clock class in Hummingbot, you'll find that it has two modes: real time and back testing.

clockmode

We are going to release an enhanced version of Hummingbot, Hummingbot Pro, that allows for high performance back testing with high resolution historical order book data. It gives you the ability to plug in any strategy written for Hummingbot, run historical order book data traces with it, and give you the output on the trading performance for that strategy. It is capable of simulating days of high frequency trading within seconds. It also allows you to test a wide range of parameters with the strategy to search for the optimal parameters for trading.

A big reason for using Cython within Hummingbot is high performance backtesting. While there are other Python open source quant frameworks that allow live trading and backtesting - most of them only work with low resolution data (e.g. daily OHLCV candles) and are not designed with high frequency trading simulations in mind. Having performance-critical code written in Cython allows Hummingbot strategies to be simulated with high-resolution order book data.

Here are some preview images of the kind of output you can get from Hummingbot Pro backtesting simulations.

ofc1
ofc2

Hummingbot Pro will be a paid service for professional traders and hedge funds. It is coming in Q4 2021.

Community and Developer Friendliness

pc

Hummingbot is designed from the ground up with developers in mind. Crypto markets are constantly changing. Whether it is the services and APIs offered by exchanges, the participants and the way the markets move - it's constantly in flux. Developer are uniquely suited to take advantage of this kind of environment, because they are able to modify and tune their strategy and connector code as the market evolves.

Debug Console

When you are writing a new connector, or a new strategy - it is critical to be able to observe the detailed behavior of your code, and diagnose any problems as it is happening. The logging facility is one tool developers can use. The other tool in a Hummingbot developer's arsenal, is the debug console.

The Hummingbot debug console is disabled by default. It needs to be enabled by editing conf/conf_global.py and setting debug_console to true.

telegram

Once that has been set, you will be able to telnet to localhost:8211 to access an interactive Python console that has access to the same memory space as the live Hummingbot instance. You can, for example, examine the live properties from the currently running strategy object and look at the active orders it has made and is tracking.

debug5

You can read more about the debug console from Hummingbot documentation.

Discord Channels

Our Discord server is a good place you can find other Hummingbot developers, who, like you, may be creating their own strategies, indicators and market connectors. We have several developer oriented channels, where you can get community support on how to create your own modifications to Hummingbot.

discord

Contributing

Finally, if you would like to report issues in Hummingbot, or contribute code - our Github page can be found at https://github.com/CoinAlpha/hummingbot.

Conclusion

Using the Avellaneda & Stoikov market making strategy as an example, we have discussed how Hummingbot strategies work, how strategies observe the markets, and how trailing indicators can be created in Hummingbot.

We then discussed the high performance aspect of Hummingbot and gave a preview for the upcoming Hummingbot Pro service.

Finally, we discussed some tricks you can use to diagnose the behavior of a live Hummingbot instance via the debug console, and how you can get help from the Hummingbot community.

This concludes part 2, and the overall Hummingbot Architecture series. If you have any further questions, feel free to drop by our Discord server at https://discord.hummingbot.io.

Related Posts

Hummingbot closes $8 million Series A round led by Initialized Capital
Hummingbot closes $8 million Series A round led by Initialized Capital
Hummingbot Roadmap - Q2 2021
Hummingbot Roadmap - Q2 2021
Hummingbot Architecture Part 2
Hummingbot Architecture Part 2

DISCLAIMER: The websites located at https://hummingbot.io, https://docs.hummingbot.io, https://miners.hummingbot.io (collectively, the "Site") are copyrighted works belonging to CoinAlpha, Inc. ("Company", "us", "our", and "we"). Certain features of the Site may be subject to additional guidelines, terms, or rules, which will be posted on the Site in connection with such features. All such additional terms, guidelines, and rules are incorporated by reference into these Terms. These terms of use (these "Terms") set forth the legally binding terms and conditions that govern your use of the Site. By accessing or using the Site, you are accepting these Terms (on behalf of yourself or the entity that you represent), and you represent and warrant that you have the right, authority, and capacity to enter into these terms (on behalf of yourself or the entity that you represent). You may not access or use the Site or accept the terms if you are not at least 18 years old. If you do not agree with all of the provisions of these terms, do not access and/or use the Site.