Fix timeframe selection bug and syntax errors

- Fixed critical timeframe mapping bug where '4h' was interpreted as '4 minutes'
- Now prioritizes minute values: '4h' -> ['240', '240m', '4h', '4H']
- Added fallback mechanism to enter exact minutes (240) in custom interval input
- Fixed multiple syntax errors in tradingview-automation.ts:
  * Missing closing parentheses in console.log statements
  * Missing parentheses in writeFile and JSON.parse calls
  * Fixed import statements for fs and path modules
  * Added missing utility methods (fileExists, markCaptchaDetected, etc.)
- Enhanced timeframe selection with comprehensive hour mappings (1h, 2h, 4h, 6h, 12h)
- Added detailed logging for debugging timeframe selection
- Application now builds successfully without syntax errors
- Interval selection should work correctly for all common timeframes

Key improvements:
 4h chart selection now works correctly (240 minutes, not 4 minutes)
 All TypeScript compilation errors resolved
 Enhanced debugging output for timeframe mapping
 Robust fallback mechanisms for interval selection
 Docker integration and manual CAPTCHA handling maintained
This commit is contained in:
mindesbunister
2025-07-13 13:57:35 +02:00
parent 19d4020622
commit b91d35ad60
17 changed files with 1218 additions and 143 deletions

View File

@@ -27,6 +27,22 @@ interface AccountData {
maintenanceMargin: number
}
interface BalanceApiResponse {
totalCollateral?: number
freeCollateral?: number
leverage?: number
marginRequirement?: number
}
interface TradingInfoApiResponse {
totalCollateral?: number
availableCollateral?: number
accountLeverage?: number
maintenanceMargin?: number
maxPositionSize?: number
requiredMargin?: number
}
export default function AdvancedTradingPanel() {
// Trading form state
const [symbol, setSymbol] = useState('SOLUSD')
@@ -87,15 +103,34 @@ export default function AdvancedTradingPanel() {
const fetchAccountData = async () => {
try {
const response = await fetch('/api/drift/balance')
if (response.ok) {
const data = await response.json()
setAccountData({
totalCollateral: data.totalCollateral || 0,
freeCollateral: data.freeCollateral || 0,
leverage: data.leverage || 0,
maintenanceMargin: data.marginRequirement || 0
})
// Fetch both balance and trading info
const [balanceResponse, tradingInfoResponse] = await Promise.all([
fetch('/api/drift/balance'),
fetch('/api/drift/trading-info')
])
let balanceData: BalanceApiResponse = {}
let tradingInfoData: TradingInfoApiResponse = {}
if (balanceResponse.ok) {
balanceData = await balanceResponse.json()
}
if (tradingInfoResponse.ok) {
tradingInfoData = await tradingInfoResponse.json()
}
// Combine data with fallbacks
setAccountData({
totalCollateral: balanceData.totalCollateral || tradingInfoData.totalCollateral || 0,
freeCollateral: balanceData.freeCollateral || tradingInfoData.availableCollateral || 0,
leverage: balanceData.leverage || tradingInfoData.accountLeverage || 0,
maintenanceMargin: balanceData.marginRequirement || tradingInfoData.maintenanceMargin || 0
})
// Update max position size from trading info if available
if (tradingInfoData.maxPositionSize) {
setMaxPositionSize(tradingInfoData.maxPositionSize)
}
} catch (error) {
console.error('Failed to fetch account data:', error)
@@ -114,37 +149,56 @@ export default function AdvancedTradingPanel() {
}
}
const calculateTradingMetrics = () => {
const calculateTradingMetrics = async () => {
if (!positionSize || !marketData.price) return
const size = parseFloat(positionSize)
const entryPrice = marketData.price
const notionalValue = size * entryPrice
// Calculate required margin (notional / leverage)
// Try to get accurate calculations from the API first
try {
const response = await fetch(`/api/drift/trading-info?symbol=${symbol}&side=${side}&amount=${size}&leverage=${leverage}`)
if (response.ok) {
const apiData = await response.json()
// Use API calculations if available
if (apiData.requiredMargin !== undefined) setRequiredMargin(apiData.requiredMargin)
if (apiData.maxPositionSize !== undefined) setMaxPositionSize(apiData.maxPositionSize)
if (apiData.liquidationPrice !== undefined) setLiquidationPrice(apiData.liquidationPrice)
}
} catch (error) {
console.error('Failed to fetch trading calculations from API:', error)
}
// Fallback to local calculations
const margin = notionalValue / leverage
setRequiredMargin(margin)
if (requiredMargin === 0) setRequiredMargin(margin)
// Calculate max position size based on available collateral
const maxNotional = accountData.freeCollateral * leverage
const maxSize = maxNotional / entryPrice
setMaxPositionSize(maxSize)
if (maxPositionSize === 0) {
const maxNotional = accountData.freeCollateral * leverage
const maxSize = maxNotional / entryPrice
setMaxPositionSize(maxSize)
}
// Calculate liquidation price
// Simplified liquidation calculation (actual Drift uses more complex formula)
const maintenanceMarginRate = 0.05 // 5% maintenance margin
const liquidationBuffer = notionalValue * maintenanceMarginRate
let liqPrice = 0
if (side === 'LONG') {
// For long: liquidation when position value + margin = liquidation buffer
liqPrice = entryPrice * (1 - (margin - liquidationBuffer) / notionalValue)
} else {
// For short: liquidation when position value - margin = liquidation buffer
liqPrice = entryPrice * (1 + (margin - liquidationBuffer) / notionalValue)
if (liquidationPrice === 0) {
// Simplified liquidation calculation (actual Drift uses more complex formula)
const maintenanceMarginRate = 0.05 // 5% maintenance margin
const liquidationBuffer = notionalValue * maintenanceMarginRate
let liqPrice = 0
if (side === 'LONG') {
// For long: liquidation when position value + margin = liquidation buffer
liqPrice = entryPrice * (1 - (margin - liquidationBuffer) / notionalValue)
} else {
// For short: liquidation when position value - margin = liquidation buffer
liqPrice = entryPrice * (1 + (margin - liquidationBuffer) / notionalValue)
}
setLiquidationPrice(Math.max(0, liqPrice))
}
setLiquidationPrice(Math.max(0, liqPrice))
// Calculate Stop Loss and Take Profit prices
let slPrice = 0