Abel222 commited on
Commit
c1b01fe
·
verified ·
1 Parent(s): 63bd1d7

Use https://twelvedata.com API key cc9af226f2dd41b9af948da524333bd5 for real time data - Initial Deployment

Browse files
Files changed (2) hide show
  1. README.md +6 -4
  2. index.html +910 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Fx
3
- emoji: 💻
4
  colorFrom: green
5
- colorTo: green
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: fx
3
+ emoji: 🐳
4
  colorFrom: green
5
+ colorTo: blue
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,910 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Forex Signal Dashboard</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://s3.tradingview.com/tv.js"></script>
9
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
10
+ <style>
11
+ .tradingview-widget-container {
12
+ height: 500px;
13
+ }
14
+ .signal-card.buy {
15
+ border-left: 4px solid #10B981;
16
+ }
17
+ .signal-card.sell {
18
+ border-left: 4px solid #EF4444;
19
+ }
20
+ .chart-container {
21
+ height: 500px;
22
+ position: relative;
23
+ }
24
+ .auth-container {
25
+ background: linear-gradient(135deg, #1e3a8a 0%, #1e40af 100%);
26
+ }
27
+ .blurred {
28
+ filter: blur(5px);
29
+ pointer-events: none;
30
+ }
31
+ </style>
32
+ </head>
33
+ <body class="bg-gray-100">
34
+ <!-- Auth Modal -->
35
+ <div id="authModal" class="fixed inset-0 z-50 flex items-center justify-center auth-container">
36
+ <div class="bg-white rounded-lg shadow-xl p-8 w-full max-w-md">
37
+ <div class="flex justify-between items-center mb-6">
38
+ <h2 class="text-2xl font-bold text-gray-800">Welcome to Forex Signals</h2>
39
+ <button id="closeAuthModal" class="text-gray-500 hover:text-gray-700">
40
+ <i class="fas fa-times"></i>
41
+ </button>
42
+ </div>
43
+
44
+ <div class="tabs flex mb-6 border-b">
45
+ <button id="loginTab" class="tab-btn active px-4 py-2 font-medium text-blue-600 border-b-2 border-blue-600">Login</button>
46
+ <button id="signupTab" class="tab-btn px-4 py-2 font-medium text-gray-500 hover:text-gray-700">Sign Up</button>
47
+ </div>
48
+
49
+ <div id="loginForm" class="auth-form">
50
+ <div class="mb-4">
51
+ <label class="block text-gray-700 mb-2" for="loginEmail">Email</label>
52
+ <input type="email" id="loginEmail" class="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
53
+ </div>
54
+ <div class="mb-6">
55
+ <label class="block text-gray-700 mb-2" for="loginPassword">Password</label>
56
+ <input type="password" id="loginPassword" class="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
57
+ </div>
58
+ <button id="loginBtn" class="w-full bg-blue-600 text-white py-2 px-4 rounded-lg hover:bg-blue-700 transition duration-200">Login</button>
59
+
60
+ <div class="mt-4 text-center">
61
+ <p class="text-gray-600">Or login with</p>
62
+ <div class="flex justify-center mt-2 space-x-4">
63
+ <button class="p-2 bg-red-100 rounded-full text-red-600 hover:bg-red-200">
64
+ <i class="fab fa-google"></i>
65
+ </button>
66
+ <button class="p-2 bg-gray-100 rounded-full text-gray-800 hover:bg-gray-200">
67
+ <i class="fab fa-apple"></i>
68
+ </button>
69
+ </div>
70
+ </div>
71
+ </div>
72
+
73
+ <div id="signupForm" class="auth-form hidden">
74
+ <div class="mb-4">
75
+ <label class="block text-gray-700 mb-2" for="signupName">Full Name</label>
76
+ <input type="text" id="signupName" class="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
77
+ </div>
78
+ <div class="mb-4">
79
+ <label class="block text-gray-700 mb-2" for="signupEmail">Email</label>
80
+ <input type="email" id="signupEmail" class="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
81
+ </div>
82
+ <div class="mb-6">
83
+ <label class="block text-gray-700 mb-2" for="signupPassword">Password</label>
84
+ <input type="password" id="signupPassword" class="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
85
+ </div>
86
+ <div class="mb-6">
87
+ <label class="block text-gray-700 mb-2">Preferred Currency Pairs</label>
88
+ <div class="flex flex-wrap gap-2">
89
+ <label class="inline-flex items-center">
90
+ <input type="checkbox" class="form-checkbox text-blue-600" value="EUR/USD">
91
+ <span class="ml-2">EUR/USD</span>
92
+ </label>
93
+ <label class="inline-flex items-center">
94
+ <input type="checkbox" class="form-checkbox text-blue-600" value="GBP/USD">
95
+ <span class="ml-2">GBP/USD</span>
96
+ </label>
97
+ <label class="inline-flex items-center">
98
+ <input type="checkbox" class="form-checkbox text-blue-600" value="USD/JPY">
99
+ <span class="ml-2">USD/JPY</span>
100
+ </label>
101
+ <label class="inline-flex items-center">
102
+ <input type="checkbox" class="form-checkbox text-blue-600" value="AUD/USD">
103
+ <span class="ml-2">AUD/USD</span>
104
+ </label>
105
+ <label class="inline-flex items-center">
106
+ <input type="checkbox" class="form-checkbox text-blue-600" value="XAU/USD">
107
+ <span class="ml-2">XAU/USD</span>
108
+ </label>
109
+ </div>
110
+ </div>
111
+ <button id="signupBtn" class="w-full bg-blue-600 text-white py-2 px-4 rounded-lg hover:bg-blue-700 transition duration-200">Sign Up</button>
112
+ </div>
113
+ </div>
114
+ </div>
115
+
116
+ <!-- Main App -->
117
+ <div id="appContainer" class="blurred">
118
+ <!-- Header -->
119
+ <header class="bg-white shadow-sm">
120
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
121
+ <div class="flex justify-between items-center py-4">
122
+ <div class="flex items-center">
123
+ <div class="w-10 h-10 bg-blue-600 rounded-full flex items-center justify-center text-white font-bold">FS</div>
124
+ <h1 class="ml-3 text-xl font-semibold text-gray-900">Forex Signals</h1>
125
+ </div>
126
+ <div class="flex items-center space-x-4">
127
+ <button id="notificationBtn" class="relative p-2 text-gray-500 hover:text-gray-700">
128
+ <i class="fas fa-bell"></i>
129
+ <span class="absolute top-0 right-0 w-2 h-2 bg-red-500 rounded-full"></span>
130
+ </button>
131
+ <div class="relative">
132
+ <button id="userMenuBtn" class="flex items-center space-x-2 focus:outline-none">
133
+ <div class="w-8 h-8 bg-blue-100 rounded-full flex items-center justify-center text-blue-600">
134
+ <i class="fas fa-user"></i>
135
+ </div>
136
+ <span class="hidden md:inline text-gray-700">User</span>
137
+ </button>
138
+ <div id="userMenu" class="hidden absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg py-1 z-50">
139
+ <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Profile</a>
140
+ <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Settings</a>
141
+ <a href="#" id="logoutBtn" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Logout</a>
142
+ </div>
143
+ </div>
144
+ </div>
145
+ </div>
146
+ </div>
147
+ </header>
148
+
149
+ <!-- Main Content -->
150
+ <main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
151
+ <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
152
+ <!-- Left Column - Signals -->
153
+ <div class="lg:col-span-1 space-y-4">
154
+ <div class="bg-white rounded-lg shadow p-4">
155
+ <div class="flex justify-between items-center mb-4">
156
+ <h2 class="text-lg font-semibold">Active Signals</h2>
157
+ <button class="text-blue-600 hover:text-blue-800">
158
+ <i class="fas fa-sync-alt"></i>
159
+ </button>
160
+ </div>
161
+ <div id="activeSignals" class="space-y-3">
162
+ <!-- Signal cards will be added here by JavaScript -->
163
+ </div>
164
+ </div>
165
+
166
+ <div class="bg-white rounded-lg shadow p-4">
167
+ <h2 class="text-lg font-semibold mb-4">Signal History</h2>
168
+ <div id="signalHistory" class="space-y-3">
169
+ <!-- History cards will be added here by JavaScript -->
170
+ </div>
171
+ </div>
172
+ </div>
173
+
174
+ <!-- Right Column - Chart and Details -->
175
+ <div class="lg:col-span-2 space-y-4">
176
+ <div class="bg-white rounded-lg shadow p-4">
177
+ <div class="flex justify-between items-center mb-4">
178
+ <h2 class="text-lg font-semibold">Market Analysis</h2>
179
+ <div class="flex space-x-2">
180
+ <select id="timeframeSelect" class="border rounded px-2 py-1 text-sm">
181
+ <option value="1">1m</option>
182
+ <option value="5">5m</option>
183
+ <option value="15">15m</option>
184
+ <option value="60">1h</option>
185
+ <option value="240" selected>4h</option>
186
+ <option value="1D">1D</option>
187
+ </select>
188
+ <select id="pairSelect" class="border rounded px-2 py-1 text-sm">
189
+ <option value="XAUUSDT">XAU/USDT</option>
190
+ <option value="EURUSD">EUR/USD</option>
191
+ <option value="GBPUSD">GBP/USD</option>
192
+ <option value="USDJPY">USD/JPY</option>
193
+ <option value="AUDUSD">AUD/USD</option>
194
+ <option value="USDCAD">USD/CAD</option>
195
+ <option value="XAUUSD">XAU/USD</option>
196
+ </select>
197
+ </div>
198
+ </div>
199
+ <div class="chart-container">
200
+ <div id="tradingview-chart"></div>
201
+ </div>
202
+ </div>
203
+
204
+ <div class="bg-white rounded-lg shadow p-4">
205
+ <h2 class="text-lg font-semibold mb-4">Signal Details</h2>
206
+ <div id="signalDetails" class="grid grid-cols-1 md:grid-cols-2 gap-4">
207
+ <div>
208
+ <h3 class="font-medium text-gray-700 mb-2">ICT Analysis</h3>
209
+ <p class="text-gray-600">This signal is based on ICT concepts including FVG, liquidity grabs, and market structure shifts.</p>
210
+ </div>
211
+ <div>
212
+ <h3 class="font-medium text-gray-700 mb-2">Key Levels</h3>
213
+ <div class="space-y-2">
214
+ <div class="flex justify-between">
215
+ <span class="text-gray-600">Entry:</span>
216
+ <span class="font-medium" id="detailEntry">1.0850</span>
217
+ </div>
218
+ <div class="flex justify-between">
219
+ <span class="text-gray-600">Stop Loss:</span>
220
+ <span class="font-medium text-red-500" id="detailSL">1.0820</span>
221
+ </div>
222
+ <div class="flex justify-between">
223
+ <span class="text-gray-600">Take Profit 1:</span>
224
+ <span class="font-medium text-green-500" id="detailTP1">1.0880</span>
225
+ </div>
226
+ <div class="flex justify-between">
227
+ <span class="text-gray-600">Take Profit 2:</span>
228
+ <span class="font-medium text-green-500" id="detailTP2">1.0920</span>
229
+ </div>
230
+ </div>
231
+ </div>
232
+ </div>
233
+ </div>
234
+ </div>
235
+ </div>
236
+ </main>
237
+
238
+ <!-- Admin Panel (hidden by default) -->
239
+ <div id="adminPanel" class="hidden fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center">
240
+ <div class="bg-white rounded-lg shadow-xl p-6 w-full max-w-4xl max-h-[90vh] overflow-y-auto">
241
+ <div class="flex justify-between items-center mb-6">
242
+ <h2 class="text-2xl font-bold">Admin Panel</h2>
243
+ <button id="closeAdminPanel" class="text-gray-500 hover:text-gray-700">
244
+ <i class="fas fa-times"></i>
245
+ </button>
246
+ </div>
247
+
248
+ <div class="mb-6">
249
+ <h3 class="text-lg font-semibold mb-3">Create New Signal</h3>
250
+ <form id="signalForm" class="grid grid-cols-1 md:grid-cols-2 gap-4">
251
+ <div>
252
+ <label class="block text-gray-700 mb-1">Currency Pair</label>
253
+ <select id="signalPair" class="w-full border rounded px-3 py-2">
254
+ <option value="EUR/USD">EUR/USD</option>
255
+ <option value="GBP/USD">GBP/USD</option>
256
+ <option value="USD/JPY">USD/JPY</option>
257
+ <option value="AUD/USD">AUD/USD</option>
258
+ <option value="XAU/USD">XAU/USD</option>
259
+ </select>
260
+ </div>
261
+ <div>
262
+ <label class="block text-gray-700 mb-1">Direction</label>
263
+ <select id="signalDirection" class="w-full border rounded px-3 py-2">
264
+ <option value="buy">Buy</option>
265
+ <option value="sell">Sell</option>
266
+ </select>
267
+ </div>
268
+ <div>
269
+ <label class="block text-gray-700 mb-1">Entry Price</label>
270
+ <input type="number" step="0.0001" id="signalEntry" class="w-full border rounded px-3 py-2">
271
+ </div>
272
+ <div>
273
+ <label class="block text-gray-700 mb-1">Stop Loss</label>
274
+ <input type="number" step="0.0001" id="signalSL" class="w-full border rounded px-3 py-2">
275
+ </div>
276
+ <div>
277
+ <label class="block text-gray-700 mb-1">Take Profit 1</label>
278
+ <input type="number" step="0.0001" id="signalTP1" class="w-full border rounded px-3 py-2">
279
+ </div>
280
+ <div>
281
+ <label class="block text-gray-700 mb-1">Take Profit 2</label>
282
+ <input type="number" step="0.0001" id="signalTP2" class="w-full border rounded px-3 py-2">
283
+ </div>
284
+ <div class="md:col-span-2">
285
+ <label class="block text-gray-700 mb-1">Analysis Notes</label>
286
+ <textarea id="signalNotes" rows="3" class="w-full border rounded px-3 py-2"></textarea>
287
+ </div>
288
+ <div class="md:col-span-2 flex justify-end space-x-3">
289
+ <button type="button" id="cancelSignal" class="px-4 py-2 border rounded-lg text-gray-700 hover:bg-gray-100">Cancel</button>
290
+ <button type="submit" class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700">Publish Signal</button>
291
+ </div>
292
+ </form>
293
+ </div>
294
+
295
+ <div>
296
+ <h3 class="text-lg font-semibold mb-3">Manage Signals</h3>
297
+ <div class="overflow-x-auto">
298
+ <table class="min-w-full divide-y divide-gray-200">
299
+ <thead class="bg-gray-50">
300
+ <tr>
301
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Pair</th>
302
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Direction</th>
303
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Entry</th>
304
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
305
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th>
306
+ </tr>
307
+ </thead>
308
+ <tbody id="adminSignalList" class="bg-white divide-y divide-gray-200">
309
+ <!-- Admin signal list will be populated here -->
310
+ </tbody>
311
+ </table>
312
+ </div>
313
+ </div>
314
+ </div>
315
+ </div>
316
+ </div>
317
+
318
+ <script>
319
+ // Sample data
320
+ const activeSignals = [
321
+ {
322
+ id: 1,
323
+ pair: 'XAU/USDT',
324
+ direction: 'buy',
325
+ entry: 2035.50,
326
+ sl: 2020.00,
327
+ tp1: 2050.00,
328
+ tp2: 2075.00,
329
+ timestamp: new Date(),
330
+ notes: 'Bullish engulfing pattern at key support level with RSI divergence'
331
+ },
332
+ {
333
+ id: 2,
334
+ pair: 'EUR/USD',
335
+ direction: 'buy',
336
+ entry: 1.0850,
337
+ sl: 1.0820,
338
+ tp1: 1.0880,
339
+ tp2: 1.0920,
340
+ timestamp: new Date(),
341
+ notes: 'ICT FVG with liquidity grab below previous low'
342
+ },
343
+ {
344
+ id: 3,
345
+ pair: 'GBP/USD',
346
+ direction: 'sell',
347
+ entry: 1.2650,
348
+ sl: 1.2685,
349
+ tp1: 1.2600,
350
+ tp2: 1.2550,
351
+ timestamp: new Date(Date.now() - 3600000),
352
+ notes: 'Bearish order block with premium array'
353
+ }
354
+ ];
355
+
356
+ const signalHistory = [
357
+ {
358
+ id: 3,
359
+ pair: 'USD/JPY',
360
+ direction: 'buy',
361
+ entry: 150.80,
362
+ sl: 150.50,
363
+ tp1: 151.20,
364
+ tp2: 151.80,
365
+ timestamp: new Date(Date.now() - 86400000),
366
+ closedAt: new Date(Date.now() - 82800000),
367
+ outcome: 'win',
368
+ closedPrice: 151.25,
369
+ notes: 'Liquidity sweep of previous low'
370
+ },
371
+ {
372
+ id: 4,
373
+ pair: 'AUD/USD',
374
+ direction: 'sell',
375
+ entry: 0.6580,
376
+ sl: 0.6610,
377
+ tp1: 0.6550,
378
+ tp2: 0.6520,
379
+ timestamp: new Date(Date.now() - 172800000),
380
+ closedAt: new Date(Date.now() - 169200000),
381
+ outcome: 'loss',
382
+ closedPrice: 0.6615,
383
+ notes: 'Failed breakdown of support'
384
+ }
385
+ ];
386
+
387
+ // DOM Elements
388
+ const authModal = document.getElementById('authModal');
389
+ const appContainer = document.getElementById('appContainer');
390
+ const loginTab = document.getElementById('loginTab');
391
+ const signupTab = document.getElementById('signupTab');
392
+ const loginForm = document.getElementById('loginForm');
393
+ const signupForm = document.getElementById('signupForm');
394
+ const loginBtn = document.getElementById('loginBtn');
395
+ const signupBtn = document.getElementById('signupBtn');
396
+ const closeAuthModal = document.getElementById('closeAuthModal');
397
+ const logoutBtn = document.getElementById('logoutBtn');
398
+ const userMenuBtn = document.getElementById('userMenuBtn');
399
+ const userMenu = document.getElementById('userMenu');
400
+ const adminPanel = document.getElementById('adminPanel');
401
+ const closeAdminPanel = document.getElementById('closeAdminPanel');
402
+ const activeSignalsContainer = document.getElementById('activeSignals');
403
+ const signalHistoryContainer = document.getElementById('signalHistory');
404
+ const pairSelect = document.getElementById('pairSelect');
405
+ const timeframeSelect = document.getElementById('timeframeSelect');
406
+ const signalForm = document.getElementById('signalForm');
407
+ const adminSignalList = document.getElementById('adminSignalList');
408
+ const detailEntry = document.getElementById('detailEntry');
409
+ const detailSL = document.getElementById('detailSL');
410
+ const detailTP1 = document.getElementById('detailTP1');
411
+ const detailTP2 = document.getElementById('detailTP2');
412
+
413
+ // Chart variables
414
+ let tvWidget = null;
415
+
416
+ // Current user state
417
+ let currentUser = null;
418
+ let isAdmin = false;
419
+
420
+ // Initialize the app
421
+ function initApp() {
422
+ // Check if user is logged in (in a real app, this would check localStorage or cookies)
423
+ const loggedIn = localStorage.getItem('forexUserLoggedIn');
424
+
425
+ if (loggedIn) {
426
+ // Simulate getting user data
427
+ currentUser = {
428
+ name: 'John Doe',
429
+ email: 'john@example.com',
430
+ isAdmin: localStorage.getItem('forexUserIsAdmin') === 'true'
431
+ };
432
+ isAdmin = currentUser.isAdmin;
433
+
434
+ // Hide auth modal and show app
435
+ authModal.classList.add('hidden');
436
+ appContainer.classList.remove('blurred');
437
+
438
+ // Load data
439
+ loadSignals();
440
+ initChart();
441
+ } else {
442
+ // Show auth modal
443
+ authModal.classList.remove('hidden');
444
+ appContainer.classList.add('blurred');
445
+ }
446
+
447
+ // Setup event listeners
448
+ setupEventListeners();
449
+ }
450
+
451
+ // Setup all event listeners
452
+ function setupEventListeners() {
453
+ // Auth modal tabs
454
+ loginTab.addEventListener('click', () => {
455
+ loginTab.classList.add('active', 'text-blue-600', 'border-blue-600');
456
+ loginTab.classList.remove('text-gray-500');
457
+ signupTab.classList.add('text-gray-500');
458
+ signupTab.classList.remove('active', 'text-blue-600', 'border-blue-600');
459
+ loginForm.classList.remove('hidden');
460
+ signupForm.classList.add('hidden');
461
+ });
462
+
463
+ signupTab.addEventListener('click', () => {
464
+ signupTab.classList.add('active', 'text-blue-600', 'border-blue-600');
465
+ signupTab.classList.remove('text-gray-500');
466
+ loginTab.classList.add('text-gray-500');
467
+ loginTab.classList.remove('active', 'text-blue-600', 'border-blue-600');
468
+ signupForm.classList.remove('hidden');
469
+ loginForm.classList.add('hidden');
470
+ });
471
+
472
+ // Login button
473
+ loginBtn.addEventListener('click', (e) => {
474
+ e.preventDefault();
475
+ const email = document.getElementById('loginEmail').value;
476
+ const password = document.getElementById('loginPassword').value;
477
+
478
+ // Simple validation
479
+ if (email && password) {
480
+ // In a real app, this would call your authentication API
481
+ currentUser = {
482
+ name: 'John Doe',
483
+ email: email,
484
+ isAdmin: email.includes('admin')
485
+ };
486
+ isAdmin = currentUser.isAdmin;
487
+
488
+ // Store login state
489
+ localStorage.setItem('forexUserLoggedIn', 'true');
490
+ localStorage.setItem('forexUserIsAdmin', isAdmin.toString());
491
+
492
+ // Hide auth modal and show app
493
+ authModal.classList.add('hidden');
494
+ appContainer.classList.remove('blurred');
495
+
496
+ // Load data
497
+ loadSignals();
498
+ initChart();
499
+
500
+ // Show welcome notification
501
+ showNotification('Welcome back! Signals loaded successfully.');
502
+ } else {
503
+ alert('Please enter both email and password');
504
+ }
505
+ });
506
+
507
+ // Signup button
508
+ signupBtn.addEventListener('click', (e) => {
509
+ e.preventDefault();
510
+ const name = document.getElementById('signupName').value;
511
+ const email = document.getElementById('signupEmail').value;
512
+ const password = document.getElementById('signupPassword').value;
513
+
514
+ // Simple validation
515
+ if (name && email && password) {
516
+ // In a real app, this would call your registration API
517
+ currentUser = {
518
+ name: name,
519
+ email: email,
520
+ isAdmin: false
521
+ };
522
+ isAdmin = false;
523
+
524
+ // Store login state
525
+ localStorage.setItem('forexUserLoggedIn', 'true');
526
+ localStorage.setItem('forexUserIsAdmin', 'false');
527
+
528
+ // Hide auth modal and show app
529
+ authModal.classList.add('hidden');
530
+ appContainer.classList.remove('blurred');
531
+
532
+ // Load data
533
+ loadSignals();
534
+ initChart();
535
+
536
+ // Show welcome notification
537
+ showNotification('Welcome to Forex Signals! Your account has been created.');
538
+ } else {
539
+ alert('Please fill in all fields');
540
+ }
541
+ });
542
+
543
+ // Close auth modal
544
+ closeAuthModal.addEventListener('click', () => {
545
+ // In a real app, you might not want to allow closing if not logged in
546
+ if (!localStorage.getItem('forexUserLoggedIn')) {
547
+ alert('Please login or sign up to continue');
548
+ } else {
549
+ authModal.classList.add('hidden');
550
+ }
551
+ });
552
+
553
+ // User menu
554
+ userMenuBtn.addEventListener('click', () => {
555
+ userMenu.classList.toggle('hidden');
556
+
557
+ // Close when clicking outside
558
+ document.addEventListener('click', (e) => {
559
+ if (!userMenu.contains(e.target) && e.target !== userMenuBtn) {
560
+ userMenu.classList.add('hidden');
561
+ }
562
+ }, { once: true });
563
+ });
564
+
565
+ // Logout
566
+ logoutBtn.addEventListener('click', () => {
567
+ localStorage.removeItem('forexUserLoggedIn');
568
+ localStorage.removeItem('forexUserIsAdmin');
569
+ currentUser = null;
570
+ isAdmin = false;
571
+
572
+ // Show auth modal and blur app
573
+ authModal.classList.remove('hidden');
574
+ appContainer.classList.add('blurred');
575
+
576
+ // Reset forms
577
+ document.getElementById('loginEmail').value = '';
578
+ document.getElementById('loginPassword').value = '';
579
+ document.getElementById('signupName').value = '';
580
+ document.getElementById('signupEmail').value = '';
581
+ document.getElementById('signupPassword').value = '';
582
+
583
+ // Switch to login tab
584
+ loginTab.click();
585
+ });
586
+
587
+ // Notification button
588
+ document.getElementById('notificationBtn').addEventListener('click', () => {
589
+ showNotification('You have no new notifications');
590
+ });
591
+
592
+ // Pair and timeframe select changes
593
+ pairSelect.addEventListener('change', reloadChart);
594
+ timeframeSelect.addEventListener('change', reloadChart);
595
+
596
+ // Signal form
597
+ signalForm.addEventListener('submit', (e) => {
598
+ e.preventDefault();
599
+ createNewSignal();
600
+ });
601
+
602
+ document.getElementById('cancelSignal').addEventListener('click', () => {
603
+ signalForm.reset();
604
+ });
605
+
606
+ // Close admin panel
607
+ closeAdminPanel.addEventListener('click', () => {
608
+ adminPanel.classList.add('hidden');
609
+ });
610
+
611
+ // Check if user is admin (for demo purposes)
612
+ if (isAdmin) {
613
+ // Add admin button to header
614
+ const header = document.querySelector('header .flex.items-center.space-x-4');
615
+ const adminBtn = document.createElement('button');
616
+ adminBtn.className = 'p-2 text-gray-500 hover:text-gray-700';
617
+ adminBtn.innerHTML = '<i class="fas fa-cog"></i>';
618
+ adminBtn.addEventListener('click', () => {
619
+ adminPanel.classList.remove('hidden');
620
+ loadAdminSignals();
621
+ });
622
+ header.insertBefore(adminBtn, header.firstChild);
623
+ }
624
+ }
625
+
626
+ // Load signals into the UI
627
+ function loadSignals() {
628
+ // Clear existing signals
629
+ activeSignalsContainer.innerHTML = '';
630
+ signalHistoryContainer.innerHTML = '';
631
+
632
+ // Add active signals
633
+ activeSignals.forEach(signal => {
634
+ const signalCard = createSignalCard(signal, false);
635
+ activeSignalsContainer.appendChild(signalCard);
636
+ });
637
+
638
+ // Add historical signals
639
+ signalHistory.forEach(signal => {
640
+ const historyCard = createSignalCard(signal, true);
641
+ signalHistoryContainer.appendChild(historyCard);
642
+ });
643
+
644
+ // If there are active signals, show the first one's details
645
+ if (activeSignals.length > 0) {
646
+ showSignalDetails(activeSignals[0]);
647
+ }
648
+ }
649
+
650
+ // Create a signal card element
651
+ function createSignalCard(signal, isHistory) {
652
+ const card = document.createElement('div');
653
+ card.className = `signal-card ${signal.direction} bg-white rounded shadow p-3 cursor-pointer hover:shadow-md transition duration-200`;
654
+ card.dataset.id = signal.id;
655
+
656
+ const directionClass = signal.direction === 'buy' ? 'text-green-500' : 'text-red-500';
657
+ const directionIcon = signal.direction === 'buy' ? 'fa-arrow-up' : 'fa-arrow-down';
658
+
659
+ let outcomeBadge = '';
660
+ if (isHistory) {
661
+ const outcomeClass = signal.outcome === 'win' ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800';
662
+ outcomeBadge = `<span class="text-xs px-2 py-1 rounded-full ${outcomeClass} ml-2">${signal.outcome}</span>`;
663
+ }
664
+
665
+ card.innerHTML = `
666
+ <div class="flex justify-between items-start">
667
+ <div>
668
+ <h3 class="font-semibold">${signal.pair}</h3>
669
+ <p class="text-sm text-gray-500">${formatDate(signal.timestamp)}</p>
670
+ </div>
671
+ <div class="flex items-center">
672
+ <i class="fas ${directionIcon} ${directionClass}"></i>
673
+ ${outcomeBadge}
674
+ </div>
675
+ </div>
676
+ <div class="mt-2 grid grid-cols-3 gap-2 text-sm">
677
+ <div>
678
+ <p class="text-gray-500">Entry</p>
679
+ <p>${signal.entry}</p>
680
+ </div>
681
+ <div>
682
+ <p class="text-gray-500">SL</p>
683
+ <p class="text-red-500">${signal.sl}</p>
684
+ </div>
685
+ <div>
686
+ <p class="text-gray-500">TP</p>
687
+ <p class="text-green-500">${signal.tp1}</p>
688
+ </div>
689
+ </div>
690
+ `;
691
+
692
+ // Add click event to show details
693
+ card.addEventListener('click', () => {
694
+ showSignalDetails(signal);
695
+
696
+ // Highlight selected card
697
+ document.querySelectorAll('.signal-card').forEach(c => {
698
+ c.classList.remove('ring-2', 'ring-blue-500');
699
+ });
700
+ card.classList.add('ring-2', 'ring-blue-500');
701
+ });
702
+
703
+ return card;
704
+ }
705
+
706
+ // Show signal details in the right panel
707
+ function showSignalDetails(signal) {
708
+ detailEntry.textContent = signal.entry;
709
+ detailSL.textContent = signal.sl;
710
+ detailTP1.textContent = signal.tp1;
711
+ detailTP2.textContent = signal.tp2 || 'N/A';
712
+
713
+ // Update chart with this pair
714
+ pairSelect.value = signal.pair.replace('/', '');
715
+ reloadChart();
716
+ }
717
+
718
+ // Format date for display
719
+ function formatDate(date) {
720
+ return new Date(date).toLocaleString('en-US', {
721
+ month: 'short',
722
+ day: 'numeric',
723
+ hour: '2-digit',
724
+ minute: '2-digit'
725
+ });
726
+ }
727
+
728
+ // Initialize TradingView chart
729
+ function initChart() {
730
+ if (tvWidget !== null) {
731
+ tvWidget.remove();
732
+ tvWidget = null;
733
+ }
734
+
735
+ const widgetOptions = {
736
+ symbol: pairSelect.value,
737
+ interval: timeframeSelect.value,
738
+ theme: 'light',
739
+ container_id: 'tradingview-chart',
740
+ datafeed: new Datafeeds.UDFCompatibleDatafeed(`https://api.twelvedata.com/time_series?symbol=${pairSelect.value}&interval=${timeframeSelect.value}&apikey=cc9af226f2dd41b9af948da524333bd5`),
741
+ library_path: 'https://s3.tradingview.com/tv.js',
742
+ locale: 'en',
743
+ disabled_features: ['header_widget', 'header_compare', 'header_screenshot', 'header_undo_redo', 'header_interval_dialog_button'],
744
+ enabled_features: ['study_templates'],
745
+ charts_storage_url: 'https://saveload.tradingview.com',
746
+ charts_storage_api_version: '1.1',
747
+ client_id: 'tradingview.com',
748
+ user_id: 'public_user_id',
749
+ fullscreen: false,
750
+ autosize: true,
751
+ studies_overrides: {},
752
+ overrides: {
753
+ 'paneProperties.background': '#ffffff',
754
+ 'paneProperties.vertGridProperties.color': '#f0f0f0',
755
+ 'paneProperties.horzGridProperties.color': '#f0f0f0',
756
+ 'mainSeriesProperties.candleStyle.upColor': '#388e3c',
757
+ 'mainSeriesProperties.candleStyle.downColor': '#d32f2f',
758
+ 'mainSeriesProperties.candleStyle.borderUpColor': '#388e3c',
759
+ 'mainSeriesProperties.candleStyle.borderDownColor': '#d32f2f',
760
+ 'mainSeriesProperties.candleStyle.wickUpColor': '#388e3c',
761
+ 'mainSeriesProperties.candleStyle.wickDownColor': '#d32f2f',
762
+ 'mainSeriesProperties.priceAxisProperties.autoScale': false,
763
+ 'mainSeriesProperties.priceAxisProperties.percentage': false,
764
+ 'mainSeriesProperties.priceAxisProperties.log': false
765
+ }
766
+ };
767
+
768
+ tvWidget = new TradingView.widget(widgetOptions);
769
+
770
+ tvWidget.onChartReady(() => {
771
+ console.log('Chart has loaded!');
772
+ });
773
+ }
774
+
775
+ // Reload chart with new symbol/interval
776
+ function reloadChart() {
777
+ initChart();
778
+ }
779
+
780
+ // Show notification
781
+ function showNotification(message) {
782
+ alert(message); // In a real app, you'd use a more elegant notification system
783
+ }
784
+
785
+ // Load signals for admin panel
786
+ function loadAdminSignals() {
787
+ adminSignalList.innerHTML = '';
788
+
789
+ const allSignals = [...activeSignals, ...signalHistory];
790
+
791
+ allSignals.forEach(signal => {
792
+ const row = document.createElement('tr');
793
+
794
+ const directionClass = signal.direction === 'buy' ? 'text-green-500' : 'text-red-500';
795
+ const directionText = signal.direction === 'buy' ? 'BUY' : 'SELL';
796
+
797
+ let statusBadge = '';
798
+ if (signalHistory.find(s => s.id === signal.id)) {
799
+ statusBadge = `<span class="px-2 py-1 text-xs rounded-full bg-gray-100 text-gray-800">Closed</span>`;
800
+ } else {
801
+ statusBadge = `<span class="px-2 py-1 text-xs rounded-full bg-blue-100 text-blue-800">Active</span>`;
802
+ }
803
+
804
+ row.innerHTML = `
805
+ <td class="px-6 py-4 whitespace-nowrap">${signal.pair}</td>
806
+ <td class="px-6 py-4 whitespace-nowrap"><span class="${directionClass}">${directionText}</span></td>
807
+ <td class="px-6 py-4 whitespace-nowrap">${signal.entry}</td>
808
+ <td class="px-6 py-4 whitespace-nowrap">${statusBadge}</td>
809
+ <td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
810
+ <button class="text-blue-600 hover:text-blue-900 mr-2 edit-signal" data-id="${signal.id}">Edit</button>
811
+ <button class="text-red-600 hover:text-red-900 delete-signal" data-id="${signal.id}">Delete</button>
812
+ </td>
813
+ `;
814
+
815
+ adminSignalList.appendChild(row);
816
+ });
817
+
818
+ // Add event listeners to edit/delete buttons
819
+ document.querySelectorAll('.edit-signal').forEach(btn => {
820
+ btn.addEventListener('click', (e) => {
821
+ const signalId = parseInt(e.target.dataset.id);
822
+ editSignal(signalId);
823
+ });
824
+ });
825
+
826
+ document.querySelectorAll('.delete-signal').forEach(btn => {
827
+ btn.addEventListener('click', (e) => {
828
+ const signalId = parseInt(e.target.dataset.id);
829
+ if (confirm('Are you sure you want to delete this signal?')) {
830
+ deleteSignal(signalId);
831
+ }
832
+ });
833
+ });
834
+ }
835
+
836
+ // Edit signal
837
+ function editSignal(signalId) {
838
+ const allSignals = [...activeSignals, ...signalHistory];
839
+ const signal = allSignals.find(s => s.id === signalId);
840
+
841
+ if (signal) {
842
+ document.getElementById('signalPair').value = signal.pair;
843
+ document.getElementById('signalDirection').value = signal.direction;
844
+ document.getElementById('signalEntry').value = signal.entry;
845
+ document.getElementById('signalSL').value = signal.sl;
846
+ document.getElementById('signalTP1').value = signal.tp1;
847
+ document.getElementById('signalTP2').value = signal.tp2 || '';
848
+ document.getElementById('signalNotes').value = signal.notes;
849
+
850
+ // Scroll to form
851
+ document.getElementById('signalForm').scrollIntoView();
852
+ }
853
+ }
854
+
855
+ // Delete signal
856
+ function deleteSignal(signalId) {
857
+ // In a real app, this would call your API to delete the signal
858
+ console.log(`Signal ${signalId} deleted`);
859
+ showNotification('Signal deleted successfully');
860
+ loadAdminSignals();
861
+ }
862
+
863
+ // Create new signal
864
+ function createNewSignal() {
865
+ const pair = document.getElementById('signalPair').value;
866
+ const direction = document.getElementById('signalDirection').value;
867
+ const entry = parseFloat(document.getElementById('signalEntry').value);
868
+ const sl = parseFloat(document.getElementById('signalSL').value);
869
+ const tp1 = parseFloat(document.getElementById('signalTP1').value);
870
+ const tp2 = parseFloat(document.getElementById('signalTP2').value) || null;
871
+ const notes = document.getElementById('signalNotes').value;
872
+
873
+ // Simple validation
874
+ if (!pair || !direction || isNaN(entry) || isNaN(sl) || isNaN(tp1)) {
875
+ alert('Please fill in all required fields');
876
+ return;
877
+ }
878
+
879
+ // Create new signal object
880
+ const newSignal = {
881
+ id: Math.max(...activeSignals.map(s => s.id), ...signalHistory.map(s => s.id)) + 1,
882
+ pair,
883
+ direction,
884
+ entry,
885
+ sl,
886
+ tp1,
887
+ tp2,
888
+ timestamp: new Date(),
889
+ notes
890
+ };
891
+
892
+ // Add to active signals (in a real app, this would call your API)
893
+ activeSignals.push(newSignal);
894
+
895
+ // Reset form
896
+ signalForm.reset();
897
+
898
+ // Show success message
899
+ showNotification('New signal published successfully!');
900
+
901
+ // Reload signals
902
+ loadSignals();
903
+ loadAdminSignals();
904
+ }
905
+
906
+ // Initialize the app when DOM is loaded
907
+ document.addEventListener('DOMContentLoaded', initApp);
908
+ </script>
909
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Abel222/fx" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
910
+ </html>