The Complete Guide to DCA Bots: Dollar-Cost Averaging Automation
DCA (Dollar-Cost Averaging) bots automate the most proven long-term crypto investment strategy. Learn how to build and configure a DCA bot that buys BTC and ETH on schedule, regardless of market conditions.
Builder of AI agents, crypto trading bots, and open-source automation tools. Sharing practical guides on how to build, deploy, and profit from AI and DeFi technology.
Why DCA Is the Most Underrated Crypto Strategy
Timing the market is hard. Even professional traders consistently fail at it. Dollar-Cost Averaging (DCA) sidesteps this problem entirely: you invest a fixed amount at regular intervals, regardless of price.
The math works because:
- You buy more when prices are low
- You buy less when prices are high
- You average down your cost basis over time
- You remove emotion from the equation entirely
DCA Bitcoin from January 2018 to December 2023 (through two bear markets): +312% return vs. trying to time entries would have required near-perfect execution to outperform.
Building a Basic DCA Bot
import ccxt
import schedule
import time
from datetime import datetime
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger('DCA Bot')
class DCABot:
def __init__(self, exchange_id: str, api_key: str, secret: str):
exchange_class = getattr(ccxt, exchange_id)
self.exchange = exchange_class({
'apiKey': api_key,
'secret': secret,
'enableRateLimit': True,
})
self.orders_log = []
def buy(self, symbol: str, usd_amount: float):
"""Execute a DCA buy order"""
try:
# Get current price
ticker = self.exchange.fetch_ticker(symbol)
current_price = ticker['last']
# Calculate quantity (most exchanges need quantity in base currency)
quantity = usd_amount / current_price
# Round to exchange requirements
market = self.exchange.market(symbol)
quantity = self.exchange.amount_to_precision(symbol, quantity)
# Place market buy order
order = self.exchange.create_market_buy_order(
symbol=symbol,
amount=quantity,
params={'quoteOrderQty': usd_amount} # Binance: buy exactly $X worth
)
logger.info(f"โ
DCA BUY: {quantity} {symbol.split('/')[0]} @ ${current_price:,.2f}")
logger.info(f" Order ID: {order['id']}")
self.orders_log.append({
'timestamp': datetime.now().isoformat(),
'symbol': symbol,
'amount_usd': usd_amount,
'price': current_price,
'quantity': float(quantity),
'order_id': order['id'],
})
return order
except Exception as e:
logger.error(f"DCA buy failed for {symbol}: {e}")
raise
# Initialize bot
bot = DCABot('binance', API_KEY, API_SECRET)
# Schedule DCA purchases
DCA_SCHEDULE = [
{'symbol': 'BTC/USDT', 'amount': 100, 'frequency': 'weekly', 'day': 'monday'},
{'symbol': 'ETH/USDT', 'amount': 50, 'frequency': 'weekly', 'day': 'monday'},
{'symbol': 'SOL/USDT', 'amount': 25, 'frequency': 'weekly', 'day': 'wednesday'},
]
def run_dca_btc():
bot.buy('BTC/USDT', 100)
def run_dca_eth():
bot.buy('ETH/USDT', 50)
# Every Monday at 12:00 UTC
schedule.every().monday.at("12:00").do(run_dca_btc)
schedule.every().monday.at("12:01").do(run_dca_eth)
while True:
schedule.run_pending()
time.sleep(60)
Advanced DCA: Value Averaging
Value Averaging is DCA's smarter cousin โ you invest more when prices are low and less when they're high:
class ValueAveragingBot:
"""
Value Averaging: maintain a target portfolio growth rate.
If portfolio grew less than target โ buy more.
If portfolio grew more than target โ buy less (or sell).
"""
def __init__(self, target_monthly_growth_usd: float):
self.target_monthly_growth = target_monthly_growth_usd
self.target_value = 0
self.month = 0
def calculate_va_buy_amount(
self,
current_portfolio_value: float,
base_monthly_amount: float = 100
) -> float:
"""
Calculate how much to buy this period.
Returns positive = buy, negative = sell
"""
self.month += 1
self.target_value = self.month * self.target_monthly_growth
# How much do we need to invest to hit target?
required_investment = self.target_value - current_portfolio_value
# Cap at 3x normal DCA amount (don't over-invest in crashes)
max_buy = base_monthly_amount * 3
# Never invest more than 3x base or sell more than full position
return max(-current_portfolio_value, min(required_investment, max_buy))
def value_average_buy(bot: DCABot, symbol: str, va_bot: ValueAveragingBot):
portfolio_value = get_portfolio_value(symbol)
amount = va_bot.calculate_va_buy_amount(portfolio_value)
if amount > 10: # Minimum $10 buy
logger.info(f"VA Buy: ${amount:.2f} (portfolio: ${portfolio_value:.2f}, target: ${va_bot.target_value:.2f})")
bot.buy(symbol, amount)
elif amount < -50: # Only sell if > $50 above target
logger.info(f"VA Sell: ${abs(amount):.2f} โ portfolio exceeding target by {abs(amount):.2f}")
# sell_position(symbol, abs(amount))
Sentiment-Adjusted DCA
Combine DCA with Fear & Greed to buy more in fear:
import requests
def get_fear_greed_index() -> int:
"""Returns 0-100 (0=extreme fear, 100=extreme greed)"""
response = requests.get('https://api.alternative.me/fng/?limit=1')
return int(response.json()['data'][0]['value'])
def sentiment_adjusted_dca_amount(base_amount: float) -> float:
"""
Adjust DCA amount based on market sentiment.
Extreme fear โ buy 2x. Extreme greed โ buy 0.5x.
"""
fg = get_fear_greed_index()
if fg <= 20: # Extreme Fear
multiplier = 2.0
elif fg <= 40: # Fear
multiplier = 1.5
elif fg <= 60: # Neutral
multiplier = 1.0
elif fg <= 80: # Greed
multiplier = 0.75
else: # Extreme Greed
multiplier = 0.5
adjusted = base_amount * multiplier
logger.info(f"Fear & Greed: {fg} โ DCA multiplier {multiplier}x โ ${adjusted:.2f}")
return adjusted
Tracking DCA Performance
def calculate_dca_performance(orders: list[dict], current_price: float) -> dict:
"""Calculate current P&L from DCA orders"""
total_invested = sum(o['amount_usd'] for o in orders)
total_quantity = sum(o['quantity'] for o in orders)
current_value = total_quantity * current_price
avg_buy_price = total_invested / total_quantity
unrealized_pnl = current_value - total_invested
roi_pct = (current_value - total_invested) / total_invested * 100
return {
'total_invested': total_invested,
'total_quantity': total_quantity,
'avg_buy_price': avg_buy_price,
'current_value': current_value,
'unrealized_pnl': unrealized_pnl,
'roi_pct': roi_pct,
'num_orders': len(orders),
}
# Example output:
# Total invested: $5,200
# Average buy price: $52,847
# Current value: $7,150 (+$1,950, +37.5%)
# Orders executed: 52 (weekly for 1 year)
DCA Configuration Guide
| Strategy | Asset | Amount | Frequency | Best For | |----------|-------|--------|-----------|---------| | Conservative | BTC 80%, ETH 20% | $100/week | Weekly | Risk-averse long-term | | Balanced | BTC 60%, ETH 30%, SOL 10% | $200/week | Weekly | Moderate risk | | Aggressive | ETH 40%, SOL 30%, BTC 30% | $300/week | Weekly | Higher risk, alt exposure | | Sentiment-adjusted | BTC 70%, ETH 30% | $100-200/week | Weekly | Active but disciplined |
DCA is boring. That's the point. The bots that generate the best long-term returns for most people aren't the clever arbitrage systems โ they're the simple, consistent DCA bots that run for years.
Tagged in
Related Articles
How to Make $500/Month With a Crypto Telegram Signals Bot (Realistic Guide)
5 min read
Passive IncomeTop 10 Crypto Passive Income Strategies Ranked by Risk and Return in 2026
5 min read
Passive IncomeCrypto Airdrop Farming Bots: Automate the Most Profitable Strategy Nobody Talks About
5 min read
Passive IncomeHow to Make $1,000/Month with Automated Crypto Trading Bots (Realistic Guide)
5 min read