Trade Executor

repository·master·Indexed 41 days ago

https://github.com/tradingstrategy-ai/trade-executor

A Python framework for algorithmic trading backtesting and live execution in the DeFi ecosystem. It supports decentralized exchanges like Uniswap and PancakeSwap, featuring a Generic Router for automated liquidity protocol selection, a webhook web server for monitoring, and integration with Pyodide and CCXT.

Tokens
143.8K
Snippets
309
Records
498
Agent score
99%

What's inside Trade Executor

  1. Overview of Trade Executor

    master
    Trade Executor is a Python framework designed for the backtesting and live execution of algorithmic trading strategies specifically on decentralized exchanges (DeFi). It supports decentralized markets like Uniswap and PancakeSwap and includes features for live trading, backtesting, and a webhook web server for integration with monitoring systems or JavaScript frontends.
  2. Overview of the Lagoon Lighter Manual Trade Tutorial

    master

    The manual-trade-executor-lighter.py tutorial is a live Ethereum-mainnet Python script designed to exercise the complete single-owner Lagoon/Lighter lifecycle. It is intended for real-money manual testing of the integration between Lagoon vaults, Safe-owned Lighter accounts, and the trade-executor engine.

    The lifecycle covered includes:

    1. Deployment: Deploying a Lagoon vault and activating its Safe-owned Lighter account via lagoon-deploy-vault.
    2. Initialization: Setting up trade-executor state and Lighter external exchange-account positions.
    3. Funding: Subscribing USDC to Lagoon and depositing it from the Safe to Lighter.
    4. Trading: Opening and closing small ETH-USD perpetual positions using Lighter API keys.
    5. Withdrawal: Securely withdrawing USDC from Lighter back to the Lagoon Safe.
    6. Redemption: Redeeming all deployer-owned Lagoon shares to return assets to the deployer.
  3. Understand the Trade-executor Vault Test Fix Plan

    master

    This document outlines the implementation plan to resolve issues identified during a 129-vault cross-chain simulation. The goal is to improve the reliability of vault simulations and diagnostics by correctly classifying failures (e.g., closed deposit windows, unsupported adapters, or capacity limits) rather than aiming for a 100% success rate.

    Key objectives include:

    • Executing synchronous vault flows via selected eth-defi deposit managers.
    • Settling asynchronous request trades without assuming standard ERC-4626 selectors.
    • Classifying unsupported adapters and closed deposit windows before pricing.
    • Bridging exact USDC proceeds from satellite vault redemptions.
    • Preserving transaction-evidence precedence during failed operations.
  4. Understand cross-chain vault simulation results and status codes

    master

    When running the vault matrix, the executor categorizes vault lifecycles into several terminal and non-terminal statuses. Understanding these helps distinguish between protocol-level issues and executor-level configuration issues.

    Success & Lifecycle States

    • Success (simulated): Deposit and redemption lifecycle completed successfully.
    • Deposit closed: The vault is currently on-chain but does not admit new deposits (e.g., Yearn maxDeposit=0).
    • Whitelisting needed: The simulated executor Safe is not admitted to the vault.

    Failure & Gap States

    • Simulation unsupported async: The redemption is asynchronous, and no Anvil driver was available to handle the pending ticket.
    • Transaction reverted: A home-chain or satellite redemption/deposit reverted on-chain.
    • Execution failed: Typed failures related to capacity, minimums, or preflight checks (e.g., redemption shares below minimum).
    • Broadcast failed: Reverts occurring during the settleDeposit() allowance phase (e.g., Lagoon).
    • Redemption unavailable: The protocol accepted the deposit but provides no redemption path (e.g., Plutus).
    • Adapter unsupported: The vault requires a specific manager (e.g., Upshift) that the current preflight logic is not routing correctly.
  5. Understand the Lighter NAV calculation and syncing

    master

    The trade-executor integrates Lighter positions into the Lagoon NAV syncing process via the ExchangeAccountSyncModel and LagoonVaultSyncModel.

    NAV Logic:

    • The system uses the Lighter exchange-account adapter to fetch total equity via fetch_lighter_total_equity().
    • The valuation uses the total asset value (collateral + unrealised PnL) rather than just the collateral amount.
    • Safe USDC is explicitly excluded from the exchange-account position to avoid double-counting.
    • Error Handling: If the public API returns negative equity, the system aborts the valuation and ensures no Lagoon valuation transaction is broadcast.
    • Syncing Workflow: The system reconciles the Lighter total asset value with the Safe's on-chain USDC balance to update the USD-denominated position and preserve valuation history.
  6. Understand the Lighter exchange account value and custody model

    master

    Lighter integration follows an external exchange-account model where capital resides in a Safe-owned account on Lighter. The Safe remains the owner and uses a guarded module to deposit USDC to Lighter or claim withdrawals back to the Safe. Trading is performed using a delegated Lighter API key registered in a specific numbered key slot.

    Valuation Logic

    The strategy universe contains a synthetic Lighter exchange-account pair. Its value is derived from Lighter's public total_asset_value (including collateral and unrealized PnL).

    The Lagoon NAV is calculated as:

    Safe native-USDC balance + public Lighter total equity + pending Lagoon settlement value

  7. Handle asynchronous vault settlement with manager-aware receipt selection

    master

    To support asynchronous vault settlement without relying on a global fixed-selector list, the system uses transaction tagging and request ordinals.

    Transaction Tagging

    At construction, every signed transaction must be tagged with a durable role:

    • vault_approval
    • vault_request

    Identity is maintained via the request ordinal and its position in the trade's transaction list. Do not use the transaction hash as the durable identity, as retry signing can change it. Instead, store the raw amount, owner, and direction required to reconstruct the eth-defi request.

    Settlement Workflow

    When vault_async_flow is detected before calling get_swap_transactions():

    1. Select all transactions tagged vault_request, ordered by their persisted request ordinal.
    2. Verify every selected request transaction has a successful receipt.
    3. Pass the ordered hash list to parse_deposit_transaction() or parse_redeem_transaction().
    4. Use the final request receipt for the lifecycle timestamp (unless the parsed ticket provides a more precise one).

    Compatibility and Migration

    • Use get_swap_transactions() only for non-async swaps and synchronous compatibility.
    • To upgrade legacy pending async trades (which lack roles), use the existing vault_request_tx_count to identify the final ordered request transactions, stamp the new roles, and persist the upgraded state before retrying.
    • New metadata should be stored in optional other_data fields to avoid schema migrations.
  8. Manage vault positions via CoW Swap

    master

    For certain vaults (specifically Lagoon vaults with CoW Swap integration enabled via TradingStrategyModuleV0), you can trade vault share tokens directly on the open market using CoW Swap. This bypasses the vault's internal deposit()/redeem() mechanisms.

    When to use CoW Swap:

    • The vault has a deposit queue or settlement delay (e.g., Lagoon vaults).
    • You need to acquire or exit shares immediately without waiting for settlement.
    • The vault share token has sufficient liquidity on DEXes (e.g., Uniswap, Balancer) that CoW Swap can route through.

    Important Considerations:

    • Liquidity: The share token must be traded on secondary markets.
    • Price Slippage: The market price on DEXes may differ from the vault's NAV-based share price. Always verify the price before executing.
    • Context: The vault object in the console refers to the Lagoon vault owning the strategy, not the target vault being traded.
    from tradeexecutor.ethereum.cowswap.swap_to_vault import (
        open_vault_position_cowswap,
        close_vault_position_cowswap,
    )
    
    # Open a new $100 position (or increase existing)
    open_vault_position_cowswap(
        locals(),
        vault_name="IPOR USDC Lending Optimizer",
        amount_usd=100.0,
    )
    
    # Close the entire position
    close_vault_position_cowswap(
        locals(),
        vault_name="IPOR USDC Lending Optimizer",
    )
    
    # Or reduce by selling a specific number of shares
    close_vault_position_cowswap(
        locals(),
        vault_name="IPOR USDC Lending Optimizer",
        shares_to_sell=50.0,
    )
  9. Understand the Async Vault Settlement Simulation Modes

    master

    When performing simulated redemption trials for vaults in trade-executor, the system uses an ordered fallback state machine to test if a vault can settle. These modes are used to distinguish between a vault that is naturally liquid/open and one that requires simulation concessions (like injected liquidity or status overrides) to succeed in a fork environment.

    All three modes are considered valid success results for the matrix, but they must be recorded distinctly to ensure the report does not falsely imply a live vault was liquid or open.

    The three simulation modes are:

    1. simulated_ok: The vault settles and claims/payouts against an unmodified fork (strict mode).
    2. simulated_liquidity_added: Used when strict mode fails due to a lack of redemption liquidity. The system injects the required fork-only liquidity on Anvil and then settles/claims/payouts. The record must include the injected raw amount, the original balance, and the shortfall.
    3. simulated_bypass_closed_status: Used when the prior modes are blocked by a closed, paused, capped, or admission/whitelist status. The system uses an Anvil-only state or policy override to settle/claim/payout. The record must include the exact bypassed status and the original preflight evidence.
  10. How automatic fork block resolution works

    master

    If you do not provide the --simulation-fork-block flag, the executor uses Automatic mode.

    In this mode, the system:

    1. Identifies the most recent naive UTC midnight at command setup.
    2. Resolves the latest block number at or before that timestamp for every selected chain using create_multi_provider_web3() and a timestamp binary search.
    3. Fails setup if a selected chain cannot resolve or serve that historical block (it will not silently fall back to a live tip).

    Provenance for these runs is recorded with fork_block_source set to automatic_midnight along with the selected midnight timestamp.

  11. Understand the Vault Test Result Contract

    master

    When performing vault tests, the system produces specific outcome results. Developers should use these typed outcomes to classify trade attempts. Every typed outcome must include a concise detail string. For capacity-related results, you must also include an outcome_data mapping containing the requested and available raw amounts in JSON-safe form to avoid requiring reporters to parse the detail string.

    New Outcomes

    • adapter_unsupported: The eth-defi submodule explicitly states the requested direction is not implemented.
    • redemption_capacity_limited: The requested immediate redemption exceeds current protocol capacity.
    • async_request_only: The configured simulation confirmed an async request without requesting its full lifecycle.

    Existing Outcomes

    • deposit_closed: Known closed deposit window, paused deposit, or zero current deposit capacity.
    • redemption_unavailable: Known closed redemption window.
    • simulation_unsupported_async: A full async lifecycle was requested but no safe Anvil settlement driver is available.
    • receipt_analysis_failed: A mined status-1 transaction exists, but the protocol adapter cannot produce a valid flow analysis.
    • execution_failed: No more specific typed or evidence-based outcome applies.
    {
      "result": "redemption_capacity_limited",
      "detail": "Immediate redemption capacity is below the requested amount",
      "outcome_data": {
        "direction": "redeem",
        "requested_raw_amount": "907757",
        "available_raw_amount": "45388"
      }
    }