Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@junduck/trading-core

junduck294MIT2.13.0TypeScript support: included

Foundation data structures and utilities for spot market trading bookkeeping, backtesting, and algorithmic trading

trading, backtest, portfolio, position, spot-market, bookkeeping, finance, investment, algorithm, statistics, rolling-window, technical-analysis, data-structures

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 management - Full order lifecycle tracking
  • 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-core

Quick Start

This library supports two approaches for managing positions, depending on your needs:

Bookkeeping Style 1: Direct Position Manipulation

For simpler workflows where you already have execution prices and quantities. Ideal for backtesting, importing trades, and simple portfolio tracking.

createPosition() → Position(initial cash)
   |
   |-- openLong/closeLong/openShort/closeShort() → Position updated
   |
   |-- market conditions update
   |
   |-- appraisePosition/appraisePortfolio() → Portfolio value
import { createPosition, openLong, closeLong, appraisePosition } from "@junduck/trading-core";

const position = createPosition(100_000);
openLong(position, "BTC", 50_000, 10, 10);
closeLong(position, "BTC", 55_000, 5, 10, "FIFO");

// Market update
const snapshot = { price: new Map([["BTC", 52_000]]), timestamp: new Date() };
const value = appraisePosition(position, snapshot);

Bookkeeping Style 2: Order Abstraction

For realistic trading with order lifecycle management. Ideal for order book simulation, partial fills, and order state tracking.

Order (intent)
   |
   |-- validateOrder() --> invalid → rejectOrder() → OrderState(REJECT)
   |
   |-- validateOrder() --> valid → acceptOrder() → OrderState(OPEN)
                                         |
                                         |-- fillOrder() → Fill + OrderState(PARTIAL/FILLED)
                                         |        |
                                         |        v
                                         |   processFill() → Position updated
                                         |
                                         |-- cancelOrder() → OrderState(CANCELLED)
import { buyOrder, acceptOrder, fillOrder, processFill } from "@junduck/trading-core";

const order = buyOrder({ symbol: "BTC", quant: 10, price: 50_000 });
const orderState = acceptOrder(order);

const fill = fillOrder({ state: orderState, quant: 5, price: 50_000, commission: 10 });
const effect = processFill(position, fill);  // Updates position

// Partial fill: orderState.status === "PARTIAL"
cancelOrder(orderState);  // Cancel remaining

When to use each:

  • Direct manipulation: Backtesting with complete data, importing historical trades, simple scenarios
  • Order abstraction: Order book simulation, partial fills, realistic order lifecycle, complex systems

Both styles update the same Position structure and can be mixed as needed.

Online Statistics: O(1) Real-Time Calculations

For streaming data scenarios, use online statistics that update incrementally with O(1) complexity:

Create instance → new data arrives → update(x) → returns new value + internal state updated
import { CMA, CuVar, RollingMax, EWMA } from "@junduck/trading-core";

// Create statistics trackers
const priceAvg = new CMA();
const priceVar = new CuVar();
const rolling5High = new RollingMax(5);
const ewma = new EWMA(0.1);

// WebSocket example: update on each tick
websocket.on('message', (data) => {
  const price = data.price;

  const mean = priceAvg.update(price);        // Cumulative mean
  const variance = priceVar.update(price);    // Cumulative variance
  const high5 = rolling5High.update(price);   // 5-period high
  const smoothed = ewma.update(price);        // Exponentially weighted MA

  console.log({ mean, variance, high5, smoothed });
});

Use cases:

  • Real-time monitoring: Track live market statistics without storing historical data
  • Memory efficiency: O(1) space complexity regardless of data volume
  • Stream processing: Calculate metrics on continuous data feeds
  • High-frequency: Fast updates suitable for tick-by-tick processing

CircularBuffer: Fixed-Size Sliding Windows

Fixed-size buffer that automatically overwrites old data - perfect for sliding windows without manual cleanup:

import { CircularBuffer } from "@junduck/trading-core";

const lastPrices = new CircularBuffer<number>(3);

lastPrices.push(100);  // [100]
lastPrices.push(102);  // [100, 102]
lastPrices.push(101);  // [100, 102, 101]
lastPrices.push(103);  // [102, 101, 103] - overwrites oldest (100)

console.log(lastPrices.toArray());  // [102, 101, 103]
console.log(lastPrices.size());     // 3

Overwriting behavior is intentional and useful:

  • No need to manually remove old elements
  • Constant memory usage for sliding windows
  • Perfect for last-N-ticks scenarios
  • Ideal for maintaining recent history in streaming contexts

PriorityQueue: Bid/Ask Order Book

Min-heap implementation for efficient order matching in a limit order book:

import { PriorityQueue } from "@junduck/trading-core";

type Order = { price: number; size: number; id: string };

// Bid queue: buyers (highest price has priority)
const bids = new PriorityQueue<Order>((a, b) => b.price - a.price);

// Ask queue: sellers (lowest price has priority)
const asks = new PriorityQueue<Order>((a, b) => a.price - b.price);

// Market makers place orders
bids.push({ price: 50000, size: 2, id: "B1" });
bids.push({ price: 50100, size: 1, id: "B2" });  // Better bid
bids.push({ price: 49900, size: 5, id: "B3" });

asks.push({ price: 50200, size: 1, id: "A1" });
asks.push({ price: 50150, size: 2, id: "A2" });  // Better ask
asks.push({ price: 50300, size: 3, id: "A3" });

// Check best bid/ask (top of book)
console.log(bids.peek());  // { price: 50100, size: 1, id: "B2" } - highest bid
console.log(asks.peek());  // { price: 50150, size: 2, id: "A2" } - lowest ask

// Market order arrives: match best prices
const bestBid = bids.pop();
const bestAsk = asks.pop();

console.log(`Spread: ${bestAsk.price - bestBid.price}`);  // 50

Use cases:

  • Limit order book implementation
  • Best bid/ask tracking
  • Order matching engines
  • Event scheduling by timestamp

Core Data Structures

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

Algorithm Foundations

Containers:

  • CircularBuffer<T> - Fixed-size circular buffer with O(1) push/pop
  • Deque<T> - Double-ended queue
  • PriorityQueue<T> - Min-heap based priority queue
  • RBTree<T> - Red-Black Tree for sorted operations

Online Statistics (Cumulative):

  • CMA - Cumulative moving average
  • CuVar, CuStddev - Variance and standard deviation
  • CuCov, CuCorr, CuBeta - Covariance, correlation, beta
  • CuSkew, CuKurt - Skewness and kurtosis
  • CuHistogram - Dynamic histogram

Rolling Window Statistics:

  • SMA, EMA, EWMA - Moving averages
  • RollingVar, RollingStddev - Variance and standard deviation
  • RollingVarEW, RollingStddevEW - Exponentially weighted variants
  • RollingZScore, RollingZScoreEW - Standardized scores
  • RollingCov, RollingCorr, RollingBeta - Covariance, correlation, beta
  • RollingMin, RollingMax, RollingMinMax - Extrema tracking
  • RollingArgMin, RollingArgMax - Extrema with indices
  • RollingMedian, RollingQuantile - Order statistics (O(n) using QuickSelect)
  • RollingSkew, RollingKurt - Higher moments
  • RollingHistogram - Rolling histogram

Probabilistic Structures:

  • CountMinSketch - Space-efficient frequency estimation
  • BloomFilter - Probabilistic set membership

Utilities:

  • Kahan - Numerically stable summation
  • SmoothedAccum - Exponential smoothing
  • maxDrawDown(), maxRelDrawDown() - Drawdown metrics
  • maxDrawUp(), maxRelDrawUp() - Drawup metrics
  • exp_factor(), wilders_factor() - Smoothing factors

Numeric Utilities (Array-based):

  • sum, min, max, argmin, argmax - Array aggregations
  • mean, variance, stddev, skew, kurt - Descriptive statistics
  • cov, corr, spearman - Correlation measures
  • median, quantile - Order statistics
  • cumsum, diff, pctChange, returns, logReturns - Series transforms
  • norm, lag, lead, coalesce, locf, winsorize - Data preparation
  • argsort, rank - Ranking utilities
  • gcd, lcm, lerp, clamp - Math utilities

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 portfolio
  • pu.createPosition(portfolio, currency, initialCash?, time?) - Create a position in portfolio
  • pu.getPosition(portfolio, currency) - Get position for currency
  • pu.getCash(portfolio, currency) - Get cash balance for currency
  • pu.getCurrencies(portfolio) - Get all currency codes in portfolio
  • pu.getAllSymbols(portfolio) - Get all symbols organized by currency
  • pu.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 position
  • pu.closeLong(portfolio, asset, price, quantity, commission?, strategy?, time?) - Close long position
  • pu.openShort(portfolio, asset, price, quantity, commission?, time?) - Open or add to short position
  • pu.closeShort(portfolio, asset, price, quantity, commission?, strategy?, time?) - Close short position

Corporate Actions (Portfolio-level):

  • pu.handleSplit(portfolio, asset, ratio, time?) - Handle stock split
  • pu.handleCashDividend(portfolio, asset, amountPerShare, taxRate?, time?) - Handle cash dividend
  • pu.handleSpinoff(portfolio, asset, newSymbol, ratio, time?) - Handle spinoff
  • pu.handleMerger(portfolio, asset, newSymbol, ratio, cashComponent?, time?) - Handle merger

Crypto Actions (Portfolio-level):

  • pu.handleHardFork(portfolio, asset, newSymbol, ratio?, time?) - Handle hard fork
  • pu.handleAirdrop(portfolio, currency, holderSymbol, airdropSymbol, amountPerToken?, fixedAmount?, time?) - Handle airdrop
  • pu.handleTokenSwap(portfolio, asset, newSymbol, ratio?, time?) - Handle token swap
  • pu.handleStakingReward(portfolio, asset, rewardPerToken, time?) - Handle staking rewards

Position Utils

Position-level functions (exported directly):

  • createPosition(initialCash?, time?) - Create a Position object
  • openLong(pos, symbol, price, quantity, commission?, time?) - Open or add to long position
  • closeLong(pos, symbol, price, quantity, commission?, strategy?, time?) - Close long position
  • openShort(pos, symbol, price, quantity, commission?, time?) - Open or add to short position
  • closeShort(pos, symbol, price, quantity, commission?, strategy?, time?) - Close short position
  • validatePosition(pos) - Validate position integrity

Market Utils

  • createUniverse(assets, timestamp?) - Create a Universe with filtering capabilities
  • appraisePosition(position, snapshot) - Calculate total position value
  • appraisePortfolio(portfolio, snapshot) - Calculate portfolio value across currencies
  • calculateUnrealizedPnL(position, snapshot) - Calculate unrealized profit/loss
  • isAssetValidAt(asset, timestamp) - Check if asset is valid at timestamp

Order Utils

Order Creation:

  • buyOrder(opts) - Create BUY order to open long position
  • sellOrder(opts) - Create SELL order to close long position
  • shortOrder(opts) - Create SELL order to open short position
  • coverOrder(opts) - Create BUY order to close short position (cover)

Order Lifecycle:

  • acceptOrder(order, time?) - Accept order and create OrderState with status "OPEN"
  • rejectOrder(order, time?) - Reject order and create OrderState with status "REJECT"
  • cancelOrder(state, time?) - Cancel active order by updating state to "CANCELLED"

Order Validation:

  • validateOrder(order, position, snapshot) - Validate order against position and market state

Fill Utils

  • fillOrder(opts) - Fill an order and create Fill receipt, updates OrderState
  • processFill(position, fill, closeStrategy?) - Process a fill to update position
  • applyFill(position, fill, closeStrategy?) - (deprecated) Apply a single fill to position
  • applyFills(position, fills, closeStrategy?) - (deprecated) Apply multiple fills sequentially

Testing

npm test                # Run all tests
npm run test:watch      # Watch mode
npm run test:ui         # UI mode
npm run test:coverage   # Coverage report

Building

npm run build           # Build to dist/
npm run dev             # Watch mode
npm run typecheck       # Type checking only

License

MIT

Credits

Documentation and core implementation assistance by Claude (Anthropic).

changelog

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[2.13.0] - 2026-01-08

Added

  • Stock adjustment primitives for complex corporate actions
    • adjustLotForSplit() - Calculates incremental shares for stock splits
    • roundAdjustLot() - Handles fractional shares with "fractional", "floor", and "cashInLieu" methods
    • applyAdjustLot() - Applies adjustment lots to position state with optional lot merging
    • taxForAdjustLot() and valueForAdjustLot() - Utilities for tax and valuation of adjustments
    • Available in @junduck/trading-core/trading deep import

[2.12.0] - 2025-12-12

Added

  • Order adjustment functions for corporate actions in order queues
    • adjustOrderSplit() - Adjusts order quantity and prices for stock splits
    • adjustOrderBonusIssue() - Adjusts orders for bonus and capitalisation issues
    • adjustOrderRightsIssueTERP() - Adjusts orders for rights issues using Theoretical Ex-Rights Price
    • Available in @junduck/trading-core/trading deep import

[2.11.0] - 2025-12-10

Added

  • handleBonusIssue() function for processing bonus issues and capitalisation issues

    • Adjusts position quantities for bonus and capitalisation ratios
    • Handles tax deduction for taxable bonus shares
    • Supports Chinese market tax regulations with configurable fair market value
    • Available in @junduck/trading-core/trading deep import
  • handleRightsIssue() function for processing rights issues

    • Creates new lots for long positions with cash deduction at offer price
    • Increases short position liability without proceeds
    • Maintains proper equity accounting for both position types
    • Available in @junduck/trading-core/trading deep import

Changed

  • Removed unnecessary validation checks and error throws in stock utilities
    • Streamlined error handling for better performance
    • Reduced code complexity while maintaining correctness

[2.10.0] - 2025-12-09

Added

  • BlockQueue<T> class - Unbounded queue implemented as linked list of array blocks
    • Provides efficient FIFO operations with automatic memory management
    • Reuses emptied blocks to avoid excessive allocations and reduce GC pressure
    • Configurable block size and maximum free blocks for performance tuning
    • Includes push()/pop() aliases for push_back()/pop_front() (consistent with CircularBuffer)
    • Similar interface to CircularBuffer but with unbounded capacity
    • Available in @junduck/trading-core/containers deep import

[2.9.0] - 2025-12-03

Added

  • PartialOrder type for flexible order data representation
    • Represents order data with optional fields for updates and queries
    • All fields optional except required id field
    • Complements existing Order and OrderState types

[2.8.0] - 2025-12-02

Added

  • PENDING status to OrderStatus type for stop orders
    • Stop orders now initialize with "PENDING" status when accepted
    • MARKET and LIMIT orders continue to initialize with "OPEN" status
    • Enables proper lifecycle management for stop orders before trigger
  • convertOrder() function to handle stop order activation
    • Converts STOP orders to MARKET orders when trigger price is hit
    • Converts STOP_LIMIT orders to LIMIT orders when trigger price is hit
    • Updates order status from "PENDING" to "OPEN" upon conversion
    • Maintains proper timestamp tracking for conversion events
    • No-op for non-stop order types

[2.7.0] - 2025-11-28

Added

  • clear() method for all stateful operators to enable easy tumbling window aggregation
    • Online/cumulative operators: CMA, CuVar, CuStddev, CuCov, CuCorr, CuBeta, CuSkew, CuKurt, CuHistogram, RunningSharpe, RunningSortino, RunningDownStats, RunningWinRate, RunningGainLoss, RunningExpectancy, RunningProfitFactor, RunningDrawdown, RunningDrawup, RunningRelDrawdown, RunningRelDrawup, RunningLongestDrawdown, RunningLongestDrawup
    • Rolling window operators: RollingSum, SMA, EMA, EWMA, RollingVar, RollingStddev, RollingVarEW, RollingStddevEW, RollingZScore, RollingZScoreEW, RollingCov, RollingCorr, RollingBeta, RollingCovEW, RollingCorrEW, RollingBetaEW, RollingMin, RollingMax, RollingMinMax, RollingArgMin, RollingArgMax, RollingArgMinMax, RollingMedian, RollingQuantile, RollingSkew, RollingKurt, RollingHistogram, RankStats, FrequencyCounter, Accumulator
    • Enables resetting operator state to initial condition without creating new instances
    • Supports efficient tumbling window patterns for time-series aggregation

[2.6.1] - 2025-11-27

Added

  • New deep import structure for clearer conceptual organization
    • @junduck/trading-core/containers - Data structures (CircularBuffer, Deque, PriorityQueue, RBTree)
    • @junduck/trading-core/online - Online/streaming algorithms (RunningSharpe, CuVar, etc.)
    • @junduck/trading-core/rolling - Rolling window algorithms (RollingVar, SMA, etc.)
    • @junduck/trading-core/batch - Stateless batch functions for arrays (sharpe, mean, variance, etc.)
    • Provides clear distinction between streaming vs batch processing
    • @junduck/trading-core/algorithm continues to work for backwards compatibility
  • Batch performance metrics for array-based computation
    • sharpe() - Sharpe ratio from array of returns
    • sortino() - Sortino ratio from array of returns
    • calmar() - Calmar ratio from array of returns
    • winRate() - Win rate (hit ratio) from array of returns
    • gainLoss() - Gain/loss ratio from array of returns
    • expectancy() - Expectancy from array of returns
    • profitFactor() - Profit factor from array of returns
    • Available in main export and @junduck/trading-core/batch deep import

[2.6.0] - 2025-11-27

Added

  • CVaR (Conditional Value at Risk) risk metrics for portfolio risk management
    • historicalCVaR() - Historical CVaR based on actual return distribution
    • parametricCVaR() - Parametric CVaR assuming normal distribution
    • expWeightedCVaR() - Exponentially weighted CVaR with configurable decay factor
    • Normal distribution utilities: invNormalCDF(), normalPDF()
    • All CVaR functions support configurable confidence levels (default α=0.05)
    • Also available in @junduck/trading-core/algorithm deep import
  • Performance metrics now exported from @junduck/trading-core/algorithm
    • Provides convenient access to running performance metrics via algorithm submodule
    • Includes Sharpe, Sortino, win rate, expectancy, and other trading metrics

Fixed

  • Missing tests for rolling covariance/correlation/beta with exponential weights

[2.5.0] - 2025-11-27

Added

  • Added value readonly property to all stateful operators
    • Provides direct access to the current computed value without calling methods
    • Available on both online (cumulative) and rolling window statistics
    • Enables more ergonomic API usage for accessing current state
  • Added running performance metrics for trading strategy evaluation
    • RunningSharpe - Tracks Sharpe ratio (mean_return - riskfree) / stddev_return
    • RunningSortino - Tracks Sortino ratio using downside volatility only
    • RunningDownStats - Tracks downside mean and standard deviation (semi-deviation)
    • RunningWinRate - Tracks percentage of positive returns (hit ratio)
    • RunningGainLoss - Tracks average gain/loss ratio
    • RunningExpectancy - Tracks expectancy: (win_rate × avg_gain) - (loss_rate × avg_loss)
    • RunningProfitFactor - Tracks sum_of_gains / sum_of_losses
  • Added running drawdown and drawup tracking utilities
    • RunningDrawdown - Tracks absolute drawdown as peak - value
    • RunningDrawup - Tracks absolute drawup as value - trough
    • RunningRelDrawdown - Tracks relative drawdown as (peak - value) / peak
    • RunningRelDrawup - Tracks relative drawup as (value - trough) / trough
    • RunningLongestDrawdown - Tracks longest drawdown duration
    • RunningLongestDrawup - Tracks longest drawup duration
    • All drawdown utilities support generic time types with Date as default

Fixed

  • Fixed potential issue from returning reference to internal state array from stateful operators in CuHistogram and RollingHistogram
    • Both histogram classes now return copies of internal arrays instead of direct references
    • Prevents accidental mutation of internal state by external code
    • Affects update() method which now returns [...this.counts] instead of direct reference

[2.4.1] - 2025-11-25

Added

  • @junduck/trading-core/algorithm and @junduck/trading-core/trading deep import. No actual change to codebase.

[2.4.0] - 2025-11-25

Added

Order Lifecycle Management:

  • acceptOrder() - Accept a submitted order and update its state
  • rejectOrder() - Reject a submitted order with reason and update its state
  • fillOrder() - Process order fills and update order state with fill tracking
    • Full order lifecycle now completed: submit → accept/reject → fill
    • Proper state transitions with timestamp tracking
    • Comprehensive fill tracking in order state

Documentation

  • Simplified and reorganized README with cleaner structure

[2.3.0] - 2025-11-25

Added

Order Constructors:

  • buyOrder() - Convenient constructor for BUY orders to open long positions
  • sellOrder() - Convenient constructor for SELL orders to close long positions
  • shortOrder() - Convenient constructor for SELL orders to open short positions
  • coverOrder() - Convenient constructor for BUY orders to close short positions (cover)
    • Order type automatically determined by price parameters:
      • No price/stopPrice → MARKET order
      • price only → LIMIT order
      • stopPrice only → STOP order
    • Simplifies order creation with clear intent-based naming

Fill Processing:

  • processFill() - New function to process a single fill and return its effect
  • FillEffect interface - Simplified interface for fill effects
    • Contains fill, cashFlow, and realisedPnL fields
    • Cleaner alternative to ApplyFillResult

Documentation

Position Utilities:

  • Enhanced JSDoc for openLong(), closeLong(), openShort(), closeShort() to clarify permissive behavior
    • Documents that these are low-level primitives that operate permissively on position state
    • Clarifies that validation and business logic enforcement is the caller's responsibility
    • Examples: won't prevent opening short while holding long, won't validate cash/margin availability
  • Enhanced JSDoc for processFill() to document permissive delegation to position primitives

Deprecated

  • applyFill() - Use processFill() instead (will be removed in v3.0)
  • applyFills() - Use processFill() with map/reduce instead (will be removed in v3.0)
  • ApplyFillResult interface - Use FillEffect instead (will be removed in v3.0)

[2.2.0] - 2025-11-22

Added

Position Query Utilities:

  • q - Opinionated query helpers for convenient position access
    • q.qty(pos, symbol), q.cost(pos, symbol) - Shortcuts for long position queries
    • q.longQty(), q.shortQty() - Get position quantities with 0 default
    • q.longCost(), q.shortProceeds() - Get cost/proceeds with 0 default
    • q.longPnL(), q.shortPnL() - Get realised PnL with 0 default
    • q.hasLong(), q.hasShort() - Check position existence with false default
    • Provides simplified accessors that flatten nested structure and return sensible defaults
    • Eliminates need for verbose optional chaining: q.longQty(pos, "AAPL") vs pos.long?.get("AAPL")?.quantity ?? 0

Testing:

  • Tests for position query helpers
  • Tests for position lot actions

Changed

  • handleAirdrop(): Removed unnecessary branch check for cleaner code

[2.1.2] - 2025-11-21

Changed

  • Position Utilities: Moved position map initialization (long/short) from openLong()/openShort() to individual lot operation functions (pushLongPositionLot, amendLongPositionLot, pushShortPositionLot, amendShortPositionLot) for safer API usage when calling lot operations directly
  • Updated JSDoc with group annotations for better documentation organization

Fixed

  • Corrected CuCov test case to use ddof: 1 for proper covariance calculation validation

[2.1.1] - 2025-11-20

Added

  • TypeDoc documentation generation

Changed

  • Updated JSDoc with group annotations for better documentation organization

[2.1.0] - 2025-11-20

Added

Numeric Utilities (src/numeric):

Array-based numeric and statistical operations for batch processing.

Array Operations:

  • sum, min, max - Basic aggregations
  • argmin, argmax - Index of extrema

Statistical Functions:

  • mean, variance, stddev - Central tendency and dispersion
  • skew, kurt - Higher moments
  • cov, corr - Covariance and Pearson correlation
  • median, quantile - Order statistics using QuickSelect

Series Transformations:

  • norm - Z-score normalization
  • sign - Element-wise sign
  • cumsum, diff - Cumulative sum and first differences
  • pctChange, returns, logReturns - Price returns
  • lag, lead - Series shifting
  • coalesce, locf - NaN handling
  • winsorize - Extreme value clamping

Ranking:

  • argsort - Stable sort indices
  • rank - Fractional ranks in [0, 1]
  • spearman - Spearman rank correlation

Math Utilities:

  • gcd, lcm - Greatest common divisor and least common multiple
  • midpoint, lerp, invLerp, remap, clamp - Interpolation utilities
  • NumericBuffer - Interface for indexed numeric access

Technical Notes

  • Welford's algorithm for numerically stable variance
  • Kahan summation for cumsum, skew, kurt
  • QuickSelect O(n) algorithm for median/quantile
  • Consistent ddof=0 default across all functions
  • All functions work on number[] arrays

[2.0.0] - 2025-11-19

Breaking Changes

Position Creation API:

  • pu.createPosition() signature changed - Function moved from portfolio utilities to position utilities with new behavior
    • Old API (removed): portfolio.positions.set("USD", pu.createPosition(100000))
    • New API: pu.createPosition(portfolio, "USD", 100000) - directly modifies portfolio
    • Migration: Use new signature pu.createPosition(portfolio, currency, initialCash, time?)
    • Alternative: Import createPosition from top-level to get Position factory: import { createPosition } from "@junduck/trading-core" then portfolio.positions.set("USD", createPosition(100000))

This change aligns the API design where pu namespace functions operate on portfolios rather than return intermediate objects.

Added

Data Structures:

  • CircularBuffer<T> - Fixed-size circular buffer with Boost-like interface
  • Deque<T> - Double-ended queue with O(1) push/pop at both ends
  • PriorityQueue<T> - Min-heap based priority queue
  • RBTree<T> - Red-Black Tree for sorted container operations

Online Statistics (Cumulative):

  • CMA - O(1) cumulative moving average with Kahan summation
  • CuVar, CuStddev - O(1) cumulative variance/stddev using Welford's algorithm
  • CuCov, CuCorr, CuBeta - O(1) cumulative covariance/correlation/beta
  • CuSkew, CuKurt - O(1) cumulative skewness and kurtosis
  • CuHistogram - Dynamic histogram with automatic bin management

Rolling Window Statistics:

  • RollingSum, SMA - O(1) rolling sum and simple moving average
  • EMA - Exponential moving average with infinite window
  • EWMA - O(1) exponential weighted moving average with fixed window
  • RollingVar, RollingStddev - O(1) rolling variance/stddev
  • RollingVarEW, RollingStddevEW - Exponentially weighted variants
  • RollingZScore, RollingZScoreEW - Standardized scores
  • RollingCov, RollingCorr, RollingBeta - Rolling covariance/correlation/beta
  • RollingCovEW, RollingCorrEW, RollingBetaEW - Exponentially weighted variants
  • RollingMin, RollingMax, RollingMinMax - O(1) extrema tracking
  • RollingArgMin, RollingArgMax, RollingArgMinMax - Extrema with indices
  • RollingMedian, RollingQuantile - Order statistics
  • RollingSkew, RollingKurt - Rolling skewness and kurtosis
  • RollingHistogram - Rolling histogram with fixed bins

Probabilistic Structures:

  • CountMinSketch - Space-efficient frequency estimation
  • BloomFilter - Probabilistic set membership testing

Utility Functions:

  • maxDrawDown(), maxRelDrawDown() - Maximum absolute/relative drawdown
  • maxDrawUp(), maxRelDrawUp() - Maximum absolute/relative drawup
  • Kahan - Kahan summation for numerical stability
  • SmoothedAccum - Exponential smoothing accumulator
  • exp_factor() - EMA-style smoothing factor (2/(n+1))
  • wilders_factor() - Wilder's smoothing factor (1/n)

Changed

  • Test suite expanded from 163 to 409 tests
  • All statistical functions use Kahan summation for numerical accuracy
  • Consistent API design across online and rolling statistics

Technical Notes

  • Most rolling statistics maintain O(1) time complexity per update
  • Rank-based statistics (median, quantile) use O(n) QuickSelect algorithm
  • Circular buffer used for efficient fixed-window operations
  • Welford's online algorithm for numerically stable variance calculations
  • Support for both observation-based and exponentially-weighted statistics
  • Configurable degrees of freedom (ddof) for variance calculations

[1.1.1] - 2025-11-14

Changed

  • Updated exports in src/index.ts to use explicit named exports
    • Improves agent lookup and IDE auto-completion experience
    • No functional changes to the API

[1.1.0] - 2025-11-10

Changed

Order Types:

  • Updated Order.created field to be optional (created?: Date)
    • Clarifies that this represents intent time, not audit time
    • Actual effective timing for audit purposes comes from OrderState.modified
    • Users can choose whether to record the intent creation time or not

Portfolio Utilities:

  • Exported getOrSetPosition() function
    • Previously internal utility now available for external use
    • Gets existing position or creates new one if not found
    • Added JSDoc documentation for clarity
  • Added getAllSymbols() function
    • Returns all symbols in portfolio organized by currency
    • Efficiently collects symbols from both long and short positions
    • Avoids duplicates when same symbol exists in both directions
    • Returns Map<currency, string[]> following TypeScript conventions

Added

Order Types:

  • REJECT status to OrderStatus type
    • Represents orders rejected by the system or exchange
    • Non-breaking change to existing order status union type

Position Management:

  • disableLot parameter for providers without lot-level accounting support
    • Added to openLong() and openShort() functions
    • When enabled, maintains single merged lot instead of tracking separate lots
    • Fully backward-compatible (default: false)

Market Data:

  • preClose property to MarketQuote interface
    • Represents the previous closing price for comparison with current price
    • Optional field to support price change calculations
    • Non-breaking change to existing interface
  • totalVolume property to MarketQuote interface
    • Represents total traded volume for the session (cumulative)
    • Distinguishes from volume which represents last trade volume
    • Supports data providers with different volume reporting semantics
    • Non-breaking change to existing interface

Market Utilities:

  • updateSnapshotQuote() - Updates MarketSnapshot with new MarketQuote using LOCF
    • Updates price for the symbol and ensures timestamp reflects most recent data
  • updateSnapshotBar() - Updates MarketSnapshot with new MarketBar using close price
    • Updates price with bar's close price and ensures timestamp reflects most recent data
  • calculateUnrealisedPnL() - Alias for calculateUnrealizedPnL() using British/AU spelling
    • Provides API consistency with interface field naming (realisedPnL)
    • Both spellings now available for user preference

Documentation:

  • amendLongPositionLot() - JSDoc for merging long position lots
  • amendShortPositionLot() - JSDoc for merging short position lots

Corporate Actions:

  • disableLot support for all corporate action functions:
    • handleHardFork(), handleAirdrop(), handleTokenSwap(), handleStakingReward()
    • handleSpinoff(), handleMerger()

Testing:

  • 8 new tests for disableLot functionality
  • 8 new tests for getAllSymbols() functionality
  • 163 total tests with comprehensive coverage

[1.0.0] - 2025-11-08

Added

Core Data Structures:

  • Order, OrderState, Fill - Trading intent and execution records
  • Position - Lot-based position tracking with FIFO/LIFO accounting
  • LongPosition, ShortPosition - Support for both long and short positions
  • Portfolio - Multi-currency portfolio management
  • Asset - Asset metadata with validity periods
  • Universe - Collection of tradable assets with filtering capabilities
  • MarketSnapshot, MarketQuote, MarketBar - Market data representations

Position Utilities:

  • openLong(), closeLong() - Long position management with lot-level tracking
  • openShort(), closeShort() - Short position management
  • validatePosition() - Position integrity validation
  • getAverageCost(), getAverageProceeds() - Average price calculations

Portfolio Utilities:

  • Portfolio creation and management (pu.create(), pu.createPosition())
  • Portfolio-level trading operations
  • Position and cash queries
  • Multi-currency support

Market Utilities:

  • createUniverse() - Universe creation with filtering
  • appraisePosition(), appraisePortfolio() - Portfolio valuation
  • calculateUnrealizedPnL() - Unrealized profit/loss calculation
  • isAssetValidAt() - Asset validity checks

Order Validation:

  • validateOrder() - Comprehensive order validation
  • Cash availability checks
  • Position existence validation
  • Price direction validation for stop orders
  • Structured error reporting

Fill Processing:

  • applyFill(), applyFills() - Fill application to positions
  • Support for partial fills
  • Realized P&L calculation

Corporate Actions:

  • Stock splits, cash dividends, spinoffs, mergers
  • Crypto hard forks, airdrops, token swaps, staking rewards

Testing:

  • 147 tests with 90.98% code coverage
  • Comprehensive test suite for all major utilities

Documentation:

  • Complete README with quick start guide
  • API reference documentation
  • JSDoc comments throughout codebase