create-polymarket-strategy 0.1.0
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 +127 -0
- package/dist/index.js.map +1 -0
- package/package.json +38 -0
- package/templates/worker/package.json +20 -0
- package/templates/worker/src/durable-objects/orders.ts +214 -0
- package/templates/worker/src/durable-objects/positions.ts +247 -0
- package/templates/worker/src/durable-objects/scheduler.ts +291 -0
- package/templates/worker/src/index.ts +221 -0
- package/templates/worker/src/scanner.ts +156 -0
- package/templates/worker/src/strategies/{{strategy-name}}.ts +119 -0
- package/templates/worker/src/types.ts +29 -0
- package/templates/worker/tsconfig.json +15 -0
- package/templates/worker/wrangler.jsonc +42 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* {{StrategyName}} Strategy
|
|
3
|
+
*
|
|
4
|
+
* A trading strategy for Polymarket.
|
|
5
|
+
* Implement the scan() and calculatePrice() methods to define your trading logic.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { Env } from "../types.js";
|
|
9
|
+
import {
|
|
10
|
+
type Strategy,
|
|
11
|
+
type StrategyContext,
|
|
12
|
+
type Signal,
|
|
13
|
+
type MarketData,
|
|
14
|
+
type StrategyConfig,
|
|
15
|
+
registerStrategy,
|
|
16
|
+
} from "polymarket-trading-sdk";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Strategy configuration type.
|
|
20
|
+
* Add your custom config fields here.
|
|
21
|
+
*/
|
|
22
|
+
interface {{StrategyName}}Config extends StrategyConfig {
|
|
23
|
+
tokenIds: string[];
|
|
24
|
+
orderSize: number;
|
|
25
|
+
// Add your config fields here
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* {{StrategyName}} Strategy Implementation
|
|
30
|
+
*/
|
|
31
|
+
export const {{strategyName}}Strategy: Strategy<Env> = {
|
|
32
|
+
name: "{{strategy-name}}",
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Scan for trading opportunities.
|
|
36
|
+
*
|
|
37
|
+
* This method is called periodically by the scheduler.
|
|
38
|
+
* Return an array of signals for markets you want to trade.
|
|
39
|
+
*/
|
|
40
|
+
async scan(ctx: StrategyContext<Env>): Promise<Signal[]> {
|
|
41
|
+
const config = ctx.config as {{StrategyName}}Config;
|
|
42
|
+
const signals: Signal[] = [];
|
|
43
|
+
|
|
44
|
+
for (const tokenId of config.tokenIds) {
|
|
45
|
+
// Get market data
|
|
46
|
+
const data = await ctx.marketData.getMarketData(tokenId);
|
|
47
|
+
|
|
48
|
+
// Example: Generate a signal if conditions are met
|
|
49
|
+
// TODO: Implement your trading logic here
|
|
50
|
+
if (data.midpoint && data.spread) {
|
|
51
|
+
// Example condition - customize this
|
|
52
|
+
const shouldTrade = false; // Your logic here
|
|
53
|
+
|
|
54
|
+
if (shouldTrade) {
|
|
55
|
+
signals.push({
|
|
56
|
+
slug: "your-market-slug",
|
|
57
|
+
label: "YES",
|
|
58
|
+
tokenId,
|
|
59
|
+
side: "buy",
|
|
60
|
+
metadata: {
|
|
61
|
+
midpoint: data.midpoint,
|
|
62
|
+
spread: data.spread,
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return signals;
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Calculate the limit price for a signal.
|
|
74
|
+
*
|
|
75
|
+
* Return a price (0-1) to place an order at that price.
|
|
76
|
+
* Return null to skip this signal.
|
|
77
|
+
*/
|
|
78
|
+
calculatePrice(
|
|
79
|
+
signal: Signal,
|
|
80
|
+
data: MarketData,
|
|
81
|
+
config: StrategyConfig
|
|
82
|
+
): number | null {
|
|
83
|
+
// Example: Bid slightly below the midpoint
|
|
84
|
+
if (!data.midpoint || !data.bid) {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// TODO: Implement your pricing logic here
|
|
89
|
+
// Example: bid 1 cent below midpoint
|
|
90
|
+
const price = Math.max(0.01, data.midpoint - 0.01);
|
|
91
|
+
|
|
92
|
+
// Ensure price is between 0.01 and 0.99
|
|
93
|
+
return Math.min(0.99, Math.max(0.01, price));
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Get strategy configuration.
|
|
98
|
+
*
|
|
99
|
+
* Configure your strategy here. You can read from env vars
|
|
100
|
+
* or hardcode values.
|
|
101
|
+
*/
|
|
102
|
+
getConfig(env: Env): {{StrategyName}}Config {
|
|
103
|
+
return {
|
|
104
|
+
// Token IDs to monitor
|
|
105
|
+
// Find these using the Gamma API or Polymarket UI
|
|
106
|
+
tokenIds: [
|
|
107
|
+
// "your-token-id-here",
|
|
108
|
+
],
|
|
109
|
+
|
|
110
|
+
// Order size in USDC
|
|
111
|
+
orderSize: 5,
|
|
112
|
+
|
|
113
|
+
// Add your custom config here
|
|
114
|
+
};
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
// Register the strategy
|
|
119
|
+
registerStrategy({{strategyName}}Strategy);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker environment types.
|
|
3
|
+
*
|
|
4
|
+
* This file contains Cloudflare-specific types that extend the SDK types.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Environment bindings for the worker.
|
|
9
|
+
*/
|
|
10
|
+
export interface Env {
|
|
11
|
+
// Durable Objects
|
|
12
|
+
ORDERS: DurableObjectNamespace;
|
|
13
|
+
POSITIONS: DurableObjectNamespace;
|
|
14
|
+
SCHEDULER: DurableObjectNamespace;
|
|
15
|
+
|
|
16
|
+
// Config
|
|
17
|
+
STRATEGY_NAME: string;
|
|
18
|
+
MODE: "paper" | "live";
|
|
19
|
+
CLOB_API: string;
|
|
20
|
+
GAMMA_API: string;
|
|
21
|
+
|
|
22
|
+
// Order Executor Lambda (Seoul) - bypasses geo-blocking
|
|
23
|
+
EXECUTOR_URL?: string;
|
|
24
|
+
EXECUTOR_WALLET_ID?: string;
|
|
25
|
+
|
|
26
|
+
// Secrets (set via wrangler secret put)
|
|
27
|
+
WORKER_API_KEY?: string; // API key to access this worker (security)
|
|
28
|
+
EXECUTOR_API_KEY?: string; // API key for executor Lambda
|
|
29
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"forceConsistentCasingInFileNames": true,
|
|
10
|
+
"lib": ["ES2022"],
|
|
11
|
+
"types": ["@cloudflare/workers-types"]
|
|
12
|
+
},
|
|
13
|
+
"include": ["src/**/*"],
|
|
14
|
+
"exclude": ["node_modules"]
|
|
15
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/cloudflare/workers-sdk/main/packages/wrangler/schemas/config.schema.json",
|
|
3
|
+
"name": "{{name}}",
|
|
4
|
+
"main": "src/index.ts",
|
|
5
|
+
"compatibility_date": "2024-01-01",
|
|
6
|
+
"compatibility_flags": ["nodejs_compat"],
|
|
7
|
+
|
|
8
|
+
// Durable Objects (all SQL-backed)
|
|
9
|
+
"durable_objects": {
|
|
10
|
+
"bindings": [
|
|
11
|
+
{ "name": "ORDERS", "class_name": "OrdersDO" },
|
|
12
|
+
{ "name": "POSITIONS", "class_name": "PositionsDO" },
|
|
13
|
+
{ "name": "SCHEDULER", "class_name": "SchedulerDO" }
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
// Migrations for SQL schema
|
|
18
|
+
"migrations": [
|
|
19
|
+
{ "tag": "v1", "new_sqlite_classes": ["OrdersDO", "PositionsDO", "SchedulerDO"] }
|
|
20
|
+
],
|
|
21
|
+
|
|
22
|
+
// Environment variables (non-secret)
|
|
23
|
+
"vars": {
|
|
24
|
+
"STRATEGY_NAME": "{{strategy-name}}",
|
|
25
|
+
"MODE": "paper",
|
|
26
|
+
"CLOB_API": "https://clob.polymarket.com",
|
|
27
|
+
"GAMMA_API": "https://gamma-api.polymarket.com",
|
|
28
|
+
|
|
29
|
+
// Order Executor Lambda (Seoul) - bypasses geo-blocking for order placement
|
|
30
|
+
// Set these when deploying in live mode
|
|
31
|
+
"EXECUTOR_URL": "",
|
|
32
|
+
"EXECUTOR_WALLET_ID": ""
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Secrets (set via `wrangler secret put`):
|
|
36
|
+
//
|
|
37
|
+
// SECURITY (required for production):
|
|
38
|
+
// - WORKER_API_KEY: API key to access this worker - generate with `openssl rand -hex 32`
|
|
39
|
+
//
|
|
40
|
+
// LIVE TRADING:
|
|
41
|
+
// - EXECUTOR_API_KEY: API key for executor Lambda (exk_...) - REQUIRED for live mode
|
|
42
|
+
}
|