create-polymarket-strategy 0.2.0 → 0.2.1
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/dist/index.js +252 -18
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/worker/package.json +1 -1
- package/templates/worker/src/durable-objects/positions.ts +189 -2
- package/templates/worker/src/durable-objects/scheduler.ts +108 -0
- package/templates/worker/src/lib/quote-manager.ts +358 -0
- package/templates/worker/src/scanner.ts +55 -3
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
* Orchestrates the scanning process:
|
|
5
5
|
* 1. Calls strategy.scan() to find signals
|
|
6
6
|
* 2. Checks for duplicate pending orders
|
|
7
|
-
* 3.
|
|
8
|
-
* 4.
|
|
7
|
+
* 3. Checks risk limits before placing
|
|
8
|
+
* 4. Calculates prices using strategy.calculatePrice()
|
|
9
|
+
* 5. Places orders via OrderManager (routes to Lambda for live mode)
|
|
9
10
|
*/
|
|
10
11
|
|
|
11
12
|
import type { Env } from "./types.js";
|
|
@@ -14,13 +15,17 @@ import {
|
|
|
14
15
|
type StrategyContext,
|
|
15
16
|
type Order,
|
|
16
17
|
type NewOrder,
|
|
18
|
+
type TokenInventory,
|
|
19
|
+
type RiskLimits,
|
|
17
20
|
MarketDataClient,
|
|
18
21
|
createOrderManagerFromEnv,
|
|
22
|
+
checkOrderRisk,
|
|
19
23
|
} from "polymarket-trading-sdk";
|
|
20
24
|
|
|
21
25
|
export interface ScanResult {
|
|
22
26
|
signalsFound: number;
|
|
23
27
|
ordersPlaced: number;
|
|
28
|
+
ordersSkippedRisk: number;
|
|
24
29
|
errors: string[];
|
|
25
30
|
}
|
|
26
31
|
|
|
@@ -34,6 +39,7 @@ export async function runScanner(
|
|
|
34
39
|
const result: ScanResult = {
|
|
35
40
|
signalsFound: 0,
|
|
36
41
|
ordersPlaced: 0,
|
|
42
|
+
ordersSkippedRisk: 0,
|
|
37
43
|
errors: [],
|
|
38
44
|
};
|
|
39
45
|
|
|
@@ -60,6 +66,9 @@ export async function runScanner(
|
|
|
60
66
|
const ordersId = env.ORDERS.idFromName("main");
|
|
61
67
|
const ordersStub = env.ORDERS.get(ordersId);
|
|
62
68
|
|
|
69
|
+
const positionsId = env.POSITIONS.idFromName("main");
|
|
70
|
+
const positionsStub = env.POSITIONS.get(positionsId);
|
|
71
|
+
|
|
63
72
|
try {
|
|
64
73
|
// 1. Scan for signals
|
|
65
74
|
const signals = await strategy.scan(ctx);
|
|
@@ -75,7 +84,24 @@ export async function runScanner(
|
|
|
75
84
|
);
|
|
76
85
|
const pendingOrders = (await pendingOrdersResponse.json()) as Order[];
|
|
77
86
|
|
|
78
|
-
// 3.
|
|
87
|
+
// 3. Get current inventories for risk checking
|
|
88
|
+
const inventoryResponse = await positionsStub.fetch(
|
|
89
|
+
new Request("http://do/inventory/all")
|
|
90
|
+
);
|
|
91
|
+
const inventories = (await inventoryResponse.json()) as TokenInventory[];
|
|
92
|
+
|
|
93
|
+
// 4. Get risk limits from config (with defaults)
|
|
94
|
+
const riskLimits: RiskLimits = {
|
|
95
|
+
maxPositionPerToken: (config.maxPositionPerToken as number) ?? 100,
|
|
96
|
+
maxTotalExposure: (config.maxTotalExposure as number) ?? 500,
|
|
97
|
+
maxLossPerToken: config.maxLossPerToken as number | undefined,
|
|
98
|
+
maxDailyLoss: config.maxDailyLoss as number | undefined,
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// Track current prices for risk calculations
|
|
102
|
+
const currentPrices = new Map<string, number>();
|
|
103
|
+
|
|
104
|
+
// 5. Process each signal
|
|
79
105
|
for (const signal of signals) {
|
|
80
106
|
try {
|
|
81
107
|
// Check dedup
|
|
@@ -95,6 +121,11 @@ export async function runScanner(
|
|
|
95
121
|
// Get market data for pricing
|
|
96
122
|
const data = await marketData.getMarketData(signal.tokenId);
|
|
97
123
|
|
|
124
|
+
// Track price for risk calc
|
|
125
|
+
if (data.midpoint !== null) {
|
|
126
|
+
currentPrices.set(signal.tokenId, data.midpoint);
|
|
127
|
+
}
|
|
128
|
+
|
|
98
129
|
// Calculate price
|
|
99
130
|
const price = strategy.calculatePrice(signal, data, config);
|
|
100
131
|
|
|
@@ -105,6 +136,27 @@ export async function runScanner(
|
|
|
105
136
|
// Determine order size
|
|
106
137
|
const size = (config.orderSize as number) ?? 5;
|
|
107
138
|
|
|
139
|
+
// Check risk limits before placing
|
|
140
|
+
const riskCheck = checkOrderRisk(
|
|
141
|
+
inventories,
|
|
142
|
+
{
|
|
143
|
+
tokenId: signal.tokenId,
|
|
144
|
+
side: signal.side,
|
|
145
|
+
size,
|
|
146
|
+
price,
|
|
147
|
+
},
|
|
148
|
+
riskLimits,
|
|
149
|
+
currentPrices
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
if (!riskCheck.allowed) {
|
|
153
|
+
result.ordersSkippedRisk++;
|
|
154
|
+
result.errors.push(
|
|
155
|
+
`Risk limit blocked ${signal.label}: ${riskCheck.reason}`
|
|
156
|
+
);
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
|
|
108
160
|
// Place order via OrderManager (handles live vs paper routing)
|
|
109
161
|
const orderResult = await orderManager.placeOrder({
|
|
110
162
|
slug: signal.slug,
|