lockylocks's picture
the stock price should be displayed here with a choice of chart types.
7665724 verified
<!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 -->
<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 Content -->
<main class="flex-grow container mx-auto px-4 py-8">
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
<!-- Strategy Configuration -->
<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">
<!-- Stock Selection -->
<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>
<!-- Date Range -->
<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>
<!-- Manual Trade Entry -->
<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>
<!-- Add Trade Button -->
<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>
<!-- Results Display -->
<div class="lg:col-span-2 space-y-6">
<!-- Price Chart -->
<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>
<!-- Performance Metrics -->
<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>
<!-- Trade Log -->
<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 -->
<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>
// Chart Configuration
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 } }
}
}
};
// Initialize Chart
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
});
// Chart Type Selector
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
});
});
// Timeframe Selector
document.getElementById('timeframe').addEventListener('change', function() {
// In a real app, this would fetch new data based on timeframe
const timeframe = this.value;
console.log(`Fetching data for ${timeframe} timeframe...`);
// Update chart data here in a real implementation
});
// Initialize Feather Icons
feather.replace();
// Stock data by market
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'}
]
};
// Market select change handler
document.getElementById('marketSelect').addEventListener('change', function() {
const market = this.value;
const stockSearch = document.getElementById('stockSearch');
stockSearch.value = '';
stockSearch.dispatchEvent(new Event('input'));
});
// Populate stock list
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);
});
}
// Initialize stock list
populateStockList();
// Update stock list when market changes
document.getElementById('marketSelect').addEventListener('change', populateStockList);
</script>
</body>
</html>