Created
July 29, 2026 12:11
-
-
Save tauseedzaman/eab56c9f6a7b2c90b2f2ee7b02ec4aab to your computer and use it in GitHub Desktop.
View MetaTrader trade history from CSV, analyze profits, and generate interactive charts using Chart.js.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>Trade History Visualizer</title> | |
| <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> | |
| <style> | |
| body { | |
| background: #111; | |
| color: white; | |
| font-family: Arial; | |
| padding: 20px; | |
| } | |
| textarea { | |
| width: 100%; | |
| height: 220px; | |
| background: #222; | |
| color: #fff; | |
| padding: 10px; | |
| font-family: monospace; | |
| } | |
| button { | |
| padding: 12px 20px; | |
| margin-top: 15px; | |
| cursor: pointer; | |
| background: #2ecc71; | |
| border: none; | |
| color: white; | |
| font-size: 16px; | |
| } | |
| canvas { | |
| margin-top: 30px; | |
| background: #fff; | |
| } | |
| table { | |
| width: 100%; | |
| margin-top: 20px; | |
| border-collapse: collapse; | |
| } | |
| td, | |
| th { | |
| border: 1px solid #333; | |
| padding: 8px; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <h2>Trade CSV Viewer</h2> | |
| <textarea id="csvInput" placeholder="Paste CSV Here"></textarea> | |
| <br> | |
| <button onclick="generateChart()"> | |
| Generate Chart | |
| </button> | |
| <canvas id="chart" height="120"></canvas> | |
| <div id="summary"></div> | |
| <script>let chart = null; | |
| function parseCSV(csv) { | |
| csv = csv.trim(); | |
| const lines = csv.split(/\r?\n/); | |
| if (lines.length < 2) | |
| return []; | |
| const headers = lines[0].split(",").map(h => h.trim()); | |
| const data = []; | |
| for (let i = 1; i < lines.length; i++) { | |
| if (!lines[i].trim()) | |
| continue; | |
| const values = lines[i].split(","); | |
| const row = {}; | |
| headers.forEach((header, index) => { | |
| row[header] = (values[index] || "").trim(); | |
| }); | |
| data.push(row); | |
| } | |
| return data; | |
| } | |
| function number(value) { | |
| if (value === "") | |
| return 0; | |
| return parseFloat(value); | |
| } | |
| function generateChart() { | |
| const csv = document.getElementById("csvInput").value.trim(); | |
| if (!csv) { | |
| alert("Paste your CSV first."); | |
| return; | |
| } | |
| const trades = parseCSV(csv); | |
| if (trades.length === 0) { | |
| alert("No trades found."); | |
| return; | |
| } | |
| let labels = []; | |
| let profits = []; | |
| let colors = []; | |
| let totalProfit = 0; | |
| let wins = 0; | |
| let losses = 0; | |
| let biggestWin = -999999; | |
| let biggestLoss = 999999; | |
| let html = ` | |
| <table> | |
| <thead> | |
| <tr> | |
| <th>Ticket</th> | |
| <th>Open</th> | |
| <th>Close</th> | |
| <th>Type</th> | |
| <th>Entry</th> | |
| <th>Exit</th> | |
| <th>Lots</th> | |
| <th>Profit</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| `; | |
| trades.forEach(trade => { | |
| const profit = number(trade.profit); | |
| const entry = number(trade.opening_price); | |
| const exit = number(trade.closing_price); | |
| labels.push(trade.ticket); | |
| profits.push(profit); | |
| colors.push(profit >= 0 ? "#2ecc71" : "#e74c3c"); | |
| totalProfit += profit; | |
| if (profit >= 0) | |
| wins++; | |
| else | |
| losses++; | |
| if (profit > biggestWin) | |
| biggestWin = profit; | |
| if (profit < biggestLoss) | |
| biggestLoss = profit; | |
| html += ` | |
| <tr> | |
| <td>${trade.ticket}</td> | |
| <td>${trade.opening_time_utc}</td> | |
| <td>${trade.closing_time_utc}</td> | |
| <td>${trade.type.toUpperCase()}</td> | |
| <td>${entry}</td> | |
| <td>${exit}</td> | |
| <td>${trade.lots}</td> | |
| <td style="color:${profit >= 0 ? 'lime' : 'red'}">${profit}</td> | |
| </tr> | |
| `; | |
| }); | |
| html += ` | |
| </tbody> | |
| </table> | |
| `; | |
| const winRate = ((wins / trades.length) * 100).toFixed(1); | |
| html += ` | |
| <br> | |
| <h2>Statistics</h2> | |
| <table> | |
| <tr><td>Total Trades</td><td>${trades.length}</td></tr> | |
| <tr><td>Wins</td><td>${wins}</td></tr> | |
| <tr><td>Losses</td><td>${losses}</td></tr> | |
| <tr><td>Win Rate</td><td>${winRate}%</td></tr> | |
| <tr><td>Total Profit</td><td>${totalProfit.toFixed(2)}</td></tr> | |
| <tr><td>Biggest Win</td><td>${biggestWin}</td></tr> | |
| <tr><td>Biggest Loss</td><td>${biggestLoss}</td></tr> | |
| </table> | |
| `; | |
| document.getElementById("summary").innerHTML = html; | |
| if (chart) | |
| chart.destroy(); | |
| chart = new Chart( | |
| document.getElementById("chart"), | |
| { | |
| type: "bar", | |
| data: { | |
| labels: labels, | |
| datasets: [{ | |
| label: "Profit / Loss", | |
| data: profits, | |
| backgroundColor: colors | |
| }] | |
| }, | |
| options: { | |
| responsive: true, | |
| interaction: { | |
| mode: "index", | |
| intersect: false | |
| }, | |
| plugins: { | |
| legend: { | |
| display: false | |
| }, | |
| tooltip: { | |
| callbacks: { | |
| label: function (ctx) { | |
| return "Profit: " + ctx.raw; | |
| } | |
| } | |
| } | |
| }, | |
| scales: { | |
| y: { | |
| title: { | |
| display: true, | |
| text: "Profit" | |
| } | |
| }, | |
| x: { | |
| title: { | |
| display: true, | |
| text: "Trade Ticket" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| ); | |
| } | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment