DCA (Dollar-Cost Averaging)
Buy a fixed amount of a token at regular intervals regardless of price. The simplest strategy to implement. Example: buy 0.1 ETH worth of USDC every hour.
Last updated:
A crypto trading bot needs three things: a price signal, swap execution, and safety checks. swapapi handles execution — one GET request returns executable calldata across 46 EVM chains, no API key required. This guide shows how to build a complete trading bot from scratch.
Architecture
A trading bot is a pipeline: data comes in, decisions are made, trades are executed, and results are monitored.
Monitor token prices via CoinGecko, on-chain oracles, or DEX prices
Decide when and what to trade: arbitrage, DCA, rebalancing
Get optimal route and executable calldata from swapapi
Sign and submit the transaction on-chain
Track results, handle failures, log P&L
Step 1
Your strategy determines everything else — what data you need, how often you trade, and what safety checks matter most.
Buy a fixed amount of a token at regular intervals regardless of price. The simplest strategy to implement. Example: buy 0.1 ETH worth of USDC every hour.
Maintain a target portfolio ratio (e.g., 60% ETH / 40% USDC). When one asset exceeds its target by a threshold, sell the excess to rebalance.
Buy where price is lower, sell where it is higher. swapapi is single-chain, so this works for cross-DEX arbitrage on the same chain — the aggregator already finds the best route.
Trade based on external signals: technical indicators, social sentiment, oracle price feeds, or on-chain events. Your bot watches for signals and executes when conditions are met.
Step 2
A single GET request returns the optimal route, expected output, price impact, and ready-to-execute calldata.
$ curl "https://api.swapapi.dev/v1/swap/1?\ tokenIn=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE&\ tokenOut=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48&\ amount=100000000000000000&\ sender=0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
tx.to, tx.data, and tx.value. No additional encoding needed.rpcUrl field, so you don't need a separate RPC provider.Step 3
Safety checks are what separate a working bot from one that loses money. Never skip these.
priceImpact < -0.05 (worse than -5%). Large price impact means you are moving the market against yourself.eth_call to check if it would revert. This costs no gas.Step 4
Complete working examples in TypeScript and Python. Copy, customize the strategy parameters, and run.
// TypeScript DCA Bot — buys USDC with ETH every hour // Dependencies: npm install viem import { createWalletClient, http, parseEther } from "viem"; import { mainnet } from "viem/chains"; import { privateKeyToAccount } from "viem/accounts"; const SWAP_API = "https://api.swapapi.dev/v1/swap"; const CHAIN_ID = 1; const ETH = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; const USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"; const AMOUNT = parseEther("0.1").toString(); // 0.1 ETH per trade const SENDER = "0xYourWalletAddress"; const MAX_PRICE_IMPACT = -0.05; async function dcaBuy() { // 1. Get swap quote const url = `${SWAP_API}/${CHAIN_ID}?` + new URLSearchParams({ tokenIn: ETH, tokenOut: USDC, amount: AMOUNT, sender: SENDER, }); const res = await fetch(url); const { success, data } = await res.json(); if (!success) { console.error("API error"); return; } if (data.status !== "Successful") { console.error(`Status: ${data.status}`); return; } // 2. Safety check if (data.priceImpact < MAX_PRICE_IMPACT) { console.error(`Price impact too high: ${data.priceImpact}`); return; } // 3. Execute const account = privateKeyToAccount("0x..."); const client = createWalletClient({ account, chain: mainnet, transport: http(data.rpcUrl), }); const hash = await client.sendTransaction({ to: data.tx.to, data: data.tx.data, value: BigInt(data.tx.value ?? "0"), }); console.log(`DCA buy executed: ${hash}`); console.log(`Expected: ${data.expectedAmountOut} USDC (raw)`); } // Run every hour setInterval(dcaBuy, 60 * 60 * 1000); dcaBuy(); // Run immediately
# Python Rebalancing Bot — maintains 60/40 ETH/USDC ratio # Dependencies: pip install requests web3 import requests from web3 import Web3 import time SWAP_API = "https://api.swapapi.dev/v1/swap" CHAIN_ID = 1 ETH = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" SENDER = "0xYourWalletAddress" TARGET_ETH_RATIO = 0.6 # 60% ETH, 40% USDC def get_swap_quote(token_in, token_out, amount): """Get swap quote from swapapi — no API key needed.""" response = requests.get( f"{SWAP_API}/{CHAIN_ID}", params={ "tokenIn": token_in, "tokenOut": token_out, "amount": str(amount), "sender": SENDER, }, timeout=15, ) result = response.json() if not result["success"]: raise Exception(f"API error: {result['error']}") return result["data"] def check_and_rebalance(): """Check portfolio balance and rebalance if needed.""" w3 = Web3(Web3.HTTPProvider("https://eth.llamarpc.com")) eth_balance = w3.eth.get_balance(SENDER) # ... check USDC balance, calculate ratios # ... if ratio deviates > 5%, execute rebalance swap quote = get_swap_quote(ETH, USDC, amount_to_sell) if quote["status"] != "Successful": print(f"No route: {quote['status']}") return if quote["priceImpact"] < -0.05: print(f"Price impact too high: {quote['priceImpact']}") return # Execute the swap tx = { "from": SENDER, "to": Web3.to_checksum_address(quote["tx"]["to"]), "data": quote["tx"]["data"], "value": int(quote["tx"].get("value", "0")), } # ... sign and send # Run every 15 minutes while True: check_and_rebalance() time.sleep(900)
Step 5
A bot that works in testing can still fail in production. These are the things that matter when real money is on the line.
UPSTREAM_ERROR (502) with exponential backoff. Don't retry INVALID_PARAMS (400) — those are bugs in your code.eth_estimateGas plus a 20% buffer. On EIP-1559 chains, let your library (viem, ethers, web3.py) handle gas pricing automatically.// Exponential backoff for transient errors async function fetchWithRetry(url: string, maxRetries = 3) { for (let i = 0; i < maxRetries; i++) { const res = await fetch(url); const json = await res.json(); if (json.success) return json.data; // Don't retry client errors (400) — fix your code if (res.status === 400) throw new Error(json.error); // Retry server errors (502) with backoff if (res.status === 502) { const delay = 1000 * Math.pow(2, i); // 1s, 2s, 4s await new Promise(r => setTimeout(r, delay)); continue; } throw new Error(`Unexpected status: ${res.status}`); } throw new Error("Max retries exceeded"); }
Next steps
Side-by-side comparison of swapapi, 1inch, 0x, Li.Fi, and more. See which fits your bot's needs.
Understand price impact, slippage tolerance, and how to set safe parameters for automated trading.
Full list of supported chains with chain IDs, native tokens, and key token addresses.
How to integrate swapapi into AI agents and autonomous systems. No API key, no credentials.