@vesper85/strategy-sdk 0.1.0 → 0.1.3
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/README.md +339 -209
- package/dist/clients/polymarket-client.d.ts +1 -18
- package/dist/engine/event-runner.d.ts +33 -3
- package/dist/engine/polymarket-event-runner.d.ts +205 -0
- package/dist/engine/strategy-runner.d.ts +3 -4
- package/dist/index.d.ts +5 -2
- package/dist/index.js +1738 -204
- package/dist/rtds/index.d.ts +9 -0
- package/dist/rtds/osiris-rtds.service.d.ts +134 -0
- package/dist/rtds/polymarket-rtds.service.d.ts +117 -0
- package/dist/rtds/unified-rtds.service.d.ts +146 -0
- package/dist/types/event-types.d.ts +281 -11
- package/dist/types/gamma.d.ts +135 -0
- package/dist/types/osiris.d.ts +3 -40
- package/dist/utils/index.d.ts +3 -0
- package/package.json +6 -4
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ yarn add @osiris-ai/strategy-sdk
|
|
|
24
24
|
|
|
25
25
|
## Quick Start
|
|
26
26
|
|
|
27
|
-
### 1. Create a
|
|
27
|
+
### 1. Create a Tick-Based Strategy
|
|
28
28
|
|
|
29
29
|
```typescript
|
|
30
30
|
import type { OsirisContext, CodeStrategy } from '@osiris-ai/strategy-sdk';
|
|
@@ -45,41 +45,72 @@ export default class MyStrategy implements CodeStrategy {
|
|
|
45
45
|
}
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
### 2.
|
|
48
|
+
### 2. Create an Event-Based Strategy
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
import type {
|
|
52
|
+
CodeStrategy,
|
|
53
|
+
EventSubscription,
|
|
54
|
+
StrategyEvent,
|
|
55
|
+
OsirisContext
|
|
56
|
+
} from '@osiris-ai/strategy-sdk';
|
|
57
|
+
|
|
58
|
+
export class PriceAlertStrategy implements CodeStrategy {
|
|
59
|
+
// Define what events to subscribe to
|
|
60
|
+
subscriptions: EventSubscription[] = [
|
|
61
|
+
{
|
|
62
|
+
type: 'price',
|
|
63
|
+
market: 'BTC-USD',
|
|
64
|
+
conditions: { priceChangePercent: 5 }
|
|
65
|
+
}
|
|
66
|
+
];
|
|
67
|
+
|
|
68
|
+
// Called when subscribed events occur
|
|
69
|
+
async onEvent(event: StrategyEvent, osiris: OsirisContext): Promise<void> {
|
|
70
|
+
osiris.log(`Price event for ${event.market}: ${event.data.price}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### 3. Run the Strategy
|
|
49
76
|
|
|
50
77
|
```typescript
|
|
51
78
|
import {
|
|
52
79
|
createOsirisContext,
|
|
53
80
|
createConsoleLogger,
|
|
54
|
-
|
|
81
|
+
createStrategyEngine,
|
|
82
|
+
createEventRunner,
|
|
55
83
|
PrivateKeySigner,
|
|
56
84
|
} from '@osiris-ai/strategy-sdk';
|
|
57
|
-
import MyStrategy from './my-strategy';
|
|
58
85
|
|
|
59
86
|
async function main() {
|
|
60
87
|
const logger = createConsoleLogger();
|
|
61
88
|
|
|
62
|
-
// Create signer
|
|
63
89
|
const signer = new PrivateKeySigner({
|
|
64
90
|
privateKey: process.env.PRIVATE_KEY!,
|
|
65
91
|
});
|
|
66
92
|
|
|
67
|
-
// Create context
|
|
68
93
|
const context = createOsirisContext({
|
|
69
94
|
strategyId: 'my-strategy',
|
|
70
|
-
market: 'hyperliquid',
|
|
95
|
+
market: 'hyperliquid',
|
|
71
96
|
userAddress: signer.getAddress()!,
|
|
72
97
|
signer,
|
|
73
98
|
});
|
|
74
99
|
|
|
75
|
-
//
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
100
|
+
// For tick-based strategies
|
|
101
|
+
const engine = createStrategyEngine(strategy, {
|
|
102
|
+
logger,
|
|
103
|
+
tickIntervalMs: 60000,
|
|
104
|
+
}, context);
|
|
105
|
+
engine.start();
|
|
106
|
+
|
|
107
|
+
// For event-based strategies
|
|
108
|
+
const runner = createEventRunner(strategy, {
|
|
109
|
+
logger,
|
|
110
|
+
eventSourceUrl: 'wss://events.example.com/ws',
|
|
111
|
+
}, context);
|
|
112
|
+
runner.start();
|
|
80
113
|
}
|
|
81
|
-
|
|
82
|
-
main();
|
|
83
114
|
```
|
|
84
115
|
|
|
85
116
|
## Execution Modes
|
|
@@ -102,7 +133,7 @@ import { createStrategyEngine } from '@osiris-ai/strategy-sdk';
|
|
|
102
133
|
|
|
103
134
|
const engine = createStrategyEngine(strategy, {
|
|
104
135
|
logger,
|
|
105
|
-
strategyId: 'my-strategy',
|
|
136
|
+
strategyId: 'my-strategy',
|
|
106
137
|
tickIntervalMs: 60000, // Run every 60 seconds
|
|
107
138
|
}, context);
|
|
108
139
|
|
|
@@ -112,7 +143,7 @@ engine.start();
|
|
|
112
143
|
|
|
113
144
|
### Event-Based Execution (Real-time WebSocket)
|
|
114
145
|
|
|
115
|
-
Reacts to real-time events from
|
|
146
|
+
Reacts to real-time events from WebSocket streams. Best for strategies that need immediate response to market changes.
|
|
116
147
|
|
|
117
148
|
```typescript
|
|
118
149
|
interface CodeStrategy {
|
|
@@ -121,55 +152,262 @@ interface CodeStrategy {
|
|
|
121
152
|
}
|
|
122
153
|
```
|
|
123
154
|
|
|
155
|
+
## Event Subscription Types
|
|
156
|
+
|
|
157
|
+
The SDK uses a discriminated union for type-safe event subscriptions:
|
|
158
|
+
|
|
159
|
+
### MarketSubscription
|
|
160
|
+
|
|
161
|
+
Subscribe to market events (price, orderbook, trade, fill):
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
{
|
|
165
|
+
type: 'price', // or 'orderbook', 'trade', 'fill'
|
|
166
|
+
market: 'BTC-USD',
|
|
167
|
+
eventSource: 'polymarket', // optional
|
|
168
|
+
conditions: {
|
|
169
|
+
priceChangePercent: 5,
|
|
170
|
+
volumeAbove: 10000,
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### WalletSubscription
|
|
176
|
+
|
|
177
|
+
Subscribe to wallet analysis events (Osiris Pub/Sub only):
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
{
|
|
181
|
+
type: 'wallet',
|
|
182
|
+
wallet: '0x1234567890abcdef...',
|
|
183
|
+
conditions: {
|
|
184
|
+
minWinRate: 60,
|
|
185
|
+
minTradeCount: 10,
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### OpportunitySubscription
|
|
191
|
+
|
|
192
|
+
Subscribe to trading opportunities (Osiris Pub/Sub only):
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
{
|
|
196
|
+
type: 'opportunity',
|
|
197
|
+
filter: 'wide_spread_markets', // optional, defaults to 'all'
|
|
198
|
+
conditions: {
|
|
199
|
+
minScore: 70,
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### CustomSubscription
|
|
205
|
+
|
|
206
|
+
Subscribe to custom topics:
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
{
|
|
210
|
+
type: 'custom',
|
|
211
|
+
topic: 'custom:my-topic',
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Event Sources
|
|
216
|
+
|
|
217
|
+
### Osiris Pub/Sub
|
|
218
|
+
|
|
219
|
+
Connect to Osiris analytics WebSocket for market analysis, wallet tracking, and opportunities:
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
const runner = createEventRunner(strategy, {
|
|
223
|
+
logger,
|
|
224
|
+
eventSourceUrl: 'wss://your-osiris-server.com/ws',
|
|
225
|
+
}, context);
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
**Supported topics:**
|
|
229
|
+
- `market:{slug}` - Market analysis events
|
|
230
|
+
- `wallet:{address}` - Wallet analysis events
|
|
231
|
+
- `opps:{filter}` - Trading opportunities
|
|
232
|
+
|
|
233
|
+
### Polymarket RTDS
|
|
234
|
+
|
|
235
|
+
Connect directly to Polymarket's Real-Time Data Socket for live market data.
|
|
236
|
+
|
|
237
|
+
#### Strategy-Based Usage
|
|
238
|
+
|
|
239
|
+
Set `eventSource: 'polymarket'` in your subscriptions:
|
|
240
|
+
|
|
124
241
|
```typescript
|
|
125
|
-
import
|
|
242
|
+
import type {
|
|
243
|
+
CodeStrategy,
|
|
244
|
+
EventSubscription,
|
|
245
|
+
StrategyEvent,
|
|
246
|
+
CryptoPricesSubscription,
|
|
247
|
+
ActivitySubscription,
|
|
248
|
+
ClobMarketSubscription,
|
|
249
|
+
CommentsSubscription
|
|
250
|
+
} from '@osiris-ai/strategy-sdk';
|
|
126
251
|
|
|
127
|
-
class
|
|
252
|
+
class MyPolymarketStrategy implements CodeStrategy {
|
|
128
253
|
subscriptions: EventSubscription[] = [
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
254
|
+
// Crypto price updates
|
|
255
|
+
{ type: 'crypto_prices', symbol: 'btcusdt', eventSource: 'polymarket' },
|
|
256
|
+
|
|
257
|
+
// Trade activity feed
|
|
258
|
+
{ type: 'activity', messageType: '*', eventSource: 'polymarket' },
|
|
259
|
+
|
|
260
|
+
// CLOB orderbook data (requires market condition ID)
|
|
261
|
+
{ type: 'clob_market', marketId: 'condition-id', messageType: 'agg_orderbook', eventSource: 'polymarket' },
|
|
262
|
+
|
|
263
|
+
// Comments and reactions
|
|
264
|
+
{ type: 'comments', messageType: '*', eventSource: 'polymarket' },
|
|
134
265
|
];
|
|
135
266
|
|
|
136
267
|
async onEvent(event: StrategyEvent, osiris: OsirisContext): Promise<void> {
|
|
137
|
-
|
|
138
|
-
|
|
268
|
+
const topic = event.data.raw?.topic;
|
|
269
|
+
|
|
270
|
+
if (topic === 'crypto_prices') {
|
|
271
|
+
console.log(`BTC: $${event.data.price}`);
|
|
272
|
+
} else if (topic === 'activity') {
|
|
273
|
+
console.log(`Trade: ${event.data.side} ${event.data.size} @ ${event.data.price}`);
|
|
274
|
+
}
|
|
139
275
|
}
|
|
140
276
|
}
|
|
141
277
|
|
|
142
278
|
const runner = createEventRunner(strategy, {
|
|
143
279
|
logger,
|
|
144
|
-
|
|
145
|
-
|
|
280
|
+
polymarket: {
|
|
281
|
+
walletAddress: '0x...',
|
|
282
|
+
// clobAuth: { key, secret, passphrase } for clob_user subscriptions
|
|
283
|
+
},
|
|
146
284
|
}, context);
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
#### Polymarket Subscription Types
|
|
288
|
+
|
|
289
|
+
| Type | Description | Auth Required |
|
|
290
|
+
|------|-------------|---------------|
|
|
291
|
+
| `crypto_prices` | Real-time BTC/ETH/etc prices | No |
|
|
292
|
+
| `activity` | Global trade activity feed | No |
|
|
293
|
+
| `clob_market` | Orderbook, price changes for specific market | No |
|
|
294
|
+
| `comments` | Comments and reactions | No |
|
|
295
|
+
| `rfq` | Request for Quote events | No |
|
|
296
|
+
| `clob_user` | Your orders and trades | Yes (clobAuth) |
|
|
297
|
+
|
|
298
|
+
#### CryptoPricesSubscription
|
|
147
299
|
|
|
148
|
-
|
|
149
|
-
|
|
300
|
+
```typescript
|
|
301
|
+
{
|
|
302
|
+
type: 'crypto_prices',
|
|
303
|
+
symbol: 'btcusdt', // or 'ethusdt', etc.
|
|
304
|
+
eventSource: 'polymarket'
|
|
305
|
+
}
|
|
150
306
|
```
|
|
151
307
|
|
|
152
|
-
####
|
|
308
|
+
#### ActivitySubscription
|
|
153
309
|
|
|
154
310
|
```typescript
|
|
155
|
-
|
|
311
|
+
{
|
|
312
|
+
type: 'activity',
|
|
313
|
+
eventSlug: 'will-bitcoin-hit-100k', // optional filter
|
|
314
|
+
marketSlug: 'market-slug', // optional filter
|
|
315
|
+
messageType: '*', // 'trades', 'positions', or '*'
|
|
316
|
+
eventSource: 'polymarket'
|
|
317
|
+
}
|
|
156
318
|
```
|
|
157
319
|
|
|
158
|
-
####
|
|
320
|
+
#### ClobMarketSubscription
|
|
159
321
|
|
|
160
322
|
```typescript
|
|
161
|
-
|
|
162
|
-
type:
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
323
|
+
{
|
|
324
|
+
type: 'clob_market',
|
|
325
|
+
marketId: '0x1234...condition-id', // Market condition ID
|
|
326
|
+
messageType: 'agg_orderbook', // 'price_change', 'last_trade_price', 'tick_size_change', '*'
|
|
327
|
+
eventSource: 'polymarket'
|
|
328
|
+
}
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
#### ClobUserSubscription (Requires Auth)
|
|
332
|
+
|
|
333
|
+
```typescript
|
|
334
|
+
{
|
|
335
|
+
type: 'clob_user',
|
|
336
|
+
messageType: '*', // 'order', 'trade', or '*'
|
|
337
|
+
eventSource: 'polymarket'
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// Config with clobAuth:
|
|
341
|
+
const runner = createEventRunner(strategy, {
|
|
342
|
+
logger,
|
|
343
|
+
polymarket: {
|
|
344
|
+
clobAuth: {
|
|
345
|
+
key: process.env.POLYMARKET_API_KEY!,
|
|
346
|
+
secret: process.env.POLYMARKET_API_SECRET!,
|
|
347
|
+
passphrase: process.env.POLYMARKET_PASSPHRASE!,
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}, context);
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
#### CommentsSubscription
|
|
354
|
+
|
|
355
|
+
```typescript
|
|
356
|
+
{
|
|
357
|
+
type: 'comments',
|
|
358
|
+
parentEntityId: 'market-id', // optional filter
|
|
359
|
+
parentEntityType: 'market', // optional filter
|
|
360
|
+
messageType: '*', // 'comment_created', 'reaction_created', '*'
|
|
361
|
+
eventSource: 'polymarket'
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
#### RfqSubscription
|
|
366
|
+
|
|
367
|
+
```typescript
|
|
368
|
+
{
|
|
369
|
+
type: 'rfq',
|
|
370
|
+
messageType: '*',
|
|
371
|
+
eventSource: 'polymarket'
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
## Type Guards
|
|
375
|
+
|
|
376
|
+
Use type guards for runtime type checking:
|
|
377
|
+
|
|
378
|
+
```typescript
|
|
379
|
+
import {
|
|
380
|
+
// Generic subscription types
|
|
381
|
+
isMarketSubscription,
|
|
382
|
+
isWalletSubscription,
|
|
383
|
+
isOpportunitySubscription,
|
|
384
|
+
isCustomSubscription,
|
|
385
|
+
|
|
386
|
+
// Polymarket RTDS subscription types
|
|
387
|
+
isClobMarketSubscription,
|
|
388
|
+
isClobUserSubscription,
|
|
389
|
+
isActivitySubscription,
|
|
390
|
+
isCommentsSubscription,
|
|
391
|
+
isCryptoPricesSubscription,
|
|
392
|
+
isRfqSubscription,
|
|
393
|
+
|
|
394
|
+
// Source routing helpers
|
|
395
|
+
isPolymarketSubscription,
|
|
396
|
+
isOsirisSubscription
|
|
397
|
+
} from '@osiris-ai/strategy-sdk';
|
|
398
|
+
|
|
399
|
+
// Check if subscription is for Polymarket
|
|
400
|
+
if (isPolymarketSubscription(subscription)) {
|
|
401
|
+
// Subscription will be routed to Polymarket RTDS
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// Check specific Polymarket types
|
|
405
|
+
if (isClobMarketSubscription(subscription)) {
|
|
406
|
+
console.log(subscription.marketId); // TypeScript knows this is ClobMarketSubscription
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
if (isCryptoPricesSubscription(subscription)) {
|
|
410
|
+
console.log(subscription.symbol); // TypeScript knows this is CryptoPricesSubscription
|
|
173
411
|
}
|
|
174
412
|
```
|
|
175
413
|
|
|
@@ -179,20 +417,34 @@ interface EventSubscription {
|
|
|
179
417
|
|
|
180
418
|
#### `CodeStrategy`
|
|
181
419
|
|
|
182
|
-
Interface that all strategies must implement
|
|
420
|
+
Interface that all strategies must implement:
|
|
183
421
|
|
|
184
422
|
```typescript
|
|
185
423
|
interface CodeStrategy {
|
|
186
|
-
// Tick-based
|
|
424
|
+
// Tick-based execution
|
|
187
425
|
shouldTrigger?(osiris: OsirisContext): Promise<boolean>;
|
|
188
426
|
onTrigger?(osiris: OsirisContext): Promise<void>;
|
|
189
|
-
|
|
190
|
-
// Event-based
|
|
427
|
+
|
|
428
|
+
// Event-based execution
|
|
191
429
|
subscriptions?: EventSubscription[];
|
|
192
430
|
onEvent?(event: StrategyEvent, osiris: OsirisContext): Promise<void>;
|
|
193
431
|
}
|
|
194
432
|
```
|
|
195
433
|
|
|
434
|
+
#### `StrategyEvent`
|
|
435
|
+
|
|
436
|
+
Event passed to `onEvent` handler:
|
|
437
|
+
|
|
438
|
+
```typescript
|
|
439
|
+
interface StrategyEvent {
|
|
440
|
+
type: EventType;
|
|
441
|
+
timestamp: number;
|
|
442
|
+
market?: string; // For market events
|
|
443
|
+
wallet?: string; // For wallet events
|
|
444
|
+
data: EventData;
|
|
445
|
+
}
|
|
446
|
+
```
|
|
447
|
+
|
|
196
448
|
#### `OsirisContext`
|
|
197
449
|
|
|
198
450
|
The context object passed to your strategy methods:
|
|
@@ -203,21 +455,19 @@ interface OsirisContext {
|
|
|
203
455
|
hyperliquid?: HyperliquidAPI; // Available when market='hyperliquid'
|
|
204
456
|
ta: TechnicalAnalysisAPI; // Technical analysis functions
|
|
205
457
|
state: OsirisState; // State management
|
|
206
|
-
signer
|
|
207
|
-
log: (message: string, meta?: any) => void;
|
|
458
|
+
signer?: SignerAPI; // Transaction signer (if configured)
|
|
459
|
+
log: (message: string, meta?: any) => void;
|
|
208
460
|
}
|
|
209
461
|
```
|
|
210
462
|
|
|
211
463
|
### State Management
|
|
212
464
|
|
|
213
|
-
#### In
|
|
465
|
+
#### In-Memory State (for testing)
|
|
214
466
|
|
|
215
467
|
```typescript
|
|
216
|
-
|
|
217
|
-
const value = await osiris.state.get('myKey');
|
|
468
|
+
import { MemoryStateManager } from '@osiris-ai/strategy-sdk';
|
|
218
469
|
|
|
219
|
-
|
|
220
|
-
await osiris.state.set('myKey', { count: 42 });
|
|
470
|
+
const stateManager = new MemoryStateManager();
|
|
221
471
|
```
|
|
222
472
|
|
|
223
473
|
#### Redis State (for production)
|
|
@@ -232,83 +482,35 @@ const stateManager = new RedisStateManager(
|
|
|
232
482
|
);
|
|
233
483
|
|
|
234
484
|
await stateManager.connect();
|
|
235
|
-
// ... use stateManager
|
|
236
|
-
await stateManager.disconnect();
|
|
237
485
|
```
|
|
238
486
|
|
|
239
487
|
### Market APIs
|
|
240
488
|
|
|
241
|
-
####
|
|
242
|
-
|
|
243
|
-
```typescript
|
|
244
|
-
if (osiris.polymarket) {
|
|
245
|
-
// Initialize trading client (required before trading)
|
|
246
|
-
await osiris.polymarket.initializeTradingClient();
|
|
247
|
-
|
|
248
|
-
// ============================================
|
|
249
|
-
// Convenience Trading Methods (Recommended)
|
|
250
|
-
// ============================================
|
|
251
|
-
|
|
252
|
-
// Limit orders
|
|
253
|
-
await osiris.polymarket.buyLimit(tokenId, 0.65, 100); // Buy 100 shares @ $0.65
|
|
254
|
-
await osiris.polymarket.sellLimit(tokenId, 0.70, 50); // Sell 50 shares @ $0.70
|
|
255
|
-
|
|
256
|
-
// Market orders (execute immediately)
|
|
257
|
-
await osiris.polymarket.buyMarket(tokenId, 100); // Buy $100 worth
|
|
258
|
-
await osiris.polymarket.sellMarket(tokenId, 50); // Sell 50 shares
|
|
259
|
-
|
|
260
|
-
// ============================================
|
|
261
|
-
// Full Order Methods (More control)
|
|
262
|
-
// ============================================
|
|
263
|
-
|
|
264
|
-
await osiris.polymarket.createLimitOrder({
|
|
265
|
-
tokenId: '0x...',
|
|
266
|
-
price: 0.65,
|
|
267
|
-
size: 100,
|
|
268
|
-
side: 'BUY',
|
|
269
|
-
feeRateBps: '0',
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
await osiris.polymarket.createMarketOrder({
|
|
273
|
-
tokenId: '0x...',
|
|
274
|
-
amount: 100,
|
|
275
|
-
side: 'BUY',
|
|
276
|
-
slippageTolerance: 0.05,
|
|
277
|
-
});
|
|
278
|
-
|
|
279
|
-
// Order management
|
|
280
|
-
const orders = await osiris.polymarket.getOpenOrders();
|
|
281
|
-
await osiris.polymarket.cancelOrder(orderId);
|
|
282
|
-
await osiris.polymarket.cancelAllOrders();
|
|
283
|
-
|
|
284
|
-
// Market data
|
|
285
|
-
const market = await osiris.polymarket.getMarket('market-slug');
|
|
286
|
-
const markets = await osiris.polymarket.getMarkets({ active: true, limit: 50 });
|
|
287
|
-
const orderBook = await osiris.polymarket.getOrderBook(tokenId);
|
|
288
|
-
}
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
#### Hyperliquid Trading
|
|
489
|
+
#### Hyperliquid API
|
|
292
490
|
|
|
293
491
|
```typescript
|
|
294
492
|
if (osiris.hyperliquid) {
|
|
295
|
-
// Get price
|
|
296
493
|
const price = await osiris.hyperliquid.getPrice('BTC');
|
|
297
|
-
|
|
298
|
-
// Get position
|
|
299
494
|
const position = await osiris.hyperliquid.getPosition('BTC');
|
|
300
|
-
|
|
301
|
-
// Get all positions
|
|
302
495
|
const positions = await osiris.hyperliquid.getPositions();
|
|
496
|
+
}
|
|
497
|
+
```
|
|
303
498
|
|
|
304
|
-
|
|
305
|
-
const candles = await osiris.hyperliquid.getCandleSnapshot(
|
|
306
|
-
'BTC', '1d', startTime, endTime
|
|
307
|
-
);
|
|
499
|
+
#### Polymarket API
|
|
308
500
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
await osiris.
|
|
501
|
+
```typescript
|
|
502
|
+
if (osiris.polymarket) {
|
|
503
|
+
const market = await osiris.polymarket.getMarket('market-slug');
|
|
504
|
+
const markets = await osiris.polymarket.getMarkets({ active: true });
|
|
505
|
+
|
|
506
|
+
// Trading (requires initialization)
|
|
507
|
+
await osiris.polymarket.initializeTradingClient();
|
|
508
|
+
await osiris.polymarket.createLimitOrder({
|
|
509
|
+
tokenId: 'token-id',
|
|
510
|
+
side: 'BUY',
|
|
511
|
+
price: 0.5,
|
|
512
|
+
size: 10,
|
|
513
|
+
});
|
|
312
514
|
}
|
|
313
515
|
```
|
|
314
516
|
|
|
@@ -318,18 +520,13 @@ if (osiris.hyperliquid) {
|
|
|
318
520
|
// Calculate RSI
|
|
319
521
|
const rsi = osiris.ta.calculate('rsi_14', ohlcvData, { period: 14 });
|
|
320
522
|
|
|
321
|
-
// Calculate MACD
|
|
523
|
+
// Calculate MACD
|
|
322
524
|
const macd = osiris.ta.calculate('macd_12_26_9', ohlcvData, {
|
|
323
525
|
fastPeriod: 12,
|
|
324
526
|
slowPeriod: 26,
|
|
325
527
|
signalPeriod: 9
|
|
326
528
|
});
|
|
327
529
|
|
|
328
|
-
// Get specific component from multi-value indicator
|
|
329
|
-
const macdSignal = osiris.ta.calculate('macd_12_26_9', ohlcvData, {
|
|
330
|
-
component: 'signal'
|
|
331
|
-
});
|
|
332
|
-
|
|
333
530
|
// Available indicators:
|
|
334
531
|
// Single-value: rsi, sma, ema, atr, adx, obv, cci, mfi, vwap, williams_r, roc, psar, wma
|
|
335
532
|
// Multi-value: macd, bollinger_bands, stochastic, stochastic_rsi, keltner_channels
|
|
@@ -337,111 +534,44 @@ const macdSignal = osiris.ta.calculate('macd_12_26_9', ohlcvData, {
|
|
|
337
534
|
|
|
338
535
|
### Signing Transactions
|
|
339
536
|
|
|
340
|
-
#### Using Private Key Signer
|
|
341
|
-
|
|
342
537
|
```typescript
|
|
343
|
-
import { PrivateKeySigner,
|
|
538
|
+
import { PrivateKeySigner, OsirisSigner } from '@osiris-ai/strategy-sdk';
|
|
344
539
|
|
|
540
|
+
// Private key signer
|
|
345
541
|
const signer = new PrivateKeySigner({
|
|
346
542
|
privateKey: process.env.PRIVATE_KEY!,
|
|
347
543
|
});
|
|
348
544
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
const context = createOsirisContext({
|
|
352
|
-
strategyId: 'my-strategy',
|
|
353
|
-
market: 'polymarket',
|
|
354
|
-
userAddress: address!,
|
|
355
|
-
signer,
|
|
356
|
-
});
|
|
357
|
-
```
|
|
358
|
-
|
|
359
|
-
#### Using Osiris Hub Signer
|
|
360
|
-
|
|
361
|
-
```typescript
|
|
362
|
-
import { OsirisSigner, createOsirisContext } from '@osiris-ai/strategy-sdk';
|
|
363
|
-
|
|
364
|
-
const signer = new OsirisSigner({
|
|
545
|
+
// Osiris Hub signer (for managed wallets)
|
|
546
|
+
const osirisSigner = new OsirisSigner({
|
|
365
547
|
hubBaseUrl: 'https://api.osirislabs.xyz/v1',
|
|
366
|
-
accessToken:
|
|
367
|
-
connectionId:
|
|
548
|
+
accessToken: 'your-oauth-token',
|
|
549
|
+
connectionId: 'wallet-connection-id',
|
|
368
550
|
});
|
|
369
551
|
|
|
552
|
+
// Use in context
|
|
370
553
|
const context = createOsirisContext({
|
|
371
554
|
strategyId: 'my-strategy',
|
|
372
555
|
market: 'polymarket',
|
|
373
|
-
userAddress:
|
|
556
|
+
userAddress: signer.getAddress()!,
|
|
374
557
|
signer,
|
|
375
|
-
polymarketOptions: {
|
|
376
|
-
useMcpForOrders: true,
|
|
377
|
-
mcpUrl: 'https://gateway.backend.osirislabs.xyz/@osiris/polymarket/mcp',
|
|
378
|
-
mcpAccessToken: process.env.MCP_ACCESS_TOKEN!,
|
|
379
|
-
},
|
|
380
558
|
});
|
|
381
559
|
```
|
|
382
560
|
|
|
383
|
-
### Logging
|
|
384
|
-
|
|
385
|
-
```typescript
|
|
386
|
-
import { createConsoleLogger } from '@osiris-ai/strategy-sdk';
|
|
387
|
-
|
|
388
|
-
const logger = createConsoleLogger();
|
|
389
|
-
```
|
|
390
|
-
|
|
391
561
|
## Examples
|
|
392
562
|
|
|
393
|
-
See the `examples/` directory:
|
|
563
|
+
See the `examples/` directory for complete working examples:
|
|
394
564
|
|
|
395
|
-
- `example-
|
|
396
|
-
- `example-polymarket.ts` - Polymarket
|
|
397
|
-
- `example-event-strategy.ts` - Price alert strategy (event-based)
|
|
398
|
-
- `example-usage.ts` - Complete usage examples
|
|
399
|
-
- `example-signer.ts` - Signer usage examples
|
|
400
|
-
|
|
401
|
-
## Strategy Patterns
|
|
402
|
-
|
|
403
|
-
### Tick-Based Strategy Pattern
|
|
404
|
-
|
|
405
|
-
```typescript
|
|
406
|
-
class MyTickStrategy implements CodeStrategy {
|
|
407
|
-
async shouldTrigger(osiris: OsirisContext): Promise<boolean> {
|
|
408
|
-
// Called every tick - return true to execute
|
|
409
|
-
return true;
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
async onTrigger(osiris: OsirisContext): Promise<void> {
|
|
413
|
-
// Your trading logic
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
```
|
|
417
|
-
|
|
418
|
-
### Event-Based Strategy Pattern
|
|
419
|
-
|
|
420
|
-
```typescript
|
|
421
|
-
class MyEventStrategy implements CodeStrategy {
|
|
422
|
-
subscriptions: EventSubscription[] = [
|
|
423
|
-
{ type: 'price', market: 'BTC-USD', conditions: { priceChangePercent: 5 } }
|
|
424
|
-
];
|
|
425
|
-
|
|
426
|
-
async onEvent(event: StrategyEvent, osiris: OsirisContext): Promise<void> {
|
|
427
|
-
// Triggered by real-time events
|
|
428
|
-
osiris.log(`Event: ${event.type} - ${JSON.stringify(event.data)}`);
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
```
|
|
565
|
+
- `example-event-strategy.ts` - Event-based price alert strategy
|
|
566
|
+
- `example-polymarket-events.ts` - Polymarket RTDS integration
|
|
432
567
|
|
|
433
568
|
## Best Practices
|
|
434
569
|
|
|
435
|
-
1. **
|
|
436
|
-
2. **
|
|
437
|
-
3. **
|
|
438
|
-
4. **
|
|
439
|
-
5. **
|
|
440
|
-
6. **Execution Mode**: Choose tick-based for polling, event-based for real-time reactions
|
|
441
|
-
|
|
442
|
-
## TypeScript Support
|
|
443
|
-
|
|
444
|
-
The SDK is written in TypeScript and provides full type definitions. All types are exported.
|
|
570
|
+
1. **Choose the right execution mode**: Use tick-based for periodic checks, event-based for real-time reactions
|
|
571
|
+
2. **State Management**: Use `osiris.state` for persistent data that should survive restarts
|
|
572
|
+
3. **Error Handling**: Always wrap API calls in try-catch blocks
|
|
573
|
+
4. **Rate Limiting**: Be mindful of API rate limits when making frequent calls
|
|
574
|
+
5. **Testing**: Use `MemoryStateManager` for testing, `RedisStateManager` for production
|
|
445
575
|
|
|
446
576
|
## License
|
|
447
577
|
|