Anatomy of a CODY strategy

How to write and troubleshoot python trading strategies

Quadency Customer Service avatar
Written by Quadency Customer Service
Updated over a week ago

CODY is a powerful trading bot that enables developers to create, test, and execute trading algorithms for cryptocurrencies. It supports backtesting, and live trading, allowing developers to test and optimize their trading strategies before deploying them in the real world.

When you write an algorithm to work with CODY, there are two main functions that need to be implemented: initialize() and handle_data():

intialize

The initialize function is called once at the beginning of the algorithm and is used to set up any initial state or configuration for the algorithm. Here's an example of an initialize function:

def initialize(context):
context.target_profit = 0.05
context.stop_loss = -0.2
log.info("Strategy initialized")

Note: context.symbol is set internally based on your selection in the UI. Other variables that only need to be set once upon start of the algorithm can be defined here. Here we are attaching target_profit and stop_loss values to the context object (which is accessible from the handle_data function)

handle_data

The handle_data function is called once for each execution interval defined in the settings UI. This function is used to implement the trading logic of the algorithm. Here's an example of a handle_data function:

def handle_data(context, data):
current_price = data.current(context.symbol, 'price')
ma = talib.SMA(data.history(context.symbol, 'price', bar_count=10, frequency="5m"), timeperiod=5)[-1]
if current_price < ma:
order(context.symbol, 100)
log.info('Placed a buy order.')
elif current_price > context.portfolio.positions[context.symbol].cost_basis * context.profit_target or current_price < context.portfolio.positions[context.symbol].cost_basis * context.stop_loss:
order(context.symbol, -100)

In the example above, we check the current price using the data.current(context.symbol, 'price') call, and request historical data using data.history which is then fed into talib.SMA to calculate simple moving average. TaLib is a python library for technical analysis and can be used to derive many other indicators in similar way.

Note: If the execution interval is set to 1H, be sure to set the same value for frequency when requesting historical data, otherwise there will be errors.

Following is a brief explanation of commonly used features of the framework:

  1. Accessing current and historical data: You can use the data.current() and data.history() methods to access the current and historical data of any asset that your algorithm is trading. For example, you could get the current price of an asset using price = data.current(asset, 'price'), or get the 10-day moving average using ma10 = data.history(asset, 'price', bar_count=10, frequency='1d').mean().

  2. Placing orders: You can use the order() methods to place orders to buy or sell assets. The order() method is used to place an order for a specific number of shares or a specific amount of money. First argument must be the symbol (context.symbol) and second argument will be amount. Third (optional) argument is price, when provided will result in a limit order being placed on the exchange. Use negative amounts to place sell orders.

  3. Managing your portfolio: You can use the context.portfolio object to manage your algorithm's portfolio. For example, you can use the context.portfolio.positions dictionary to get a dictionary of all the assets currently held in the portfolio, or use the context.portfolio.cash attribute to get the current cash balance of the portfolio. Remember, portfolio in this context means assets that the algorithm has bought, and is not the same as your Quadency account or portfolio.

  4. Using external data sources: You can use external data sources, such as market data or news feeds, to inform your trading decisions. Catalyst provides several APIs for integrating with external data sources, including the catalyst.data.bundles API, which provides access to historical market data, and the catalyst.data.alpaca API, which provides real-time market data and account information for the Alpaca trading platform.

  5. Implementing complex trading strategies: handle_data can be used to implement more complex trading strategies than just the simple ones shown in the previous example. For example, you could implement a mean reversion strategy that buys assets when they are oversold and sells them when they are overbought, or a momentum strategy that buys assets that are trending up and sells assets that are trending down.

Did this answer your question?