Package Exports
- @junduck/trading-core
Readme
trading-core
Foundation data structures and utilities for spot market trading bookkeeping, backtesting, and algorithmic trading.
What It Does
This library provides comprehensive building blocks for trading systems in two main areas:
1. Trading Bookkeeping
- Position tracking - Long and short positions with lot-level accounting (FIFO/LIFO)
- Portfolio management - Multi-currency positions with corporate actions support
- Order validation - Pre-execution order checking
- Portfolio valuation - Real-time value and P&L calculations
- Market data - Price snapshots, quotes, and bars
- Corporate actions - Stock splits, dividends, spinoffs, mergers, hard forks, airdrops
2. Algorithm Foundations
- Data structures - CircularBuffer, Deque, PriorityQueue, RBTree
- Online statistics - O(1) cumulative mean, variance, covariance, correlation, beta, skewness, kurtosis
- Rolling statistics - Sliding window SMA, EMA, EWMA, variance, z-scores (O(1)), min/max (O(1)), median/quantile (O(n))
- Numeric utilities - Array-based stats (mean, variance, correlation), series transforms (returns, lag/lead, winsorize), ranking (argsort, spearman)
- Probabilistic structures - CountMinSketch, BloomFilter
- Performance metrics - Drawdown/drawup calculations with Kahan summation for numerical stability
What It Does NOT Do
This library provides primitives, not complete systems. It does NOT include:
- Strategy engines or signal generation
- Matching engines or broker simulators
- Backtesting frameworks or event loops
- Data fetching or storage
- Charting or visualization
Installation
npm install @junduck/trading-coreQuick Start
Bookkeeping: Create a Portfolio
import { pu } from "@junduck/trading-core";
// Create portfolio
const portfolio = pu.create("my-portfolio", "My Trading Portfolio");
// Initialize USD position with cash
pu.createPosition(portfolio, "USD", 100000);Bookkeeping: Open a Long Position
import { pu } from "@junduck/trading-core";
import type { Asset } from "@junduck/trading-core";
const asset: Asset = {
symbol: "AAPL",
currency: "USD"
};
pu.openLong(portfolio, asset, 150, 100, 1);Bookkeeping: Close a Position
import { pu } from "@junduck/trading-core";
pu.closeLong(portfolio, asset, 160, 50, 1, "FIFO");Calculate Portfolio Value
import { appraisePortfolio } from "@junduck/trading-core";
import type { MarketSnapshot } from "@junduck/trading-core";
const snapshot: MarketSnapshot = {
timestamp: new Date(),
price: new Map([
["AAPL", 155],
["TSLA", 200]
])
};
const values = appraisePortfolio(portfolio, snapshot);
console.log(`USD Portfolio Value: $${values.get("USD")}`);Calculate Unrealized P&L
import { calculateUnrealizedPnL } from "@junduck/trading-core";
const position = portfolio.positions.get("USD")!;
const unrealizedPnL = calculateUnrealizedPnL(position, snapshot);
console.log(`Unrealized P&L: $${unrealizedPnL}`);Bookkeeping: Validate an Order
import { validateOrder } from "@junduck/trading-core";
import type { Order } from "@junduck/trading-core";
const order: Order = {
id: "order-1",
symbol: "AAPL",
side: "BUY",
effect: "OPEN_LONG",
type: "MARKET",
quantity: 100,
created: new Date()
};
const position = portfolio.positions.get("USD")!;
const result = validateOrder(order, position, snapshot);
if (!result.valid) {
console.error(`Order invalid: ${result.error?.type}`);
}Algorithms: Rolling Window Statistics
import { SMA, EMA, RollingStddev } from "@junduck/trading-core";
// Simple Moving Average
const sma = new SMA({ period: 20 });
sma.update(100); // returns 100
sma.update(102); // returns 101
// Exponential Moving Average
const ema = new EMA({ period: 12 });
ema.update(100);
ema.update(105);
// Rolling Standard Deviation
const std = new RollingStddev({ period: 20 });
const { mean, stddev } = std.update(100);Algorithms: Online Statistics
import { CMA, CuVar, CuCorr } from "@junduck/trading-core";
// Cumulative Moving Average
const cma = new CMA();
cma.update(100); // returns 100
cma.update(200); // returns 150
// Cumulative Variance
const variance = new CuVar({ ddof: 1 });
const { mean, variance: v } = variance.update(100);
// Cumulative Correlation
const corr = new CuCorr();
const { corr: correlation } = corr.update(100, 200);Algorithms: Performance Metrics
import { CircularBuffer, maxDrawDown, maxRelDrawDown } from "@junduck/trading-core";
const equity = new CircularBuffer<number>(1000);
equity.push(100000);
equity.push(105000);
equity.push(102000);
equity.push(108000);
const mdd = maxDrawDown(equity); // Absolute drawdown
const relMdd = maxRelDrawDown(equity); // Percentage drawdownAlgorithms: Numeric Utilities
import {
mean, stddev, corr, spearman,
returns, logReturns, winsorize,
argsort, rank
} from "@junduck/trading-core";
// Basic statistics
const prices = [100, 102, 98, 105, 103];
const avg = mean(prices); // 101.6
const std = stddev(prices, 1); // sample stddev
// Returns
const rets = returns(prices); // [0.02, -0.039, 0.071, -0.019]
const logRets = logReturns(prices); // log returns
// Correlation
const x = [1, 2, 3, 4, 5];
const y = [2, 4, 5, 4, 5];
const pearson = corr(x, y); // Pearson correlation
const spear = spearman(x, y); // Spearman rank correlation
// Ranking
const ranks = rank(prices); // [0, 0.5, 0, 1, 0.75]
const sorted = argsort(prices); // [2, 0, 1, 4, 3]
// Data preparation
const clean = winsorize(prices, { lower: 0.05, upper: 0.95 });Core Data Structures
Algorithm Foundations
Containers:
CircularBuffer<T>- Fixed-size circular buffer with O(1) push/popDeque<T>- Double-ended queuePriorityQueue<T>- Min-heap based priority queueRBTree<T>- Red-Black Tree for sorted operations
Online Statistics (Cumulative):
CMA- Cumulative moving averageCuVar,CuStddev- Variance and standard deviationCuCov,CuCorr,CuBeta- Covariance, correlation, betaCuSkew,CuKurt- Skewness and kurtosisCuHistogram- Dynamic histogram
Rolling Window Statistics:
SMA,EMA,EWMA- Moving averagesRollingVar,RollingStddev- Variance and standard deviationRollingVarEW,RollingStddevEW- Exponentially weighted variantsRollingZScore,RollingZScoreEW- Standardized scoresRollingCov,RollingCorr,RollingBeta- Covariance, correlation, betaRollingMin,RollingMax,RollingMinMax- Extrema trackingRollingArgMin,RollingArgMax- Extrema with indicesRollingMedian,RollingQuantile- Order statistics (O(n) using QuickSelect)RollingSkew,RollingKurt- Higher momentsRollingHistogram- Rolling histogram
Probabilistic Structures:
CountMinSketch- Space-efficient frequency estimationBloomFilter- Probabilistic set membership
Utilities:
Kahan- Numerically stable summationSmoothedAccum- Exponential smoothingmaxDrawDown(),maxRelDrawDown()- Drawdown metricsmaxDrawUp(),maxRelDrawUp()- Drawup metricsexp_factor(),wilders_factor()- Smoothing factors
Numeric Utilities (Array-based):
sum,min,max,argmin,argmax- Array aggregationsmean,variance,stddev,skew,kurt- Descriptive statisticscov,corr,spearman- Correlation measuresmedian,quantile- Order statisticscumsum,diff,pctChange,returns,logReturns- Series transformsnorm,lag,lead,coalesce,locf,winsorize- Data preparationargsort,rank- Ranking utilitiesgcd,lcm,lerp,clamp- Math utilities
Bookkeeping Structures
Position - Represents a currency account with:
- Cash balance
- Long positions (Map of symbol → LongPosition)
- Short positions (Map of symbol → ShortPosition)
- Realized P&L and commission tracking
Portfolio - Multi-currency portfolio containing:
- Map of currency → Position
- Portfolio metadata (id, name, timestamps)
Order & Fill:
- Order: Trading intent (BUY/SELL with OPEN/CLOSE effect)
- Fill: Actual execution record (price, quantity, commission)
Market Data:
- MarketSnapshot: Point-in-time market prices
- MarketQuote: Bid/ask quotes
- MarketBar: OHLCV bars
- Universe: Collection of tradable assets
API Reference
Portfolio Utils
All portfolio utilities are under the pu namespace to avoid naming conflicts with position-level utilities (both have openLong, closeLong, openShort, closeShort functions).
Portfolio Management:
pu.create(id, name)- Create a new portfoliopu.createPosition(portfolio, currency, initialCash?, time?)- Create a position in portfoliopu.getPosition(portfolio, currency)- Get position for currencypu.getCash(portfolio, currency)- Get cash balance for currencypu.getCurrencies(portfolio)- Get all currency codes in portfoliopu.getAllSymbols(portfolio)- Get all symbols organized by currencypu.hasAsset(portfolio, asset)- Check if asset exists in portfolio
Trading (Portfolio-level):
pu.openLong(portfolio, asset, price, quantity, commission?, time?)- Open or add to long positionpu.closeLong(portfolio, asset, price, quantity, commission?, strategy?, time?)- Close long positionpu.openShort(portfolio, asset, price, quantity, commission?, time?)- Open or add to short positionpu.closeShort(portfolio, asset, price, quantity, commission?, strategy?, time?)- Close short position
Corporate Actions (Portfolio-level):
pu.handleSplit(portfolio, asset, ratio, time?)- Handle stock splitpu.handleCashDividend(portfolio, asset, amountPerShare, taxRate?, time?)- Handle cash dividendpu.handleSpinoff(portfolio, asset, newSymbol, ratio, time?)- Handle spinoffpu.handleMerger(portfolio, asset, newSymbol, ratio, cashComponent?, time?)- Handle merger
Crypto Actions (Portfolio-level):
pu.handleHardFork(portfolio, asset, newSymbol, ratio?, time?)- Handle hard forkpu.handleAirdrop(portfolio, currency, holderSymbol, airdropSymbol, amountPerToken?, fixedAmount?, time?)- Handle airdroppu.handleTokenSwap(portfolio, asset, newSymbol, ratio?, time?)- Handle token swappu.handleStakingReward(portfolio, asset, rewardPerToken, time?)- Handle staking rewards
Position Utils
Position-level functions (exported directly):
createPosition(initialCash?, time?)- Create a Position objectopenLong(pos, symbol, price, quantity, commission?, time?)- Open or add to long positioncloseLong(pos, symbol, price, quantity, commission?, strategy?, time?)- Close long positionopenShort(pos, symbol, price, quantity, commission?, time?)- Open or add to short positioncloseShort(pos, symbol, price, quantity, commission?, strategy?, time?)- Close short positionvalidatePosition(pos)- Validate position integrity
Market Utils
createUniverse(assets, timestamp?)- Create a Universe with filtering capabilitiesappraisePosition(position, snapshot)- Calculate total position valueappraisePortfolio(portfolio, snapshot)- Calculate portfolio value across currenciescalculateUnrealizedPnL(position, snapshot)- Calculate unrealized profit/lossisAssetValidAt(asset, timestamp)- Check if asset is valid at timestamp
Fill Utils
applyFill(position, fill, closeStrategy?)- Apply a single fill to positionapplyFills(position, fills, closeStrategy?)- Apply multiple fills sequentially
Order Validation
validateOrder(order, position, snapshot)- Validate order against position and market state
Example: Complete Trading Flow
import {
pu,
appraisePortfolio,
calculateUnrealizedPnL,
validateOrder
} from "@junduck/trading-core";
import type { Asset, Order, MarketSnapshot } from "@junduck/trading-core";
// 1. Create portfolio with initial cash
const portfolio = pu.create("backtest-1", "Momentum Strategy");
pu.createPosition(portfolio, "USD", 100000);
// 2. Define asset and market data
const aapl: Asset = { symbol: "AAPL", currency: "USD" };
const snapshot1: MarketSnapshot = {
timestamp: new Date("2024-01-01"),
price: new Map([["AAPL", 150]])
};
// 3. Validate and execute buy order
const buyOrder: Order = {
id: "order-1",
symbol: "AAPL",
side: "BUY",
effect: "OPEN_LONG",
type: "MARKET",
quantity: 100,
created: new Date("2024-01-01")
};
const validation = validateOrder(buyOrder, usdPos, snapshot1);
if (validation.valid) {
pu.openLong(portfolio, aapl, 150, 100, 1);
}
// 4. Check portfolio value after some time
const snapshot2: MarketSnapshot = {
timestamp: new Date("2024-02-01"),
price: new Map([["AAPL", 160]])
};
const position = portfolio.positions.get("USD")!;
const unrealizedPnL = calculateUnrealizedPnL(position, snapshot2);
const totalValue = appraisePortfolio(portfolio, snapshot2).get("USD")!;
console.log(`Unrealized P&L: $${unrealizedPnL}`);
console.log(`Total Value: $${totalValue}`);
// 5. Close position
pu.closeLong(portfolio, aapl, 160, 100, 1, "FIFO");
console.log(`Realized P&L: $${position.realisedPnL}`);Testing
npm test # Run all tests
npm run test:watch # Watch mode
npm run test:ui # UI mode
npm run test:coverage # Coverage reportBuilding
npm run build # Build to dist/
npm run dev # Watch mode
npm run typecheck # Type checking onlyLicense
MIT
Credits
Documentation and core implementation assistance by Claude (Anthropic).