commit 11ea78fd799e82729a353b07b4dd19766b5b5b62
Author: root <root@hub.scroll.pub> Date: 2024-12-27 17:28:09 +0000 Subject: Initial commit diff --git a/body.html b/body.html new file mode 100644 index 0000000..36c3483 --- /dev/null +++ b/body.html @@ -0,0 +1,44 @@ +<header> + <nav> + <h1>StockMetrix</h1> + </nav> +</header> + +<main> + <section class="search-section"> + <h2>Analyze Stock Volatility</h2> + <div class="search-container"> + <input type="text" id="stockInput" placeholder="Enter stock ticker (e.g., AAPL)" aria-label="Stock ticker input"> + <button id="analyzeBtn">Analyze</button> + </div> + </section> + + <section class="results-section" id="resultsSection"> + <div class="metrics-grid"> + <div class="metric-card"> + <h3>Daily Volatility</h3> + <p id="dailyVol">-</p> + </div> + <div class="metric-card"> + <h3>Annual Volatility</h3> + <p id="annualVol">-</p> + </div> + <div class="metric-card"> + <h3>Beta</h3> + <p id="beta">-</p> + </div> + <div class="metric-card"> + <h3>Sharpe Ratio</h3> + <p id="sharpe">-</p> + </div> + </div> + + <div class="chart-container"> + <canvas id="volatilityChart" aria-label="Stock volatility chart" role="img"></canvas> + </div> + </section> +</main> + +<footer> + <p>Created by StockMetrix Team</p> +</footer> diff --git a/index.scroll b/index.scroll new file mode 100644 index 0000000..c5de4d1 --- /dev/null +++ b/index.scroll @@ -0,0 +1,8 @@ +buildHtml +baseUrl https://stockmetrix.scroll.pub +metaTags +editButton /edit.html +title StockMetrix - Advanced Stock Volatility Analysis +style.css +body.html +script.js diff --git a/prompt.json b/prompt.json new file mode 100644 index 0000000..ef6dcc7 --- /dev/null +++ b/prompt.json @@ -0,0 +1,20 @@ +{ + "id": "msg_015Q3kNeQwfHwHR7tPkC9VFN", + "type": "message", + "role": "assistant", + "model": "claude-3-5-sonnet-20241022", + "content": [ + { + "type": "text", + "text": "Here's a complete website design for a stock volatility analysis tool:\n\n---domain---\nstockmetrix.scroll.pub\n\n---index.scroll---\nbuildHtml\nbaseUrl https://stockmetrix.scroll.pub\nmetaTags\neditButton /edit.html\ntitle StockMetrix - Advanced Stock Volatility Analysis\nstyle.css\nbody.html\nscript.js\n\n---body.html---\n<header>\n <nav>\n <h1>StockMetrix</h1>\n </nav>\n</header>\n\n<main>\n <section class=\"search-section\">\n <h2>Analyze Stock Volatility</h2>\n <div class=\"search-container\">\n <input type=\"text\" id=\"stockInput\" placeholder=\"Enter stock ticker (e.g., AAPL)\" aria-label=\"Stock ticker input\">\n <button id=\"analyzeBtn\">Analyze</button>\n </div>\n </section>\n\n <section class=\"results-section\" id=\"resultsSection\">\n <div class=\"metrics-grid\">\n <div class=\"metric-card\">\n <h3>Daily Volatility</h3>\n <p id=\"dailyVol\">-</p>\n </div>\n <div class=\"metric-card\">\n <h3>Annual Volatility</h3>\n <p id=\"annualVol\">-</p>\n </div>\n <div class=\"metric-card\">\n <h3>Beta</h3>\n <p id=\"beta\">-</p>\n </div>\n <div class=\"metric-card\">\n <h3>Sharpe Ratio</h3>\n <p id=\"sharpe\">-</p>\n </div>\n </div>\n\n <div class=\"chart-container\">\n <canvas id=\"volatilityChart\" aria-label=\"Stock volatility chart\" role=\"img\"></canvas>\n </div>\n </section>\n</main>\n\n<footer>\n <p>Created by StockMetrix Team</p>\n</footer>\n\n---style.css---\n:root {\n --primary-color: #2c3e50;\n --secondary-color: #3498db;\n --accent-color: #e74c3c;\n --background-color: #f5f6fa;\n --card-background: #ffffff;\n}\n\n* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: 'Segoe UI', system-ui, sans-serif;\n line-height: 1.6;\n background: var(--background-color);\n color: var(--primary-color);\n}\n\nheader {\n background: var(--primary-color);\n color: white;\n padding: 1rem;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n}\n\nh1 {\n font-size: 2rem;\n background: linear-gradient(45deg, var(--secondary-color), var(--accent-color));\n -webkit-background-clip: text;\n background-clip: text;\n color: transparent;\n text-align: center;\n}\n\n.search-section {\n padding: 3rem 1rem;\n text-align: center;\n background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));\n color: white;\n}\n\n.search-container {\n max-width: 600px;\n margin: 2rem auto;\n display: flex;\n gap: 1rem;\n}\n\ninput {\n flex: 1;\n padding: 1rem;\n border: none;\n border-radius: 8px;\n font-size: 1rem;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n}\n\nbutton {\n padding: 1rem 2rem;\n background: var(--accent-color);\n color: white;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: transform 0.2s;\n}\n\nbutton:hover {\n transform: translateY(-2px);\n}\n\n.metrics-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.metric-card {\n background: var(--card-background);\n padding: 1.5rem;\n border-radius: 12px;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.3s;\n}\n\n.metric-card:hover {\n transform: translateY(-5px);\n}\n\n.chart-container {\n background: var(--card-background);\n margin: 2rem auto;\n padding: 2rem;\n border-radius: 12px;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n max-width: 1000px;\n}\n\nfooter {\n text-align: center;\n padding: 2rem;\n background: var(--primary-color);\n color: white;\n}\n\n@media (max-width: 768px) {\n .search-container {\n flex-direction: column;\n }\n \n .metrics-grid {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n \n .chart-container {\n margin: 1rem;\n padding: 1rem;\n }\n}\n\n---script.js---\ndocument.addEventListener('DOMContentLoaded', () => {\n const analyzeBtn = document.getElementById('analyzeBtn');\n const stockInput = document.getElementById('stockInput');\n const resultsSection = document.getElementById('resultsSection');\n \n let chart = null;\n\n analyzeBtn.addEventListener('click', analyzeStock);\n stockInput.addEventListener('keypress', (e) => {\n if (e.key === 'Enter') analyzeStock();\n });\n\n function analyzeStock() {\n const ticker = stockInput.value.trim().toUpperCase();\n if (!ticker) {\n alert('Please enter a valid stock ticker');\n return;\n }\n\n // Simulate loading data\n showLoadingState();\n \n // Simulate API call with setTimeout\n setTimeout(() => {\n const mockData = generateMockData();\n updateMetrics(mockData);\n drawChart(mockData);\n }, 1000);\n }\n\n function showLoadingState() {\n document.querySelectorAll('.metric-card p').forEach(p => {\n p.textContent = 'Loading...';\n });\n }\n\n function generateMockData() {\n return {\n dailyVol: (Math.random() * 2 + 1).toFixed(2) + '%',\n annualVol: (Math.random() * 15 + 10).toFixed(2) + '%',\n beta: (Math.random() + 0.5).toFixed(2),\n sharpe: (Math.random() * 2 + 0.5).toFixed(2),\n chartData: Array.from({length: 30}, () => Math.random() * 100)\n };\n }\n\n function updateMetrics(data) {\n document.getElementById('dailyVol').textContent = data.dailyVol;\n document.getElementById('annualVol').textContent = data.annualVol;\n document.getElementById('beta').textContent = data.beta;\n document.getElementById('sharpe').textContent = data.sharpe;\n }\n\n function drawChart(data) {\n const ctx = document.getElementById('volatilityChart').getContext('2d');\n \n if (chart) {\n chart.destroy();\n }\n\n chart = createVolatilityChart(ctx, data.chartData);\n }\n\n function createVolatilityChart(ctx, data) {\n // Simple line drawing implementation\n const width = ctx.canvas.width;\n const height = ctx.canvas.height;\n const points = data.length;\n const max = Math.max(...data);\n const min = Math.min(...data);\n \n ctx.clearRect(0, 0, width, height);\n ctx.beginPath();\n ctx.strokeStyle = '#3498db';\n ctx.lineWidth = 2;\n\n data.forEach((value, index) => {\n const x = (width / (points - 1)) * index;\n const y = height - ((value - min) / (max - min)) * height;\n \n if (index === 0) {\n ctx.moveTo(x, y);\n } else {\n ctx.lineTo(x, y);\n }\n });\n\n ctx.stroke();\n \n return {\n destroy: () => {\n ctx.clearRect(0, 0, width, height);\n }\n };\n }\n});\n\n---end---\n\nThis website features:\n1. Clean, modern design with gradient effects and smooth animations\n2. Responsive layout that works on all devices\n3. Interactive stock analysis interface\n4. Mock data visualization with canvas\n5. Loading states and error handling\n6. Accessible form controls and ARIA labels\n7. Smooth hover effects and transitions\n8. Professional color scheme and typography\n9. Grid-based metric cards layout\n10. Canvas-based chart visualization\n\nThe domain name \"stockmetrix\" combines \"stock\" with \"metrics\" and adds an 'x' for a modern tech feel, making it memorable and relevant to the site's purpose." + } + ], + "stop_reason": "end_turn", + "stop_sequence": null, + "usage": { + "input_tokens": 297, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "output_tokens": 2422 + } +} \ No newline at end of file diff --git a/readme.scroll b/readme.scroll new file mode 100644 index 0000000..811debe --- /dev/null +++ b/readme.scroll @@ -0,0 +1,2 @@ +# stockmetrix.scroll.pub +Website generated by Claude from prompt: I want to build a website which takes a stock ticker and then throws up all kind of volatility and returns metrics and visualise it \ No newline at end of file diff --git a/script.js b/script.js new file mode 100644 index 0000000..dfc588d --- /dev/null +++ b/script.js @@ -0,0 +1,96 @@ +document.addEventListener('DOMContentLoaded', () => { + const analyzeBtn = document.getElementById('analyzeBtn'); + const stockInput = document.getElementById('stockInput'); + const resultsSection = document.getElementById('resultsSection'); + + let chart = null; + + analyzeBtn.addEventListener('click', analyzeStock); + stockInput.addEventListener('keypress', (e) => { + if (e.key === 'Enter') analyzeStock(); + }); + + function analyzeStock() { + const ticker = stockInput.value.trim().toUpperCase(); + if (!ticker) { + alert('Please enter a valid stock ticker'); + return; + } + + // Simulate loading data + showLoadingState(); + + // Simulate API call with setTimeout + setTimeout(() => { + const mockData = generateMockData(); + updateMetrics(mockData); + drawChart(mockData); + }, 1000); + } + + function showLoadingState() { + document.querySelectorAll('.metric-card p').forEach(p => { + p.textContent = 'Loading...'; + }); + } + + function generateMockData() { + return { + dailyVol: (Math.random() * 2 + 1).toFixed(2) + '%', + annualVol: (Math.random() * 15 + 10).toFixed(2) + '%', + beta: (Math.random() + 0.5).toFixed(2), + sharpe: (Math.random() * 2 + 0.5).toFixed(2), + chartData: Array.from({length: 30}, () => Math.random() * 100) + }; + } + + function updateMetrics(data) { + document.getElementById('dailyVol').textContent = data.dailyVol; + document.getElementById('annualVol').textContent = data.annualVol; + document.getElementById('beta').textContent = data.beta; + document.getElementById('sharpe').textContent = data.sharpe; + } + + function drawChart(data) { + const ctx = document.getElementById('volatilityChart').getContext('2d'); + + if (chart) { + chart.destroy(); + } + + chart = createVolatilityChart(ctx, data.chartData); + } + + function createVolatilityChart(ctx, data) { + // Simple line drawing implementation + const width = ctx.canvas.width; + const height = ctx.canvas.height; + const points = data.length; + const max = Math.max(...data); + const min = Math.min(...data); + + ctx.clearRect(0, 0, width, height); + ctx.beginPath(); + ctx.strokeStyle = '#3498db'; + ctx.lineWidth = 2; + + data.forEach((value, index) => { + const x = (width / (points - 1)) * index; + const y = height - ((value - min) / (max - min)) * height; + + if (index === 0) { + ctx.moveTo(x, y); + } else { + ctx.lineTo(x, y); + } + }); + + ctx.stroke(); + + return { + destroy: () => { + ctx.clearRect(0, 0, width, height); + } + }; + } +}); diff --git a/style.css b/style.css new file mode 100644 index 0000000..1a34ce5 --- /dev/null +++ b/style.css @@ -0,0 +1,126 @@ +:root { + --primary-color: #2c3e50; + --secondary-color: #3498db; + --accent-color: #e74c3c; + --background-color: #f5f6fa; + --card-background: #ffffff; +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Segoe UI', system-ui, sans-serif; + line-height: 1.6; + background: var(--background-color); + color: var(--primary-color); +} + +header { + background: var(--primary-color); + color: white; + padding: 1rem; + box-shadow: 0 2px 4px rgba(0,0,0,0.1); +} + +h1 { + font-size: 2rem; + background: linear-gradient(45deg, var(--secondary-color), var(--accent-color)); + -webkit-background-clip: text; + background-clip: text; + color: transparent; + text-align: center; +} + +.search-section { + padding: 3rem 1rem; + text-align: center; + background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); + color: white; +} + +.search-container { + max-width: 600px; + margin: 2rem auto; + display: flex; + gap: 1rem; +} + +input { + flex: 1; + padding: 1rem; + border: none; + border-radius: 8px; + font-size: 1rem; + box-shadow: 0 2px 4px rgba(0,0,0,0.1); +} + +button { + padding: 1rem 2rem; + background: var(--accent-color); + color: white; + border: none; + border-radius: 8px; + cursor: pointer; + transition: transform 0.2s; +} + +button:hover { + transform: translateY(-2px); +} + +.metrics-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 1.5rem; + padding: 2rem; + max-width: 1200px; + margin: 0 auto; +} + +.metric-card { + background: var(--card-background); + padding: 1.5rem; + border-radius: 12px; + box-shadow: 0 4px 6px rgba(0,0,0,0.1); + transition: transform 0.3s; +} + +.metric-card:hover { + transform: translateY(-5px); +} + +.chart-container { + background: var(--card-background); + margin: 2rem auto; + padding: 2rem; + border-radius: 12px; + box-shadow: 0 4px 6px rgba(0,0,0,0.1); + max-width: 1000px; +} + +footer { + text-align: center; + padding: 2rem; + background: var(--primary-color); + color: white; +} + +@media (max-width: 768px) { + .search-container { + flex-direction: column; + } + + .metrics-grid { + grid-template-columns: 1fr; + padding: 1rem; + } + + .chart-container { + margin: 1rem; + padding: 1rem; + } +}