Skip to content

Instantly share code, notes, and snippets.

@AlanGreyjoy
Created December 22, 2024 16:51
Show Gist options
  • Save AlanGreyjoy/384fe1af7341825e91b1b74a03f330f2 to your computer and use it in GitHub Desktop.
Save AlanGreyjoy/384fe1af7341825e91b1b74a03f330f2 to your computer and use it in GitHub Desktop.
Paper trading price simulator
import { usePrices } from "../hooks/usePrices"; //Implement your own service for fetching realtime stock prices or mock data.
interface SimulatedPrice {
price: number;
timestamp: Date;
}
class PriceSimulator {
private simulatedPrices: Map<string, SimulatedPrice> = new Map();
private volatility = 0.002; // 0.2% base volatility
private trendStrength = 0.3; // How strong the trend is
private meanReversionStrength = 0.2; // How strongly price returns to base
private trends: Map<string, number> = new Map(); // Track trend direction per symbol
simulatePrice(symbol: string, basePrice: number): number {
const existing = this.simulatedPrices.get(symbol);
const now = new Date();
// Generate new price every second
if (!existing || now.getTime() - existing.timestamp.getTime() > 1000) {
// Initialize or update trend
if (!this.trends.has(symbol)) {
this.trends.set(symbol, Math.random() > 0.5 ? 1 : -1);
} else if (Math.random() < 0.1) {
// 10% chance to switch trend
this.trends.set(symbol, this.trends.get(symbol)! * -1);
}
const trend = this.trends.get(symbol)!;
// Random component (volatility)
const randomWalk = (Math.random() - 0.5) * 2 * this.volatility;
// Trend component
const trendComponent = trend * this.trendStrength * this.volatility;
// Mean reversion component
const meanReversion = existing
? (basePrice - existing.price) * this.meanReversionStrength
: 0;
// Combine all components
let newPrice =
(existing?.price || basePrice) * (1 + randomWalk + trendComponent) +
meanReversion;
// Add some noise to make it more realistic
newPrice *= 1 + (Math.random() - 0.5) * 0.0001;
// Prevent extreme deviations from base price (±30%)
const maxDeviation = basePrice * 0.3;
newPrice = Math.max(
basePrice - maxDeviation,
Math.min(basePrice + maxDeviation, newPrice)
);
this.simulatedPrices.set(symbol, {
price: newPrice,
timestamp: now,
});
return newPrice;
}
return existing.price;
}
setVolatility(value: number) {
this.volatility = value;
}
}
export const priceSimulator = new PriceSimulator();
// Hook to get simulated prices
export function useSimulatedPrices() {
const { prices: realPrices } = usePrices();
const getSimulatedPrice = (symbol: string) => {
const basePrice = realPrices[symbol];
if (!basePrice) return null;
return priceSimulator.simulatePrice(symbol, basePrice);
};
return {
getSimulatedPrice,
setVolatility: priceSimulator.setVolatility.bind(priceSimulator),
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment