{"slug": "how-i-built-a-multi-chain-dex-trading-bot-with-hermes-agent-as-my-trading", "title": "How I Built a Multi-Chain DEX Trading Bot with Hermes Agent as My Trading Partner", "summary": "A developer built IYOP Trading Bot, an AI-powered multi-chain DEX trading bot that executes trades across Solana (Jupiter), Ethereum (Uniswap V3), and BSC (PancakeSwap V2). The bot uses MiMo v2 for market analysis, generates signals from multiple technical indicators, and manages risk with position sizing and drawdown protection, running as a FastAPI backend with a web dashboard.", "body_md": "*This is a submission for the Hermes Agent Challenge: Build With Hermes Agent*\n\nIYOP Trading Bot is an AI-powered multi-chain DEX trading bot that executes trades across Solana (Jupiter), Ethereum (Uniswap V3), and BSC (PancakeSwap V2). It uses MiMo v2 for market analysis, generates signals from multiple technical indicators, and manages risk with position sizing and drawdown protection.\n\nThe problem I was solving: decentralized trading is fragmented. Each chain has its own DEX, its own quirks, its own liquidity pools. Monitoring them manually is impossible. Executing trades across chains requires different SDKs, different gas management, different wallet handling.\n\nI needed a unified layer that could:\n\nAnd I needed Hermes Agent to make the development process fast enough to actually ship.\n\n**Live Demo:** [iyop-trading-terminal.vercel.app](https://iyop-trading-terminal.vercel.app)\n\n**Source:** [github.com/iyop666/iyop-trading-bot](https://github.com/iyop666/iyop-trading-bot)\n\nThe bot runs as a FastAPI backend with a web dashboard. Key features:\n\nHere are the core modules that Hermes Agent helped build:\n\nThe analyzer connects to IYOP v2 for fast market analysis, signal generation, and sentiment analysis:\n\n``` python\nimport httpx\nfrom dataclasses import dataclass\nfrom enum import Enum\n\nMIMO_API_URL = \"http://127.0.0.1:19911/v1/chat/completions\"\nMIMO_MODEL = \"gitlawb/mimo-v2-flash\"\n\nclass Signal(Enum):\n    BUY = \"buy\"\n    SELL = \"sell\"\n    HOLD = \"hold\"\n\n@dataclass\nclass MarketAnalysis:\n    signal: Signal\n    confidence: float\n    reasoning: str\n    risk_level: str\n\nasync def analyze_market(pair: str, timeframe: str) -> MarketAnalysis:\n    \"\"\"Send market data to MiMo v2 for analysis.\"\"\"\n    async with httpx.AsyncClient() as client:\n        response = await client.post(\n            MIMO_API_URL,\n            json={\n                \"model\": MIMO_MODEL,\n                \"messages\": [\n                    {\"role\": \"system\", \"content\": \"Analyze this trading pair...\"},\n                    {\"role\": \"user\", \"content\": f\"Pair: {pair}, Timeframe: {timeframe}\"}\n                ],\n                \"temperature\": 0.1\n            },\n            timeout=30\n        )\n        result = response.json()\n        return parse_analysis(result)\n```\n\nCombines multiple technical indicators with weighted scoring:\n\n``` python\nfrom dataclasses import dataclass\nfrom enum import Enum\n\nclass SignalType(Enum):\n    STRONG_BUY = \"strong_buy\"\n    BUY = \"buy\"\n    WEAK_BUY = \"weak_buy\"\n    HOLD = \"hold\"\n    WEAK_SELL = \"weak_sell\"\n    SELL = \"sell\"\n    STRONG_SELL = \"strong_sell\"\n\n@dataclass\nclass TradeSignal:\n    signal_type: SignalType\n    confidence: float  # 0.0 to 1.0\n    pair: str\n    price: float\n    indicators: dict\n    reasoning: str\n\ndef generate_signal(indicators: dict, ai_analysis: dict) -> TradeSignal:\n    \"\"\"Combine technical indicators with AI analysis.\"\"\"\n    weights = {\n        \"rsi\": 0.25,\n        \"macd\": 0.20,\n        \"bollinger\": 0.15,\n        \"volume\": 0.15,\n        \"ai_analysis\": 0.25\n    }\n\n    score = 0.0\n    for indicator, weight in weights.items():\n        score += normalize(indicators.get(indicator, 0)) * weight\n\n    signal_type = classify_signal(score)\n    return TradeSignal(\n        signal_type=signal_type,\n        confidence=abs(score),\n        pair=indicators[\"pair\"],\n        price=indicators[\"price\"],\n        indicators=indicators,\n        reasoning=build_reasoning(indicators, ai_analysis)\n    )\n```\n\nUnified interface for Jupiter, Uniswap V3, and PancakeSwap:\n\n``` python\nfrom enum import Enum\nimport httpx\n\nclass DEX(Enum):\n    JUPITER = \"jupiter\"      # Solana\n    UNISWAP = \"uniswap\"      # Ethereum\n    PANCAKESWAP = \"pancakeswap\"  # BSC\n\nclass Chain(Enum):\n    SOLANA = \"solana\"\n    ETHEREUM = \"ethereum\"\n    BSC = \"bsc\"\n\n@dataclass\nclass SwapResult:\n    success: bool\n    tx_hash: str\n    input_amount: float\n    output_amount: float\n    chain: Chain\n    dex: DEX\n    gas_used: float\n\nasync def execute_swap(\n    dex: DEX,\n    chain: Chain,\n    token_in: str,\n    token_out: str,\n    amount: float,\n    slippage: float = 0.5\n) -> SwapResult:\n    \"\"\"Execute a swap on the specified DEX.\"\"\"\n    if dex == DEX.JUPITER:\n        return await jupiter_swap(token_in, token_out, amount, slippage)\n    elif dex == DEX.UNISWAP:\n        return await uniswap_swap(token_in, token_out, amount, slippage)\n    elif dex == DEX.PANCAKESWAP:\n        return await pancakeswap_swap(token_in, token_out, amount, slippage)\n```\n\nPosition sizing and drawdown protection:\n\n```\n@dataclass\nclass RiskManager:\n    max_position_pct: float = 0.1  # 10% max per position\n    max_daily_loss: float = 0.05   # 5% max daily loss\n    max_drawdown: float = 0.15     # 15% max drawdown\n    current_drawdown: float = 0.0\n    daily_pnl: float = 0.0\n\n    def can_open_position(self, portfolio_value: float, position_size: float) -> bool:\n        \"\"\"Check if a new position is within risk limits.\"\"\"\n        # Check position size limit\n        if position_size / portfolio_value > self.max_position_pct:\n            return False\n\n        # Check daily loss limit\n        if self.daily_pnl < -(portfolio_value * self.max_daily_loss):\n            return False\n\n        # Check drawdown limit\n        if self.current_drawdown > self.max_drawdown:\n            return False\n\n        return True\n\n    def calculate_position_size(\n        self,\n        portfolio_value: float,\n        entry_price: float,\n        stop_loss: float\n    ) -> float:\n        \"\"\"Calculate optimal position size based on risk parameters.\"\"\"\n        risk_per_trade = portfolio_value * self.max_position_pct\n        price_risk = abs(entry_price - stop_loss) / entry_price\n        return risk_per_trade / price_risk if price_risk > 0 else 0\n```\n\nHandles order lifecycle with stop-loss and take-profit:\n\n```\nclass Side(str, Enum):\n    BUY = \"buy\"\n    SELL = \"sell\"\n\nclass OrderStatus(str, Enum):\n    PENDING = \"pending\"\n    FILLED = \"filled\"\n    CANCELLED = \"cancelled\"\n    SL_HIT = \"stop_loss_hit\"\n    TP_HIT = \"take_profit_hit\"\n\n@dataclass\nclass Position:\n    id: str\n    pair: str\n    side: Side\n    entry_price: float\n    current_price: float\n    size: float\n    stop_loss: float\n    take_profit: float\n    pnl: float\n    chain: Chain\n    dex: DEX\n\nclass Trader:\n    def __init__(self, risk_manager: RiskManager):\n        self.positions: dict[str, Position] = {}\n        self.risk_manager = risk_manager\n        self.trade_history: list[dict] = []\n\n    async def open_position(\n        self,\n        pair: str,\n        side: Side,\n        size: float,\n        stop_loss: float,\n        take_profit: float,\n        chain: Chain,\n        dex: DEX\n    ) -> Position:\n        \"\"\"Open a new position with risk checks.\"\"\"\n        if not self.risk_manager.can_open_position(self.portfolio_value, size):\n            raise RiskLimitExceeded(\"Position exceeds risk limits\")\n\n        # Execute the swap\n        result = await execute_swap(dex, chain, pair, size)\n\n        position = Position(\n            id=str(uuid.uuid4()),\n            pair=pair,\n            side=side,\n            entry_price=result.price,\n            current_price=result.price,\n            size=size,\n            stop_loss=stop_loss,\n            take_profit=take_profit,\n            pnl=0.0,\n            chain=chain,\n            dex=dex\n        )\n\n        self.positions[position.id] = position\n        return position\n```\n\nWhen I started building the trading bot, I described the requirements to Hermes:\n\n\"I need a multi-chain DEX trading bot with AI analysis, signal generation, risk management, and trade execution. It should support Jupiter, Uniswap V3, and PancakeSwap.\"\n\nHermes designed the module structure:\n\n`backend/ai/`\n\nfor AI analysis and signal generation`backend/core/`\n\nfor DEX integration, risk management, and trade executionThat architecture saved me hours of refactoring later.\n\nEach DEX has different APIs, different transaction formats, different gas estimation. Instead of reading docs for each one, I told Hermes:\n\n\"Write async swap functions for Jupiter, Uniswap V3, and PancakeSwap. Use httpx, handle errors, return transaction hashes.\"\n\nHermes generated the integration code for all three DEXs. I reviewed the error handling, adjusted the slippage parameters, and tested. What would have taken a full day of reading docs and writing boilerplate took 30 minutes.\n\nThe risk manager needed to handle position sizing, drawdown limits, and daily loss caps. I described the rules:\n\n\"Max 10% per position, max 5% daily loss, max 15% drawdown. Calculate position size based on stop-loss distance.\"\n\nHermes implemented the logic with proper edge cases. When I tested it with extreme values (100% loss scenarios), it correctly rejected the trades.\n\nCombining multiple indicators into a single signal required a weighting system. I asked Hermes:\n\n\"Create a signal generator that weights RSI (25%), MACD (20%), Bollinger (15%), Volume (15%), and AI analysis (25%). Normalize each to -1 to +1 range.\"\n\nHermes built the weighted scoring system with configurable weights. I later adjusted the AI analysis weight to 30% after testing showed it was the most predictive.\n\nWhen the bot was not executing trades correctly, I asked Hermes to trace the issue:\n\n\"Trades are not executing. Check the swap function, the risk manager, and the trade executor. Find the bottleneck.\"\n\nHermes read through the code, found that the risk manager was rejecting trades because the portfolio value was not being updated after each trade. One line fix, but finding it manually would have taken an hour of debugging.\n\nBuilding a trading bot requires:\n\nHermes handled all of these because it maintained context across the entire codebase. When I changed the risk manager, it automatically suggested updates to the trader. When I added a new DEX, it updated the signal generator to include the new chain.\n\nThat cross-module awareness is what made the difference between a prototype and a working bot.\n\n**Project Stats:**\n\n**Links:**", "url": "https://wpnews.pro/news/how-i-built-a-multi-chain-dex-trading-bot-with-hermes-agent-as-my-trading", "canonical_source": "https://dev.to/iyop666/how-i-built-a-multi-chain-dex-trading-bot-with-hermes-agent-as-my-trading-partner-14nf", "published_at": "2026-05-27 20:02:00+00:00", "updated_at": "2026-05-27 20:11:28.380380+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "artificial-intelligence", "ai-products", "ai-startups"], "entities": ["Hermes Agent", "IYOP Trading Bot", "Solana", "Jupiter", "Ethereum", "Uniswap V3", "BSC", "PancakeSwap V2"], "alternates": {"html": "https://wpnews.pro/news/how-i-built-a-multi-chain-dex-trading-bot-with-hermes-agent-as-my-trading", "markdown": "https://wpnews.pro/news/how-i-built-a-multi-chain-dex-trading-bot-with-hermes-agent-as-my-trading.md", "text": "https://wpnews.pro/news/how-i-built-a-multi-chain-dex-trading-bot-with-hermes-agent-as-my-trading.txt", "jsonld": "https://wpnews.pro/news/how-i-built-a-multi-chain-dex-trading-bot-with-hermes-agent-as-my-trading.jsonld"}}