In the last article, I discussed best practices for developing trading software, such as using events, data storage, or separate configurations. This time, let's delve into the strategic part, specifically how to organize it effectively from an architectural standpoint.
Strategy Module
The simplest approach is to assume that this part of the system receives input data, such as price changes, and generates events—signals. All logic can be encapsulated within this module. Here’s an example:
def run(self, event):
signal = self.calc_rsi(event)
if signal != 'FLAT':
self.create_event(event, signal)
In this example, we calculate the RSI and generate events like BUY or SELL based on it. This is a basic illustration, but the concept is clear. The signal might include the desired buy/sell price. Of course, a real trading algorithm is more complex, but you already know that!
Portfolio Module
It's beneficial to have all data on balances or open positions gathered in one place. This way, you know your total holdings in USD or BTC. This knowledge is essential for determining the size of your orders when the system generates signals.
def run(self, event):
# Calculate USD values
# Calculate targets
# Check targets
# Generate orders
This pseudocode outlines the following steps:
Calculate the total balances in USD
Determine portfolio targets according to the strategy
Check if current balances meet the targets
Generate orders of the necessary size if there are discrepancies
You get all the balance data, signals, verify if the positions align with the desired ones, and generate orders if they don't.
Risk Management Module
This module is closely related to the Portfolio module. Sometimes, risk management logic can be implemented directly within it, especially if you're managing a small sum and have just started. For large firms, this could be the most complex system element, and each firm defines its precise algorithm. Here are some tasks that can be addressed within risk management:
Check correlations between positions to avoid 100% long or short
Verify the maximum size of one position
Halt the entire system if losses reach a certain percentage
Stop the system in case of data stream failures or other components issues
The longer you’re in the market, the more critical this part of the trading algorithm becomes.
Execution Module
After obtaining all price and balance data, generating signals, calculating the optimal portfolio size, and accounting for all possible risks, there’s no reason not to send an order to the exchange. This might seem like the simplest part unless you're implementing order routing across multiple exchanges. Usually, you format the order correctly and send it to the exchange you trade on.
We discussed the functions of four modules, each of which is useful in 90% of trading algorithms. Structure your code, choose a good architecture, and maintaining and updating your trading system will be much less painful.
The complete code will be available as an open-source trading algorithm for aspis.finance. It will include a couple of simple trading strategies, but the key feature is the ability to create storage through Aspis smart contracts, attract investor funds, and ensure transparent profit-sharing. You can develop your strategy, connect it to Aspis, your algorithm will trade on DEXs, and investors and managers (you) will earn profit through a smart contract. Stay tuned!