The Scheduling Challenge for Trading Bots
Trading bots need to act on time:
- Check prices at specific intervals
- Rebalance portfolios at market open
- Execute strategies at predetermined times
- Harvest yields and compound rewards
- Generate end-of-day reports
But most trading bots run on serverless infrastructure (cheaper, simpler, no servers to manage). And serverless can't maintain its own timers.
CronSynth solves this by providing reliable, cryptographically-verified triggers on any schedule.
---Common Trading Bot Schedules
Price MonitoringSchedule: "*/5 * * * *" (every 5 minutes)
Action: Fetch prices, check conditions, alert if thresholds crossed
Portfolio Rebalancing
Schedule: "0 9 * * 1-5" (9 AM UTC weekdays)
Action: Calculate current allocation, compare to target, execute trades
Yield Harvesting (DeFi)
Schedule: "0 0 * * *" (daily at midnight)
Action: Claim rewards, compound into position, log results
Strategy Execution
Schedule: "0 14 * * *" (2 PM UTC daily)
Action: Run trading algorithm, execute generated signals
End-of-Day Summary
Schedule: "0 21 * * 1-5" (9 PM UTC weekdays, after US market close)
Action: Calculate P&L, generate report, send notification
---
Architecture Example
┌─────────────────────────────────────────────────────────┐
│ CronSynth │
│ Triggers on schedule with HMAC-signed webhooks │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Trading Bot Webhook │
│ Vercel / Lambda / Workers serverless function │
│ │
│ 1. Verify CronSynth signature │
│ 2. Fetch current market data │
│ 3. Run strategy logic │
│ 4. Execute trades via exchange API │
│ 5. Log results │
│ 6. Return acknowledgment │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Exchange APIs / DeFi Protocols │
│ Binance, Coinbase, Uniswap, Aave, etc. │
└─────────────────────────────────────────────────────────┘
---
Implementation Example: Price Alert Bot
A bot that checks Bitcoin price every 5 minutes and alerts if it crosses thresholds.
1. Create the Webhook Handler// api/price-check.ts
import crypto from 'crypto';
const ALERT_THRESHOLD_HIGH = 100000;
const ALERT_THRESHOLD_LOW = 80000;
export default async function handler(req, res) {
// Verify CronSynth signature
const signature = req.headers['x-cronsynth-signature'];
const secret = process.env.CRONSYNTH_WEBHOOK_SECRET;
const payload = JSON.stringify(req.body);
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
if (signature !== expected) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Fetch price
const response = await fetch(
'https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd'
);
const data = await response.json();
const btcPrice = data.bitcoin.usd;
// Check thresholds
let alert = null;
if (btcPrice > ALERT_THRESHOLD_HIGH) {
alert = BTC above $${ALERT_THRESHOLD_HIGH}: $${btcPrice};
} else if (btcPrice < ALERT_THRESHOLD_LOW) {
alert = BTC below $${ALERT_THRESHOLD_LOW}: $${btcPrice};
}
// Send alert if triggered
if (alert) {
await sendTelegramAlert(alert);
}
// Log and respond
console.log(Price check: BTC = $${btcPrice}, Alert: ${alert || 'none'});
return res.status(200).json({
ok: true,
price: btcPrice,
alert
});
}
2. Register with CronSynth
curl -X POST https://cronsynth.xyz/api/schedule \
-H "Content-Type: application/json" \
-H "X-402-Session: your-session" \
-d '{
"webhookUrl": "https://your-bot.vercel.app/api/price-check",
"cron": "*/5 * * * *",
"label": "btc-price-alert"
}'
---
Implementation Example: Portfolio Rebalancer
A bot that rebalances a crypto portfolio to target allocations daily.
// api/rebalance.ts
import { verifyCronSynthSignature } from '../lib/cronsynth';
import { getPortfolio, executeTrade } from '../lib/exchange';
const TARGET_ALLOCATION = {
BTC: 0.5, // 50%
ETH: 0.3, // 30%
USDC: 0.2 // 20%
};
const REBALANCE_THRESHOLD = 0.05; // 5% drift triggers rebalance
export default async function handler(req, res) {
if (!verifyCronSynthSignature(req)) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Get current portfolio
const portfolio = await getPortfolio();
const totalValue = Object.values(portfolio).reduce((a, b) => a + b, 0);
// Calculate current allocation
const currentAllocation = {};
for (const [asset, value] of Object.entries(portfolio)) {
currentAllocation[asset] = value / totalValue;
}
// Check if rebalancing needed
const trades = [];
for (const [asset, target] of Object.entries(TARGET_ALLOCATION)) {
const current = currentAllocation[asset] || 0;
const drift = Math.abs(current - target);
if (drift > REBALANCE_THRESHOLD) {
const targetValue = totalValue * target;
const currentValue = portfolio[asset] || 0;
const tradeValue = targetValue - currentValue;
trades.push({
asset,
action: tradeValue > 0 ? 'buy' : 'sell',
amount: Math.abs(tradeValue)
});
}
}
// Execute trades
const results = [];
for (const trade of trades) {
const result = await executeTrade(trade);
results.push(result);
}
return res.status(200).json({
ok: true,
rebalanced: trades.length > 0,
trades: results
});
}
---
Why CronSynth for Trading Bots?
1. ReliabilityMissed triggers mean missed opportunities (or worse, unmanaged risk). CronSynth's automatic retries ensure transient failures don't become missed executions.
2. SecurityTrading bot endpoints are high-value targets. HMAC signatures prevent attackers from triggering unauthorized trades by spoofing webhooks.
3. VerifiabilityOn-chain attestation creates an immutable record of when your bot executed. Useful for auditing, compliance, and debugging.
4. Cost EfficiencyPay-per-trigger pricing means you only pay when your bot runs. No idle server costs.
5. Platform IndependenceMove your bot between Vercel, AWS, Cloudflare, or any platform without changing your scheduling setup.
---Best Practices for Trading Bots
1. Verify Signatures AlwaysNever skip signature verification. Trading endpoints are high-value attack targets.
2. Implement Circuit BreakersIf something goes wrong, your bot should stop, not keep executing bad trades:
const recentErrors = await getRecentErrorCount();
if (recentErrors > 5) {
console.error('Too many recent errors, pausing bot');
return res.status(200).json({ ok: false, paused: true });
}
3. Log Everything
Trading requires auditability. Log every decision, every trade, every trigger:
await logExecution({
scheduleId: req.body.scheduleId,
runNumber: req.body.runNumber,
timestamp: new Date().toISOString(),
trades,
results
});
4. Use Idempotency Keys
Prevent duplicate trades from duplicate triggers:
const idempotencyKey = ${scheduleId}-${runNumber};
const existing = await checkIdempotencyKey(idempotencyKey);
if (existing) {
return res.status(200).json({ ok: true, skipped: true });
}
5. Test Thoroughly
Before running with real money, test your bot extensively with paper trading or testnets.
---Getting Started
1. Build your trading logic as a serverless function
2. Add CronSynth signature verification to protect the endpoint
3. Register your schedule via CronSynth API
4. Monitor executions via logs and the /api/schedules endpoint
[Read the full User Guide](/docs/guide) | [View API Reference](/docs/api)