# Reactive Programming in Financial Markets
A complete introduction to a reactive programming model for algorithmic operativity in global financial markets.
# Abstract
One of the most recurrent problems when dealing with data analysis or algorithmic trading in financial markets is keeping track of the market prices and its derived data, this is fundamental to update the logic and state of our program according to the new market state. This production illustrates a TypeScript implementation of a reactive method which can be easily extended to any other programming language and technology.
# Table of Contents
# Introduction
The first case is the creation of a trading system (a trading bot executing a trading strategy), when creating a trading system we have to define its market entry and exit conditions. Such conditions may depend on various data analysis procedures involving technical indicators, price action calculations, fundamental data analysis, usage of machine learning based algorithms and so on...
The idea behind a reactive programming model comes along with the idea of using isolated components doing calculations on an internal state based on the actual market conditions. For example, every trading system entry condition could have its own independent component, internally establishing if the condition is favorable or not.
Such reality would allow implementing a hedache-less trading system composed of components (like lego pieces) being part of the trading system execution.
In short the benefits would be:
- Quicker declarative implementations with less code;
- Direct access to a single source of truth automatically keeping data updated;
- Less maintainability required;
- Reduced probability to introduce bugs.
# Reactive Market Components
Finally, let's write some code, the following examples are an existing implementation made with Mida: the framework for algotrading in global financial markets.
TIP
A market component is a way to encapsulate logic and data evolving as the underlying market changes.
The following example declares a component made of a
Relative Strength Index indicator and a isOverbought
property automatically updated.
import { marketComponent, } from "@reiryoku/mida";
// A reactive component detecting overbought markets
const OverboughtDetector = marketComponent({
indicators: {
myIndicator: {
type: "RSI",
options: { length: 14, },
input: {
timeframe: MidaTimeframe.M30, // Use M30 candles
type: "close", // Use close prices
},
},
},
computed: {
// A variable calculated every market update
isOverbought () {
return this.myIndicator.lastValue.greaterThan(80);
},
},
// Invoked every market update
update () {
console.log(this.isOverbought);
},
});
Now the component can be generated with a trading account and market symbol.
const overboughtDetector = await OverboughtDetector(myAccount, "ETHUSD");
Components can be used for any logic and data dependent on a market state. For example, this is a simple market ticker.
- Example 1
import { marketComponent, } from "@reiryoku/mida";
// A component logging the market prices
const Ticker = marketComponent({
computed: {
spread () {
return this.$ask.subtract(this.$bid);
},
},
update () {
console.log(`Market price has changed for symbol ${this.$symbol}`);
console.log(`Bid price is ${this.$bid}`);
console.log(`Ask price is ${this.$ask}`);
console.log(`The spread is ${this.spread}`);
},
});
To get back, the final use case for market components would be implementing a trading strategy made of multiple independent market components.
- Example 2
import { marketComponent, MidaTimeframe, } from "@reiryoku/mida";
const TrendDetector = marketComponent({
indicators: {
// Simple Moving Average on 5 periods
sma5: {
type: "SMA",
options: { length: 5, },
input: {
timeframe: MidaTimeframe.H1, // Use H1 candles
type: "close", // Use close prices
},
},
// Simple Moving Average on 15 periods
sma15: {
type: "SMA",
options: { length: 15, },
input: {
timeframe: MidaTimeframe.H1, // Use H1 candles
type: "close", // Use close prices
},
},
},
computed: {
isBullish () {
return this.sma5.lastValue.greaterThan(this.sma15.lastValue);
},
},
update () {
if (this.isBullish) {
console.log("SMA5 is above SMA15");
}
else {
console.log("SMA5 is below SMA15");
}
},
});
Finally a trading strategy would have all the components as dependency and use them to decide if the setup is ready to enter/exit the market.
- Example 3
import { marketComponent, } from "@reiryoku/mida";
const TradingSystem = marketComponent({
dependencies: {
overboughtDetector: OverboughtDetector,
trendDetector: TrendDetector,
},
// Invoked when market updates (after all the dependencies have completed their cycle)
update () {
if (this.trendDetector.isBullish && !this.overboughtDetector.isOverbought) {
// Enter the market...
}
},
});
# Component Structure
# Market State
The this
of a market component assumes the state of the component defined by data, computed, indicators
and methods, plus some builtin variables such as the current bid and tick prices in the market.
- Interface
type MidaMarketComponentState = Record<string, any> & {
$component: MidaMarketComponent;
$dependencies: MidaMarketComponentState[];
$tradingAccount: MidaTradingAccount;
$watcher: MidaMarketWatcherDirectives;
$symbol: string;
$bid: MidaDecimal;
$ask: MidaDecimal;
$ticks: MidaTick[];
$periods: Record<string, MidaPeriod[]>;
$livePeriods: Record<string, MidaPeriod>;
$indicators: Record<string, any>;
};
# Market Update
The update()
hook represents any market change such as a market tick, a candle being closed or
simply the market being closed or opened.
This means that every market event has its own hook.
- Example
import { marketComponent, } from "@reiryoku/mida";
const Component = marketComponent({
async tick () {
// Invoked when there is a market tick
},
async periodUpdate (period) {
// Invoked when a last live candlestick is updated
},
async periodClose (period) {
// Invoked when a candlestick is closed
},
// Furthermore, specific timeframes can be targeted
async m15PeriodClose (period) {
// Invoked when a M15 candlestick is closed
},
async marketOpen () {
// Invoked when the market opens
},
async update () {
// Invoked when there is any market update: a tick, a candle close, a market open/close...
},
});
# Dependencies
The dependencies are a fundamental functionality of market components. All market updates are delivered first to the dependencies, this means that a component is updated only after all its dependencies are updated.
- Example
import { marketComponent, } from "@reiryoku/mida";
// A component logging the market prices
const Component = marketComponent({
dependencies: {
overboughtDetector: OverboughtDetector,
},
// Invoked when market changes and dependencies have completed their cycle
update () {
console.log(this.overboughtDetector.isOverbought);
},
});
# Conclusion
I consider that this publication and the work behind are still a draft, so there may be future updates. For the people familiar with Vue.js or Unity3D, I took inspiration from my experience with them. As the financial markets and programming fields are still very closed and proprietary-directed, I hope this publication can inspire others for future projects.