Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 49 additions & 6 deletions optimize-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,26 @@ function parseScoringWeights() {
const scoringWeights = parseScoringWeights();
const normalizedScoringWeights = scoringWeights.normalized;

function parseSelectedSymbols() {
const raw = process.env.OPTIMIZER_SELECTED_SYMBOLS;
if (!raw) {
return null;
}

try {
const parsed = JSON.parse(raw);
if (Array.isArray(parsed)) {
return parsed.filter((symbol) => typeof symbol === 'string' && symbol.trim().length > 0);
}
} catch (_error) {
console.warn('Warning: Failed to parse OPTIMIZER_SELECTED_SYMBOLS, ignoring value.');
}

return null;
}

const selectedSymbols = parseSelectedSymbols();

const formatWeightPercent = (value) => {
if (!Number.isFinite(value)) {
return '0%';
Expand Down Expand Up @@ -1219,7 +1239,9 @@ function optimizeThresholds() {
console.log('========================================\n');

// Focus on most active symbols
const topSymbols = ['ASTERUSDT', 'BTCUSDT', 'ETHUSDT', 'SOLUSDT'];
const topSymbols = selectedSymbols && selectedSymbols.length > 0
? selectedSymbols
: ['ASTERUSDT', 'BTCUSDT', 'ETHUSDT', 'SOLUSDT'];

topSymbols.forEach(symbol => {
if (!config.symbols[symbol]) return;
Expand Down Expand Up @@ -1763,7 +1785,19 @@ async function generateRecommendations(deployableCapital) {
const optimizedConfig = JSON.parse(JSON.stringify(config));
const sanitizedCapital = Number.isFinite(deployableCapital) && deployableCapital > 0 ? deployableCapital : 0;

const symbolEntries = Object.entries(config.symbols);
let symbolEntries = Object.entries(config.symbols);

if (selectedSymbols && selectedSymbols.length > 0) {
symbolEntries = symbolEntries.filter(([symbol]) => selectedSymbols.includes(symbol));

if (symbolEntries.length === 0) {
console.log(`Warning: No matching symbols found for selection ${selectedSymbols.join(', ')}. Falling back to all symbols.`);
symbolEntries = Object.entries(config.symbols);
} else {
console.log(`Optimizing selected symbols: ${symbolEntries.map(([symbol]) => symbol).join(', ')}`);
}
}

if (symbolEntries.length === 0) {
return { recommendations, optimizedConfig, recommendedGlobalMax: 0 };
}
Expand All @@ -1778,12 +1812,17 @@ async function generateRecommendations(deployableCapital) {
? Math.max(0.25, Math.min(2.5, sanitizedCapital / baselineTotalMargin))
: 1;

for (const [symbol, symbolConfig] of symbolEntries) {
const totalSymbols = symbolEntries.length;

for (let index = 0; index < symbolEntries.length; index++) {
const [symbol, symbolConfig] = symbolEntries[index];
const spanDays = getSymbolDataSpanDays(symbol);
const fallbackMargin = (symbolConfig.tradeSize || 20) * 5;
const baseMargin = symbolConfig.maxPositionMarginUSDT || fallbackMargin;
const capitalBudget = Math.max(5, Math.min(sanitizedCapital || baseMargin, baseMargin * scaleFactor));

console.log(`Analyzing ${symbol} (${index + 1}/${totalSymbols})`);

const optimization = await optimizeSymbolParameters(symbol, symbolConfig, capitalBudget, spanDays);

const currentDaily = optimization.current.performance.dailyPnl;
Expand Down Expand Up @@ -2035,7 +2074,9 @@ async function analyzeRealTradingHistory(credentials) {
console.log('???? REAL TRADING HISTORY ANALYSIS');
console.log('=================================\n');

const symbols = ['ASTERUSDT'];
const symbols = selectedSymbols && selectedSymbols.length > 0
? selectedSymbols
: ['ASTERUSDT', 'BTCUSDT', 'ETHUSDT', 'SOLUSDT'];
const sevenDaysAgo = Date.now() - (7 * 24 * 60 * 60 * 1000);

for (const symbol of symbols) {
Expand Down Expand Up @@ -2456,14 +2497,16 @@ async function main() {
const deployableCapital = capitalInfo.calculatedTotal || parseFloat(accountInfo?.totalWalletBalance ?? 0);
const { recommendations, optimizedConfig, recommendedGlobalMax } = await generateRecommendations(deployableCapital);

// Optimize capital allocation
console.log('Finalizing results: optimizing capital allocation...');
const capitalOptimization = optimizeCapitalAllocation(accountInfo, recommendations, optimizedConfig.symbols);

// Generate final summary
console.log('Finalizing results: generating summary...');
const optimizationResults = generateOptimizationSummary(recommendations, capitalOptimization, optimizedConfig, recommendedGlobalMax);

console.log('Finalizing results: writing outputs...');
await maybeApplyOptimizedConfig(config, optimizedConfig, optimizationResults.summary);

console.log('Optimization complete');
console.log('???? Optimization analysis complete!');
const totalValue = parseFloat(accountInfo?.totalMarginBalance || balance.totalWalletBalance || 0);
console.log(`???? Total account value: $${formatLargeNumber(totalValue)}`);
Expand Down
2 changes: 1 addition & 1 deletion src/app/api/positions/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export const GET = withAuth(async (request: NextRequest, _user) => {
entryPrice,
markPrice,
pnl: unRealizedProfit,
pnlPercent: notionalValue > 0 ? (unRealizedProfit / notionalValue) * 100 : 0,
pnlPercent: (currentNotionalValue / leverage) > 0 ? (unRealizedProfit / (currentNotionalValue / leverage)) * 100 : 0,
margin: currentNotionalValue / leverage,
leverage,
liquidationPrice: pos.liquidationPrice ? parseFloat(pos.liquidationPrice) : undefined,
Expand Down
7 changes: 4 additions & 3 deletions src/components/PositionTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -339,14 +339,15 @@ export default function PositionTable({

const priceDiff = liveMarkPrice - entryPrice;
const livePnL = isLong ? priceDiff * quantity : -priceDiff * quantity;
const notionalValue = quantity * entryPrice;
const livePnLPercent = notionalValue > 0 ? (livePnL / notionalValue) * 100 : 0;
const margin = (quantity * liveMarkPrice) / position.leverage;
const livePnLPercent = Math.abs(margin) > 0 ? (livePnL / Math.abs(margin)) * 100 : 0;

return {
...position,
markPrice: liveMarkPrice,
pnl: livePnL,
pnlPercent: livePnLPercent
pnlPercent: livePnLPercent,
margin: margin
};
}
return position;
Expand Down
Loading
Loading