mobenta commited on
Commit
07d4f38
·
verified ·
1 Parent(s): 9978ad9

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +1328 -4
index.html CHANGED
@@ -6,7 +6,553 @@
6
  <title>Trading Affirmations App</title>
7
  <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
8
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.4.0/css/all.min.css">
9
- <link rel="stylesheet" href="/static/css/styles.css">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  </head>
11
  <body>
12
  <!-- Header and Navigation -->
@@ -310,7 +856,7 @@
310
 
311
  <div class="widget mt-4">
312
  <div class="widget-title">Session-Zeiten</div>
313
- <table class="w-full text-sm">
314
  <tr>
315
  <td>London (GMT):</td>
316
  <td class="font-medium">08:00 - 16:30</td>
@@ -1029,6 +1575,784 @@
1029
  </div>
1030
  </div>
1031
 
1032
- <script src="/static/js/main.js"></script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1033
  </body>
1034
- </html>
 
6
  <title>Trading Affirmations App</title>
7
  <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
8
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.4.0/css/all.min.css">
9
+ <style>
10
+ :root {
11
+ --primary: #2c3e50;
12
+ --secondary: #3498db;
13
+ --accent: #e74c3c;
14
+ --light: #ecf0f1;
15
+ --dark: #2c3e50;
16
+ --success: #2ecc71;
17
+ --warning: #f39c12;
18
+ }
19
+
20
+ body {
21
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
22
+ background-color: #f5f7fa;
23
+ color: #333;
24
+ overflow-x: hidden;
25
+ }
26
+
27
+ .navbar {
28
+ background-color: var(--primary);
29
+ color: white;
30
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
31
+ position: sticky;
32
+ top: 0;
33
+ z-index: 100;
34
+ }
35
+
36
+ .ticker-container {
37
+ background-color: #1d2630;
38
+ color: white;
39
+ overflow: hidden;
40
+ white-space: nowrap;
41
+ padding: 8px 0;
42
+ position: relative;
43
+ }
44
+
45
+ .ticker-content {
46
+ display: inline-block;
47
+ animation: ticker 30s linear infinite;
48
+ }
49
+
50
+ @keyframes ticker {
51
+ 0% { transform: translateX(100%); }
52
+ 100% { transform: translateX(-100%); }
53
+ }
54
+
55
+ .ticker-item {
56
+ display: inline-block;
57
+ padding: 0 20px;
58
+ }
59
+
60
+ .ticker-item.up {
61
+ color: #2ecc71;
62
+ }
63
+
64
+ .ticker-item.down {
65
+ color: #e74c3c;
66
+ }
67
+
68
+ .section {
69
+ background: white;
70
+ border-radius: 8px;
71
+ box-shadow: 0 2px 10px rgba(0,0,0,0.05);
72
+ margin-bottom: 20px;
73
+ padding: 20px;
74
+ }
75
+
76
+ .section-title {
77
+ color: var(--primary);
78
+ border-bottom: 2px solid var(--secondary);
79
+ padding-bottom: 8px;
80
+ margin-bottom: 16px;
81
+ font-weight: 600;
82
+ }
83
+
84
+ .btn-primary {
85
+ background-color: var(--secondary);
86
+ color: white;
87
+ border: none;
88
+ padding: 8px 16px;
89
+ border-radius: 4px;
90
+ cursor: pointer;
91
+ transition: all 0.3s;
92
+ }
93
+
94
+ .btn-primary:hover {
95
+ background-color: #2980b9;
96
+ transform: translateY(-2px);
97
+ box-shadow: 0 2px 5px rgba(0,0,0,0.1);
98
+ }
99
+
100
+ .btn-danger {
101
+ background-color: var(--accent);
102
+ color: white;
103
+ }
104
+
105
+ .btn-danger:hover {
106
+ background-color: #c0392b;
107
+ }
108
+
109
+ .card {
110
+ background: white;
111
+ border-radius: 8px;
112
+ box-shadow: 0 2px 5px rgba(0,0,0,0.05);
113
+ margin-bottom: 16px;
114
+ transition: all 0.3s;
115
+ }
116
+
117
+ .card:hover {
118
+ transform: translateY(-2px);
119
+ box-shadow: 0 5px 15px rgba(0,0,0,0.1);
120
+ }
121
+
122
+ .tab-container {
123
+ display: flex;
124
+ border-bottom: 1px solid #ddd;
125
+ margin-bottom: 16px;
126
+ }
127
+
128
+ .tab {
129
+ padding: 10px 16px;
130
+ cursor: pointer;
131
+ border-bottom: 3px solid transparent;
132
+ transition: all 0.3s;
133
+ }
134
+
135
+ .tab.active {
136
+ border-bottom: 3px solid var(--secondary);
137
+ color: var(--secondary);
138
+ font-weight: bold;
139
+ }
140
+
141
+ .tab-content {
142
+ display: none;
143
+ }
144
+
145
+ .tab-content.active {
146
+ display: block;
147
+ }
148
+
149
+ .badge {
150
+ padding: 4px 8px;
151
+ border-radius: 4px;
152
+ font-size: 12px;
153
+ font-weight: 600;
154
+ }
155
+
156
+ .badge-success {
157
+ background-color: var(--success);
158
+ color: white;
159
+ }
160
+
161
+ .badge-warning {
162
+ background-color: var(--warning);
163
+ color: white;
164
+ }
165
+
166
+ .badge-danger {
167
+ background-color: var(--accent);
168
+ color: white;
169
+ }
170
+
171
+ .form-group {
172
+ margin-bottom: 16px;
173
+ }
174
+
175
+ .form-control {
176
+ width: 100%;
177
+ padding: 8px 12px;
178
+ border: 1px solid #ddd;
179
+ border-radius: 4px;
180
+ transition: border 0.3s;
181
+ }
182
+
183
+ .form-control:focus {
184
+ border-color: var(--secondary);
185
+ outline: none;
186
+ box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2);
187
+ }
188
+
189
+ .select-control {
190
+ width: 100%;
191
+ padding: 8px 12px;
192
+ border: 1px solid #ddd;
193
+ border-radius: 4px;
194
+ background-color: white;
195
+ }
196
+
197
+ .session-card {
198
+ background: linear-gradient(145deg, #2c3e50, #34495e);
199
+ color: white;
200
+ border-radius: 8px;
201
+ padding: 16px;
202
+ margin-bottom: 16px;
203
+ }
204
+
205
+ .session-title {
206
+ font-size: 18px;
207
+ font-weight: 600;
208
+ margin-bottom: 8px;
209
+ }
210
+
211
+ .session-time {
212
+ font-size: 14px;
213
+ opacity: 0.8;
214
+ }
215
+
216
+ .session-status {
217
+ display: inline-block;
218
+ padding: 4px 8px;
219
+ border-radius: 4px;
220
+ font-size: 12px;
221
+ font-weight: 600;
222
+ margin-top: 8px;
223
+ }
224
+
225
+ .widget {
226
+ background: white;
227
+ border-radius: 8px;
228
+ box-shadow: 0 2px 5px rgba(0,0,0,0.05);
229
+ margin-bottom: 16px;
230
+ padding: 16px;
231
+ }
232
+
233
+ .widget-title {
234
+ font-size: 16px;
235
+ font-weight: 600;
236
+ margin-bottom: 12px;
237
+ color: var(--primary);
238
+ }
239
+
240
+ .event-item {
241
+ padding: 8px 0;
242
+ border-bottom: 1px solid #eee;
243
+ }
244
+
245
+ .event-time {
246
+ font-size: 12px;
247
+ color: #777;
248
+ }
249
+
250
+ .event-name {
251
+ font-weight: 500;
252
+ }
253
+
254
+ .event-impact {
255
+ width: 10px;
256
+ height: 10px;
257
+ border-radius: 50%;
258
+ display: inline-block;
259
+ margin-right: 4px;
260
+ }
261
+
262
+ .event-impact.high {
263
+ background-color: var(--accent);
264
+ }
265
+
266
+ .event-impact.medium {
267
+ background-color: var(--warning);
268
+ }
269
+
270
+ .event-impact.low {
271
+ background-color: var(--success);
272
+ }
273
+
274
+ .market-item {
275
+ display: flex;
276
+ justify-content: space-between;
277
+ padding: 8px 0;
278
+ border-bottom: 1px solid #eee;
279
+ }
280
+
281
+ .market-name {
282
+ font-weight: 500;
283
+ }
284
+
285
+ .market-value.up {
286
+ color: var(--success);
287
+ }
288
+
289
+ .market-value.down {
290
+ color: var(--accent);
291
+ }
292
+
293
+ .intermarket-grid {
294
+ display: grid;
295
+ grid-template-columns: repeat(2, 1fr);
296
+ gap: 16px;
297
+ }
298
+
299
+ .correlation-matrix {
300
+ background: white;
301
+ border-radius: 8px;
302
+ padding: 16px;
303
+ box-shadow: 0 2px 5px rgba(0,0,0,0.05);
304
+ }
305
+
306
+ .matrix-title {
307
+ font-size: 16px;
308
+ font-weight: 600;
309
+ margin-bottom: 12px;
310
+ color: var(--primary);
311
+ }
312
+
313
+ .matrix-table {
314
+ width: 100%;
315
+ border-collapse: collapse;
316
+ }
317
+
318
+ .matrix-table th, .matrix-table td {
319
+ padding: 8px;
320
+ text-align: center;
321
+ border: 1px solid #eee;
322
+ }
323
+
324
+ .matrix-table th {
325
+ background-color: #f5f7fa;
326
+ font-weight: 600;
327
+ }
328
+
329
+ .correlation-positive {
330
+ background-color: rgba(46, 204, 113, 0.2);
331
+ }
332
+
333
+ .correlation-negative {
334
+ background-color: rgba(231, 76, 60, 0.2);
335
+ }
336
+
337
+ .correlation-neutral {
338
+ background-color: rgba(241, 196, 15, 0.1);
339
+ }
340
+
341
+ .affirmation-card {
342
+ background: linear-gradient(145deg, #3498db, #2980b9);
343
+ color: white;
344
+ border-radius: 8px;
345
+ padding: 20px;
346
+ margin-bottom: 16px;
347
+ }
348
+
349
+ .affirmation-text {
350
+ font-size: 18px;
351
+ line-height: 1.6;
352
+ font-style: italic;
353
+ margin-bottom: 16px;
354
+ }
355
+
356
+ .affirmation-category {
357
+ font-size: 14px;
358
+ opacity: 0.8;
359
+ text-align: right;
360
+ }
361
+
362
+ .trade-item {
363
+ background: white;
364
+ border-radius: 8px;
365
+ padding: 16px;
366
+ margin-bottom: 16px;
367
+ box-shadow: 0 2px 5px rgba(0,0,0,0.05);
368
+ position: relative;
369
+ }
370
+
371
+ .trade-symbol {
372
+ font-size: 18px;
373
+ font-weight: 600;
374
+ margin-bottom: 4px;
375
+ }
376
+
377
+ .trade-details {
378
+ margin-bottom: 8px;
379
+ font-size: 14px;
380
+ color: #666;
381
+ }
382
+
383
+ .trade-pnl {
384
+ position: absolute;
385
+ top: 16px;
386
+ right: 16px;
387
+ font-weight: 600;
388
+ }
389
+
390
+ .trade-pnl.profit {
391
+ color: var(--success);
392
+ }
393
+
394
+ .trade-pnl.loss {
395
+ color: var(--accent);
396
+ }
397
+
398
+ .trade-actions {
399
+ display: flex;
400
+ justify-content: flex-end;
401
+ gap: 8px;
402
+ margin-top: 8px;
403
+ }
404
+
405
+ .chat-popup {
406
+ position: fixed;
407
+ bottom: 20px;
408
+ right: 20px;
409
+ width: 350px;
410
+ background: white;
411
+ border-radius: 8px 8px 0 0;
412
+ box-shadow: 0 -2px 10px rgba(0,0,0,0.1);
413
+ z-index: 1000;
414
+ transition: all 0.3s;
415
+ }
416
+
417
+ .chat-header {
418
+ background: var(--primary);
419
+ color: white;
420
+ padding: 10px 16px;
421
+ border-radius: 8px 8px 0 0;
422
+ display: flex;
423
+ justify-content: space-between;
424
+ align-items: center;
425
+ cursor: pointer;
426
+ }
427
+
428
+ .chat-body {
429
+ padding: 16px;
430
+ max-height: 300px;
431
+ overflow-y: auto;
432
+ }
433
+
434
+ .chat-message {
435
+ margin-bottom: 16px;
436
+ }
437
+
438
+ .chat-message.user {
439
+ text-align: right;
440
+ }
441
+
442
+ .chat-message.user .message-content {
443
+ background-color: var(--secondary);
444
+ color: white;
445
+ border-radius: 18px 18px 0 18px;
446
+ padding: 8px 16px;
447
+ display: inline-block;
448
+ max-width: 80%;
449
+ }
450
+
451
+ .chat-message.ai .message-content {
452
+ background-color: #f1f1f1;
453
+ color: #333;
454
+ border-radius: 18px 18px 18px 0;
455
+ padding: 8px 16px;
456
+ display: inline-block;
457
+ max-width: 80%;
458
+ }
459
+
460
+ .chat-footer {
461
+ padding: 10px 16px;
462
+ border-top: 1px solid #eee;
463
+ display: flex;
464
+ gap: 8px;
465
+ }
466
+
467
+ .chat-input {
468
+ flex: 1;
469
+ padding: 8px 12px;
470
+ border: 1px solid #ddd;
471
+ border-radius: 20px;
472
+ outline: none;
473
+ }
474
+
475
+ .minimized {
476
+ height: 46px;
477
+ overflow: hidden;
478
+ }
479
+
480
+ .gemini-badge {
481
+ background: linear-gradient(135deg, #1a73e8, #8e24aa);
482
+ color: white;
483
+ padding: 4px 10px;
484
+ border-radius: 12px;
485
+ font-size: 12px;
486
+ margin-left: 8px;
487
+ }
488
+
489
+ .api-key-container {
490
+ display: flex;
491
+ align-items: center;
492
+ gap: 8px;
493
+ }
494
+
495
+ .api-key-input {
496
+ background-color: rgba(255, 255, 255, 0.1);
497
+ border: 1px solid rgba(255, 255, 255, 0.2);
498
+ color: white;
499
+ padding: 4px 8px;
500
+ border-radius: 4px;
501
+ font-size: 14px;
502
+ width: 160px;
503
+ }
504
+
505
+ .api-key-input::placeholder {
506
+ color: rgba(255, 255, 255, 0.6);
507
+ }
508
+
509
+ .api-status {
510
+ width: 8px;
511
+ height: 8px;
512
+ border-radius: 50%;
513
+ background-color: #e74c3c;
514
+ margin-right: 4px;
515
+ }
516
+
517
+ .api-status.connected {
518
+ background-color: #2ecc71;
519
+ }
520
+
521
+ .loading-spinner {
522
+ border: 3px solid rgba(255, 255, 255, 0.3);
523
+ border-top: 3px solid #ffffff;
524
+ border-radius: 50%;
525
+ width: 16px;
526
+ height: 16px;
527
+ animation: spin 1s linear infinite;
528
+ margin-left: 5px;
529
+ display: none;
530
+ }
531
+
532
+ @keyframes spin {
533
+ 0% { transform: rotate(0deg); }
534
+ 100% { transform: rotate(360deg); }
535
+ }
536
+
537
+ /* Responsive adjustments */
538
+ @media (max-width: 768px) {
539
+ .intermarket-grid {
540
+ grid-template-columns: 1fr;
541
+ }
542
+
543
+ .chat-popup {
544
+ width: 100%;
545
+ left: 0;
546
+ right: 0;
547
+ bottom: 0;
548
+ border-radius: 0;
549
+ }
550
+
551
+ .chat-header {
552
+ border-radius: 0;
553
+ }
554
+ }
555
+ </style>
556
  </head>
557
  <body>
558
  <!-- Header and Navigation -->
 
856
 
857
  <div class="widget mt-4">
858
  <div class="widget-title">Session-Zeiten</div>
859
+ <table class="w-full text-sm">
860
  <tr>
861
  <td>London (GMT):</td>
862
  <td class="font-medium">08:00 - 16:30</td>
 
1575
  </div>
1576
  </div>
1577
 
1578
+ <script>
1579
+ // Global variables
1580
+ let apiKey = '';
1581
+ let apiConnected = false;
1582
+ let affirmationTimerInterval;
1583
+ let affirmationTimeLeft = 300; // 5 minutes in seconds
1584
+ let affirmationTimerRunning = false;
1585
+
1586
+ // Initialize the app
1587
+ document.addEventListener('DOMContentLoaded', function() {
1588
+ initTabs();
1589
+ updateDateTime();
1590
+ updateTicker();
1591
+ checkStoredApiKey();
1592
+
1593
+ // Set interval updates
1594
+ setInterval(updateDateTime, 1000);
1595
+ setInterval(updateTicker, 10000);
1596
+ setInterval(updateActiveTrades, 5000);
1597
+
1598
+ // Initialize tooltips, if needed
1599
+ // initTooltips();
1600
+ });
1601
+
1602
+ // Tab navigation
1603
+ function initTabs() {
1604
+ const tabs = document.querySelectorAll('.tab');
1605
+
1606
+ tabs.forEach(tab => {
1607
+ tab.addEventListener('click', function() {
1608
+ // Remove active class from all tabs and contents
1609
+ document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
1610
+ document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
1611
+
1612
+ // Add active class to clicked tab
1613
+ this.classList.add('active');
1614
+
1615
+ // Show corresponding content
1616
+ const tabId = this.getAttribute('data-tab');
1617
+ document.getElementById(tabId).classList.add('active');
1618
+ });
1619
+ });
1620
+ }
1621
+
1622
+ // API key functions
1623
+ function saveApiKey() {
1624
+ const keyInput = document.getElementById('geminiApiKey');
1625
+ if (keyInput.value.trim()) {
1626
+ apiKey = keyInput.value.trim();
1627
+ localStorage.setItem('geminiApiKey', apiKey);
1628
+ // Visual confirmation that key was saved
1629
+ keyInput.style.borderColor = '#2ecc71';
1630
+ setTimeout(() => {
1631
+ keyInput.style.borderColor = '';
1632
+ }, 2000);
1633
+ }
1634
+ }
1635
+
1636
+ function checkStoredApiKey() {
1637
+ const storedKey = localStorage.getItem('geminiApiKey');
1638
+ if (storedKey) {
1639
+ apiKey = storedKey;
1640
+ document.getElementById('geminiApiKey').value = storedKey;
1641
+ // Optional: Auto-connect with stored key
1642
+ // connectApi();
1643
+ }
1644
+ }
1645
+
1646
+ function connectApi() {
1647
+ if (!apiKey) {
1648
+ alert('Bitte gib einen API-Schlüssel ein.');
1649
+ return;
1650
+ }
1651
+
1652
+ const connectText = document.getElementById('connectText');
1653
+ const apiSpinner = document.getElementById('apiSpinner');
1654
+ const apiStatus = document.getElementById('apiStatus');
1655
+
1656
+ // Show spinner, change button text
1657
+ connectText.textContent = 'Verbinde...';
1658
+ apiSpinner.style.display = 'inline-block';
1659
+
1660
+ // Simulate API connection (replace with actual API call in production)
1661
+ setTimeout(() => {
1662
+ // Connection successful
1663
+ apiConnected = true;
1664
+ connectText.textContent = 'Verbunden';
1665
+ apiSpinner.style.display = 'none';
1666
+ apiStatus.classList.add('connected');
1667
+
1668
+ // Add success class to button
1669
+ const connectButton = document.querySelector('button[onclick="connectApi()"]');
1670
+ connectButton.style.backgroundColor = '#2ecc71';
1671
+ connectButton.disabled = true;
1672
+
1673
+ // Show a welcome message in chat
1674
+ addChatMessage('ai', 'API-Verbindung hergestellt! Ich bin jetzt bereit, dir mit KI-gestützten Trading-Analysen zu helfen. Frag mich etwas zu Märkten, Trading-Strategien oder deinen aktuellen Trades.');
1675
+ }, 2000);
1676
+ }
1677
+
1678
+ // Update date and time
1679
+ function updateDateTime() {
1680
+ const now = new Date();
1681
+
1682
+ // Update trading session status
1683
+ updateSessionStatus(now);
1684
+
1685
+ // Update any countdown timers
1686
+ updateCountdowns(now);
1687
+ }
1688
+
1689
+ function updateSessionStatus(now) {
1690
+ const hour = now.getUTCHours();
1691
+ const isWeekend = now.getUTCDay() === 0 || now.getUTCDay() === 6;
1692
+
1693
+ // This is a simplified version - a real implementation would be more nuanced
1694
+ if (!isWeekend) {
1695
+ // Asia session (roughly 00:00-09:00 CET / 23:00-08:00 UTC)
1696
+ if (hour >= 23 || hour < 8) {
1697
+ updateSessionElement('asia', 'active');
1698
+ updateSessionElement('europe', 'upcoming');
1699
+ updateSessionElement('us', 'closed');
1700
+ }
1701
+ // Europe session (roughly 08:00-16:30 CET / 07:00-15:30 UTC)
1702
+ else if (hour >= 8 && hour < 16) {
1703
+ updateSessionElement('asia', 'closed');
1704
+ updateSessionElement('europe', 'active');
1705
+ updateSessionElement('us', 'upcoming');
1706
+ }
1707
+ // US session (roughly 14:30-21:00 CET / 13:30-20:00 UTC)
1708
+ else if (hour >= 16 && hour < 20) {
1709
+ updateSessionElement('asia', 'upcoming');
1710
+ updateSessionElement('europe', 'closed');
1711
+ updateSessionElement('us', 'active');
1712
+ }
1713
+ // Overlap or non-active period
1714
+ else {
1715
+ updateSessionElement('asia', 'upcoming');
1716
+ updateSessionElement('europe', 'closed');
1717
+ updateSessionElement('us', 'closed');
1718
+ }
1719
+ } else {
1720
+ // Weekend - all markets closed
1721
+ updateSessionElement('asia', 'closed');
1722
+ updateSessionElement('europe', 'closed');
1723
+ updateSessionElement('us', 'closed');
1724
+ }
1725
+ }
1726
+
1727
+ function updateSessionElement(session, status) {
1728
+ // This is a placeholder - would need to be implemented with actual elements
1729
+ // console.log(`Session ${session} is now ${status}`);
1730
+ }
1731
+
1732
+ function updateCountdowns(now) {
1733
+ // Update any countdown timers in the UI
1734
+ // This is a placeholder for actual countdown logic
1735
+ }
1736
+
1737
+ // Ticker update function
1738
+ function updateTicker() {
1739
+ const tickerItems = document.querySelectorAll('.ticker-item');
1740
+
1741
+ tickerItems.forEach(item => {
1742
+ // Simulate price change (replace with actual API data in production)
1743
+ const randomChange = (Math.random() * 0.2 - 0.1).toFixed(2);
1744
+ const currentValue = parseFloat(item.querySelector('span').textContent);
1745
+ const newValue = (currentValue * (1 + randomChange / 100)).toFixed(2);
1746
+
1747
+ item.querySelector('span').textContent = newValue;
1748
+
1749
+ // Update direction indicator
1750
+ if (randomChange > 0) {
1751
+ item.classList.remove('down');
1752
+ item.classList.add('up');
1753
+ item.querySelector('i').className = 'fas fa-caret-up';
1754
+ } else {
1755
+ item.classList.remove('up');
1756
+ item.classList.add('down');
1757
+ item.querySelector('i').className = 'fas fa-caret-down';
1758
+ }
1759
+
1760
+ // Update percentage
1761
+ const percentEl = item.querySelector('i').nextSibling;
1762
+ percentEl.textContent = ` ${Math.abs(randomChange)}%`;
1763
+ });
1764
+ }
1765
+
1766
+ // Affirmation functions
1767
+ function updateAffirmation() {
1768
+ const status = document.getElementById('traderStatus').value;
1769
+ let affirmationText = '';
1770
+ let categoryText = '';
1771
+
1772
+ switch (status) {
1773
+ case 'preparing':
1774
+ affirmationText = 'Ich bereite mich gründlich vor und analysiere den Markt mit Klarheit und Fokus. Ich warte geduldig auf hochwertige Setups und halte mich an meine Handelsstrategie.';
1775
+ categoryText = 'Geduld und Vorbereitung';
1776
+ break;
1777
+ case 'active':
1778
+ affirmationText = 'Ich bleibe ruhig und diszipliniert während mein Trade läuft. Ich halte mich an meinen Plan und lasse keine Emotionen meine Entscheidungen beeinflussen.';
1779
+ categoryText = 'Emotionale Kontrolle';
1780
+ break;
1781
+ case 'developing':
1782
+ affirmationText = 'Ich entwickle meine Strategie mit Klarheit und Weisheit. Ich ziehe Lehren aus vergangenen Trades und verbessere kontinuierlich meine Fähigkeiten.';
1783
+ categoryText = 'Strategische Entwicklung';
1784
+ break;
1785
+ case 'break':
1786
+ affirmationText = 'Ich nehme mir bewusst Zeit für Erholung und Reflexion. Diese Pause stärkt meine Handelsleistung und schärft meinen Fokus.';
1787
+ categoryText = 'Erholung und Reflexion';
1788
+ break;
1789
+ }
1790
+
1791
+ document.getElementById('currentAffirmation').textContent = affirmationText;
1792
+ document.getElementById('affirmationCategory').textContent = categoryText;
1793
+ }
1794
+
1795
+ function updateAffirmationTab() {
1796
+ const status = document.getElementById('affirmationTraderStatus').value;
1797
+ const category = document.getElementById('affirmationCategory').value;
1798
+
1799
+ // Map of affirmations based on status and category
1800
+ const affirmations = {
1801
+ discipline: {
1802
+ preparing: 'Ich bin ein disziplinierter und geduldiger Trader, der seinem Handelsplan mit unerschütterlichem Engagement folgt. Ich vertraue auf die Wirksamkeit meiner Strategien und warte geduldig auf Setups mit hoher Wahrscheinlichkeit. Ich habe die Selbstkontrolle, mich an meine etablierten Regeln zu halten und impulsive Handlungen zu vermeiden.',
1803
+ active: 'Während mein Trade aktiv ist, bleibe ich diszipliniert und geduldig. Ich folge meinem Plan und erlaube keiner Emotion, meine Strategie zu untergraben. Ich bin ruhig und kontrolliert, selbst wenn der Markt volatil wird.',
1804
+ developing: 'Beim Entwickeln meiner Strategie wende ich Disziplin und Geduld an. Ich nehme mir die Zeit, jedes Detail zu durchdenken und teste gründlich, bevor ich handele. Qualität geht vor Schnelligkeit.',
1805
+ break: 'In dieser Pause pflege ich meine Disziplin und Geduld, indem ich reflektiere und lerne. Ich verstehe, dass Ruhezeiten wesentlich für nachhaltigen Trading-Erfolg sind.'
1806
+ },
1807
+ abundance: {
1808
+ preparing: 'Ich ziehe reichlich Handelsmöglichkeiten an, die mit meiner Strategie übereinstimmen. Der Markt bietet einen endlosen Strom von Gelegenheiten, und ich bin bereit, sie zu nutzen.',
1809
+ active: 'Mein aktueller Trade ist eine von vielen Gelegenheiten für Wohlstand. Ich denke in Fülle und weiß, dass unabhängig vom Ausgang dieses Trades weitere profitable Chancen folgen werden.',
1810
+ developing: 'Ich entwickle meine Strategie mit einer Überfluss-Denkweise. Ich erkenne die unbegrenzten Möglichkeiten des Marktes an und erschaffe einen Ansatz, der diesen Reichtum anzieht.',
1811
+ break: 'Während dieser Pause ziehe ich neue Erkenntnisse und Möglichkeiten an. Ich nutze diese Zeit, um meine Überfluss-Denkweise zu stärken und mich auf neue Handelschancen vorzubereiten.'
1812
+ }
1813
+ // Additional categories would be added here
1814
+ };
1815
+
1816
+ // Get the appropriate affirmation or default
1817
+ let affirmationText = 'Ich handle mit Klarheit, Disziplin und Vertrauen.';
1818
+ if (affirmations[category] && affirmations[category][status]) {
1819
+ affirmationText = affirmations[category][status];
1820
+ }
1821
+
1822
+ // Update the display
1823
+ document.getElementById('detailedAffirmation').querySelector('.affirmation-text').textContent = affirmationText;
1824
+
1825
+ // Update the category display
1826
+ let categoryDisplayText = '';
1827
+ switch (category) {
1828
+ case 'discipline': categoryDisplayText = 'Disziplin und Geduld entwickeln'; break;
1829
+ case 'abundance': categoryDisplayText = 'Überflussdenken fördern'; break;
1830
+ case 'selection': categoryDisplayText = 'Handelsauswahl verbessern'; break;
1831
+ case 'burnout': categoryDisplayText = 'Burnout und Erschöpfung überwinden'; break;
1832
+ case 'bias': categoryDisplayText = 'Bestätigungsfehler überwinden'; break;
1833
+ case 'paralysis': categoryDisplayText = 'Entscheidungslähmung überwinden'; break;
1834
+ case 'fomo': categoryDisplayText = 'FOMO überwinden'; break;
1835
+ case 'losses': categoryDisplayText = 'Verluste schnell akzeptieren'; break;
1836
+ case 'emotional': categoryDisplayText = 'Emotionale Bindung an Trades lösen'; break;
1837
+ case 'overtrading': categoryDisplayText = 'Überhandel widerstehen'; break;
1838
+ case 'patience': categoryDisplayText = 'Geduld bei langsamen Märkten bewahren'; break;
1839
+ default: categoryDisplayText = 'Allgemeine Trading-Affirmation';
1840
+ }
1841
+
1842
+ document.getElementById('detailedAffirmation').querySelector('.affirmation-category').textContent = categoryDisplayText;
1843
+ }
1844
+
1845
+ // Affirmation Timer functions
1846
+ function startAffirmationTimer() {
1847
+ if (affirmationTimerRunning) return;
1848
+
1849
+ document.getElementById('startTimerBtn').disabled = true;
1850
+ document.getElementById('pauseTimerBtn').disabled = false;
1851
+
1852
+ affirmationTimerRunning = true;
1853
+
1854
+ affirmationTimerInterval = setInterval(() => {
1855
+ affirmationTimeLeft--;
1856
+
1857
+ const minutes = Math.floor(affirmationTimeLeft / 60);
1858
+ const seconds = affirmationTimeLeft % 60;
1859
+
1860
+ document.getElementById('affirmationTimer').textContent =
1861
+ `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
1862
+
1863
+ if (affirmationTimeLeft <= 0) {
1864
+ clearInterval(affirmationTimerInterval);
1865
+ affirmationTimerRunning = false;
1866
+ document.getElementById('startTimerBtn').disabled = false;
1867
+ document.getElementById('pauseTimerBtn').disabled = true;
1868
+ document.getElementById('affirmationTimer').textContent = "00:00";
1869
+ // Play sound or notification
1870
+ // playTimerEndSound();
1871
+ }
1872
+ }, 1000);
1873
+ }
1874
+
1875
+ function pauseAffirmationTimer() {
1876
+ clearInterval(affirmationTimerInterval);
1877
+ affirmationTimerRunning = false;
1878
+ document.getElementById('startTimerBtn').disabled = false;
1879
+ document.getElementById('pauseTimerBtn').disabled = true;
1880
+ }
1881
+
1882
+ function resetAffirmationTimer() {
1883
+ clearInterval(affirmationTimerInterval);
1884
+ affirmationTimerRunning = false;
1885
+ affirmationTimeLeft = 300; // Reset to 5 minutes
1886
+ document.getElementById('affirmationTimer').textContent = "05:00";
1887
+ document.getElementById('startTimerBtn').disabled = false;
1888
+ document.getElementById('pauseTimerBtn').disabled = true;
1889
+ }
1890
+
1891
+ function saveCurrentAffirmation() {
1892
+ const affirmationText = document.getElementById('detailedAffirmation').querySelector('.affirmation-text').textContent;
1893
+ const categoryText = document.getElementById('detailedAffirmation').querySelector('.affirmation-category').textContent;
1894
+
1895
+ // Create a shortened version
1896
+ const shortAffirmation = affirmationText.substring(0, 60) + (affirmationText.length > 60 ? '...' : '');
1897
+
1898
+ // Create new element
1899
+ const newSavedAffirmation = document.createElement('div');
1900
+ newSavedAffirmation.className = 'event-item';
1901
+ newSavedAffirmation.innerHTML = `
1902
+ <div class="font-medium">${shortAffirmation}</div>
1903
+ <div class="text-sm text-gray-600">Kategorie: ${categoryText}</div>
1904
+ `;
1905
+
1906
+ // Add to saved affirmations
1907
+ const savedAffirmationsContainer = document.getElementById('savedAffirmations');
1908
+ savedAffirmationsContainer.prepend(newSavedAffirmation);
1909
+
1910
+ // Show success message
1911
+ alert('Affirmation gespeichert!');
1912
+ }
1913
+
1914
+ // Trading opportunity functions
1915
+ function generateOpportunity() {
1916
+ const symbol = document.getElementById('opportunitySymbol').value;
1917
+
1918
+ if (!symbol) {
1919
+ alert('Bitte wähle ein Symbol aus.');
1920
+ return;
1921
+ }
1922
+
1923
+ if (!apiConnected) {
1924
+ alert('Bitte verbinde zuerst die Gemini API.');
1925
+ return;
1926
+ }
1927
+
1928
+ // Get other parameters
1929
+ const timeframe = document.getElementById('opportunityTimeframe').value;
1930
+ const style = document.getElementById('opportunityStyle').value;
1931
+ const instructions = document.getElementById('opportunityInstructions').value;
1932
+
1933
+ // Show loading state
1934
+ document.getElementById('analyzeText').textContent = 'Analysiere...';
1935
+ document.getElementById('opportunitySpinner').style.display = 'inline-block';
1936
+
1937
+ // Simulate API call (replace with actual API call in production)
1938
+ setTimeout(() => {
1939
+ // Reset button
1940
+ document.getElementById('analyzeText').textContent = 'Trading Opportunity analysieren';
1941
+ document.getElementById('opportunitySpinner').style.display = 'none';
1942
+
1943
+ // Generate result
1944
+ const result = generateOpportunityResult(symbol, timeframe, style, instructions);
1945
+
1946
+ // Display result
1947
+ document.getElementById('opportunityResults').innerHTML = result;
1948
+ }, 3000);
1949
+ }
1950
+
1951
+ function generateOpportunityResult(symbol, timeframe, style, instructions) {
1952
+ // This is a simulation - in production this would come from the Gemini API
1953
+
1954
+ // Extract symbol name
1955
+ const symbolName = symbol.split(':')[1];
1956
+
1957
+ // Determine direction (random for demo)
1958
+ const isLong = Math.random() > 0.5;
1959
+
1960
+ // Generate fictional analysis
1961
+ let analysis = '';
1962
+ let technicalInsights = '';
1963
+ let fundamentalInsights = '';
1964
+ let tradeSetup = '';
1965
+
1966
+ // Technical insights
1967
+ if (style === 'technical' || style === 'combined') {
1968
+ const patterns = ['Double Bottom', 'Bull Flag', 'Cup and Handle', 'Descending Triangle', 'Head and Shoulders'];
1969
+ const indicators = ['RSI', 'MACD', 'Moving Average', 'Bollinger Bands', 'Fibonacci Retracement'];
1970
+
1971
+ const pattern = patterns[Math.floor(Math.random() * patterns.length)];
1972
+ const indicator1 = indicators[Math.floor(Math.random() * indicators.length)];
1973
+ const indicator2 = indicators[Math.floor(Math.random() * indicators.length)];
1974
+
1975
+ technicalInsights = `<p class="mb-3"><strong>Technische Analyse:</strong> ${symbolName} zeigt ein ${pattern}-Muster, das auf eine potenzielle ${isLong ? 'Aufwärts' : 'Abwärts'}bewegung hindeutet. Der ${indicator1} ist ${isLong ? 'überverkauft' : 'überkauft'}, während der ${indicator2} ein ${isLong ? 'bullisches' : 'bärisches'} Signal gibt.</p>`;
1976
+ }
1977
+
1978
+ // Fundamental insights
1979
+ if (style === 'fundamental' || style === 'combined') {
1980
+ fundamentalInsights = `<p class="mb-3"><strong>Fundamentale Analyse:</strong> ${symbolName} ${isLong ? 'profitiert von positiven Branchentrends und zeigt starkes Gewinnwachstum' : 'steht vor Herausforderungen durch Branchendruck und Margenschwäche'}. Bevorstehende Ereignisse könnten ${isLong ? 'positive' : 'negative'} Auswirkungen auf den Kurs haben.</p>`;
1981
+ }
1982
+
1983
+ // Trade setup
1984
+ const currentPrice = Math.random() * 1000;
1985
+ const stopLoss = isLong ? currentPrice * 0.95 : currentPrice * 1.05;
1986
+ const takeProfit = isLong ? currentPrice * 1.1 : currentPrice * 0.9;
1987
+
1988
+ tradeSetup = `
1989
+ <div class="p-3 bg-gray-50 rounded-lg mt-4">
1990
+ <h4 class="font-semibold mb-2">Trade Setup</h4>
1991
+ <div class="grid grid-cols-2 gap-3 text-sm">
1992
+ <div>
1993
+ <div class="text-gray-600">Richtung:</div>
1994
+ <div class="font-medium">${isLong ? 'Long (Kaufen)' : 'Short (Verkaufen)'}</div>
1995
+ </div>
1996
+ <div>
1997
+ <div class="text-gray-600">Einstieg:</div>
1998
+ <div class="font-medium">${currentPrice.toFixed(2)}</div>
1999
+ </div>
2000
+ <div>
2001
+ <div class="text-gray-600">Stop-Loss:</div>
2002
+ <div class="font-medium">${stopLoss.toFixed(2)}</div>
2003
+ </div>
2004
+ <div>
2005
+ <div class="text-gray-600">Take-Profit:</div>
2006
+ <div class="font-medium">${takeProfit.toFixed(2)}</div>
2007
+ </div>
2008
+ <div>
2009
+ <div class="text-gray-600">Risk/Reward:</div>
2010
+ <div class="font-medium">1:${isLong ? '2' : '3'}</div>
2011
+ </div>
2012
+ <div>
2013
+ <div class="text-gray-600">Zeitrahmen:</div>
2014
+ <div class="font-medium">${timeframe === 'shortTerm' ? 'Kurzfristig (1-3 Tage)' : timeframe === 'mediumTerm' ? 'Mittelfristig (1-2 Wochen)' : 'Langfristig (1+ Monate)'}</div>
2015
+ </div>
2016
+ </div>
2017
+ </div>
2018
+ `;
2019
+
2020
+ // Build the full analysis
2021
+ analysis = `
2022
+ <div>
2023
+ <div class="mb-4 flex justify-between items-start">
2024
+ <div>
2025
+ <h3 class="font-semibold text-lg">${symbol}</h3>
2026
+ <div class="text-sm text-gray-600">${new Date().toLocaleString()}</div>
2027
+ </div>
2028
+ <div class="badge ${isLong ? 'badge-success' : 'badge-danger'}">${isLong ? 'Long' : 'Short'}</div>
2029
+ </div>
2030
+
2031
+ ${technicalInsights}
2032
+ ${fundamentalInsights}
2033
+
2034
+ <p class="mb-4">
2035
+ <strong>Analyse:</strong> Basierend auf ${style === 'technical' ? 'technischer Analyse' : style === 'fundamental' ? 'fundamentaler Analyse' : 'technischer und fundamentaler Analyse'}
2036
+ erscheint ${symbolName} als ${isLong ? 'attraktive Long-Opportunity' : 'potentielle Short-Position'} für den ${timeframe === 'shortTerm' ? 'kurzfristigen' : timeframe === 'mediumTerm' ? 'mittelfristigen' : 'langfristigen'} Handel.
2037
+ </p>
2038
+
2039
+ ${tradeSetup}
2040
+
2041
+ <div class="mt-6 flex justify-end gap-3">
2042
+ <button class="btn-primary text-sm" onclick="saveOpportunity()">Speichern</button>
2043
+ <button class="btn-primary text-sm" onclick="createTradeFromOpportunity()">Trade erstellen</button>
2044
+ </div>
2045
+ </div>
2046
+ `;
2047
+
2048
+ return analysis;
2049
+ }
2050
+
2051
+ function saveOpportunity() {
2052
+ alert('Trading Opportunity gespeichert!');
2053
+ }
2054
+
2055
+ function createTradeFromOpportunity() {
2056
+ alert('Trade aus dieser Opportunity wird erstellt. Bitte bestätige die Details im "Meine Trades" Bereich.');
2057
+
2058
+ // Switch to the My Trades tab
2059
+ document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
2060
+ document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
2061
+
2062
+ document.querySelector('[data-tab="mytrades"]').classList.add('active');
2063
+ document.getElementById('mytrades').classList.add('active');
2064
+ }
2065
+
2066
+ // Trade functions
2067
+ function addNewTrade() {
2068
+ const symbol = document.getElementById('newTradeSymbol').value;
2069
+ if (!symbol) {
2070
+ alert('Bitte wähle ein Symbol aus.');
2071
+ return;
2072
+ }
2073
+
2074
+ const entry = document.getElementById('newTradeEntry').value;
2075
+ if (!entry) {
2076
+ alert('Bitte gib einen Einstiegspreis ein.');
2077
+ return;
2078
+ }
2079
+
2080
+ const direction = document.getElementById('newTradeDirection').value;
2081
+ const stop = document.getElementById('newTradeStop').value;
2082
+ const target = document.getElementById('newTradeTarget').value;
2083
+ const position = document.getElementById('newTradePosition').value;
2084
+ const notes = document.getElementById('newTradeNotes').value;
2085
+
2086
+ // Create trade element
2087
+ const tradeElement = document.createElement('div');
2088
+ tradeElement.className = 'trade-item';
2089
+
2090
+ // Random P&L for demo
2091
+ const pnl = ((Math.random() * 2) - 0.5).toFixed(2);
2092
+ const isProfitable = parseFloat(pnl) > 0;
2093
+
2094
+ tradeElement.innerHTML = `
2095
+ <div class="trade-symbol">${symbol}</div>
2096
+ <div class="trade-details">${direction === 'long' ? 'Long' : 'Short'} @ ${entry} • Stop: ${stop} • Target: ${target}</div>
2097
+ <div class="trade-pnl ${isProfitable ? 'profit' : 'loss'}">${pnl > 0 ? '+' : ''}${pnl}%</div>
2098
+ <div class="text-sm text-gray-500 mt-2">Eröffnet: ${new Date().toLocaleString()}</div>
2099
+ ${notes ? `
2100
+ <div class="mt-3 text-sm">
2101
+ <div class="font-medium">Notizen:</div>
2102
+ <p class="text-gray-600">${notes}</p>
2103
+ </div>
2104
+ ` : ''}
2105
+ <div class="trade-actions">
2106
+ <button class="btn-primary text-xs py-1">Bearbeiten</button>
2107
+ <button class="btn-danger text-xs py-1" onclick="removeTrade(this)">Entfernen</button>
2108
+ </div>
2109
+ `;
2110
+
2111
+ // Add to trades list
2112
+ document.getElementById('tradesList').prepend(tradeElement);
2113
+
2114
+ // Clear form
2115
+ document.getElementById('newTradeSymbol').value = '';
2116
+ document.getElementById('newTradeEntry').value = '';
2117
+ document.getElementById('newTradeStop').value = '';
2118
+ document.getElementById('newTradeTarget').value = '';
2119
+ document.getElementById('newTradePosition').value = '';
2120
+ document.getElementById('newTradeNotes').value = '';
2121
+
2122
+ // Update trade count and statistics
2123
+ updateTradeStatistics();
2124
+
2125
+ // Show notification
2126
+ alert('Trade erfolgreich hinzugefügt!');
2127
+ }
2128
+
2129
+ function removeTrade(button) {
2130
+ // Find the parent trade item and remove it
2131
+ const tradeItem = button.closest('.trade-item');
2132
+ tradeItem.style.opacity = '0.5';
2133
+
2134
+ // Simulate a delay before removal
2135
+ setTimeout(() => {
2136
+ tradeItem.remove();
2137
+ // Update statistics
2138
+ updateTradeStatistics();
2139
+ // Show notification
2140
+ alert('Trade entfernt!');
2141
+ }, 500);
2142
+ }
2143
+
2144
+ function updateTradeStatistics() {
2145
+ // This would calculate real statistics in production
2146
+ // For demo, we'll just update the count
2147
+ const tradeCount = document.querySelectorAll('.trade-item').length;
2148
+ // Update the trade count in the statistics
2149
+ // This assumes there's an element to update
2150
+ }
2151
+
2152
+ function updateActiveTrades() {
2153
+ // This would update real trade data in production
2154
+ // For demo, we'll randomly update P&L
2155
+
2156
+ const tradeItems = document.querySelectorAll('.trade-item');
2157
+
2158
+ tradeItems.forEach(item => {
2159
+ const pnlElement = item.querySelector('.trade-pnl');
2160
+ if (pnlElement) {
2161
+ // Get current value
2162
+ const currentValue = parseFloat(pnlElement.textContent.replace('%', '').replace('+', ''));
2163
+
2164
+ // Small random change
2165
+ const change = (Math.random() * 0.2) - 0.1;
2166
+ const newValue = (currentValue + change).toFixed(2);
2167
+
2168
+ // Update display
2169
+ const isProfit = parseFloat(newValue) > 0;
2170
+ pnlElement.className = `trade-pnl ${isProfit ? 'profit' : 'loss'}`;
2171
+ pnlElement.textContent = `${isProfit ? '+' : ''}${newValue}%`;
2172
+ }
2173
+ });
2174
+ }
2175
+
2176
+ function sortTrades() {
2177
+ const sortOption = document.getElementById('tradeSortOption').value;
2178
+ const tradesList = document.getElementById('tradesList');
2179
+ const trades = Array.from(tradesList.querySelectorAll('.trade-item'));
2180
+
2181
+ // Clear the container
2182
+ tradesList.innerHTML = '';
2183
+
2184
+ // Sort trades based on option
2185
+ switch (sortOption) {
2186
+ case 'newest':
2187
+ // Just reverse the current order for demo
2188
+ trades.reverse();
2189
+ break;
2190
+ case 'oldest':
2191
+ // Keep current order for demo
2192
+ break;
2193
+ case 'profit':
2194
+ trades.sort((a, b) => {
2195
+ const aPnl = parseFloat(a.querySelector('.trade-pnl').textContent.replace('%', '').replace('+', ''));
2196
+ const bPnl = parseFloat(b.querySelector('.trade-pnl').textContent.replace('%', '').replace('+', ''));
2197
+ return bPnl - aPnl; // Descending
2198
+ });
2199
+ break;
2200
+ case 'loss':
2201
+ trades.sort((a, b) => {
2202
+ const aPnl = parseFloat(a.querySelector('.trade-pnl').textContent.replace('%', '').replace('+', ''));
2203
+ const bPnl = parseFloat(b.querySelector('.trade-pnl').textContent.replace('%', '').replace('+', ''));
2204
+ return aPnl - bPnl; // Ascending
2205
+ });
2206
+ break;
2207
+ }
2208
+
2209
+ // Add sorted trades back to container
2210
+ trades.forEach(trade => tradesList.appendChild(trade));
2211
+ }
2212
+
2213
+ function refreshTrades() {
2214
+ updateActiveTrades();
2215
+ alert('Trades aktualisiert!');
2216
+ }
2217
+
2218
+ // Intermarket Analysis
2219
+ function updateIntermarketAnalysis() {
2220
+ const stockIndex = document.getElementById('stockIndex').value;
2221
+ const bondIndex = document.getElementById('bondIndex').value;
2222
+ const commodityIndex = document.getElementById('commodityIndex').value;
2223
+ const currencyIndex = document.getElementById('currencyIndex').value;
2224
+
2225
+ // In a real app, this would fetch data and update the charts/analysis
2226
+ alert(`Intermarket-Analyse wird aktualisiert mit: ${stockIndex}, ${bondIndex}, ${commodityIndex}, ${currencyIndex}`);
2227
+ }
2228
+
2229
+ // Chat functions
2230
+ function toggleChat() {
2231
+ const chatPopup = document.getElementById('chatPopup');
2232
+ const chevron = document.getElementById('chatChevron');
2233
+
2234
+ if (chatPopup.classList.contains('minimized')) {
2235
+ chatPopup.classList.remove('minimized');
2236
+ chevron.className = 'fas fa-chevron-down';
2237
+ } else {
2238
+ chatPopup.classList.add('minimized');
2239
+ chevron.className = 'fas fa-chevron-up';
2240
+ }
2241
+ }
2242
+
2243
+ function sendChatMessage() {
2244
+ const chatInput = document.getElementById('chatInput');
2245
+ const message = chatInput.value.trim();
2246
+
2247
+ if (!message) return;
2248
+
2249
+ // Add user message
2250
+ addChatMessage('user', message);
2251
+
2252
+ // Clear input
2253
+ chatInput.value = '';
2254
+
2255
+ // Check API connection
2256
+ if (!apiConnected) {
2257
+ addChatMessage('ai', 'Bitte verbinde zuerst die Gemini API, um mit dem Chat zu interagieren.');
2258
+ return;
2259
+ }
2260
+
2261
+ // Show typing indicator
2262
+ showTypingIndicator();
2263
+
2264
+ // Simulate AI response (replace with actual API call in production)
2265
+ setTimeout(() => {
2266
+ // Remove typing indicator
2267
+ removeTypingIndicator();
2268
+
2269
+ // Generate response
2270
+ const response = generateChatResponse(message);
2271
+
2272
+ // Add AI message
2273
+ addChatMessage('ai', response);
2274
+
2275
+ // Scroll to bottom
2276
+ scrollChatToBottom();
2277
+ }, 1500);
2278
+ }
2279
+
2280
+ function handleChatKeyPress(event) {
2281
+ if (event.key === 'Enter') {
2282
+ sendChatMessage();
2283
+ }
2284
+ }
2285
+
2286
+ function addChatMessage(sender, text) {
2287
+ const chatBody = document.getElementById('chatBody');
2288
+ const messageDiv = document.createElement('div');
2289
+ messageDiv.className = `chat-message ${sender}`;
2290
+
2291
+ messageDiv.innerHTML = `
2292
+ <div class="message-content">${text}</div>
2293
+ `;
2294
+
2295
+ chatBody.appendChild(messageDiv);
2296
+
2297
+ // Expand chat if minimized
2298
+ if (document.getElementById('chatPopup').classList.contains('minimized')) {
2299
+ toggleChat();
2300
+ }
2301
+
2302
+ // Scroll to bottom
2303
+ scrollChatToBottom();
2304
+ }
2305
+
2306
+ function scrollChatToBottom() {
2307
+ const chatBody = document.getElementById('chatBody');
2308
+ chatBody.scrollTop = chatBody.scrollHeight;
2309
+ }
2310
+
2311
+ function showTypingIndicator() {
2312
+ const chatBody = document.getElementById('chatBody');
2313
+ const typingDiv = document.createElement('div');
2314
+ typingDiv.className = 'chat-message ai';
2315
+ typingDiv.id = 'typingIndicator';
2316
+
2317
+ typingDiv.innerHTML = `
2318
+ <div class="message-content">
2319
+ <div class="typing-indicator">
2320
+ <span></span>
2321
+ <span></span>
2322
+ <span></span>
2323
+ </div>
2324
+ </div>
2325
+ `;
2326
+
2327
+ chatBody.appendChild(typingDiv);
2328
+ scrollChatToBottom();
2329
+ }
2330
+
2331
+ function removeTypingIndicator() {
2332
+ const typingIndicator = document.getElementById('typingIndicator');
2333
+ if (typingIndicator) {
2334
+ typingIndicator.remove();
2335
+ }
2336
+ }
2337
+
2338
+ function generateChatResponse(message) {
2339
+ // This is a simulation - in production this would come from the Gemini API
2340
+
2341
+ // Simple pattern matching for demo
2342
+ if (message.toLowerCase().includes('hallo') || message.toLowerCase().includes('hi')) {
2343
+ return 'Hallo! Wie kann ich dir bei deinem Trading heute helfen?';
2344
+ } else if (message.toLowerCase().includes('market') || message.toLowerCase().includes('markt')) {
2345
+ return 'Die Märkte zeigen heute gemischte Signale. US-Indizes sind leicht im Plus, während europäische Märkte sich seitwärts bewegen. Gold steigt aufgrund geopolitischer Spannungen.';
2346
+ } else if (message.toLowerCase().includes('affirmation')) {
2347
+ return 'Affirmationen können deine Trading-Psychologie stark verbessern. Ich empfehle dir, täglich 5 Minuten für Affirmationen einzuplanen, besonders vor Handelssessions oder nach Verlusten.';
2348
+ } else if (message.toLowerCase().includes('verlust') || message.toLowerCase().includes('loss')) {
2349
+ return 'Verluste sind ein normaler Teil des Tradings. Das Wichtigste ist, wie du darauf reagierst. Halte dich an dein Risikomanagement und betrachte jeden Verlust als Lernchance.';
2350
+ } else if (message.toLowerCase().includes('strategie') || message.toLowerCase().includes('strategy')) {
2351
+ return 'Eine erfolgreiche Trading-Strategie sollte klare Ein- und Ausstiegskriterien, Risikomanagement und ein positives Erwartungswert haben. Möchtest du Hilfe bei einem bestimmten Aspekt deiner Strategie?';
2352
+ } else {
2353
+ return 'Danke für deine Nachricht. Ich kann dir bei Trading-Analysen, Affirmationen, Marktinformationen und Handelsstrategien helfen. Was interessiert dich am meisten?';
2354
+ }
2355
+ }
2356
+ </script>
2357
  </body>
2358
+ </html>