SDK for writing and running trading strategies with Polymarket and Hyperliquid integrations
npm install @vesper85/strategy-sdkSDK for writing and running trading strategies with Polymarket and Hyperliquid integrations.
- TypeScript-first: Full type safety with IntelliSense support
- Market Integrations: Polymarket and Hyperliquid APIs
- Technical Analysis: Built-in technical indicators (RSI, MACD, Bollinger Bands, etc.)
- State Management: In-memory or Redis-backed persistent state
- Dual Execution Modes: Tick-based (polling) or Event-based (real-time WebSocket)
- Flexible Logging: Use built-in console logger or provide your own
- Transaction Signing: Support for both Osiris Hub signing and private key signing (EVM & Solana)
``bash`
npm install @vesper85/strategy-sdkor
pnpm add @vesper85/strategy-sdkor
yarn add @vesper85/strategy-sdk
Note: This package supports both ESM and CommonJS. You can use it in either type of project without needing to add "type": "module" to your package.json.
`typescript
import type { OsirisContext, CodeStrategy } from '@vesper85/strategy-sdk';
export default class MyStrategy implements CodeStrategy {
async shouldTrigger(osiris: OsirisContext): Promise
// Return true when you want to execute the strategy
return true;
}
async onTrigger(osiris: OsirisContext): Promise
// Your trading logic here
if (osiris.hyperliquid) {
const price = await osiris.hyperliquid.getPrice('BTC');
osiris.log(Current BTC price: ${price});`
}
}
}
`typescript
import type {
CodeStrategy,
EventSubscription,
StrategyEvent,
OsirisContext
} from '@vesper85/strategy-sdk';
export class PriceAlertStrategy implements CodeStrategy {
// Define what events to subscribe to
subscriptions: EventSubscription[] = [
{
type: 'price',
market: 'BTC-USD',
conditions: { priceChangePercent: 5 }
}
];
// Called when subscribed events occur
async onEvent(event: StrategyEvent, osiris: OsirisContext): Promise
osiris.log(Price event for ${event.market}: ${event.data.price});`
}
}
`typescript
import {
createOsirisContext,
createConsoleLogger,
createStrategyEngine,
createEventRunner,
PrivateKeySigner,
} from '@osiris-ai/strategy-sdk';
async function main() {
const logger = createConsoleLogger();
const signer = new PrivateKeySigner({
privateKey: process.env.PRIVATE_KEY!,
});
const context = createOsirisContext({
strategyId: 'my-strategy',
market: 'hyperliquid',
userAddress: signer.getAddress()!,
signer,
});
// For tick-based strategies
const engine = createStrategyEngine(strategy, context, {
logger,
tickIntervalMs: 60000,
});
engine.start();
// For event-based strategies
const runner = createEventRunner(strategy, {
logger,
eventSourceUrl: 'wss://events.example.com/ws',
}, context);
runner.start();
}
`
The SDK supports two mutually exclusive execution modes:
Runs your strategy at fixed intervals. Best for strategies that check conditions periodically.
`typescript`
interface CodeStrategy {
shouldTrigger(osiris: OsirisContext): Promise
onTrigger(osiris: OsirisContext): Promise
}
`typescript
import { createStrategyEngine } from '@vesper85/strategy-sdk';
const engine = createStrategyEngine(strategy, context, {
logger,
strategyId: 'my-strategy',
tickIntervalMs: 60000, // Run every 60 seconds
});
engine.start();
// engine.stop();
`
Reacts to real-time events from WebSocket streams. Best for strategies that need immediate response to market changes.
`typescript`
interface CodeStrategy {
subscriptions: EventSubscription[];
onEvent(event: StrategyEvent, osiris: OsirisContext): Promise
}
The SDK uses a discriminated union for type-safe event subscriptions:
Subscribe to market events (price, orderbook, trade, fill):
`typescript`
{
type: 'price', // or 'orderbook', 'trade', 'fill'
market: 'BTC-USD',
eventSource: 'polymarket', // optional
conditions: {
priceChangePercent: 5,
volumeAbove: 10000,
}
}
Subscribe to wallet analysis events (Osiris Pub/Sub only):
`typescript`
{
type: 'wallet',
wallet: '0x1234567890abcdef...',
conditions: {
minWinRate: 60,
minTradeCount: 10,
}
}
Subscribe to trading opportunities (Osiris Pub/Sub only):
`typescript`
{
type: 'opportunity',
filter: 'wide_spread_markets', // optional, defaults to 'all'
conditions: {
minScore: 70,
}
}
Subscribe to custom topics:
`typescript`
{
type: 'custom',
topic: 'custom:my-topic',
}
Connect to Osiris analytics WebSocket for market analysis, wallet tracking, and opportunities:
`typescript`
const runner = createEventRunner(strategy, {
logger,
eventSourceUrl: 'wss://your-osiris-server.com/ws',
}, context);
Supported topics:
- market:{slug} - Market analysis eventswallet:{address}
- - Wallet analysis eventsopps:{filter}
- - Trading opportunities
Connect directly to Polymarket's Real-Time Data Socket for live market data.
#### Strategy-Based Usage
Set eventSource: 'polymarket' in your subscriptions:
`typescript
import type {
CodeStrategy,
EventSubscription,
StrategyEvent,
CryptoPricesSubscription,
ActivitySubscription,
ClobMarketSubscription,
CommentsSubscription
} from '@vesper85/strategy-sdk';
class MyPolymarketStrategy implements CodeStrategy {
subscriptions: EventSubscription[] = [
// Crypto price updates
{ type: 'crypto_prices', symbol: 'btcusdt', eventSource: 'polymarket' },
// Trade activity feed
{ type: 'activity', messageType: '*', eventSource: 'polymarket' },
// CLOB orderbook data (requires market condition ID)
{ type: 'clob_market', marketId: 'condition-id', messageType: 'agg_orderbook', eventSource: 'polymarket' },
// Comments and reactions
{ type: 'comments', messageType: '*', eventSource: 'polymarket' },
];
async onEvent(event: StrategyEvent, osiris: OsirisContext): Promise
const topic = event.data.raw?.topic;
if (topic === 'crypto_prices') {
console.log(BTC: $${event.data.price});Trade: ${event.data.side} ${event.data.size} @ ${event.data.price}
} else if (topic === 'activity') {
console.log();
}
}
}
const runner = createEventRunner(strategy, {
logger,
polymarket: {
walletAddress: '0x...',
// clobAuth: { key, secret, passphrase } for clob_user subscriptions
},
}, context);
`
#### Polymarket Subscription Types
| Type | Description | Auth Required |
|------|-------------|---------------|
| crypto_prices | Real-time BTC/ETH/etc prices | No |activity
| | Global trade activity feed | No |clob_market
| | Orderbook, price changes for specific market | No |comments
| | Comments and reactions | No |rfq
| | Request for Quote events | No |clob_user
| | Your orders and trades | Yes (clobAuth) |
#### CryptoPricesSubscription
`typescript`
{
type: 'crypto_prices',
symbol: 'btcusdt', // or 'ethusdt', etc.
eventSource: 'polymarket'
}
#### ActivitySubscription
`typescript`
{
type: 'activity',
eventSlug: 'will-bitcoin-hit-100k', // optional filter
marketSlug: 'market-slug', // optional filter
messageType: '', // 'trades', 'positions', or ''
eventSource: 'polymarket'
}
#### ClobMarketSubscription
`typescript`
{
type: 'clob_market',
marketId: '0x1234...condition-id', // Market condition ID
messageType: 'agg_orderbook', // 'price_change', 'last_trade_price', 'tick_size_change', '*'
eventSource: 'polymarket'
}
#### ClobUserSubscription (Requires Auth)
`typescript
{
type: 'clob_user',
messageType: '', // 'order', 'trade', or ''
eventSource: 'polymarket'
}
// Config with clobAuth:
const runner = createEventRunner(strategy, {
logger,
polymarket: {
clobAuth: {
key: process.env.POLYMARKET_API_KEY!,
secret: process.env.POLYMARKET_API_SECRET!,
passphrase: process.env.POLYMARKET_PASSPHRASE!,
}
}
}, context);
`
#### CommentsSubscription
`typescript`
{
type: 'comments',
parentEntityId: 'market-id', // optional filter
parentEntityType: 'market', // optional filter
messageType: '', // 'comment_created', 'reaction_created', ''
eventSource: 'polymarket'
}
#### RfqSubscription
`typescript`
{
type: 'rfq',
messageType: '*',
eventSource: 'polymarket'
}
Use type guards for runtime type checking:
`typescript
import {
// Generic subscription types
isMarketSubscription,
isWalletSubscription,
isOpportunitySubscription,
isCustomSubscription,
// Polymarket RTDS subscription types
isClobMarketSubscription,
isClobUserSubscription,
isActivitySubscription,
isCommentsSubscription,
isCryptoPricesSubscription,
isRfqSubscription,
// Source routing helpers
isPolymarketSubscription,
isOsirisSubscription
} from '@vesper85/strategy-sdk';
// Check if subscription is for Polymarket
if (isPolymarketSubscription(subscription)) {
// Subscription will be routed to Polymarket RTDS
}
// Check specific Polymarket types
if (isClobMarketSubscription(subscription)) {
console.log(subscription.marketId); // TypeScript knows this is ClobMarketSubscription
}
if (isCryptoPricesSubscription(subscription)) {
console.log(subscription.symbol); // TypeScript knows this is CryptoPricesSubscription
}
`
#### CodeStrategy
Interface that all strategies must implement:
`typescript
interface CodeStrategy {
// Tick-based execution
shouldTrigger?(osiris: OsirisContext): Promise
onTrigger?(osiris: OsirisContext): Promise
// Event-based execution
subscriptions?: EventSubscription[];
onEvent?(event: StrategyEvent, osiris: OsirisContext): Promise
}
`
#### StrategyEvent
Event passed to onEvent handler:
`typescript`
interface StrategyEvent {
type: EventType;
timestamp: number;
market?: string; // For market events
wallet?: string; // For wallet events
data: EventData;
}
#### OsirisContext
The context object passed to your strategy methods:
`typescript`
interface OsirisContext {
polymarket?: PolymarketAPI; // Available when market='polymarket'
hyperliquid?: HyperliquidAPI; // Available when market='hyperliquid'
ta: TechnicalAnalysisAPI; // Technical analysis functions
state: OsirisState; // State management
signer?: SignerAPI; // Transaction signer (if configured)
log: (message: string, meta?: any) => void;
}
#### In-Memory State (for testing)
`typescript
import { MemoryStateManager } from '@vesper85/strategy-sdk';
const stateManager = new MemoryStateManager();
`
#### Redis State (for production)
`typescript
import { RedisStateManager } from '@vesper85/strategy-sdk';
const stateManager = new RedisStateManager(
'redis://localhost:6379',
'strategy-id',
logger
);
await stateManager.connect();
`
#### Hyperliquid API
`typescript`
if (osiris.hyperliquid) {
const price = await osiris.hyperliquid.getPrice('BTC');
const position = await osiris.hyperliquid.getPosition('BTC');
const positions = await osiris.hyperliquid.getPositions();
}
#### Polymarket API
`typescript
if (osiris.polymarket) {
const market = await osiris.polymarket.getMarket('market-slug');
const markets = await osiris.polymarket.getMarkets({ active: true });
// Trading (requires initialization)
await osiris.polymarket.initializeTradingClient();
await osiris.polymarket.createLimitOrder({
tokenId: 'token-id',
side: 'BUY',
price: 0.5,
size: 10,
});
}
`
`typescript
// Calculate RSI
const rsi = osiris.ta.calculate('rsi_14', ohlcvData, { period: 14 });
// Calculate MACD
const macd = osiris.ta.calculate('macd_12_26_9', ohlcvData, {
fastPeriod: 12,
slowPeriod: 26,
signalPeriod: 9
});
// Available indicators:
// Single-value: rsi, sma, ema, atr, adx, obv, cci, mfi, vwap, williams_r, roc, psar, wma
// Multi-value: macd, bollinger_bands, stochastic, stochastic_rsi, keltner_channels
`
`typescript
import { PrivateKeySigner, OsirisSigner } from '@vesper85/strategy-sdk';
// Private key signer
const signer = new PrivateKeySigner({
privateKey: process.env.PRIVATE_KEY!,
});
// Osiris Hub signer (for managed wallets)
const osirisSigner = new OsirisSigner({
hubBaseUrl: 'https://api.osirislabs.xyz/v1',
accessToken: 'your-oauth-token',
connectionId: 'wallet-connection-id',
});
// Use in context
const context = createOsirisContext({
strategyId: 'my-strategy',
market: 'polymarket',
userAddress: signer.getAddress()!,
signer,
});
`
See the examples/ directory for complete working examples:
- example-event-strategy.ts - Event-based price alert strategyexample-polymarket-events.ts
- - Polymarket RTDS integration
1. Choose the right execution mode: Use tick-based for periodic checks, event-based for real-time reactions
2. State Management: Use osiris.state for persistent data that should survive restartsMemoryStateManager
3. Error Handling: Always wrap API calls in try-catch blocks
4. Rate Limiting: Be mindful of API rate limits when making frequent calls
5. Testing: Use for testing, RedisStateManager` for production
MIT