Skip to content

Strategy Building Workflow

What is a trading strategy

A trading strategy is a set of rules that consumes market events (e.g. arrival of new data points, a order getting executed or rejected etc.) and responds by producing a series of trading orders. A trading strategy is, then , just a set of rules (or a program) that can tells us what to do under any market event. A trading engine can be thought of the sum of tools and infrastructure, that allows a trading strategy to run. A trading engine invokes and run the trading strategy, makes the market events available to the strategy to consume, and routes the orders generated from it to appropriate destinations.

A strategy can be memory-less, i.e. while consuming market events and producing orders, it does not have to remember past events or actions. The rule(s) in this case depends only on the current event and nothing else. An example of this: if last price greater than 10-period moving average1, then buy 5 units of the stock. Trading engines that are most suitable for such strategies are known as rule engines. These are stateless trading engine.

More sophisticated strategies usually depend not only on the latest events but also the past events, and actions. The strategies are no longer memory-less. They need access to past events and its own actions. Trading engines suitable for such cases are known as complext event processing engines or CEP engines. CEP engines are stateful. Blueshift is a CEP engine, capable of running strategies of any complexity.

Strategy Events for Bluesfhit

Strategies for CEP engines focus on defining how to handle market events. These events depends on the specific engine. On Blueshift, we follow the typical events a quant developer will care about. These includes:

  • Start of the strategy: This is an event the strategy will receive only once - at the very start of the run. This is useful for setting up all sorts of initialization that the strategy needs - for e.g. defining the trading universe, trade parameters, placeholder variables etc. On Blueshift, this event invokes the function initialize defined within the user strategy. A user strategy on blueshift without defining this function is not a legal strategy.

  • Start of the day: This event is raised at the start of the every trading day while the strategy is running. The corresponding function on Blueshift is before_trading_start. This is a useful event to carry out start of the day stuff - like periodic model evaluation, book-keeping etc. It is optional to define this function in the strategy.

  • Data event: This event is triggered at each incoming data candles. On Blueshift, data candles are generated at minute frequency. This means the corresponding function - handle_data - is called every minute. This usually the core of the strategy where data fetching and buying and selling logics go. This is optional as well.

Optionally, you can also define analyze function, that corresponds to an event which is raised on the strategy run completes. Apart from this events, on Blueshift we can also generate time-based events through the schedule_function function. This allows us to define a rich set of date and time based rules. The Blueshift engine will trigger events based on these rules and we can respond (take action, make a trade etc.) by responding to it.

We have already seen a sample strategy in the quick start section. Now we can hopefully follow the logic more clearly.

Extra event handling for Live Trading

If the live trading broker supports, Blueshift allows to respond to streaming events as well. For this, use the on_data function (with the signature as on_data(callback)) to respond to streaming data events in real-time. Or use the on_trade function for responding to order fills events. Note: not all brokers support both (or any) of these, in which case, these callback functions will be ignored and never be invoked. The signature of the callback functions are the usual callback(context, data). The on_data and on_trade are API function so must be imported from blueshift api (from blueshift.api import on_data, on_trade). Also both have a corresponding function to remove the handler, off_data and off_trade.

  1. Although last 10 period moving average sounds like it depends on past data, in a looser sense, this still can be classified as memory-less as most trading interface allows us to query for past 10 data points anytime.