@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 CHANGED
@@ -24,7 +24,7 @@ yarn add @osiris-ai/strategy-sdk
24
24
 
25
25
  ## Quick Start
26
26
 
27
- ### 1. Create a Strategy (Tick-Based)
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. Run the Strategy
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
- runStrategy,
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', // or 'polymarket'
95
+ market: 'hyperliquid',
71
96
  userAddress: signer.getAddress()!,
72
97
  signer,
73
98
  });
74
99
 
75
- // Create strategy instance
76
- const strategy = new MyStrategy();
77
-
78
- // Run strategy once
79
- await runStrategy(strategy, { logger }, context);
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', // Optional, for logging
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 your WebSocket server. Best for reactive strategies (price alerts, arbitrage, etc.)
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 { createEventRunner, type EventSubscription, type StrategyEvent } from '@osiris-ai/strategy-sdk';
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 PriceAlertStrategy implements CodeStrategy {
252
+ class MyPolymarketStrategy implements CodeStrategy {
128
253
  subscriptions: EventSubscription[] = [
129
- {
130
- type: 'price',
131
- market: 'BTC-USD',
132
- conditions: { priceChangePercent: 5 }
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
- osiris.log(`Price changed: ${event.data.changePercent}%`);
138
- // React to price change...
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
- eventSourceUrl: 'wss://your-event-server.com/ws',
145
- strategyId: 'price-alert', // Optional
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
- runner.start();
149
- // runner.stop();
300
+ ```typescript
301
+ {
302
+ type: 'crypto_prices',
303
+ symbol: 'btcusdt', // or 'ethusdt', etc.
304
+ eventSource: 'polymarket'
305
+ }
150
306
  ```
151
307
 
152
- #### Event Types
308
+ #### ActivitySubscription
153
309
 
154
310
  ```typescript
155
- type EventType = 'price' | 'orderbook' | 'time' | 'trade' | 'fill' | 'liquidation' | 'custom';
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
- #### Event Subscriptions
320
+ #### ClobMarketSubscription
159
321
 
160
322
  ```typescript
161
- interface EventSubscription {
162
- type: EventType;
163
- market?: string;
164
- conditions?: {
165
- priceAbove?: number;
166
- priceBelow?: number;
167
- priceChangePercent?: number;
168
- spreadAbove?: number;
169
- volumeAbove?: number;
170
- cron?: string;
171
- interval?: number;
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 (choose one execution mode):
420
+ Interface that all strategies must implement:
183
421
 
184
422
  ```typescript
185
423
  interface CodeStrategy {
186
- // Tick-based (optional if using event-based)
424
+ // Tick-based execution
187
425
  shouldTrigger?(osiris: OsirisContext): Promise<boolean>;
188
426
  onTrigger?(osiris: OsirisContext): Promise<void>;
189
-
190
- // Event-based (optional if using tick-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: SignerAPI; // Transaction signer
207
- log: (message: string, meta?: any) => void; // Logging function
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 Strategy
465
+ #### In-Memory State (for testing)
214
466
 
215
467
  ```typescript
216
- // Get state
217
- const value = await osiris.state.get('myKey');
468
+ import { MemoryStateManager } from '@osiris-ai/strategy-sdk';
218
469
 
219
- // Set state
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
- #### Polymarket Trading
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
- // Get candle data
305
- const candles = await osiris.hyperliquid.getCandleSnapshot(
306
- 'BTC', '1d', startTime, endTime
307
- );
499
+ #### Polymarket API
308
500
 
309
- // Execute trades
310
- await osiris.hyperliquid.buy('BTC', 0.1);
311
- await osiris.hyperliquid.sell('BTC', 0.1);
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 (returns [MACD, signal, histogram])
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, createOsirisContext } from '@osiris-ai/strategy-sdk';
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
- const address = signer.getAddress();
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: process.env.OSIRIS_ACCESS_TOKEN!,
367
- connectionId: process.env.WALLET_CONNECTION_ID!,
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: '0x...',
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-rsi.ts` - RSI-based trading strategy (tick-based)
396
- - `example-polymarket.ts` - Polymarket arbitrage strategy (tick-based)
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. **State Management**: Use `osiris.state` for persistent data that should survive restarts
436
- 2. **Error Handling**: Always wrap API calls in try-catch blocks
437
- 3. **Rate Limiting**: Be mindful of API rate limits when making frequent calls
438
- 4. **Testing**: Use `MemoryStateManager` for testing, `RedisStateManager` for production
439
- 5. **Logging**: Use `osiris.log()` for strategy-specific logs
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