running prettier for cleanup

This commit is contained in:
Boki 2025-06-11 10:13:25 -04:00
parent fe7733aeb5
commit d85cd58acd
151 changed files with 29158 additions and 27966 deletions

View file

@ -1,159 +1,159 @@
import { getLogger } from '@stock-bot/logger';
export interface Position {
symbol: string;
quantity: number;
averagePrice: number;
currentPrice: number;
marketValue: number;
unrealizedPnL: number;
unrealizedPnLPercent: number;
costBasis: number;
lastUpdated: Date;
}
export interface PortfolioSnapshot {
timestamp: Date;
totalValue: number;
cashBalance: number;
positions: Position[];
totalReturn: number;
totalReturnPercent: number;
dayChange: number;
dayChangePercent: number;
}
export interface Trade {
id: string;
symbol: string;
quantity: number;
price: number;
side: 'buy' | 'sell';
timestamp: Date;
commission: number;
}
export class PortfolioManager {
private logger = getLogger('PortfolioManager');
private positions: Map<string, Position> = new Map();
private trades: Trade[] = [];
private cashBalance: number = 100000; // Starting cash
constructor(initialCash: number = 100000) {
this.cashBalance = initialCash;
}
addTrade(trade: Trade): void {
this.trades.push(trade);
this.updatePosition(trade);
logger.info(`Trade added: ${trade.symbol} ${trade.side} ${trade.quantity} @ ${trade.price}`);
}
private updatePosition(trade: Trade): void {
const existing = this.positions.get(trade.symbol);
if (!existing) {
// New position
if (trade.side === 'buy') {
this.positions.set(trade.symbol, {
symbol: trade.symbol,
quantity: trade.quantity,
averagePrice: trade.price,
currentPrice: trade.price,
marketValue: trade.quantity * trade.price,
unrealizedPnL: 0,
unrealizedPnLPercent: 0,
costBasis: trade.quantity * trade.price + trade.commission,
lastUpdated: trade.timestamp
});
this.cashBalance -= (trade.quantity * trade.price + trade.commission);
}
return;
}
// Update existing position
if (trade.side === 'buy') {
const newQuantity = existing.quantity + trade.quantity;
const newCostBasis = existing.costBasis + (trade.quantity * trade.price) + trade.commission;
existing.quantity = newQuantity;
existing.averagePrice = (newCostBasis - this.getTotalCommissions(trade.symbol)) / newQuantity;
existing.costBasis = newCostBasis;
existing.lastUpdated = trade.timestamp;
this.cashBalance -= (trade.quantity * trade.price + trade.commission);
} else if (trade.side === 'sell') {
existing.quantity -= trade.quantity;
existing.lastUpdated = trade.timestamp;
const proceeds = trade.quantity * trade.price - trade.commission;
this.cashBalance += proceeds;
// Remove position if quantity is zero
if (existing.quantity <= 0) {
this.positions.delete(trade.symbol);
}
}
}
updatePrice(symbol: string, price: number): void {
const position = this.positions.get(symbol);
if (position) {
position.currentPrice = price;
position.marketValue = position.quantity * price;
position.unrealizedPnL = position.marketValue - (position.quantity * position.averagePrice);
position.unrealizedPnLPercent = position.unrealizedPnL / (position.quantity * position.averagePrice) * 100;
position.lastUpdated = new Date();
}
}
getPosition(symbol: string): Position | undefined {
return this.positions.get(symbol);
}
getAllPositions(): Position[] {
return Array.from(this.positions.values());
}
getPortfolioSnapshot(): PortfolioSnapshot {
const positions = this.getAllPositions();
const totalMarketValue = positions.reduce((sum, pos) => sum + pos.marketValue, 0);
const totalValue = totalMarketValue + this.cashBalance;
const totalUnrealizedPnL = positions.reduce((sum, pos) => sum + pos.unrealizedPnL, 0);
return {
timestamp: new Date(),
totalValue,
cashBalance: this.cashBalance,
positions,
totalReturn: totalUnrealizedPnL, // Simplified - should include realized gains
totalReturnPercent: (totalUnrealizedPnL / (totalValue - totalUnrealizedPnL)) * 100,
dayChange: 0, // TODO: Calculate from previous day
dayChangePercent: 0
};
}
getTrades(symbol?: string): Trade[] {
if (symbol) {
return this.trades.filter(trade => trade.symbol === symbol);
}
return this.trades;
}
private getTotalCommissions(symbol: string): number {
return this.trades
.filter(trade => trade.symbol === symbol)
.reduce((sum, trade) => sum + trade.commission, 0);
}
getCashBalance(): number {
return this.cashBalance;
}
getNetLiquidationValue(): number {
const positions = this.getAllPositions();
const positionValue = positions.reduce((sum, pos) => sum + pos.marketValue, 0);
return positionValue + this.cashBalance;
}
}
import { getLogger } from '@stock-bot/logger';
export interface Position {
symbol: string;
quantity: number;
averagePrice: number;
currentPrice: number;
marketValue: number;
unrealizedPnL: number;
unrealizedPnLPercent: number;
costBasis: number;
lastUpdated: Date;
}
export interface PortfolioSnapshot {
timestamp: Date;
totalValue: number;
cashBalance: number;
positions: Position[];
totalReturn: number;
totalReturnPercent: number;
dayChange: number;
dayChangePercent: number;
}
export interface Trade {
id: string;
symbol: string;
quantity: number;
price: number;
side: 'buy' | 'sell';
timestamp: Date;
commission: number;
}
export class PortfolioManager {
private logger = getLogger('PortfolioManager');
private positions: Map<string, Position> = new Map();
private trades: Trade[] = [];
private cashBalance: number = 100000; // Starting cash
constructor(initialCash: number = 100000) {
this.cashBalance = initialCash;
}
addTrade(trade: Trade): void {
this.trades.push(trade);
this.updatePosition(trade);
logger.info(`Trade added: ${trade.symbol} ${trade.side} ${trade.quantity} @ ${trade.price}`);
}
private updatePosition(trade: Trade): void {
const existing = this.positions.get(trade.symbol);
if (!existing) {
// New position
if (trade.side === 'buy') {
this.positions.set(trade.symbol, {
symbol: trade.symbol,
quantity: trade.quantity,
averagePrice: trade.price,
currentPrice: trade.price,
marketValue: trade.quantity * trade.price,
unrealizedPnL: 0,
unrealizedPnLPercent: 0,
costBasis: trade.quantity * trade.price + trade.commission,
lastUpdated: trade.timestamp,
});
this.cashBalance -= trade.quantity * trade.price + trade.commission;
}
return;
}
// Update existing position
if (trade.side === 'buy') {
const newQuantity = existing.quantity + trade.quantity;
const newCostBasis = existing.costBasis + trade.quantity * trade.price + trade.commission;
existing.quantity = newQuantity;
existing.averagePrice = (newCostBasis - this.getTotalCommissions(trade.symbol)) / newQuantity;
existing.costBasis = newCostBasis;
existing.lastUpdated = trade.timestamp;
this.cashBalance -= trade.quantity * trade.price + trade.commission;
} else if (trade.side === 'sell') {
existing.quantity -= trade.quantity;
existing.lastUpdated = trade.timestamp;
const proceeds = trade.quantity * trade.price - trade.commission;
this.cashBalance += proceeds;
// Remove position if quantity is zero
if (existing.quantity <= 0) {
this.positions.delete(trade.symbol);
}
}
}
updatePrice(symbol: string, price: number): void {
const position = this.positions.get(symbol);
if (position) {
position.currentPrice = price;
position.marketValue = position.quantity * price;
position.unrealizedPnL = position.marketValue - position.quantity * position.averagePrice;
position.unrealizedPnLPercent =
(position.unrealizedPnL / (position.quantity * position.averagePrice)) * 100;
position.lastUpdated = new Date();
}
}
getPosition(symbol: string): Position | undefined {
return this.positions.get(symbol);
}
getAllPositions(): Position[] {
return Array.from(this.positions.values());
}
getPortfolioSnapshot(): PortfolioSnapshot {
const positions = this.getAllPositions();
const totalMarketValue = positions.reduce((sum, pos) => sum + pos.marketValue, 0);
const totalValue = totalMarketValue + this.cashBalance;
const totalUnrealizedPnL = positions.reduce((sum, pos) => sum + pos.unrealizedPnL, 0);
return {
timestamp: new Date(),
totalValue,
cashBalance: this.cashBalance,
positions,
totalReturn: totalUnrealizedPnL, // Simplified - should include realized gains
totalReturnPercent: (totalUnrealizedPnL / (totalValue - totalUnrealizedPnL)) * 100,
dayChange: 0, // TODO: Calculate from previous day
dayChangePercent: 0,
};
}
getTrades(symbol?: string): Trade[] {
if (symbol) {
return this.trades.filter(trade => trade.symbol === symbol);
}
return this.trades;
}
private getTotalCommissions(symbol: string): number {
return this.trades
.filter(trade => trade.symbol === symbol)
.reduce((sum, trade) => sum + trade.commission, 0);
}
getCashBalance(): number {
return this.cashBalance;
}
getNetLiquidationValue(): number {
const positions = this.getAllPositions();
const positionValue = positions.reduce((sum, pos) => sum + pos.marketValue, 0);
return positionValue + this.cashBalance;
}
}