@balchemyai/agent-sdk 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +48 -0
- package/README.md +12 -12
- package/dist/agent-loop/agent-loop.d.ts +11 -0
- package/dist/agent-loop/agent-loop.d.ts.map +1 -1
- package/dist/agent-loop/agent-loop.js +57 -5
- package/dist/agent-loop/agent-loop.js.map +1 -1
- package/dist/agent-loop/llm-cost-tracker.d.ts +2 -0
- package/dist/agent-loop/llm-cost-tracker.d.ts.map +1 -1
- package/dist/agent-loop/llm-cost-tracker.js +7 -0
- package/dist/agent-loop/llm-cost-tracker.js.map +1 -1
- package/dist/agent-loop/rule-checker.d.ts +45 -0
- package/dist/agent-loop/rule-checker.d.ts.map +1 -0
- package/dist/agent-loop/rule-checker.js +72 -0
- package/dist/agent-loop/rule-checker.js.map +1 -0
- package/dist/agent-loop/types.d.ts +5 -0
- package/dist/agent-loop/types.d.ts.map +1 -1
- package/dist/agent-loop/types.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/docs/BEHAVIOR_RULES.md +184 -0
- package/docs/DEPLOYMENT.md +195 -0
- package/docs/QUICKSTART.md +123 -0
- package/docs/error-retry-strategy.md +27 -0
- package/docs/examples/custom-strategy.yaml +73 -0
- package/docs/examples/dca-accumulator.yaml +41 -0
- package/docs/examples/memecoin-sniper.yaml +47 -0
- package/docs/examples/swing-trader.yaml +50 -0
- package/docs/partner-integration-checklist.md +32 -0
- package/docs/python-parity-backlog.md +20 -0
- package/docs/release-policy.md +24 -0
- package/package.json +3 -4
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# Behavior Rules (BRL) — YAML Reference
|
|
2
|
+
|
|
3
|
+
Behavior rules define how your agent trades. They are validated by the Balchemy
|
|
4
|
+
backend before any trade is executed. The agent's LLM reads a compressed summary
|
|
5
|
+
of your rules as context for every decision.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Where to set rules
|
|
10
|
+
|
|
11
|
+
**In `agent.config.yaml`** (inline):
|
|
12
|
+
|
|
13
|
+
```yaml
|
|
14
|
+
behavior_rules:
|
|
15
|
+
version: "1"
|
|
16
|
+
preset: custom
|
|
17
|
+
risk:
|
|
18
|
+
max_single_trade_usd: 50
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**As a separate file** (referenced by path):
|
|
22
|
+
|
|
23
|
+
```yaml
|
|
24
|
+
behavior_rules_path: ./my-rules.yaml
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Schema
|
|
30
|
+
|
|
31
|
+
### Top-level fields
|
|
32
|
+
|
|
33
|
+
| Field | Type | Required | Description |
|
|
34
|
+
|-------|------|----------|-------------|
|
|
35
|
+
| `version` | string | Yes | Rule schema version. Always `"1"`. |
|
|
36
|
+
| `preset` | string | No | Base preset to inherit (`memecoin-sniper`, `dca-accumulator`, `swing-trader`, `custom`). Inline fields override preset defaults. |
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
### `risk` — global safety limits
|
|
41
|
+
|
|
42
|
+
```yaml
|
|
43
|
+
risk:
|
|
44
|
+
max_single_trade_usd: 50 # Hard cap per trade. Default: 50
|
|
45
|
+
max_daily_loss_usd: 200 # Pause trading after this daily loss. Default: 500
|
|
46
|
+
max_open_positions: 5 # Max simultaneous positions. Default: 10
|
|
47
|
+
pause_on_drawdown_pct: 20 # Pause if portfolio drops this % from peak. Default: none
|
|
48
|
+
allowed_chains: [solana] # Restrict to specific chains. Default: [solana, base]
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
### `filters` — asset eligibility
|
|
54
|
+
|
|
55
|
+
```yaml
|
|
56
|
+
filters:
|
|
57
|
+
min_liquidity_usd: 10000 # Reject tokens below this liquidity. Default: 5000
|
|
58
|
+
max_market_cap_usd: 10000000 # Reject tokens above this market cap. Default: none
|
|
59
|
+
require_verified_contract: false # Only trade verified contracts. Default: false
|
|
60
|
+
blocked_tokens: # Token addresses to never trade
|
|
61
|
+
- "So11111111111111111111111111111111111111112"
|
|
62
|
+
allowed_tokens: # Allowlist (if set, only these tokens trade)
|
|
63
|
+
- "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
### `entry` — trade entry conditions
|
|
69
|
+
|
|
70
|
+
```yaml
|
|
71
|
+
entry:
|
|
72
|
+
trigger: launch_signal # launch_signal | price_drop | rsi_signal | manual
|
|
73
|
+
max_position_usd: 100 # Max USD per position. Default: 50
|
|
74
|
+
slippage_bps: 200 # Max slippage in basis points. Default: 100
|
|
75
|
+
min_confidence: 0.7 # Min LLM confidence score to enter. Default: 0.5
|
|
76
|
+
indicators: [rsi, macd] # Required indicators for entry. Default: []
|
|
77
|
+
rsi_oversold: 30 # Enter when RSI below this value. Default: 30
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
### `exit` — trade exit conditions
|
|
83
|
+
|
|
84
|
+
```yaml
|
|
85
|
+
exit:
|
|
86
|
+
take_profit_pct: 50 # Close position when up this %. Default: none
|
|
87
|
+
stop_loss_pct: 25 # Close position when down this %. Default: none
|
|
88
|
+
trailing_stop_pct: 10 # Trailing stop loss. Default: none
|
|
89
|
+
max_hold_minutes: 120 # Force exit after this many minutes. Default: none
|
|
90
|
+
min_hold_hours: 1 # Do not exit before this time. Default: 0
|
|
91
|
+
max_hold_hours: 72 # Force exit after this time. Default: none
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
### `dca` — dollar-cost averaging (DCA preset)
|
|
97
|
+
|
|
98
|
+
```yaml
|
|
99
|
+
dca:
|
|
100
|
+
target_token: SOL # Token to accumulate
|
|
101
|
+
amount_usd: 10 # USD per interval purchase
|
|
102
|
+
interval_hours: 24 # Purchase interval in hours
|
|
103
|
+
max_total_usd: 1000 # Stop after this total invested. Default: none
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Preset defaults
|
|
109
|
+
|
|
110
|
+
### memecoin-sniper
|
|
111
|
+
|
|
112
|
+
```yaml
|
|
113
|
+
behavior_rules:
|
|
114
|
+
version: "1"
|
|
115
|
+
preset: memecoin-sniper
|
|
116
|
+
filters:
|
|
117
|
+
min_liquidity_usd: 10000
|
|
118
|
+
max_market_cap_usd: 5000000
|
|
119
|
+
require_verified_contract: false
|
|
120
|
+
entry:
|
|
121
|
+
trigger: launch_signal
|
|
122
|
+
max_position_usd: 50
|
|
123
|
+
slippage_bps: 300
|
|
124
|
+
exit:
|
|
125
|
+
take_profit_pct: 100
|
|
126
|
+
stop_loss_pct: 50
|
|
127
|
+
max_hold_minutes: 60
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### dca-accumulator
|
|
131
|
+
|
|
132
|
+
```yaml
|
|
133
|
+
behavior_rules:
|
|
134
|
+
version: "1"
|
|
135
|
+
preset: dca-accumulator
|
|
136
|
+
dca:
|
|
137
|
+
target_token: SOL
|
|
138
|
+
amount_usd: 10
|
|
139
|
+
interval_hours: 24
|
|
140
|
+
max_total_usd: 1000
|
|
141
|
+
risk:
|
|
142
|
+
max_single_trade_usd: 10
|
|
143
|
+
pause_on_drawdown_pct: 30
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### swing-trader
|
|
147
|
+
|
|
148
|
+
```yaml
|
|
149
|
+
behavior_rules:
|
|
150
|
+
version: "1"
|
|
151
|
+
preset: swing-trader
|
|
152
|
+
entry:
|
|
153
|
+
indicators: [rsi, macd]
|
|
154
|
+
rsi_oversold: 30
|
|
155
|
+
max_position_usd: 200
|
|
156
|
+
slippage_bps: 100
|
|
157
|
+
exit:
|
|
158
|
+
take_profit_pct: 20
|
|
159
|
+
stop_loss_pct: 10
|
|
160
|
+
min_hold_hours: 2
|
|
161
|
+
max_hold_hours: 72
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Enforcement
|
|
167
|
+
|
|
168
|
+
Rules are enforced at three levels:
|
|
169
|
+
|
|
170
|
+
1. **Pre-check** — asset filters applied before the LLM is called (no LLM cost)
|
|
171
|
+
2. **LLM context** — compressed rule summary injected into every decision prompt
|
|
172
|
+
3. **Post-check** — Balchemy backend validates trade parameters against rules before execution
|
|
173
|
+
|
|
174
|
+
If a trade violates a rule at any level, it is rejected with an error logged via `onError`.
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Tips
|
|
179
|
+
|
|
180
|
+
- Start with a preset and override only the fields you need
|
|
181
|
+
- Keep `max_single_trade_usd` low (≤ $50) until you trust your strategy
|
|
182
|
+
- Use `blocked_tokens` to exclude known scams
|
|
183
|
+
- Use `min_confidence` to reduce false positives when LLM is uncertain
|
|
184
|
+
- Monitor LLM cost with `onStatusChange` — `llmCostToday` / `maxDailyLlmCost`
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# Deployment Guide
|
|
2
|
+
|
|
3
|
+
Your agent runs as a long-lived Node.js process. The recommended deployment targets
|
|
4
|
+
are a personal VPS ($4–7/mo) or a managed container platform (Railway, Render).
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Option A: Docker on a VPS (recommended)
|
|
9
|
+
|
|
10
|
+
This is the most reliable option. The agent runs in a Docker container that restarts
|
|
11
|
+
automatically on failure or reboot.
|
|
12
|
+
|
|
13
|
+
### Requirements
|
|
14
|
+
|
|
15
|
+
- Any Linux VPS with Docker installed (Ubuntu 22.04 LTS recommended)
|
|
16
|
+
- At least 256 MB RAM, 1 vCPU
|
|
17
|
+
- Providers: DigitalOcean, Hetzner, Vultr, Linode — all work fine
|
|
18
|
+
|
|
19
|
+
### Steps
|
|
20
|
+
|
|
21
|
+
**1. On your local machine:**
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npx create-balchemy-agent # Setup wizard
|
|
25
|
+
npx balchemy-agent docker # Generate Dockerfile + docker-compose.yml
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
This creates:
|
|
29
|
+
```
|
|
30
|
+
Dockerfile
|
|
31
|
+
docker-compose.yml
|
|
32
|
+
.env.example ← copy to .env, fill in credentials
|
|
33
|
+
agent.config.yaml ← edit behavior_rules as needed
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**2. Copy files to your VPS:**
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
scp Dockerfile docker-compose.yml agent.config.yaml .env user@your-vps:/home/user/agent/
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**3. On your VPS:**
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
cd /home/user/agent
|
|
46
|
+
docker compose up -d
|
|
47
|
+
docker compose logs -f # Watch logs
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**4. Verify the agent is running:**
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
docker compose ps
|
|
54
|
+
# balchemy-agent Up (healthy)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Managing the agent
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
docker compose stop # Graceful stop
|
|
61
|
+
docker compose start # Start after stop
|
|
62
|
+
docker compose restart # Restart
|
|
63
|
+
docker compose logs -f # Tail logs
|
|
64
|
+
docker compose pull && docker compose up -d # Update
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Updating config without rebuilding
|
|
68
|
+
|
|
69
|
+
The `agent.config.yaml` is mounted read-only into the container. Edit it on the
|
|
70
|
+
VPS and restart:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
nano agent.config.yaml
|
|
74
|
+
docker compose restart
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Option B: Railway
|
|
80
|
+
|
|
81
|
+
Railway provides free-tier hosting for small containers.
|
|
82
|
+
|
|
83
|
+
1. Push your agent directory to a GitHub repo (exclude `.env`)
|
|
84
|
+
2. Create a new Railway project → Deploy from GitHub
|
|
85
|
+
3. Set environment variables in Railway dashboard:
|
|
86
|
+
- `MCP_ENDPOINT`, `BALCHEMY_API_KEY`, `LLM_API_KEY`
|
|
87
|
+
4. Railway auto-detects `Dockerfile` and builds the image
|
|
88
|
+
5. Set restart policy to "Always"
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Option C: Render
|
|
93
|
+
|
|
94
|
+
Similar to Railway. Use Render's "Background Worker" service type (not Web Service).
|
|
95
|
+
|
|
96
|
+
1. Connect your GitHub repo
|
|
97
|
+
2. Select "Background Worker" (no port required)
|
|
98
|
+
3. Set environment variables in Render dashboard
|
|
99
|
+
4. Set "Restart Policy" to "Always"
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Option D: systemd daemon (Linux without Docker)
|
|
104
|
+
|
|
105
|
+
If you prefer to run the agent directly as a system service:
|
|
106
|
+
|
|
107
|
+
**1. Install globally:**
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
npm install -g create-balchemy-agent @balchemy/agent-sdk
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**2. Create a systemd unit file:**
|
|
114
|
+
|
|
115
|
+
```ini
|
|
116
|
+
# /etc/systemd/system/balchemy-agent.service
|
|
117
|
+
[Unit]
|
|
118
|
+
Description=Balchemy Trading Agent
|
|
119
|
+
After=network.target
|
|
120
|
+
|
|
121
|
+
[Service]
|
|
122
|
+
Type=simple
|
|
123
|
+
User=ubuntu
|
|
124
|
+
WorkingDirectory=/home/ubuntu/agent
|
|
125
|
+
ExecStart=/usr/bin/balchemy-agent start /home/ubuntu/agent/agent.config.yaml
|
|
126
|
+
EnvironmentFile=/home/ubuntu/agent/.env
|
|
127
|
+
Restart=always
|
|
128
|
+
RestartSec=10
|
|
129
|
+
StandardOutput=journal
|
|
130
|
+
StandardError=journal
|
|
131
|
+
|
|
132
|
+
[Install]
|
|
133
|
+
WantedBy=multi-user.target
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**3. Enable and start:**
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
sudo systemctl daemon-reload
|
|
140
|
+
sudo systemctl enable balchemy-agent
|
|
141
|
+
sudo systemctl start balchemy-agent
|
|
142
|
+
sudo journalctl -u balchemy-agent -f
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Security checklist
|
|
148
|
+
|
|
149
|
+
- `.env` must have permissions `600`: `chmod 600 .env`
|
|
150
|
+
- Never expose `agent.config.yaml` or `.env` via HTTP
|
|
151
|
+
- Use a non-root user inside the container (default Dockerfile uses `node` user)
|
|
152
|
+
- Rotate API keys regularly in Hub > Agents > API Keys
|
|
153
|
+
- Set `max_single_trade_usd` and `max_daily_loss_usd` to safe values before deploying
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Monitoring
|
|
158
|
+
|
|
159
|
+
The agent logs to stdout in this format:
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
[agent] status=running events=42 decisions=7 trades=2 llmCost=$0.0120/5.00
|
|
163
|
+
[agent] decision action=buy token=SOL amount=10 confidence=0.87
|
|
164
|
+
[agent] error: trade_command failed: insufficient balance
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
To forward logs to a log aggregator (e.g., Loki, Datadog):
|
|
168
|
+
|
|
169
|
+
```yaml
|
|
170
|
+
# In docker-compose.yml
|
|
171
|
+
logging:
|
|
172
|
+
driver: loki
|
|
173
|
+
options:
|
|
174
|
+
loki-url: "http://your-loki-host:3100/loki/api/v1/push"
|
|
175
|
+
loki-labels: "service=balchemy-agent"
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Troubleshooting
|
|
181
|
+
|
|
182
|
+
**Agent exits immediately:**
|
|
183
|
+
- Check `.env` — all required vars must be set
|
|
184
|
+
- Check `agent.config.yaml` — `mcp_endpoint` and `api_key` are required
|
|
185
|
+
- Run `docker compose logs` to see the error
|
|
186
|
+
|
|
187
|
+
**Agent starts but makes no decisions:**
|
|
188
|
+
- Verify your API key has `trade` scope (Hub > API Keys > Scopes)
|
|
189
|
+
- Check that your agent has a funded wallet
|
|
190
|
+
- Lower `min_confidence` in `behavior_rules`
|
|
191
|
+
|
|
192
|
+
**Budget exhausted quickly:**
|
|
193
|
+
- Reduce `max_daily_usd` in `llm` config
|
|
194
|
+
- Switch to a cheaper model (`claude-haiku-4-5` or `gpt-4o-mini`)
|
|
195
|
+
- Add more specific filters to avoid processing low-quality signals
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Balchemy Agent — Quickstart
|
|
2
|
+
|
|
3
|
+
Get an autonomous trading agent running in under 5 minutes.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
- Node.js 18+ (or Docker)
|
|
10
|
+
- A Balchemy account with at least one agent created in the Hub
|
|
11
|
+
- An API key from Hub > Agents > your agent > API Keys
|
|
12
|
+
- An LLM API key (Anthropic or OpenAI)
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Step 1: Create an agent in the Hub
|
|
17
|
+
|
|
18
|
+
1. Go to [balchemy.ai](https://balchemy.ai) and sign in
|
|
19
|
+
2. Open Hub > Agents > New Agent
|
|
20
|
+
3. Complete the setup wizard (wallets, trading config, connect)
|
|
21
|
+
4. Copy the MCP endpoint from the API tab: `https://api.balchemy.ai/mcp/YOUR_PUBLIC_ID`
|
|
22
|
+
5. Generate an API key and copy it (shown once)
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Step 2: Run the setup wizard
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npx create-balchemy-agent
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
The wizard asks:
|
|
33
|
+
- MCP endpoint
|
|
34
|
+
- Balchemy API key
|
|
35
|
+
- LLM provider (Anthropic or OpenAI) + API key + model
|
|
36
|
+
- Daily LLM budget (USD)
|
|
37
|
+
- Strategy preset
|
|
38
|
+
|
|
39
|
+
It writes `agent.config.yaml` and `.env` to the current directory.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Step 3: Start the agent
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npx balchemy-agent start
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
You should see:
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
Starting Balchemy agent from: /path/to/agent.config.yaml
|
|
53
|
+
[agent] Running. Press Ctrl+C to stop.
|
|
54
|
+
[agent] status=running events=0 decisions=0 trades=0 llmCost=$0.0000/5
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The agent:
|
|
58
|
+
1. Connects to the Balchemy SSE event stream
|
|
59
|
+
2. Receives market signals and platform events
|
|
60
|
+
3. Calls your LLM to decide whether to buy, sell, or hold
|
|
61
|
+
4. Executes approved trades via MCP tool calls
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Step 4: Docker (production)
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npx balchemy-agent docker
|
|
69
|
+
docker compose up -d
|
|
70
|
+
docker compose logs -f
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The generated `docker-compose.yml` runs the agent with:
|
|
74
|
+
- `restart: always` — survives crashes and reboots
|
|
75
|
+
- Mounted `agent.config.yaml` — edit config without rebuilding
|
|
76
|
+
- JSON log rotation (10 MB × 5 files)
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Programmatic usage (TypeScript)
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import { AgentLoop } from '@balchemy/agent-sdk';
|
|
84
|
+
|
|
85
|
+
// From YAML config file
|
|
86
|
+
const loop = AgentLoop.fromConfig('./agent.config.yaml');
|
|
87
|
+
await loop.start();
|
|
88
|
+
|
|
89
|
+
// Or inline config
|
|
90
|
+
const loop2 = new AgentLoop({
|
|
91
|
+
mcpEndpoint: 'https://api.balchemy.ai/mcp/YOUR_PUBLIC_ID',
|
|
92
|
+
apiKey: process.env.BALCHEMY_API_KEY!,
|
|
93
|
+
llmProvider: 'anthropic',
|
|
94
|
+
llmApiKey: process.env.ANTHROPIC_API_KEY!,
|
|
95
|
+
llmModel: 'claude-haiku-4-5',
|
|
96
|
+
maxDailyLlmCost: 5,
|
|
97
|
+
onStatusChange: (s) => console.log('status', s.status),
|
|
98
|
+
onDecision: (d) => console.log('decision', d),
|
|
99
|
+
onError: (e) => console.error('error', e.message),
|
|
100
|
+
});
|
|
101
|
+
await loop2.start();
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Strategy presets
|
|
107
|
+
|
|
108
|
+
| Preset | Description | Recommended model |
|
|
109
|
+
|--------|-------------|-------------------|
|
|
110
|
+
| `dca-accumulator` | Buy fixed-USD at regular intervals | gpt-4o-mini |
|
|
111
|
+
| `memecoin-sniper` | Buy on launch signals, sell on pump | claude-haiku-4-5 |
|
|
112
|
+
| `swing-trader` | Hold positions 2–72h, exit on RSI/MACD | claude-haiku-4-5 |
|
|
113
|
+
| `custom` | Define your own rules in `behavior_rules` | any |
|
|
114
|
+
|
|
115
|
+
See [BEHAVIOR_RULES.md](./BEHAVIOR_RULES.md) for the full rule schema.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Next steps
|
|
120
|
+
|
|
121
|
+
- [BEHAVIOR_RULES.md](./BEHAVIOR_RULES.md) — customize your agent's trading logic
|
|
122
|
+
- [DEPLOYMENT.md](./DEPLOYMENT.md) — deploy to a VPS, Railway, or Render
|
|
123
|
+
- [examples/](./examples/) — ready-to-use strategy YAML files
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Error Classification and Retry Strategy
|
|
2
|
+
|
|
3
|
+
## Error Classes
|
|
4
|
+
|
|
5
|
+
- `auth_error`: JWT/identity mismatch, unauthorized onboarding.
|
|
6
|
+
- `policy_error`: guardrail rejection, invalid payload, unsupported mode/provider.
|
|
7
|
+
- `rate_limit_error`: endpoint throttling.
|
|
8
|
+
- `provider_auth_error`: upstream provider verify authorization failure.
|
|
9
|
+
- `network_error`: timeout, DNS, transport errors.
|
|
10
|
+
- `execution_error`: MCP call returned JSON-RPC error.
|
|
11
|
+
- `invalid_response`: malformed payload.
|
|
12
|
+
- `unknown_error`: fallback.
|
|
13
|
+
|
|
14
|
+
## Recommended Retry Rules
|
|
15
|
+
|
|
16
|
+
- `rate_limit_error`: exponential backoff with jitter (`2s`, `5s`, `10s`, `20s`).
|
|
17
|
+
- `network_error`: bounded retries (`max=3`) with linear backoff (`1s`, `2s`, `3s`).
|
|
18
|
+
- `execution_error`: retry only if tool is idempotent (`tools/list`, status calls).
|
|
19
|
+
- `policy_error` / `auth_error` / `provider_auth_error`: do not blind-retry; require input or credential fix.
|
|
20
|
+
|
|
21
|
+
## Safe Retry Gate
|
|
22
|
+
|
|
23
|
+
Retry only when all conditions hold:
|
|
24
|
+
|
|
25
|
+
1. Error class is retryable (`network_error` or `rate_limit_error`).
|
|
26
|
+
2. Operation is idempotent or duplicate-safe.
|
|
27
|
+
3. Retry budget for the request has remaining attempts.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Custom Strategy — Annotated Example
|
|
2
|
+
#
|
|
3
|
+
# This file shows every supported behavior_rules field.
|
|
4
|
+
# Use it as a reference when building your own strategy.
|
|
5
|
+
# Delete or comment out fields you do not need.
|
|
6
|
+
|
|
7
|
+
mcp_endpoint: "${MCP_ENDPOINT}"
|
|
8
|
+
api_key: "${BALCHEMY_API_KEY}"
|
|
9
|
+
|
|
10
|
+
llm:
|
|
11
|
+
provider: anthropic # anthropic | openai
|
|
12
|
+
api_key: "${LLM_API_KEY}"
|
|
13
|
+
model: claude-haiku-4-5 # Use haiku/gpt-4o-mini for cost, sonnet/gpt-5 for quality
|
|
14
|
+
max_daily_usd: 5 # Hard LLM budget cap in USD per day
|
|
15
|
+
timeout_ms: 10000 # LLM call timeout in milliseconds
|
|
16
|
+
|
|
17
|
+
# Optional: separate cheap/full models for model routing
|
|
18
|
+
# cheapModel: claude-haiku-4-5 # Used for low-significance events (score < 60)
|
|
19
|
+
# fullModel: claude-sonnet-4 # Used for high-significance events (score >= 60)
|
|
20
|
+
|
|
21
|
+
strategy: custom
|
|
22
|
+
|
|
23
|
+
# Optional webhook receiver — receives Balchemy push events directly
|
|
24
|
+
# webhook:
|
|
25
|
+
# port: 4242
|
|
26
|
+
# secret: "${WEBHOOK_SECRET}"
|
|
27
|
+
|
|
28
|
+
behavior_rules:
|
|
29
|
+
version: "1"
|
|
30
|
+
preset: custom # custom | memecoin-sniper | dca-accumulator | swing-trader
|
|
31
|
+
|
|
32
|
+
# ─── Risk limits (applied globally, cannot be overridden per trade) ──────────
|
|
33
|
+
risk:
|
|
34
|
+
max_single_trade_usd: 50 # Hard cap per trade
|
|
35
|
+
max_daily_loss_usd: 200 # Pause after this daily loss
|
|
36
|
+
max_open_positions: 5 # Max simultaneous open positions
|
|
37
|
+
pause_on_drawdown_pct: 20 # Pause if portfolio drops 20% from peak
|
|
38
|
+
allowed_chains: [solana] # solana | base | ethereum | arbitrum
|
|
39
|
+
|
|
40
|
+
# ─── Asset filters (applied before LLM call — zero LLM cost) ────────────────
|
|
41
|
+
filters:
|
|
42
|
+
min_liquidity_usd: 20000
|
|
43
|
+
max_market_cap_usd: 50000000
|
|
44
|
+
require_verified_contract: false
|
|
45
|
+
blocked_tokens: # Addresses to never trade
|
|
46
|
+
- "So11111111111111111111111111111111111111112"
|
|
47
|
+
# allowed_tokens: # If set, only these tokens will be traded
|
|
48
|
+
# - "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
|
|
49
|
+
|
|
50
|
+
# ─── Entry conditions ────────────────────────────────────────────────────────
|
|
51
|
+
entry:
|
|
52
|
+
# Trigger type: launch_signal | price_drop | rsi_signal | manual
|
|
53
|
+
trigger: price_drop
|
|
54
|
+
indicators: [rsi]
|
|
55
|
+
rsi_oversold: 35
|
|
56
|
+
max_position_usd: 100
|
|
57
|
+
slippage_bps: 150
|
|
58
|
+
min_confidence: 0.7 # LLM confidence threshold (0.0–1.0)
|
|
59
|
+
|
|
60
|
+
# ─── Exit conditions ─────────────────────────────────────────────────────────
|
|
61
|
+
exit:
|
|
62
|
+
take_profit_pct: 30
|
|
63
|
+
stop_loss_pct: 15
|
|
64
|
+
trailing_stop_pct: 10 # Activate once in profit; trail 10% below peak
|
|
65
|
+
min_hold_hours: 0 # Allow immediate exit if conditions are met
|
|
66
|
+
max_hold_hours: 48 # Force exit after 48 hours
|
|
67
|
+
|
|
68
|
+
# ─── DCA config (only for dca-accumulator preset) ───────────────────────────
|
|
69
|
+
# dca:
|
|
70
|
+
# target_token: SOL
|
|
71
|
+
# amount_usd: 10
|
|
72
|
+
# interval_hours: 24
|
|
73
|
+
# max_total_usd: 500
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# DCA Accumulator Strategy
|
|
2
|
+
#
|
|
3
|
+
# Dollar-cost averages into SOL on a fixed schedule.
|
|
4
|
+
# Buys $10 of SOL every 24 hours regardless of price.
|
|
5
|
+
# Pauses DCA if portfolio drops more than 30% from peak.
|
|
6
|
+
#
|
|
7
|
+
# Risk profile: LOW — patient accumulation, no active trading decisions.
|
|
8
|
+
# Recommended LLM: gpt-4o-mini (sufficient for simple buy confirmations)
|
|
9
|
+
|
|
10
|
+
mcp_endpoint: "${MCP_ENDPOINT}"
|
|
11
|
+
api_key: "${BALCHEMY_API_KEY}"
|
|
12
|
+
|
|
13
|
+
llm:
|
|
14
|
+
provider: openai
|
|
15
|
+
api_key: "${LLM_API_KEY}"
|
|
16
|
+
model: gpt-4o-mini
|
|
17
|
+
max_daily_usd: 1 # DCA fires once per day — very low LLM cost
|
|
18
|
+
timeout_ms: 15000
|
|
19
|
+
|
|
20
|
+
strategy: dca-accumulator
|
|
21
|
+
|
|
22
|
+
behavior_rules:
|
|
23
|
+
version: "1"
|
|
24
|
+
preset: dca-accumulator
|
|
25
|
+
|
|
26
|
+
dca:
|
|
27
|
+
target_token: SOL
|
|
28
|
+
amount_usd: 10 # Buy $10 per interval
|
|
29
|
+
interval_hours: 24 # Daily purchases
|
|
30
|
+
max_total_usd: 1000 # Stop after $1000 total invested
|
|
31
|
+
|
|
32
|
+
risk:
|
|
33
|
+
max_single_trade_usd: 10 # Each DCA buy is capped at $10
|
|
34
|
+
pause_on_drawdown_pct: 30 # Pause if portfolio value drops 30% from peak
|
|
35
|
+
max_open_positions: 1 # Only hold SOL — single-asset strategy
|
|
36
|
+
allowed_chains: [solana]
|
|
37
|
+
|
|
38
|
+
filters:
|
|
39
|
+
allowed_tokens:
|
|
40
|
+
# Wrapped SOL (wSOL) — the only token this strategy trades
|
|
41
|
+
- "So11111111111111111111111111111111111111112"
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Memecoin Sniper Strategy
|
|
2
|
+
#
|
|
3
|
+
# Buys newly launched memecoins on Solana within the first few minutes
|
|
4
|
+
# of listing. Takes profit at 100% gain, cuts losses at 50% drop.
|
|
5
|
+
# Positions are never held longer than 60 minutes.
|
|
6
|
+
#
|
|
7
|
+
# Risk profile: HIGH — many trades will lose, winners cover losers.
|
|
8
|
+
# Recommended LLM: claude-haiku-4-5 (fast, cheap, sufficient for signal routing)
|
|
9
|
+
|
|
10
|
+
mcp_endpoint: "${MCP_ENDPOINT}"
|
|
11
|
+
api_key: "${BALCHEMY_API_KEY}"
|
|
12
|
+
|
|
13
|
+
llm:
|
|
14
|
+
provider: anthropic
|
|
15
|
+
api_key: "${LLM_API_KEY}"
|
|
16
|
+
model: claude-haiku-4-5
|
|
17
|
+
max_daily_usd: 3 # Memecoin sniper fires frequently — keep budget low
|
|
18
|
+
timeout_ms: 5000 # Tight timeout — stale signals are worthless
|
|
19
|
+
|
|
20
|
+
strategy: memecoin-sniper
|
|
21
|
+
|
|
22
|
+
behavior_rules:
|
|
23
|
+
version: "1"
|
|
24
|
+
preset: memecoin-sniper
|
|
25
|
+
|
|
26
|
+
filters:
|
|
27
|
+
min_liquidity_usd: 10000 # Avoid rugpulls with thin liquidity
|
|
28
|
+
max_market_cap_usd: 5000000 # Only micro-caps — higher upside
|
|
29
|
+
require_verified_contract: false # Most new launches are unverified
|
|
30
|
+
allowed_chains: [solana]
|
|
31
|
+
|
|
32
|
+
entry:
|
|
33
|
+
trigger: launch_signal # React to new token launch events
|
|
34
|
+
max_position_usd: 25 # Small positions — many trades
|
|
35
|
+
slippage_bps: 400 # High slippage accepted for fast entry
|
|
36
|
+
min_confidence: 0.55 # Lower threshold — sniper takes more swings
|
|
37
|
+
|
|
38
|
+
exit:
|
|
39
|
+
take_profit_pct: 100 # Double or nothing
|
|
40
|
+
stop_loss_pct: 50 # Cut at -50%
|
|
41
|
+
max_hold_minutes: 60 # Force exit after 1 hour no matter what
|
|
42
|
+
trailing_stop_pct: 20 # Lock in gains if price reverses 20% from peak
|
|
43
|
+
|
|
44
|
+
risk:
|
|
45
|
+
max_single_trade_usd: 25
|
|
46
|
+
max_daily_loss_usd: 100 # Hard daily stop
|
|
47
|
+
max_open_positions: 3 # Never hold more than 3 memecoins at once
|