| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>TradeWizard Backtester</title> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> |
| <script src="https://unpkg.com/feather-icons"></script> |
| <script> |
| tailwind.config = { |
| theme: { |
| extend: { |
| colors: { |
| primary: '#3b82f6', |
| secondary: '#10b981', |
| } |
| } |
| } |
| } |
| </script> |
| </head> |
| <body class="bg-gray-50"> |
| <div class="min-h-screen flex flex-col"> |
| |
| <header class="bg-white shadow-sm py-4"> |
| <div class="container mx-auto px-4 flex justify-between items-center"> |
| <h1 class="text-2xl font-bold text-primary">TradeWizard 🧙♂️</h1> |
| <nav class="flex items-center space-x-6"> |
| <a href="#" class="text-gray-600 hover:text-primary">Backtester</a> |
| <a href="#" class="text-gray-600 hover:text-primary">Strategies</a> |
| <a href="#" class="text-gray-600 hover:text-primary">Performance</a> |
| </nav> |
| </div> |
| </header> |
|
|
| |
| <main class="flex-grow container mx-auto px-4 py-8"> |
| <div class="grid grid-cols-1 lg:grid-cols-3 gap-8"> |
| |
| <div class="lg:col-span-1 bg-white rounded-lg shadow p-6"> |
| <h2 class="text-xl font-semibold mb-4 text-gray-800">Trade Entry</h2> |
| <div class="space-y-4"> |
| |
| <div> |
| <div class="mb-2"> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Market Index</label> |
| <select id="marketSelect" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent"> |
| <option value="ftse">FTSE All-Share</option> |
| <option value="sp500">S&P 500</option> |
| <option value="nasdaq">NASDAQ Composite</option> |
| <option value="dax">DAX</option> |
| </select> |
| </div> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Stock Selection</label> |
| <div id="stockList" class="border border-gray-300 rounded-md max-h-60 overflow-y-auto p-2"> |
| <div class="grid grid-cols-1 gap-2"> |
| <template id="stockItemTemplate"> |
| <div class="flex items-center p-2 hover:bg-gray-50 rounded cursor-pointer"> |
| <input type="radio" name="selectedStock" class="mr-2"> |
| <div> |
| <div class="font-medium text-gray-800 stock-symbol"></div> |
| <div class="text-xs text-gray-500 stock-name"></div> |
| </div> |
| </div> |
| </template> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="grid grid-cols-2 gap-4"> |
| <div> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Start Date</label> |
| <input type="date" |
| class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent"> |
| </div> |
| <div> |
| <label class="block text-sm font-medium text-gray-700 mb-1">End Date</label> |
| <input type="date" |
| class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent"> |
| </div> |
| </div> |
| |
| <div class="space-y-2"> |
| <div> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Action</label> |
| <select class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent"> |
| <option>BUY</option> |
| <option>SELL</option> |
| </select> |
| </div> |
| <div class="flex items-center"> |
| <label class="w-24 text-sm text-gray-600">Price</label> |
| <input type="number" step="0.01" |
| class="flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent"> |
| </div> |
| <div class="flex items-center"> |
| <label class="w-24 text-sm text-gray-600">Quantity</label> |
| <input type="number" |
| class="flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent"> |
| </div> |
| <div class="flex items-center"> |
| <label class="w-24 text-sm text-gray-600">Date</label> |
| <input type="date" |
| class="flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent"> |
| </div> |
| </div> |
| |
| |
| <button class="w-full bg-primary hover:bg-blue-600 text-white py-2 px-4 rounded-md transition duration-200"> |
| Add Trade |
| </button> |
| </div> |
| </div> |
| |
| |
| <div class="lg:col-span-2 space-y-6"> |
| |
| <div class="bg-white rounded-lg shadow p-6"> |
| <div class="flex justify-between items-center mb-4"> |
| <h2 class="text-xl font-semibold text-gray-800">Stock Price Analysis</h2> |
| <div class="flex space-x-2"> |
| <select id="chartType" class="px-3 py-1 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-primary"> |
| <option value="line">Line Chart</option> |
| <option value="bar">Bar Chart</option> |
| <option value="candlestick">Candlestick</option> |
| </select> |
| <select id="timeframe" class="px-3 py-1 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-primary"> |
| <option value="1d">1 Day</option> |
| <option value="1w">1 Week</option> |
| <option value="1m">1 Month</option> |
| <option value="3m">3 Months</option> |
| <option value="1y">1 Year</option> |
| <option value="5y">5 Years</option> |
| </select> |
| </div> |
| </div> |
| <div class="h-80"> |
| <canvas id="priceChart"></canvas> |
| </div> |
| </div> |
| |
| <div class="bg-white rounded-lg shadow p-6"> |
| <h2 class="text-xl font-semibold mb-4 text-gray-800">Performance Metrics</h2> |
| <div class="grid grid-cols-2 md:grid-cols-4 gap-4"> |
| <div class="bg-gray-50 p-4 rounded"> |
| <p class="text-sm text-gray-500">Total Return</p> |
| <p class="text-2xl font-bold text-primary">+24.5%</p> |
| </div> |
| <div class="bg-gray-50 p-4 rounded"> |
| <p class="text-sm text-gray-500">Win Rate</p> |
| <p class="text-2xl font-bold text-primary">68%</p> |
| </div> |
| <div class="bg-gray-50 p-4 rounded"> |
| <p class="text-sm text-gray-500">Max Drawdown</p> |
| <p class="text-2xl font-bold text-primary">-12.3%</p> |
| </div> |
| <div class="bg-gray-50 p-4 rounded"> |
| <p class="text-sm text-gray-500">Sharpe Ratio</p> |
| <p class="text-2xl font-bold text-primary">1.45</p> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="bg-white rounded-lg shadow p-6"> |
| <h2 class="text-xl font-semibold mb-4 text-gray-800">Trade Log</h2> |
| <div class="overflow-x-auto"> |
| <table class="min-w-full divide-y divide-gray-200"> |
| <thead class="bg-gray-50"> |
| <tr> |
| <th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Date</th> |
| <th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Action</th> |
| <th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Price</th> |
| <th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Quantity</th> |
| <th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">PnL</th> |
| </tr> |
| </thead> |
| <tbody class="bg-white divide-y divide-gray-200"> |
| <tr> |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">2023-01-15</td> |
| <td class="px-4 py-2 whitespace-nowrap text-sm font-medium text-green-600">BUY</td> |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">$142.35</td> |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">100</td> |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">-</td> |
| </tr> |
| <tr> |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">2023-02-28</td> |
| <td class="px-4 py-2 whitespace-nowrap text-sm font-medium text-red-600">SELL</td> |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">$158.72</td> |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">100</td> |
| <td class="px-4 py-2 whitespace-nowrap text-sm font-medium text-green-600">+$1,637</td> |
| </tr> |
| <tr> |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">2023-03-10</td> |
| <td class="px-4 py-2 whitespace-nowrap text-sm font-medium text-green-600">BUY</td> |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">$152.89</td> |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">100</td> |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">-</td> |
| </tr> |
| <tr> |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">2023-04-22</td> |
| <td class="px-4 py-2 whitespace-nowrap text-sm font-medium text-red-600">SELL</td> |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">$168.34</td> |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">100</td> |
| <td class="px-4 py-2 whitespace-nowrap text-sm font-medium text-green-600">+$1,545</td> |
| </tr> |
| </tbody> |
| </table> |
| </div> |
| </div> |
| </div> |
| </div> |
| </main> |
|
|
| |
| <footer class="bg-white py-4 border-t"> |
| <div class="container mx-auto px-4 text-center text-gray-500 text-sm"> |
| <p>TradeWizard Backtester - Test your trading strategies with confidence</p> |
| </div> |
| </footer> |
| </div> |
|
|
| <script> |
| |
| const chartConfig = { |
| line: { |
| type: 'line', |
| options: { |
| responsive: true, |
| maintainAspectRatio: false, |
| plugins: { |
| legend: { position: 'top' } |
| }, |
| scales: { y: { beginAtZero: false } } |
| } |
| }, |
| bar: { |
| type: 'bar', |
| options: { |
| responsive: true, |
| maintainAspectRatio: false, |
| plugins: { |
| legend: { position: 'top' } |
| }, |
| scales: { y: { beginAtZero: false } } |
| } |
| }, |
| candlestick: { |
| type: 'candlestick', |
| options: { |
| responsive: true, |
| maintainAspectRatio: false, |
| plugins: { |
| legend: { position: 'top' } |
| }, |
| scales: { y: { beginAtZero: false } } |
| } |
| } |
| }; |
| |
| |
| const ctx = document.getElementById('priceChart').getContext('2d'); |
| let priceChart = new Chart(ctx, { |
| type: chartConfig.line.type, |
| data: { |
| labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'], |
| datasets: [ |
| { |
| label: 'Stock Price', |
| data: [140, 158, 153, 168, 175, 182], |
| borderColor: '#3b82f6', |
| backgroundColor: 'rgba(59, 130, 246, 0.1)', |
| tension: 0.1, |
| fill: true |
| }, |
| { |
| label: 'Short MA', |
| data: [138, 148, 151, 162, 170, 178], |
| borderColor: '#10b981', |
| borderDash: [5, 5], |
| tension: 0.1 |
| }, |
| { |
| label: 'Long MA', |
| data: [135, 142, 148, 155, 160, 165], |
| borderColor: '#ef4444', |
| borderDash: [5, 5], |
| tension: 0.1 |
| } |
| ] |
| }, |
| options: chartConfig.line.options |
| }); |
| |
| |
| document.getElementById('chartType').addEventListener('change', function() { |
| const chartType = this.value; |
| priceChart.destroy(); |
| priceChart = new Chart(ctx, { |
| type: chartConfig[chartType].type, |
| data: priceChart.data, |
| options: chartConfig[chartType].options |
| }); |
| }); |
| |
| |
| document.getElementById('timeframe').addEventListener('change', function() { |
| |
| const timeframe = this.value; |
| console.log(`Fetching data for ${timeframe} timeframe...`); |
| |
| }); |
| |
| feather.replace(); |
| |
| |
| const stockData = { |
| ftse: [ |
| {symbol: 'III', name: '3i Group'}, |
| {symbol: 'ADM', name: 'Admiral Group'}, |
| {symbol: 'AAL', name: 'Anglo American'}, |
| {symbol: 'AZN', name: 'AstraZeneca'}, |
| {symbol: 'AV', name: 'Aviva'}, |
| {symbol: 'BATS', name: 'British American Tobacco'} |
| ], |
| sp500: [ |
| {symbol: 'AAPL', name: 'Apple Inc.'}, |
| {symbol: 'MSFT', name: 'Microsoft'}, |
| {symbol: 'AMZN', name: 'Amazon'}, |
| {symbol: 'GOOGL', name: 'Alphabet (Google)'}, |
| {symbol: 'TSLA', name: 'Tesla'}, |
| {symbol: 'JPM', name: 'JPMorgan Chase'} |
| ], |
| nasdaq: [ |
| {symbol: 'AAPL', name: 'Apple Inc.'}, |
| {symbol: 'MSFT', name: 'Microsoft'}, |
| {symbol: 'AMZN', name: 'Amazon'}, |
| {symbol: 'GOOGL', name: 'Alphabet (Google)'}, |
| {symbol: 'META', name: 'Meta (Facebook)'}, |
| {symbol: 'TSLA', name: 'Tesla'} |
| ], |
| dax: [ |
| {symbol: 'SAP', name: 'SAP SE'}, |
| {symbol: 'SIE', name: 'Siemens AG'}, |
| {symbol: 'DTE', name: 'Deutsche Telekom'}, |
| {symbol: 'ALV', name: 'Allianz SE'}, |
| {symbol: 'DBK', name: 'Deutsche Bank'}, |
| {symbol: 'BMW', name: 'BMW AG'} |
| ] |
| }; |
| |
| |
| document.getElementById('marketSelect').addEventListener('change', function() { |
| const market = this.value; |
| const stockSearch = document.getElementById('stockSearch'); |
| stockSearch.value = ''; |
| stockSearch.dispatchEvent(new Event('input')); |
| }); |
| |
| function populateStockList() { |
| const market = document.getElementById('marketSelect').value; |
| const stockList = document.getElementById('stockList'); |
| const template = document.getElementById('stockItemTemplate'); |
| const container = stockList.querySelector('.grid'); |
| |
| container.innerHTML = ''; |
| |
| stockData[market].forEach(stock => { |
| const clone = template.content.cloneNode(true); |
| const radio = clone.querySelector('input[type="radio"]'); |
| radio.value = stock.symbol; |
| radio.id = `stock-${stock.symbol}`; |
| |
| clone.querySelector('.stock-symbol').textContent = stock.symbol; |
| clone.querySelector('.stock-name').textContent = stock.name; |
| |
| container.appendChild(clone); |
| }); |
| } |
| |
| |
| populateStockList(); |
| |
| |
| document.getElementById('marketSelect').addEventListener('change', populateStockList); |
| </script> |
| </body> |
| </html> |
|
|