Adding a New Exchange

To add a custom exchange to the project, follow these guidelines and requirements. Every custom exchange must be implemented as a class that extends the BaseExchange class and should adhere to the directory and naming conventions outlined below.

Directory Structure

  1. Create a directory for your custom exchange inside custom_modules/exchanges/:

    custom_modules/exchanges/<name of your exchange>/
  2. Your exchange implementation must be contained in a file named exchange.py.

Implementing a Custom Exchange

  1. Class Definition:

    • Every exchange class must be named Exchange and should extend from the BaseExchange class.

    • Here's a basic example of what a custom exchange implementation might look like:

    from ats.exchanges.base_exchange import BaseExchange
    
    class Exchange(BaseExchange):
        def validate_config(self) -> None:
            # Add your custom configuration validation logic here
            pass
    
        def connect(self) -> None:
            # Add logic to establish a connection with the exchange
            pass
    
        def disconnect(self) -> None:
            # Add logic to disconnect from the exchange
            pass
    
        def submit_order(self, order: Order) -> None:
            # Logic to submit an order
            pass
    
        def cancel_order(self, order: Order) -> None:
            # Logic to cancel an order
            pass
    
        def get_order(self, order_id) -> Union[Order, None]:
            # Retrieve an order based on its ID
            pass
    
        def get_wallet_balance(self) -> Dict[str, AssetBalance]:
            # Get wallet balances as a dictionary of AssetBalance objects
            pass
    
        def get_fees(self) -> Tuple[float, float]:
            # Retrieve maker and taker fees
            pass
    
        def is_back_trading(self) -> bool:
            # Return True if the exchange is used for backtrading, otherwise False
            pass
  2. Requirements:

    • Ensure your class implements all abstract methods defined in BaseExchange. These include:

      • validate_config(): Responsible for validating the configuration provided for the exchange. Raise ConfigValidationException if any required configuration is missing or invalid.

      • connect(): Establishes a connection with the exchange.

      • disconnect(): Terminates the connection with the exchange.

      • submit_order(order: Order): Submits an order to the exchange.

      • cancel_order(order: Order): Cancels a specific order on the exchange.

      • get_order(order_id): Retrieves details of an order using its order ID.

      • get_wallet_balance(): Retrieves wallet balances as a dictionary of AssetBalance objects.

      • get_fees(): Fetches the maker and taker fee rates.

      • is_back_trading(): Indicates whether the exchange is used for backtrading (simulated trading) or live trading. Returns True if it is a backtrading exchange, otherwise False.

    • You may also override other methods from BaseExchange as needed.

Configuration Validation

To ensure your exchange works correctly, configurations must be validated using validate_config(). The BaseExchange class provides a _validate_base_configs() method to validate essential configuration properties. Custom exchanges should extend this functionality as needed to enforce exchange-specific configuration requirements.

By following these guidelines, your custom exchange will be properly integrated into the project, ensuring compatibility and adherence to project conventions. This structure allows for consistent, maintainable, and extensible exchange integration within the system.

Notes on Plotting Data

The BaseExchange class provides mechanisms for plotting data through the PlotData object. If you need to visualize events like order placements or completed trades, make use of the provided plot topics and methods. Ensure to call methods like self._plot_data.add() to populate plot data based on exchange activity.

Last updated