Files
trading_bot_v3/lib/price-fetcher.ts
mindesbunister ba354c609d feat: implement dynamic position calculator with leverage slider
- Added comprehensive PositionCalculator component with real-time PnL calculations
- Implemented dynamic leverage adjustment with slider (1x to 100x)
- Added investment amount input for position sizing
- Integrated liquidation price calculations based on leverage and maintenance margin
- Added real-time price fetching from multiple sources (CoinGecko, CoinCap, Binance)
- Implemented automatic stop loss and take profit extraction from AI analysis
- Added risk/reward ratio calculations and position metrics
- Included trading fee calculations and net investment display
- Added position type selection (Long/Short) with dynamic PnL calculation
- Integrated high leverage warning system for risk management
- Added advanced settings for customizable trading fees and maintenance margins
- Automatically updates calculations when analysis parameters change
- Supports both manual price input and real-time market data
- Fully responsive design with gradient styling matching app theme
2025-07-18 13:16:11 +02:00

153 lines
4.1 KiB
TypeScript

// Price fetcher utility for getting current market prices
export class PriceFetcher {
private static cache = new Map<string, { price: number; timestamp: number }>()
private static readonly CACHE_DURATION = 30000 // 30 seconds
static async getCurrentPrice(symbol: string): Promise<number> {
const cacheKey = symbol.toUpperCase()
const cached = this.cache.get(cacheKey)
// Return cached price if recent
if (cached && Date.now() - cached.timestamp < this.CACHE_DURATION) {
return cached.price
}
try {
// Try multiple price sources
let price = await this.fetchFromCoinGecko(symbol)
if (!price) {
price = await this.fetchFromCoinCap(symbol)
}
if (!price) {
price = await this.fetchFromBinance(symbol)
}
if (price) {
this.cache.set(cacheKey, { price, timestamp: Date.now() })
return price
}
return 0
} catch (error) {
console.error('Error fetching price:', error)
return cached?.price || 0
}
}
private static async fetchFromCoinGecko(symbol: string): Promise<number | null> {
try {
const coinId = this.getCoinGeckoId(symbol)
if (!coinId) return null
const response = await fetch(
`https://api.coingecko.com/api/v3/simple/price?ids=${coinId}&vs_currencies=usd`,
{ cache: 'no-cache' }
)
if (!response.ok) return null
const data = await response.json()
return data[coinId]?.usd || null
} catch (error) {
console.error('CoinGecko fetch error:', error)
return null
}
}
private static async fetchFromCoinCap(symbol: string): Promise<number | null> {
try {
const asset = this.getCoinCapAsset(symbol)
if (!asset) return null
const response = await fetch(
`https://api.coincap.io/v2/assets/${asset}`,
{ cache: 'no-cache' }
)
if (!response.ok) return null
const data = await response.json()
return parseFloat(data.data?.priceUsd) || null
} catch (error) {
console.error('CoinCap fetch error:', error)
return null
}
}
private static async fetchFromBinance(symbol: string): Promise<number | null> {
try {
const binanceSymbol = this.getBinanceSymbol(symbol)
if (!binanceSymbol) return null
const response = await fetch(
`https://api.binance.com/api/v3/ticker/price?symbol=${binanceSymbol}`,
{ cache: 'no-cache' }
)
if (!response.ok) return null
const data = await response.json()
return parseFloat(data.price) || null
} catch (error) {
console.error('Binance fetch error:', error)
return null
}
}
private static getCoinGeckoId(symbol: string): string | null {
const mapping: Record<string, string> = {
'BTCUSD': 'bitcoin',
'ETHUSD': 'ethereum',
'SOLUSD': 'solana',
'SUIUSD': 'sui',
'ADAUSD': 'cardano',
'DOTUSD': 'polkadot',
'AVAXUSD': 'avalanche-2',
'LINKUSD': 'chainlink',
'MATICUSD': 'matic-network',
'UNIUSD': 'uniswap'
}
return mapping[symbol.toUpperCase()] || null
}
private static getCoinCapAsset(symbol: string): string | null {
const mapping: Record<string, string> = {
'BTCUSD': 'bitcoin',
'ETHUSD': 'ethereum',
'SOLUSD': 'solana',
'SUIUSD': 'sui',
'ADAUSD': 'cardano',
'DOTUSD': 'polkadot',
'AVAXUSD': 'avalanche',
'LINKUSD': 'chainlink',
'MATICUSD': 'polygon',
'UNIUSD': 'uniswap'
}
return mapping[symbol.toUpperCase()] || null
}
private static getBinanceSymbol(symbol: string): string | null {
const mapping: Record<string, string> = {
'BTCUSD': 'BTCUSDT',
'ETHUSD': 'ETHUSDT',
'SOLUSD': 'SOLUSDT',
'SUIUSD': 'SUIUSDT',
'ADAUSD': 'ADAUSDT',
'DOTUSD': 'DOTUSDT',
'AVAXUSD': 'AVAXUSDT',
'LINKUSD': 'LINKUSDT',
'MATICUSD': 'MATICUSDT',
'UNIUSD': 'UNIUSDT'
}
return mapping[symbol.toUpperCase()] || null
}
static clearCache(): void {
this.cache.clear()
}
}
export default PriceFetcher