Gekko's architecture #
Every Gekko instance has two core components:
- A market
- A GekkoStream
Communication between those two components is handled by Node.JS' Stream API. The Market implements a Readable Stream interface while the GekkoStream implements a Writeable Stream interface.
A Market #
All markets in Gekko eventually output candle
data. Where these candles come from and how old they are does not matter to the GekkoStream they get piped into. On default Gekko looks for markets in the core/markets/
directory. The top orange block in the picture is a BudFox market (the default semi-realtime market that gets live data from exchanges).
Example Markets that come included with Gekko are:
- BudFox (a realtime market): this market stays on indefinitely and outputs candles from the live markets in semi-realtime (cryptocurrency exchanges run 24/7).
- backtest: this market reads candles from a database and outputs them as fast as the GekkoStream is able to consume them (the GekkoStream will run TA strategies over these candles).
- importer: the importer market will fetch historical data from an exchange and pass on (to the GekkoStream who inserts them in a database).
A GekkoStream #
A GekkoStream is nothing more than a collection of plugins. Plugins are simple modules that can subscribe to events, and do something based on event data. The most basic event every GekkoStream has is the "candle" event, this event comes from the market.
However plugins are allowed to broadcast their own events, which other plugins can subscribe to. An example of this is the tradingAdvisor
plugin. This plugin will implement a strategy that will be fed candle data. As soon as the strategy suggests to take a certain position in the market ("I detect an uptrend, I advice to go long") it will broadcast an advice
event. The paperTrader
is a plugin that simulates trading using these advices, the trader
is a plugin that creates real market orders based on these advices. You can decide to only turn the paperTrader
on or to turn the trader
on (you now have a live trading bot).
When you run a backtest using Gekko the following things happen:
- Gekko configures a
backtest
market. - Gekko loads all configured plugins that are supported in the
backtest
mode* into a GekkoStream. - Gekko pipes the market into the GekkoStream and voila!
*Gekko refuses to load plugins that are unsupported in specific modes. During backtests you never want to enable the real trader to enter market orders. Because if you would the advice would be based on specific moments in the backtest, not on the current state of the market.
Plugins & Adapters #
Those two core components describe the majority of Gekko's flow. A lot "core functionality" like saving candles to disk are simply plugins that push all candles to a database.
Separated architecture #
The modular nature of Gekko makes it very dynamic and allows for rapidly creating new plugins. However there is an ugly side to this story:
The tradingAdvisor
runs TA strategies against a market. The problem however is that most TA indicators need some history before they can give accurate results. If you want to use an EMA (exponential moving average), you need some history to base the initial average on. But because the tradingAdvisor doesn't know what market data is going to be made available later by the market, it needs to do some fetching itself and compare that to locally available market data (stored in the local database) to see if it can stitch the two sources.