polly-gamba 1.0.20 → 1.0.23

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.
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.ClaudeTrader = void 0;
7
7
  const child_process_1 = require("child_process");
8
8
  const fs_1 = require("fs");
9
+ const path_1 = require("path");
9
10
  const readline_1 = require("readline");
10
11
  const ioredis_1 = __importDefault(require("ioredis"));
11
12
  function findClaudeBin() {
@@ -66,6 +67,11 @@ class ClaudeTrader {
66
67
  '--verbose',
67
68
  '--dangerously-skip-permissions',
68
69
  ];
70
+ // Explicitly load MCP config — --print mode doesn't auto-discover settings.json
71
+ const settingsPath = (0, path_1.join)(this.config.cwd, 'settings.json');
72
+ if ((0, fs_1.existsSync)(settingsPath)) {
73
+ args.push('--mcp-config', settingsPath);
74
+ }
69
75
  if (this.config.model) {
70
76
  args.push('--model', this.config.model);
71
77
  }
@@ -108,7 +114,7 @@ RULES:
108
114
 
109
115
  ## POSITION DISCIPLINE:
110
116
  - Max $100 per market (20% of $500 budget). The MCP enforces this — don't fight it.
111
- - To add to an existing position: you MUST cite a specific new catalyst (news published in last 24h, not price movement). Price dipping is NOT a catalyst. Price rising is NOT a catalyst. New information is a catalyst.
117
+ - To add to an existing position with the SAME outcome: (1) you MUST cite a specific new catalyst (news published in last 24h, not price movement), AND (2) the current price must be ≥20% below your last entry price (e.g. if you bought YES at 0.15, new entry only valid at ≤0.12). The MCP enforces this — attempts at a smaller discount will be rejected. Price dipping alone is NOT a catalyst. New information is a catalyst.
112
118
  - exit_trigger is required on every trade. Be specific: "Exit when price hits 0.X" or "Exit when [specific news event]" — not "when narrative converges."
113
119
  - Call get_budget_status at the start of each scan to know available capital.`
114
120
  }
@@ -272,7 +278,7 @@ CLOSE RULES — apply ALL that match, no thesis override allowed:
272
278
  2. Position is down >35% AND the fundamental thesis has materially weakened or been disproven (market structure changed, key assumption invalidated).
273
279
  3. Your side of the position is priced below 10% — HARD CLOSE. The market has strongly repriced against you. Do NOT override this with "thesis not disproven yet." At <10%, expected value of holding is near zero.
274
280
  4. Position is down >50% — HARD CLOSE regardless of thesis. Cut losses. No exceptions.
275
- 5. You have 2+ open positions in the SAME market and both are losing — close the one with the higher percentage loss to reduce duplicate exposure.
281
+ 5. You have 2+ open positions in the SAME market with the SAME outcome — close the NEWER entry (higher ts value) regardless of P&L. Duplicate same-outcome positions double exposure without incremental edge. Keep the original entry.
276
282
 
277
283
  HOLD RULES: If NONE of the close rules apply and exit trigger NOT triggered, do nothing (no output needed).`;
278
284
  const msg = JSON.stringify({
@@ -137,6 +137,20 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (req) => {
137
137
  }]
138
138
  };
139
139
  }
140
+ // Check 1b: Same-outcome re-entry requires ≥20% price improvement (prevents pyramiding into losers)
141
+ const sameOutcomePositions = sameMarketPositions.filter((p) => String(p.outcome).toLowerCase() === String(a.outcome).toLowerCase());
142
+ if (sameOutcomePositions.length > 0) {
143
+ const lastEntry = Math.max(...sameOutcomePositions.map((p) => p.price || 0));
144
+ const requiredPrice = lastEntry * 0.80;
145
+ if (a.price > requiredPrice) {
146
+ return {
147
+ content: [{
148
+ type: 'text',
149
+ text: `Error: Re-entry blocked. Last ${a.outcome} entry at ${lastEntry.toFixed(4)}. Require price ≤ ${requiredPrice.toFixed(4)} (20% better) to add same-direction position. Current price ${a.price.toFixed(4)} is too close to last entry. Wait for a larger dislocation before averaging.`
150
+ }]
151
+ };
152
+ }
153
+ }
140
154
  // Check 2: $500 total budget cap
141
155
  const totalDeployed = openPositions.reduce((s, p) => s + (p.size_usdc || 0), 0);
142
156
  if (totalDeployed + a.size_usdc > TOTAL_BUDGET) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polly-gamba",
3
- "version": "1.0.20",
3
+ "version": "1.0.23",
4
4
  "description": "Coinbase price signal → Claude brain → Polymarket CLOB execution",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
package/service.log CHANGED
@@ -177,3 +177,183 @@ npm warn deprecated prebuild-install@7.1.3: No longer maintained. Please contact
177
177
  [gamma] Loaded 496 markets (filtered from 500)
178
178
  [expiring] 0 expiring markets for review
179
179
  [expiring] no expiring markets found this cycle
180
+ [polly-gamba] Starting paper trading service
181
+ [polly-gamba] Claude cwd: /Users/feral/polly-gamba
182
+ [polly-gamba] Expiring trader cwd: /Users/feral/polly-gamba-expiring
183
+ [coinbase-ws] Connecting to wss://ws-feed.exchange.coinbase.com
184
+ [polly-gamba] Listening for BTC/ETH price signals (threshold: 0.5% in 60s)...
185
+ [scan] fetching high-quality markets (vol24h>$50k, liq>$50k, price 0.10-0.90)
186
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
187
+ [expiring] fetching expiring markets (closing within 72h, vol24h>$10k, liq>$10k, price 0.05-0.95)
188
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
189
+ [coinbase-ws] Connected
190
+ [position-monitor] checked=24 review_candidates=7 hard_stops=0 (moved>5% or <72h expiry)
191
+ [gamma] Loaded 496 markets (filtered from 500)
192
+ [expiring] 0 expiring markets for review
193
+ [expiring] no expiring markets found this cycle
194
+ [gamma] Loaded 496 markets (filtered from 500)
195
+ [scan] 16 high-quality markets for autonomous review
196
+ [claude-trader:anthropic] ready
197
+ [claude-trader:ollama] ready
198
+ [claude-trader:expiring] ready
199
+ [scan] fetching high-quality markets (vol24h>$50k, liq>$50k, price 0.10-0.90)
200
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
201
+ [expiring] fetching expiring markets (closing within 72h, vol24h>$10k, liq>$10k, price 0.05-0.95)
202
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
203
+ [position-monitor] checked=25 review_candidates=7 hard_stops=0 (moved>5% or <72h expiry)
204
+ [gamma] Loaded 496 markets (filtered from 500)
205
+ [expiring] 0 expiring markets for review
206
+ [expiring] no expiring markets found this cycle
207
+ [gamma] Loaded 496 markets (filtered from 500)
208
+ [scan] 16 high-quality markets for autonomous review
209
+ [scan] fetching high-quality markets (vol24h>$50k, liq>$50k, price 0.10-0.90)
210
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
211
+ [expiring] fetching expiring markets (closing within 72h, vol24h>$10k, liq>$10k, price 0.05-0.95)
212
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
213
+ [position-monitor] checked=25 review_candidates=7 hard_stops=0 (moved>5% or <72h expiry)
214
+ [gamma] Loaded 496 markets (filtered from 500)
215
+ [scan] 16 high-quality markets for autonomous review
216
+ [gamma] Loaded 496 markets (filtered from 500)
217
+ [expiring] 0 expiring markets for review
218
+ [expiring] no expiring markets found this cycle
219
+ [scan] fetching high-quality markets (vol24h>$50k, liq>$50k, price 0.10-0.90)
220
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
221
+ [position-monitor] checked=25 review_candidates=7 hard_stops=0 (moved>5% or <72h expiry)
222
+ [gamma] Loaded 496 markets (filtered from 500)
223
+ [scan] 16 high-quality markets for autonomous review
224
+ [expiring] fetching expiring markets (closing within 72h, vol24h>$10k, liq>$10k, price 0.05-0.95)
225
+ [expiring] 0 expiring markets for review
226
+ [expiring] no expiring markets found this cycle
227
+ [position-monitor] checked=25 review_candidates=7 hard_stops=0 (moved>5% or <72h expiry)
228
+ [scan] fetching high-quality markets (vol24h>$50k, liq>$50k, price 0.10-0.90)
229
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
230
+ [gamma] Loaded 496 markets (filtered from 500)
231
+ [scan] 16 high-quality markets for autonomous review
232
+ [expiring] fetching expiring markets (closing within 72h, vol24h>$10k, liq>$10k, price 0.05-0.95)
233
+ [expiring] 0 expiring markets for review
234
+ [expiring] no expiring markets found this cycle
235
+ [polly-gamba] Starting paper trading service
236
+ [polly-gamba] Claude cwd: /Users/feral/polly-gamba
237
+ [polly-gamba] Expiring trader cwd: /Users/feral/polly-gamba-expiring
238
+ [coinbase-ws] Connecting to wss://ws-feed.exchange.coinbase.com
239
+ [polly-gamba] Listening for BTC/ETH price signals (threshold: 0.5% in 60s)...
240
+ [scan] fetching high-quality markets (vol24h>$50k, liq>$50k, price 0.10-0.90)
241
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
242
+ [expiring] fetching expiring markets (closing within 72h, vol24h>$10k, liq>$10k, price 0.05-0.95)
243
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
244
+ [gamma] Loaded 496 markets (filtered from 500)
245
+ [expiring] 0 expiring markets for review
246
+ [expiring] no expiring markets found this cycle
247
+ [gamma] Loaded 496 markets (filtered from 500)
248
+ [scan] 16 high-quality markets for autonomous review
249
+ [coinbase-ws] Connected
250
+ [position-monitor] checked=25 review_candidates=7 hard_stops=0 (moved>5% or <72h expiry)
251
+ [claude-trader:anthropic] ready
252
+ [claude-trader:ollama] ready
253
+ [claude-trader:expiring] ready
254
+ [scan] fetching high-quality markets (vol24h>$50k, liq>$50k, price 0.10-0.90)
255
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
256
+ [expiring] fetching expiring markets (closing within 72h, vol24h>$10k, liq>$10k, price 0.05-0.95)
257
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
258
+ [position-monitor] checked=25 review_candidates=7 hard_stops=0 (moved>5% or <72h expiry)
259
+ [gamma] Loaded 496 markets (filtered from 500)
260
+ [expiring] 0 expiring markets for review
261
+ [expiring] no expiring markets found this cycle
262
+ [gamma] Loaded 496 markets (filtered from 500)
263
+ [scan] 16 high-quality markets for autonomous review
264
+ [scan] fetching high-quality markets (vol24h>$50k, liq>$50k, price 0.10-0.90)
265
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
266
+ [expiring] fetching expiring markets (closing within 72h, vol24h>$10k, liq>$10k, price 0.05-0.95)
267
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
268
+ [position-monitor] checked=25 review_candidates=7 hard_stops=0 (moved>5% or <72h expiry)
269
+ [gamma] Loaded 496 markets (filtered from 500)
270
+ [scan] 16 high-quality markets for autonomous review
271
+ [gamma] Loaded 496 markets (filtered from 500)
272
+ [expiring] 0 expiring markets for review
273
+ [expiring] no expiring markets found this cycle
274
+ [scan] fetching high-quality markets (vol24h>$50k, liq>$50k, price 0.10-0.90)
275
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
276
+ [expiring] fetching expiring markets (closing within 72h, vol24h>$10k, liq>$10k, price 0.05-0.95)
277
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
278
+ [position-monitor] checked=25 review_candidates=7 hard_stops=0 (moved>5% or <72h expiry)
279
+ [gamma] Loaded 496 markets (filtered from 500)
280
+ [scan] 16 high-quality markets for autonomous review
281
+ [gamma] Loaded 496 markets (filtered from 500)
282
+ [expiring] 0 expiring markets for review
283
+ [expiring] no expiring markets found this cycle
284
+ [position-monitor] checked=25 review_candidates=7 hard_stops=0 (moved>5% or <72h expiry)
285
+ [scan] fetching high-quality markets (vol24h>$50k, liq>$50k, price 0.10-0.90)
286
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
287
+ [gamma] Loaded 496 markets (filtered from 500)
288
+ [scan] 16 high-quality markets for autonomous review
289
+ [expiring] fetching expiring markets (closing within 72h, vol24h>$10k, liq>$10k, price 0.05-0.95)
290
+ [expiring] 0 expiring markets for review
291
+ [expiring] no expiring markets found this cycle
292
+ [polly-gamba] Starting paper trading service
293
+ [polly-gamba] Claude cwd: /Users/feral/polly-gamba
294
+ [polly-gamba] Expiring trader cwd: /Users/feral/polly-gamba-expiring
295
+ [coinbase-ws] Connecting to wss://ws-feed.exchange.coinbase.com
296
+ [polly-gamba] Listening for BTC/ETH price signals (threshold: 0.5% in 60s)...
297
+ [scan] fetching high-quality markets (vol24h>$50k, liq>$50k, price 0.10-0.90)
298
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
299
+ [expiring] fetching expiring markets (closing within 72h, vol24h>$10k, liq>$10k, price 0.05-0.95)
300
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
301
+ [gamma] Loaded 496 markets (filtered from 500)
302
+ [scan] 16 high-quality markets for autonomous review
303
+ [gamma] Loaded 496 markets (filtered from 500)
304
+ [expiring] 0 expiring markets for review
305
+ [expiring] no expiring markets found this cycle
306
+ [coinbase-ws] Connected
307
+ [position-monitor] checked=25 review_candidates=7 hard_stops=0 (moved>5% or <72h expiry)
308
+ [claude-trader:anthropic] ready
309
+ [claude-trader:ollama] ready
310
+ [claude-trader:expiring] ready
311
+ [scan] fetching high-quality markets (vol24h>$50k, liq>$50k, price 0.10-0.90)
312
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
313
+ [expiring] fetching expiring markets (closing within 72h, vol24h>$10k, liq>$10k, price 0.05-0.95)
314
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
315
+ [gamma] Loaded 496 markets (filtered from 500)
316
+ [scan] 16 high-quality markets for autonomous review
317
+ [position-monitor] checked=25 review_candidates=7 hard_stops=0 (moved>5% or <72h expiry)
318
+ [gamma] Loaded 496 markets (filtered from 500)
319
+ [expiring] 0 expiring markets for review
320
+ [expiring] no expiring markets found this cycle
321
+ [scan] fetching high-quality markets (vol24h>$50k, liq>$50k, price 0.10-0.90)
322
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
323
+ [expiring] fetching expiring markets (closing within 72h, vol24h>$10k, liq>$10k, price 0.05-0.95)
324
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
325
+ [gamma] Loaded 496 markets (filtered from 500)
326
+ [scan] 17 high-quality markets for autonomous review
327
+ [position-monitor] checked=25 review_candidates=7 hard_stops=0 (moved>5% or <72h expiry)
328
+ [gamma] Loaded 496 markets (filtered from 500)
329
+ [expiring] 0 expiring markets for review
330
+ [expiring] no expiring markets found this cycle
331
+ [scan] fetching high-quality markets (vol24h>$50k, liq>$50k, price 0.10-0.90)
332
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
333
+ [expiring] fetching expiring markets (closing within 72h, vol24h>$10k, liq>$10k, price 0.05-0.95)
334
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
335
+ [position-monitor] checked=25 review_candidates=7 hard_stops=0 (moved>5% or <72h expiry)
336
+ [gamma] Loaded 496 markets (filtered from 500)
337
+ [scan] 16 high-quality markets for autonomous review
338
+ [gamma] Loaded 496 markets (filtered from 500)
339
+ [expiring] 0 expiring markets for review
340
+ [expiring] no expiring markets found this cycle
341
+ [polly-gamba] Starting paper trading service
342
+ [polly-gamba] Claude cwd: /Users/feral/polly-gamba
343
+ [polly-gamba] Expiring trader cwd: /Users/feral/polly-gamba-expiring
344
+ [coinbase-ws] Connecting to wss://ws-feed.exchange.coinbase.com
345
+ [polly-gamba] Listening for BTC/ETH price signals (threshold: 0.5% in 60s)...
346
+ [scan] fetching high-quality markets (vol24h>$50k, liq>$50k, price 0.10-0.90)
347
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
348
+ [expiring] fetching expiring markets (closing within 72h, vol24h>$10k, liq>$10k, price 0.05-0.95)
349
+ [gamma] Fetching active markets from https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=500
350
+ [coinbase-ws] Connected
351
+ [position-monitor] checked=25 review_candidates=7 hard_stops=0 (moved>5% or <72h expiry)
352
+ [gamma] Loaded 496 markets (filtered from 500)
353
+ [expiring] 0 expiring markets for review
354
+ [expiring] no expiring markets found this cycle
355
+ [gamma] Loaded 496 markets (filtered from 500)
356
+ [scan] 17 high-quality markets for autonomous review
357
+ [claude-trader:anthropic] ready
358
+ [claude-trader:ollama] ready
359
+ [claude-trader:expiring] ready
@@ -1,5 +1,6 @@
1
1
  import { spawn, ChildProcess, execSync } from 'child_process'
2
2
  import { existsSync } from 'fs'
3
+ import { join } from 'path'
3
4
  import { createInterface } from 'readline'
4
5
  import Redis from 'ioredis'
5
6
  import { PriceSignal } from './signals/coinbase-ws'
@@ -77,6 +78,12 @@ export class ClaudeTrader {
77
78
  '--dangerously-skip-permissions',
78
79
  ]
79
80
 
81
+ // Explicitly load MCP config — --print mode doesn't auto-discover settings.json
82
+ const settingsPath = join(this.config.cwd, 'settings.json')
83
+ if (existsSync(settingsPath)) {
84
+ args.push('--mcp-config', settingsPath)
85
+ }
86
+
80
87
  if (this.config.model) {
81
88
  args.push('--model', this.config.model)
82
89
  }
@@ -124,7 +131,7 @@ RULES:
124
131
 
125
132
  ## POSITION DISCIPLINE:
126
133
  - Max $100 per market (20% of $500 budget). The MCP enforces this — don't fight it.
127
- - To add to an existing position: you MUST cite a specific new catalyst (news published in last 24h, not price movement). Price dipping is NOT a catalyst. Price rising is NOT a catalyst. New information is a catalyst.
134
+ - To add to an existing position with the SAME outcome: (1) you MUST cite a specific new catalyst (news published in last 24h, not price movement), AND (2) the current price must be ≥20% below your last entry price (e.g. if you bought YES at 0.15, new entry only valid at ≤0.12). The MCP enforces this — attempts at a smaller discount will be rejected. Price dipping alone is NOT a catalyst. New information is a catalyst.
128
135
  - exit_trigger is required on every trade. Be specific: "Exit when price hits 0.X" or "Exit when [specific news event]" — not "when narrative converges."
129
136
  - Call get_budget_status at the start of each scan to know available capital.`
130
137
  }
@@ -323,7 +330,7 @@ CLOSE RULES — apply ALL that match, no thesis override allowed:
323
330
  2. Position is down >35% AND the fundamental thesis has materially weakened or been disproven (market structure changed, key assumption invalidated).
324
331
  3. Your side of the position is priced below 10% — HARD CLOSE. The market has strongly repriced against you. Do NOT override this with "thesis not disproven yet." At <10%, expected value of holding is near zero.
325
332
  4. Position is down >50% — HARD CLOSE regardless of thesis. Cut losses. No exceptions.
326
- 5. You have 2+ open positions in the SAME market and both are losing — close the one with the higher percentage loss to reduce duplicate exposure.
333
+ 5. You have 2+ open positions in the SAME market with the SAME outcome — close the NEWER entry (higher ts value) regardless of P&L. Duplicate same-outcome positions double exposure without incremental edge. Keep the original entry.
327
334
 
328
335
  HOLD RULES: If NONE of the close rules apply and exit trigger NOT triggered, do nothing (no output needed).`
329
336
 
package/src/mcp-server.ts CHANGED
@@ -138,6 +138,23 @@ server.setRequestHandler(CallToolRequestSchema, async (req) => {
138
138
  }
139
139
  }
140
140
 
141
+ // Check 1b: Same-outcome re-entry requires ≥20% price improvement (prevents pyramiding into losers)
142
+ const sameOutcomePositions = sameMarketPositions.filter((p: any) =>
143
+ String(p.outcome).toLowerCase() === String(a.outcome).toLowerCase()
144
+ )
145
+ if (sameOutcomePositions.length > 0) {
146
+ const lastEntry = Math.max(...sameOutcomePositions.map((p: any) => p.price || 0))
147
+ const requiredPrice = lastEntry * 0.80
148
+ if (a.price > requiredPrice) {
149
+ return {
150
+ content: [{
151
+ type: 'text',
152
+ text: `Error: Re-entry blocked. Last ${a.outcome} entry at ${lastEntry.toFixed(4)}. Require price ≤ ${requiredPrice.toFixed(4)} (20% better) to add same-direction position. Current price ${a.price.toFixed(4)} is too close to last entry. Wait for a larger dislocation before averaging.`
153
+ }]
154
+ }
155
+ }
156
+ }
157
+
141
158
  // Check 2: $500 total budget cap
142
159
  const totalDeployed = openPositions.reduce((s: number, p: any) => s + (p.size_usdc || 0), 0)
143
160
  if (totalDeployed + a.size_usdc > TOTAL_BUDGET) {