Skip to main content

A flexible, event-driven, multi-agent framework for building algorithmic trading strategies using the Alpaca API.

Project description

Trading Algo Framework

A flexible, event-driven, multi-agent framework for building algorithmic trading strategies using the Alpaca API.

Key Features

  • Multi-Agent Architecture: Build your strategy by combining independent, reusable agents.
  • Event-Driven: Agents communicate through an event bus, reacting to market data or other internal events.
  • Hybrid Agent Support: Supports both event-driven agents (reacting to market data) and periodic agents (running on a schedule).
  • Extensible: Easily create your own custom agents to encapsulate specific logic.
  • Alpaca Integration: Connects to Alpaca for market data streams and trade execution.
  • Live Performance Tracking: Includes a built-in agent for live PnL tracking with graphical visualization.

Core Concepts

  • Trading Hub: The central engine that manages the lifecycle of agents, and orchestrates the flow of data.
  • EventDrivenAgent: A base class for agents that react to market data events. The frequency of execution is controlled by a throttle.
  • PeriodicAgent: A base class for agents that run on a fixed schedule. The execution frequency is controlled by a period.
  • Communication Bus: A publish-subscribe system that allows agents to communicate with each other in a decoupled manner. Agents can publish events and subscribe to listen to events from other agents.
  • DataObject: A standardized container for data flowing through the communication bus.

Installation

You can install the trading-algo package directly from PyPI:

pip install trading-algo

Prerequisites

  • Python 3 3.9+

Configuration

This framework requires Alpaca API keys to connect to the market. You can provide these in two ways:

  1. Environment Variables (Recommended for Production): Set APCA_API_KEY_ID and APCA_API_SECRET_KEY in your environment. The TradingHub will automatically pick these up if no keys are explicitly provided.

  2. Directly to TradingHub (Recommended for Examples/Development): You can pass your API key and secret directly when initializing the TradingHub:

    from trading_algo import TradingHub
    trading_hub = TradingHub(api_key="YOUR_API_KEY", secret_key="YOUR_SECRET_KEY", paper=True)
    

    For examples, you might read these from a local config.ini file (as shown in the examples) or other local configuration.

Usage

The main entry point for a strategy is a script where you instantiate a TradingHub, add your desired agents, and start the hub.

Here's an example demonstrating a simple multi-agent strategy:

# examples/multi_agent_strategy.py

import asyncio
import os
import configparser
from loguru import logger

from trading_algo import TradingHub, Spotter, SpreadCalculator, DeltaHedger, Quoter, PerformanceTrackerAgent

async def main():
    """Main function to set up and run the algorithm."""
    logger.remove()
    logger.add("multi_agent_strategy.log", rotation="5 MB", level="DEBUG", catch=False)
    logger.add(sys.stderr, level="INFO")
    logger.info("Setting up the TradingHub and its agents.")

    # --- API Key Configuration ---
    # For examples, we'll try to read from config.ini first, then environment variables.
    # In a production setup, environment variables are recommended.
    api_key = os.getenv("APCA_API_KEY_ID")
    secret_key = os.getenv("APCA_API_SECRET_KEY")
    paper_trading = True # Set to False for live trading

    if not api_key or not secret_key:
        config = configparser.ConfigParser()
        config_path = os.path.join(os.path.dirname(__file__), '..', 'config.ini')
        if os.path.exists(config_path):
            config.read(config_path)
            try:
                api_key = config['alpaca']['api_key']
                secret_key = config['alpaca']['secret_key']
                logger.info("Alpaca API keys loaded from config.ini")
            except KeyError:
                logger.warning("API keys not found in config.ini. Please ensure [alpaca] section with api_key and secret_key exists.")
        else:
            logger.warning("config.ini not found. Attempting to use environment variables.")

    if not api_key or not secret_key:
        logger.error("Alpaca API keys not found in config.ini or environment variables (APCA_API_KEY_ID, APCA_API_SECRET_KEY). Please provide them.")
        return

    # 1. Initialize the core components
    trading_hub = TradingHub(api_key=api_key, secret_key=secret_key, paper=paper_trading)

    # 2. Define the instruments to trade
    instruments = ["AAPL", "MSFT"]

    # 3. Instantiate and add agents to the hub
    await trading_hub.add_agent(Spotter, {'instruments': instruments, 'throttle': '5s'})
    await trading_hub.add_agent(SpreadCalculator, {'instruments': instruments, 'throttle': '200ms'})
    await trading_hub.add_agent(DeltaHedger, {'period': '30s'})
    await trading_hub.add_agent(Quoter, {'instruments': instruments, 'period': '5s'})
    await trading_hub.add_agent(PerformanceTrackerAgent, {'period': '30s'}) # Added performance tracker

    # 4. Start the hub. This will run until interrupted.
    await trading_hub.start()


if __name__ == "__main__":
    asyncio.run(main())

To run the example strategy, execute the following command from the project root:

python examples/multi_agent_strategy.py

Creating a Custom Agent

You can easily create your own agents by inheriting from EventDrivenAgent or PeriodicAgent. The example below shows a simple PeriodicAgent that calculates and publishes a quote.

from trading_algo import PeriodicAgent, DataObject

class MyCustomQuoter(PeriodicAgent): # Renamed class to avoid conflict with example
    """
    A simple periodic agent that calculates and publishes quotes.
    """
    def __init__(self, config, data_cache, communication_bus):
        # Pass a 'period' for periodic execution
        super().__init__(config, data_cache, communication_bus, period='5s')
        self.last_spot_price = None

    async def initialize(self):
        # Subscribe to spot price events from other agents
        await self.communication_bus.subscribe_listener(
            "SPOT_PRICE('AAPL')",
            self.on_spot_price
        )

    async def on_spot_price(self, spot_price: DataObject):
        # Store the latest spot price
        self.last_spot_price = spot_price.get('value')

    async def run(self):
        # Core logic for the periodic agent
        if self.last_spot_price:
            # Calculate bid/ask
            bid_price = self.last_spot_price * 0.99
            ask_price = self.last_spot_price * 1.01
            
            # Publish the new quote on the communication bus
            quote_data = DataObject.create('quote', bid=bid_price, ask=ask_price)
            await self.communication_bus.publish("QUOTE('AAPL')", value=quote_data)
            print(f"Published quote for AAPL: Bid={bid_price:.2f}, Ask={ask_price:.2f}")

To use this agent, you would add it to the TradingHub in your main script:

await trading_hub.add_agent(MyCustomQuoter, {'period': '5s'})

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

trading_algo-0.1.2.tar.gz (18.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

trading_algo-0.1.2-py3-none-any.whl (20.5 kB view details)

Uploaded Python 3

File details

Details for the file trading_algo-0.1.2.tar.gz.

File metadata

  • Download URL: trading_algo-0.1.2.tar.gz
  • Upload date:
  • Size: 18.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.5

File hashes

Hashes for trading_algo-0.1.2.tar.gz
Algorithm Hash digest
SHA256 c7b65529fab98e528aafc55dd36e1529cbcb7268bc4faec013ed7bd4d5c4dc14
MD5 fa18c4c68ff3a02a0d601ea96079561e
BLAKE2b-256 6662f8a05ecbe47025016ea262d68823095b29b7236d7518b548f9a9ca3ea1ec

See more details on using hashes here.

File details

Details for the file trading_algo-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: trading_algo-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 20.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.5

File hashes

Hashes for trading_algo-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 92027fb525401bc9da20c2cae85f78a7cf3f78c25a9ed95ed25cdbabb7f2c8f6
MD5 4e962abcb8967e97adc9b70a567cbab6
BLAKE2b-256 18df59296439aebd9fc1f4e5f23e5a6b4c5b8de1cb57fd4a242eb0c6139f5fa6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page