2026-01-19 06:06:56 +07:00
<!DOCTYPE html>
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< title > MQL5 Trading Automation Dashboard< / title >
2026-02-01 19:18:55 +00:00
< link rel = "manifest" href = "/manifest.json" >
2026-02-13 11:40:16 +00:00
< meta name = "theme-color" content = "#4f46e5" >
2026-02-01 19:18:55 +00:00
< meta name = "description" content = "GenX FX Trading System - SMC + Trend Breakout (MTF) for Exness MT5" >
< link rel = "apple-touch-icon" href = "/icons/icon-192x192.png" >
2026-01-19 06:06:56 +07:00
< style >
* {
margin : 0 ;
padding : 0 ;
box-sizing : border-box ;
}
body {
font-family : - apple-system , BlinkMacSystemFont , 'Segoe UI' , Roboto , Oxygen , Ubuntu , Cantarell , sans-serif ;
2026-02-13 11:40:16 +00:00
background : linear-gradient ( 135 deg , #4f46e5 0 % , #764ba2 100 % ) ;
2026-01-19 06:06:56 +07:00
min-height : 100 vh ;
padding : 20 px ;
}
. container {
max-width : 1200 px ;
margin : 0 auto ;
}
. header {
background : white ;
padding : 30 px ;
border-radius : 15 px ;
box-shadow : 0 10 px 30 px rgba ( 0 , 0 , 0 , 0.2 ) ;
margin-bottom : 30 px ;
text-align : center ;
}
. header h1 {
color : #333 ;
font-size : 2.5 em ;
margin-bottom : 10 px ;
}
. header p {
color : #666 ;
font-size : 1.1 em ;
}
. grid {
display : grid ;
grid-template-columns : repeat ( auto - fit , minmax ( 300 px , 1 fr ) ) ;
gap : 20 px ;
margin-bottom : 30 px ;
}
. card {
background : white ;
padding : 25 px ;
border-radius : 15 px ;
box-shadow : 0 5 px 15 px rgba ( 0 , 0 , 0 , 0.1 ) ;
transition : transform 0.3 s , box-shadow 0.3 s ;
}
. card : hover {
transform : translateY ( -5 px ) ;
box-shadow : 0 10 px 25 px rgba ( 0 , 0 , 0 , 0.2 ) ;
}
. card h2 {
2026-02-13 11:40:16 +00:00
color : #4f46e5 ;
2026-01-19 06:06:56 +07:00
margin-bottom : 15 px ;
font-size : 1.5 em ;
}
. card p {
color : #666 ;
line-height : 1.6 ;
margin-bottom : 15 px ;
}
. btn {
display : inline-block ;
padding : 12 px 24 px ;
2026-02-13 11:40:16 +00:00
background : #4f46e5 ;
2026-01-19 06:06:56 +07:00
color : white ;
text-decoration : none ;
border-radius : 8 px ;
font-weight : 600 ;
transition : background 0.3 s ;
}
. btn : hover {
2026-02-13 11:40:16 +00:00
background : #4338ca ;
2026-01-19 06:06:56 +07:00
}
2026-02-07 11:23:41 +00:00
. btn : focus-visible {
2026-02-13 11:40:16 +00:00
outline : 2 px solid #4f46e5 ;
2026-02-07 11:23:41 +00:00
outline-offset : 2 px ;
}
2026-01-19 06:06:56 +07:00
. status {
background : white ;
padding : 25 px ;
border-radius : 15 px ;
box-shadow : 0 5 px 15 px rgba ( 0 , 0 , 0 , 0.1 ) ;
}
. status-item {
display : flex ;
justify-content : space-between ;
padding : 15 px 0 ;
border-bottom : 1 px solid #eee ;
}
. status-item : last-child {
border-bottom : none ;
}
. status-label {
color : #666 ;
font-weight : 600 ;
}
. status-value {
2026-02-13 11:40:16 +00:00
color : #4f46e5 ;
2026-01-19 06:06:56 +07:00
font-weight : 700 ;
2026-02-17 11:36:17 +00:00
display : inline-flex ;
align-items : center ;
}
/* Copy Button */
. copy-btn {
background : none ;
border : none ;
cursor : pointer ;
padding : 4 px ;
margin-left : 8 px ;
color : #666 ;
border-radius : 4 px ;
transition : all 0.2 s ;
vertical-align : middle ;
opacity : 0.6 ;
display : inline-flex ;
align-items : center ;
}
. copy-btn : hover {
background : #eef2ff ;
color : #4f46e5 ;
opacity : 1 ;
}
. copy-btn : focus-visible {
outline : 2 px solid #4f46e5 ;
opacity : 1 ;
2026-01-19 06:06:56 +07:00
}
. badge {
display : inline-block ;
padding : 4 px 12 px ;
border-radius : 20 px ;
font-size : 0.85 em ;
font-weight : 600 ;
}
. badge-success {
background : #10b981 ;
color : white ;
}
. badge-warning {
background : #f59e0b ;
color : white ;
}
. footer {
text-align : center ;
color : white ;
margin-top : 40 px ;
opacity : 0.9 ;
}
2026-02-08 11:20:56 +00:00
. skip-link {
position : absolute ;
top : -40 px ;
left : 0 ;
2026-02-13 11:40:16 +00:00
background : #4f46e5 ;
2026-02-08 11:20:56 +00:00
color : white ;
padding : 8 px ;
z-index : 100 ;
transition : top 0.3 s ;
text-decoration : none ;
border-radius : 0 0 8 px 0 ;
font-weight : 600 ;
}
. skip-link : focus {
top : 0 ;
outline : 2 px solid white ;
outline-offset : -2 px ;
}
2026-02-12 11:36:12 +00:00
/* Service Worker Toast */
2026-02-13 11:40:16 +00:00
. toast { position : fixed ; bottom : 20 px ; right : 20 px ; background : white ; padding : 15 px ; border-radius : 8 px ; box-shadow : 0 4 px 12 px rgba ( 0 , 0 , 0 , 0.15 ) ; transform : translateY ( 100 px ) ; transition : transform 0.3 s ; z-index : 1000 ; border-left : 4 px solid #4f46e5 ; display : flex ; align-items : center ; gap : 10 px ; }
2026-02-12 11:36:12 +00:00
. toast . show { transform : translateY ( 0 ) ; }
. toast-btn { border : none ; padding : 6 px 12 px ; border-radius : 4 px ; cursor : pointer ; font-weight : 600 ; }
2026-02-13 11:40:16 +00:00
. toast-btn-primary { background : #4f46e5 ; color : white ; }
. toast-btn-primary : hover { background : #4338ca ; }
2026-02-12 11:36:12 +00:00
. toast-btn-secondary { background : #f3f4f6 ; color : #333 ; }
. toast-btn-secondary : hover { background : #e5e7eb ; }
2026-01-19 06:06:56 +07:00
< / style >
< / head >
< body >
2026-02-08 11:20:56 +00:00
< a href = "#main-content" class = "skip-link" > Skip to content< / a >
2026-01-19 06:06:56 +07:00
< div class = "container" >
< div class = "header" >
2026-02-09 11:13:59 +00:00
< h1 > < span role = "img" aria-label = "Rocket" > 🚀< / span > MQL5 Trading Automation< / h1 >
2026-01-19 06:06:56 +07:00
< p > GenX FX Trading System Dashboard< / p >
< / div >
2026-02-08 11:20:56 +00:00
< div class = "grid" id = "main-content" >
2026-01-19 06:06:56 +07:00
< div class = "card" >
2026-02-09 11:13:59 +00:00
< h2 > < span role = "img" aria-label = "Chart" > 📊< / span > Trading Indicators< / h2 >
2026-01-19 06:06:56 +07:00
< p > SMC + Trend Breakout (MTF) indicator with BOS/CHoCH and Donchian breakout signals.< / p >
2026-02-07 11:23:41 +00:00
< a href = "#" class = "btn" role = "button" > View Indicators< / a >
2026-01-19 06:06:56 +07:00
< / div >
< div class = "card" >
2026-02-09 11:13:59 +00:00
< h2 > < span role = "img" aria-label = "Robot" > 🤖< / span > Expert Advisors< / h2 >
2026-01-19 06:06:56 +07:00
< p > Automated trading EAs with smart risk management and multi-timeframe confirmation.< / p >
2026-02-07 11:23:41 +00:00
< a href = "#" class = "btn" role = "button" > Manage EAs< / a >
2026-01-19 06:06:56 +07:00
< / div >
< div class = "card" >
2026-02-09 11:13:59 +00:00
< h2 > < span role = "img" aria-label = "Cloud" > ☁️< / span > Cloud Deployment< / h2 >
2026-01-19 06:06:56 +07:00
< p > Deploy your trading automation to Fly.io, Render, Railway, or GitHub Pages.< / p >
2026-02-07 11:23:41 +00:00
< a href = "#" class = "btn" role = "button" > Deploy Now< / a >
2026-01-19 06:06:56 +07:00
< / div >
< div class = "card" >
2026-02-09 11:13:59 +00:00
< h2 > < span role = "img" aria-label = "Mobile Phone" > 📱< / span > Telegram Bot< / h2 >
2026-01-19 06:06:56 +07:00
< p > Control deployments and monitor trading via @GenX_FX_bot on Telegram.< / p >
2026-02-07 11:23:41 +00:00
< a href = "https://t.me/GenX_FX_bot" class = "btn" target = "_blank" rel = "noopener noreferrer" aria-label = "Open Bot (opens in new tab)" > Open Bot< / a >
2026-01-19 06:06:56 +07:00
< / div >
< div class = "card" >
2026-02-09 11:13:59 +00:00
< h2 > < span role = "img" aria-label = "Chart Increasing" > 📈< / span > Exness Terminal< / h2 >
2026-01-19 06:06:56 +07:00
< p > Connect to Exness MT5 terminal for live trading execution.< / p >
2026-02-07 11:23:41 +00:00
< a href = "https://my.exness.global/webtrading/" class = "btn" target = "_blank" rel = "noopener noreferrer" aria-label = "Open Terminal (opens in new tab)" > Open Terminal< / a >
2026-01-19 06:06:56 +07:00
< / div >
< div class = "card" >
2026-02-09 11:13:59 +00:00
< h2 > < span role = "img" aria-label = "Wrench" > 🔧< / span > Settings< / h2 >
2026-01-19 06:06:56 +07:00
< p > Configure risk parameters, notifications, and automation preferences.< / p >
2026-02-07 11:23:41 +00:00
< a href = "#" class = "btn" role = "button" > Configure< / a >
2026-01-19 06:06:56 +07:00
< / div >
2026-02-01 19:18:55 +00:00
< div class = "card" >
2026-02-09 11:13:59 +00:00
< h2 > < span role = "img" aria-label = "Magnifying Glass" > 🔍< / span > Service Worker< / h2 >
2026-02-01 19:18:55 +00:00
< p > Inspect and manage PWA service worker, cache storage, and offline functionality.< / p >
< a href = "/sw-inspector.html" class = "btn" > Inspect Views< / a >
< / div >
2026-01-19 06:06:56 +07:00
< / div >
< div class = "status" >
2026-02-13 11:40:16 +00:00
< h2 style = "color: #4f46e5; margin-bottom: 20px;" > System Status< / h2 >
2026-01-19 06:06:56 +07:00
< div class = "status-item" >
< span class = "status-label" > Deployment Status< / span >
< span class = "badge badge-success" > Active< / span >
< / div >
< div class = "status-item" >
< span class = "status-label" > Fly.io App< / span >
2026-02-17 11:36:17 +00:00
< span class = "status-value" >
< span id = "fly-app-id" > mql5-automation< / span >
< button class = "copy-btn" onclick = "copyToClipboard('mql5-automation', this)" aria-label = "Copy Fly.io App ID" >
< svg width = "14" height = "14" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" stroke-linecap = "round" stroke-linejoin = "round" > < rect x = "9" y = "9" width = "13" height = "13" rx = "2" ry = "2" > < / rect > < path d = "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" > < / path > < / svg >
< / button >
< / span >
2026-01-19 06:06:56 +07:00
< / div >
< div class = "status-item" >
< span class = "status-label" > Telegram Bot< / span >
2026-02-17 11:36:17 +00:00
< span class = "status-value" >
< span id = "telegram-bot-id" > @GenX_FX_bot< / span >
< button class = "copy-btn" onclick = "copyToClipboard('@GenX_FX_bot', this)" aria-label = "Copy Telegram Bot Handle" >
< svg width = "14" height = "14" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" stroke-linecap = "round" stroke-linejoin = "round" > < rect x = "9" y = "9" width = "13" height = "13" rx = "2" ry = "2" > < / rect > < path d = "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" > < / path > < / svg >
< / button >
< / span >
2026-01-19 06:06:56 +07:00
< / div >
< div class = "status-item" >
< span class = "status-label" > Last Updated< / span >
< span class = "status-value" id = "lastUpdate" > < / span >
< / div >
< / div >
< div class = "footer" >
< p > © 2026 GenX FX Trading System | Built with ❤️ for Trading Automation< / p >
< / div >
< / div >
2026-02-12 11:36:12 +00:00
<!-- Service Worker Toast Notification -->
< div id = "update-toast" class = "toast" role = "alert" aria-live = "polite" >
< span > New version available!< / span >
2026-02-13 11:40:16 +00:00
< button id = "update-btn" class = "toast-btn toast-btn-primary" aria-label = "Update application to latest version" > Update< / button >
2026-02-12 11:36:12 +00:00
< button id = "dismiss-btn" class = "toast-btn toast-btn-secondary" aria-label = "Dismiss" > ✕< / button >
< / div >
2026-01-19 06:06:56 +07:00
< script >
// Set last update time
document . getElementById ( 'lastUpdate' ) . textContent = new Date ( ) . toLocaleString ( ) ;
// Add interactivity
document . querySelectorAll ( '.card a.btn' ) . forEach ( btn => {
2026-02-07 11:23:41 +00:00
const href = btn . getAttribute ( 'href' ) ;
if ( ! href || href === '#' ) {
2026-01-19 06:06:56 +07:00
btn . addEventListener ( 'click' , ( e ) => {
e . preventDefault ( ) ;
2026-02-07 11:23:41 +00:00
const originalText = btn . textContent ;
btn . textContent = 'Coming Soon! 🚧' ;
setTimeout ( ( ) => {
btn . textContent = originalText ;
} , 2000 ) ;
2026-01-19 06:06:56 +07:00
} ) ;
}
} ) ;
2026-02-01 19:18:55 +00:00
2026-02-17 11:36:17 +00:00
// Copy to Clipboard
function copyToClipboard ( text , btn ) {
if ( btn . classList . contains ( 'copied' ) ) return ;
const originalContent = btn . innerHTML ;
navigator . clipboard . writeText ( text ) . then ( ( ) => {
btn . classList . add ( 'copied' ) ;
// Checkmark icon
btn . innerHTML = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#10b981" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg>' ;
setTimeout ( ( ) => {
btn . innerHTML = originalContent ;
btn . classList . remove ( 'copied' ) ;
} , 2000 ) ;
} ) . catch ( err => {
console . error ( 'Failed to copy: ' , err ) ;
} ) ;
}
2026-02-01 19:18:55 +00:00
// Register Service Worker for PWA functionality
if ( 'serviceWorker' in navigator ) {
window . addEventListener ( 'load' , ( ) => {
navigator . serviceWorker . register ( '/service-worker.js' )
. then ( registration => {
console . log ( 'Service Worker registered successfully:' , registration . scope ) ;
// Check for updates
registration . addEventListener ( 'updatefound' , ( ) => {
const newWorker = registration . installing ;
console . log ( 'Service Worker update found' ) ;
newWorker . addEventListener ( 'statechange' , ( ) => {
if ( newWorker . state === 'installed' && navigator . serviceWorker . controller ) {
2026-02-12 11:36:12 +00:00
// New service worker available, show toast
const toast = document . getElementById ( 'update-toast' ) ;
const updateBtn = document . getElementById ( 'update-btn' ) ;
const dismissBtn = document . getElementById ( 'dismiss-btn' ) ;
if ( toast ) {
toast . classList . add ( 'show' ) ;
updateBtn . onclick = ( ) => {
newWorker . postMessage ( { type : 'SKIP_WAITING' } ) ;
window . location . reload ( ) ;
} ;
dismissBtn . onclick = ( ) => {
toast . classList . remove ( 'show' ) ;
} ;
2026-02-01 19:18:55 +00:00
}
}
} ) ;
} ) ;
} )
. catch ( error => {
console . error ( 'Service Worker registration failed:' , error ) ;
} ) ;
// Handle service worker controller change
navigator . serviceWorker . addEventListener ( 'controllerchange' , ( ) => {
window . location . reload ( ) ;
} ) ;
} ) ;
}
2026-01-19 06:06:56 +07:00
< / script >
< / body >
< / html >