tradeflow-bot / script.js
Mikkka88's picture
ch möchte eine App erstellen die in erster Linie als trading Bot dient. Sie soll Handels Signale die durch pine script Strategien oder Indikatoren auf Tradingview generiert werden, per webhook an meine Exchange wie Bitget, Pionex oder Bybit weiterleiten. Die anbindung zur Exchange läuft über die Exchange Api.
c54a803 verified
// TradeFlow Bot - Main JavaScript
// Mock Data Generators
const generateMockSignal = (index = 0) => {
const actions = ['BUY', 'SELL'];
const pairs = ['BTC/USDT', 'ETH/USDT', 'SOL/USDT', 'AVAX/USDT', 'MATIC/USDT'];
const strategies = ['TrendMaster v2.1', 'ScalpPro 3.0', 'MoonSignal Alpha', 'GridFlow Pro'];
const statuses = ['executed', 'pending', 'failed'];
return {
id: `sig_${Date.now()}_${index}`,
timestamp: new Date(Date.now() - Math.random() * 3600000),
pair: pairs[Math.floor(Math.random() * pairs.length)],
action: actions[Math.floor(Math.random() * actions.length)],
price: (Math.random() * 50000 + 1000).toFixed(2),
strategy: strategies[Math.floor(Math.random() * strategies.length)],
exchange: ['Bitget', 'Pionex', 'Bybit'][Math.floor(Math.random() * 3)],
status: statuses[Math.floor(Math.random() * statuses.length)],
pnl: (Math.random() * 200 - 50).toFixed(2)
};
};
const generateMockTrade = (index = 0) => {
const signal = generateMockSignal(index);
return {
...signal,
executionTime: new Date(Date.now() - Math.random() * 86400000),
filledPrice: (parseFloat(signal.price) * (1 + (Math.random() - 0.5) * 0.001)).toFixed(2),
filledAmount: (Math.random() * 2 + 0.1).toFixed(4)
};
};
// DOM Manipulation Helpers
const formatTime = (date) => {
return new Intl.DateTimeFormat('en-US', {
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
}).format(date);
};
const formatDate = (date) => {
return new Intl.DateTimeFormat('en-US', {
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
}).format(date);
};
const getStatusBadge = (status) => {
const classes = {
'executed': 'status-connected',
'pending': 'status-pending',
'failed': 'status-disconnected'
};
const icons = {
'executed': 'check-circle',
'pending': 'clock',
'failed': 'x-circle'
};
return `
<span class="status-badge ${classes[status]}">
<i data-feather="${icons[status]}" class="w-3 h-3"></i>
${status}
</span>
`;
};
// Signal Feed Manager
class SignalFeedManager {
constructor(containerId) {
this.container = document.getElementById(containerId);
this.signals = [];
this.maxSignals = 10;
}
addSignal(signal) {
this.signals.unshift(signal);
if (this.signals.length > this.maxSignals) {
this.signals.pop();
}
this.render();
}
render() {
if (!this.container) return;
const signalsHTML = this.signals.map(signal => `
<div class="signal-item ${signal.action.toLowerCase()} glass-card p-4 rounded-lg border">
<div class="flex items-center justify-between">
<div class="flex items-center gap-4">
<div class="flex flex-col">
<span class="text-2xl font-bold ${signal.action === 'BUY' ? 'text-emerald-400' : 'text-red-400'}">
${signal.action}
</span>
<span class="text-xs text-slate-400">${signal.pair}</span>
</div>
<div class="flex flex-col">
<span class="text-lg font-semibold">$${signal.price}</span>
<span class="text-xs text-slate-400">Price</span>
</div>
</div>
<div class="flex flex-col items-end gap-2">
<span class="text-sm font-medium">${signal.strategy}</span>
<span class="text-xs text-slate-400">${signal.exchange}</span>
<span class="text-xs text-slate-500">${formatTime(signal.timestamp)}</span>
</div>
</div>
<div class="mt-3 flex items-center justify-between">
${getStatusBadge(signal.status)}
<span class="text-xs text-slate-500">${signal.pnl ? `Est. PnL: $${signal.pnl}` : ''}</span>
</div>
</div>
`).join('');
this.container.innerHTML = signalsHTML;
feather.replace();
}
startLiveFeed() {
// Initial load
for (let i = 0; i < 5; i++) {
setTimeout(() => {
this.addSignal(generateMockSignal(i));
}, i * 200);
}
// Live updates every 3-7 seconds
const scheduleNext = () => {
const delay = Math.random() * 4000 + 3000;
setTimeout(() => {
this.addSignal(generateMockSignal());
scheduleNext();
}, delay);
};
scheduleNext();
}
}
// Trades Table Manager
class TradesTableManager {
constructor(containerId) {
this.container = document.getElementById(containerId);
this.trades = [];
this.maxTrades = 8;
}
addTrade(trade) {
this.trades.unshift(trade);
if (this.trades.length > this.maxTrades) {
this.trades.pop();
}
this.render();
}
render() {
if (!this.container) return;
const tradesHTML = this.trades.map(trade => `
<tr class="hover:bg-slate-800/50 transition-colors">
<td class="py-4">${formatDate(trade.executionTime)}</td>
<td class="py-4 font-mono font-semibold">${trade.pair}</td>
<td class="py-4">
<span class="font-bold ${trade.action === 'BUY' ? 'text-emerald-400' : 'text-red-400'}">
${trade.action}
</span>
</td>
<td class="py-4">${trade.exchange}</td>
<td class="py-4">${getStatusBadge(trade.status)}</td>
<td class="py-4 font-semibold ${parseFloat(trade.pnl) > 0 ? 'text-emerald-400' : 'text-red-400'}">
${parseFloat(trade.pnl) > 0 ? '+' : ''}$${trade.pnl}
</td>
</tr>
`).join('');
this.container.innerHTML = tradesHTML;
feather.replace();
}
loadInitial() {
for (let i = 0; i < this.maxTrades; i++) {
this.trades.push(generateMockTrade(i));
}
this.render();
}
}
// Initialize App
document.addEventListener('DOMContentLoaded', () => {
// Initialize signal feed
const signalManager = new SignalFeedManager('signal-feed');
signalManager.startLiveFeed();
// Initialize trades table
const tradesManager = new TradesTableManager('trades-table');
tradesManager.loadInitial();
// Auto-update stats
const updateStats = () => {
const statsCards = document.querySelectorAll('tf-stats-card');
statsCards.forEach(card => {
if (card.getAttribute('title') === 'Total PnL') {
const currentValue = parseFloat(card.getAttribute('value').replace(/[$,]/g, ''));
const change = (Math.random() - 0.5) * 100;
const newValue = (currentValue + change).toFixed(2);
card.setAttribute('value', `$${newValue.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}`);
}
if (card.getAttribute('title') === 'Total Trades') {
const currentValue = parseInt(card.getAttribute('value'));
if (Math.random() > 0.8) {
card.setAttribute('value', (currentValue + 1).toString());
}
}
});
};
// Update stats every 10 seconds
setInterval(updateStats, 10000);
// Page navigation
window.navigateTo = (page) => {
window.location.href = page;
};
console.log('🚀 TradeFlow Bot initialized successfully');
});