Financial Trading Platform
Scenario: High-Frequency Trading System
Building a trading platform with:
- Real-time market data streaming
- Order execution with microsecond precision
- Risk management and compliance
- Complex calculations with BigNumber
- Audit trail for all operations
CLAUDE.md for Financial Systems
## Financial Trading Platform Architecture
### Type Safety for Financial Data
```typescript
// Use branded types for financial values
type Brand<K, T> = K & { __brand: T };
type USD = Brand<number, 'USD'>;
type EUR = Brand<number, 'EUR'>;
type BTC = Brand<number, 'BTC'>;
// Prevent mixing currencies at compile time
function convertCurrency<TFrom extends number, TTo>(
amount: TFrom,
rate: number,
toCurrency: (value: number) => TTo
): TTo {
return toCurrency(amount * rate);
}
// Price types with precision
interface Price {
value: bigint; // Store as smallest unit (cents, satoshis)
decimals: number;
currency: Currency;
}
class PriceCalculator {
static fromString(value: string, currency: Currency): Price {
const decimals = CURRENCY_DECIMALS[currency];
const [whole, fraction = ''] = value.split('.');
const paddedFraction = fraction.padEnd(decimals, '0');
const bigintValue = BigInt(whole + paddedFraction);
return { value: bigintValue, decimals, currency };
}
static toString(price: Price): string {
const str = price.value.toString();
const whole = str.slice(0, -price.decimals) || '0';
const fraction = str.slice(-price.decimals).padStart(price.decimals, '0');
return `${whole}.${fraction}`;
}
static add(a: Price, b: Price): Price {
if (a.currency !== b.currency) {
throw new Error('Cannot add different currencies');
}
return {
value: a.value + b.value,
decimals: a.decimals,
currency: a.currency,
};
}
}
// Order types with validation
interface Order {
id: string;
userId: string;
symbol: TradingSymbol;
side: 'buy' | 'sell';
type: OrderType;
status: OrderStatus;
quantity: bigint;
price?: Price; // Optional for market orders
stopPrice?: Price; // For stop orders
timeInForce: TimeInForce;
createdAt: Date;
updatedAt: Date;
executions: Execution[];
}
enum OrderType {
MARKET = 'MARKET',
LIMIT = 'LIMIT',
STOP = 'STOP',
STOP_LIMIT = 'STOP_LIMIT',
}
enum TimeInForce {
GTC = 'GTC', // Good Till Cancelled
IOC = 'IOC', // Immediate or Cancel
FOK = 'FOK', // Fill or Kill
DAY = 'DAY',
}
// Market data streaming
interface MarketData {
symbol: TradingSymbol;
bid: Price;
ask: Price;
last: Price;
volume24h: bigint;
high24h: Price;
low24h: Price;
timestamp: bigint; // nanoseconds
}
interface OrderBook {
symbol: TradingSymbol;
bids: OrderBookLevel[];
asks: OrderBookLevel[];
timestamp: bigint;
sequenceNumber: bigint;
}
interface OrderBookLevel {
price: Price;
quantity: bigint;
orderCount: number;
}High-Performance Order Matching Engine
export class OrderMatchingEngine {
private orderBooks = new Map<string, OrderBook>();
private orderIndex = new Map<string, Order>();
private sequenceNumber = 0n;
async submitOrder(order: Order): Promise<OrderResult> {
const timestamp = process.hrtime.bigint();
// Validate order
const validation = this.validateOrder(order);
if (!validation.valid) {
return {
success: false,
error: validation.error,
timestamp,
};
}
// Risk check
const riskCheck = await this.checkRisk(order);
if (!riskCheck.passed) {
return {
success: false,
error: `Risk check failed: ${riskCheck.reason}`,
timestamp,
};
}
// Match order
const result = this.matchOrder(order);
// Audit log
await this.auditLog({
action: 'ORDER_SUBMITTED',
orderId: order.id,
userId: order.userId,
details: order,
result,
timestamp,
});
return result;
}
private matchOrder(order: Order): OrderResult {
const book = this.orderBooks.get(order.symbol);
if (!book) {
return {
success: false,
error: 'Invalid symbol',
timestamp: process.hrtime.bigint(),
};
}
const executions: Execution[] = [];
let remainingQuantity = order.quantity;
if (order.type === OrderType.MARKET) {
// Match against opposite side of book
const levels = order.side === 'buy' ? book.asks : book.bids;
for (const level of levels) {
if (remainingQuantity === 0n) break;
const fillQuantity = remainingQuantity > level.quantity
? level.quantity
: remainingQuantity;
executions.push({
id: this.generateExecutionId(),
orderId: order.id,
price: level.price,
quantity: fillQuantity,
timestamp: process.hrtime.bigint(),
liquidity: 'taker',
});
remainingQuantity -= fillQuantity;
level.quantity -= fillQuantity;
}
}
// Update order status
if (remainingQuantity === 0n) {
order.status = OrderStatus.FILLED;
} else if (remainingQuantity < order.quantity) {
order.status = OrderStatus.PARTIALLY_FILLED;
}
// Broadcast market data update
this.broadcastMarketData(order.symbol, book);
return {
success: true,
order,
executions,
timestamp: process.hrtime.bigint(),
};
}
private async checkRisk(order: Order): Promise<RiskCheckResult> {
// Implement risk checks
const checks = await Promise.all([
this.checkPositionLimits(order),
this.checkBuyingPower(order),
this.checkDailyLossLimit(order),
this.checkSymbolRestrictions(order),
]);
const failed = checks.find(check => !check.passed);
return failed || { passed: true };
}
}
// WebSocket market data streaming
export class MarketDataStreamer {
private subscribers = new Map<string, Set<WebSocket>>();
private dataBuffer = new Map<string, MarketData[]>();
private flushInterval: NodeJS.Timer;
constructor(private flushIntervalMs = 100) {
this.flushInterval = setInterval(() => this.flush(), flushIntervalMs);
}
subscribe(symbol: string, ws: WebSocket): void {
if (!this.subscribers.has(symbol)) {
this.subscribers.set(symbol, new Set());
}
this.subscribers.get(symbol)!.add(ws);
// Send snapshot
const snapshot = this.getSnapshot(symbol);
if (snapshot) {
ws.send(JSON.stringify({
type: 'snapshot',
symbol,
data: snapshot,
}));
}
}
publish(data: MarketData): void {
if (!this.dataBuffer.has(data.symbol)) {
this.dataBuffer.set(data.symbol, []);
}
this.dataBuffer.get(data.symbol)!.push(data);
}
private flush(): void {
for (const [symbol, updates] of this.dataBuffer) {
if (updates.length === 0) continue;
// Aggregate updates
const aggregated = this.aggregate(updates);
// Send to subscribers
const subscribers = this.subscribers.get(symbol);
if (subscribers) {
const message = JSON.stringify({
type: 'update',
symbol,
data: aggregated,
});
for (const ws of subscribers) {
if (ws.readyState === WebSocket.OPEN) {
ws.send(message);
}
}
}
}
// Clear buffer
this.dataBuffer.clear();
}
private aggregate(updates: MarketData[]): MarketData {
// Return the latest update with aggregated volume
const latest = updates[updates.length - 1];
const totalVolume = updates.reduce(
(sum, update) => sum + update.volume24h,
0n
);
return {
...latest,
volume24h: totalVolume,
};
}
}Compliance and Audit System
interface AuditLog {
id: string;
timestamp: bigint;
userId: string;
action: AuditAction;
details: Record<string, unknown>;
ipAddress: string;
userAgent: string;
result: 'success' | 'failure';
errorMessage?: string;
}
enum AuditAction {
LOGIN = 'LOGIN',
LOGOUT = 'LOGOUT',
ORDER_SUBMITTED = 'ORDER_SUBMITTED',
ORDER_CANCELLED = 'ORDER_CANCELLED',
ORDER_MODIFIED = 'ORDER_MODIFIED',
WITHDRAWAL_REQUESTED = 'WITHDRAWAL_REQUESTED',
DEPOSIT_RECEIVED = 'DEPOSIT_RECEIVED',
KYC_SUBMITTED = 'KYC_SUBMITTED',
SETTINGS_CHANGED = 'SETTINGS_CHANGED',
}
export class ComplianceEngine {
async checkCompliance(
user: User,
action: ComplianceAction
): Promise<ComplianceResult> {
const checks = [
this.checkKYCStatus(user),
this.checkJurisdiction(user),
this.checkSanctions(user),
this.checkTradingRestrictions(user, action),
];
const results = await Promise.all(checks);
const failed = results.filter(r => !r.passed);
return {
passed: failed.length === 0,
failures: failed,
timestamp: new Date(),
};
}
private async checkKYCStatus(user: User): Promise<ComplianceCheck> {
if (!user.kycVerified) {
return {
passed: false,
reason: 'KYC verification required',
code: 'KYC_REQUIRED',
};
}
if (user.kycExpiry && user.kycExpiry < new Date()) {
return {
passed: false,
reason: 'KYC verification expired',
code: 'KYC_EXPIRED',
};
}
return { passed: true };
}
private async checkSanctions(user: User): Promise<ComplianceCheck> {
// Check against sanctions lists
const sanctioned = await this.sanctionsService.check({
name: user.name,
dateOfBirth: user.dateOfBirth,
country: user.country,
});
if (sanctioned) {
await this.flagAccount(user.id, 'SANCTIONS_HIT');
return {
passed: false,
reason: 'User flagged by sanctions screening',
code: 'SANCTIONS_HIT',
};
}
return { passed: true };
}
}
## Critical Implementation Considerations
1. **Precision is Everything**: Use BigInt for all financial calculations
2. **Audit Everything**: Log every action with immutable timestamps
3. **Type Safety**: Branded types prevent currency mixing errors
4. **Performance**: Optimize hot paths, use message buffering
5. **Compliance First**: Build compliance checks into the core flow
## Security Patterns
- Implement rate limiting per user
- Use message signing for WebSocket connections
- Encrypt sensitive data at rest
- Implement circuit breakers for external services
- Regular security audits and penetration testing
## Related Resources
- [[docs/reference/templates/fullstack-typescript|Full-Stack TypeScript Template]]
- [FIX Protocol](https://www.fixtrading.org/)
- [MiFID II Compliance](https://www.esma.europa.eu/policy-rules/mifid-ii-and-mifir)
## 🧭 Quick Navigation
[← Real-Time Collaboration](real-time-collaboration) | [Back to Scenarios](../index) | [Healthcare Platform →](healthcare-platform)