jgtml 0.0.330__tar.gz → 0.0.332__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {jgtml-0.0.330/jgtml.egg-info → jgtml-0.0.332}/PKG-INFO +1 -1
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/__init__.py +1 -1
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/enhanced_trading_cli.py +57 -6
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/jgtapp.py +10 -4
- jgtml-0.0.332/jgtml/trading_orchestrator.py +359 -0
- {jgtml-0.0.330 → jgtml-0.0.332/jgtml.egg-info}/PKG-INFO +1 -1
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml.egg-info/SOURCES.txt +1 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/pyproject.toml +1 -1
- {jgtml-0.0.330 → jgtml-0.0.332}/LICENSE +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/README.md +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/README.rst +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/AlligatorIllusionDetector.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/JGTBalanceAnalyzer.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/JGTOutputHelper.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/MLFRequest.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/SOHelper.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/SignalOrderingHelper.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/TideAlligatorAnalysis.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/alligator_cli.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/anhelper.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/automated_fdb_trading_system.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/enhanced_fdb_scanner_with_illusion_detection.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/fdb_pattern_intelligence.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/fdb_scanner_2408.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/fdb_signal_quality_predictor.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/jdash.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/jgtml_obsds_240515_TIDE_SIGNALS.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/jgtmlcli.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/jplt.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/jtc.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/mfihelper2.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/mlclicommon.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/mlcliconstants.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/mlconstants.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/mldatahelper.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/mlfcli.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/mlfsvc.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/mlutils.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/mxcli.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/mxconstants.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/mxhelper.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/mxsvc.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/pncli.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/pto250518.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/ptomlf.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/ptottf.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/ptottfpatterns.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/realityhelper.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/test_get_files_in_ns.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/test_pncli.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/test_signal_ordering_helper.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/test_soh_gator_validations.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/tst_barhelper_and_pd.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/tst_jgtpov.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/ttfcli.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/ttfsvc.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/unified_discovery_dataset_generator.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/xhelper.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml/zonehelper.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml.egg-info/dependency_links.txt +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml.egg-info/entry_points.txt +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml.egg-info/requires.txt +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/jgtml.egg-info/top_level.txt +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/setup.cfg +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/setup.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/tests/test-calc-targets-2.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/tests/test-calc-targets.py +0 -0
- {jgtml-0.0.330 → jgtml-0.0.332}/tests/test-plot-CDS.py +0 -0
|
@@ -263,8 +263,11 @@ Examples:
|
|
|
263
263
|
|
|
264
264
|
# Automated trading system command
|
|
265
265
|
auto_parser = subparsers.add_parser('auto', help='Run complete automated trading system')
|
|
266
|
-
auto_parser.add_argument('-i', '--
|
|
267
|
-
auto_parser.add_argument('-t', '--timeframes', nargs='+', default=['
|
|
266
|
+
auto_parser.add_argument('-i', '--instruments', required=True, help='Comma-separated instruments to analyze (e.g., EUR-USD,GBP-USD,XAU-USD)')
|
|
267
|
+
auto_parser.add_argument('-t', '--timeframes', nargs='+', default=['H4', 'H1', 'm15'], help='Timeframes to analyze')
|
|
268
|
+
auto_parser.add_argument('--demo', action='store_true', default=True, help='Use demo mode (default)')
|
|
269
|
+
auto_parser.add_argument('--real', action='store_true', help='Use real trading mode')
|
|
270
|
+
auto_parser.add_argument('--quality-threshold', type=float, default=8.0, help='Minimum quality threshold for campaign creation (default: 8.0)')
|
|
268
271
|
|
|
269
272
|
# Illusion detection command
|
|
270
273
|
illusion_parser = subparsers.add_parser('illusion', help='Run standalone alligator illusion detection')
|
|
@@ -299,10 +302,58 @@ Examples:
|
|
|
299
302
|
print(f"✅ Production scan completed: {result.get('message', 'Success')}")
|
|
300
303
|
|
|
301
304
|
elif args.command == 'auto':
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
305
|
+
# Parse instruments
|
|
306
|
+
instruments = [inst.strip() for inst in args.instruments.split(',')]
|
|
307
|
+
demo_mode = not args.real # Real overrides demo
|
|
308
|
+
|
|
309
|
+
print(f"\n🤖 AUTOMATED FDB TRADING - Enhanced Mode")
|
|
310
|
+
print("=" * 60)
|
|
311
|
+
print(f"Instruments: {instruments}")
|
|
312
|
+
print(f"Mode: {'DEMO' if demo_mode else 'REAL'}")
|
|
313
|
+
print(f"Quality Threshold: {args.quality_threshold}")
|
|
314
|
+
print("=" * 60)
|
|
315
|
+
|
|
316
|
+
all_results = {}
|
|
317
|
+
campaigns_created = []
|
|
318
|
+
|
|
319
|
+
for instrument in instruments:
|
|
320
|
+
try:
|
|
321
|
+
print(f"\n🚀 ANALYZING {instrument}")
|
|
322
|
+
print("-" * 40)
|
|
323
|
+
result = run_automated_trading_system(instrument, args.timeframes)
|
|
324
|
+
all_results[instrument] = result
|
|
325
|
+
|
|
326
|
+
if result and result.get("entries", 0) > 0:
|
|
327
|
+
campaigns_created.append({
|
|
328
|
+
"instrument": instrument,
|
|
329
|
+
"entries": result.get("entries", 0),
|
|
330
|
+
"quality": args.quality_threshold # Use threshold as reference
|
|
331
|
+
})
|
|
332
|
+
|
|
333
|
+
except Exception as e:
|
|
334
|
+
print(f"❌ Error processing {instrument}: {e}")
|
|
335
|
+
all_results[instrument] = {"error": str(e)}
|
|
336
|
+
|
|
337
|
+
# Summary
|
|
338
|
+
print("\n🎯 AUTOMATED TRADING RESULTS")
|
|
339
|
+
print("=" * 50)
|
|
340
|
+
|
|
341
|
+
for instrument, result in all_results.items():
|
|
342
|
+
if "error" in result:
|
|
343
|
+
print(f"❌ {instrument}: Error - {result['error']}")
|
|
344
|
+
else:
|
|
345
|
+
entries = result.get("entries", 0) if result else 0
|
|
346
|
+
status = "✅ ENTRIES FOUND" if entries > 0 else "📋 MANUAL REVIEW"
|
|
347
|
+
print(f"📈 {instrument}: {entries} entries (Q: {args.quality_threshold:.1f}) - {status}")
|
|
348
|
+
|
|
349
|
+
if campaigns_created:
|
|
350
|
+
print(f"\n🚀 INSTRUMENTS WITH ENTRIES: {len(campaigns_created)}")
|
|
351
|
+
for campaign in campaigns_created:
|
|
352
|
+
print(f" ✅ {campaign['instrument']}: {campaign['entries']} entries")
|
|
353
|
+
print(f"\n📁 Campaign files: ./campaigns/")
|
|
354
|
+
print("📋 Review and execute campaigns using entry scripts")
|
|
355
|
+
else:
|
|
356
|
+
print("\n📋 No high-quality signals found for automated campaigns")
|
|
306
357
|
|
|
307
358
|
elif args.command == 'illusion':
|
|
308
359
|
run_standalone_illusion_detection(args.instrument, args.timeframes)
|
|
@@ -244,11 +244,17 @@ def fxmvstop(tradeid,stop,flag_pips=False, demo=False,args=None):
|
|
|
244
244
|
#@STCIssue pass the error code to the caller context. ex. fxmvstop is ran directly from the CLI, the error code should be passed by exiting the process with the error code, else if used by fxmvstopgator, the error code should be passed to the caller context in a raised exception.
|
|
245
245
|
#look at the args command to guess the context
|
|
246
246
|
|
|
247
|
-
def ids(instrument, timeframe,use_full=False,use_fresh=True):
|
|
247
|
+
def ids(instrument, timeframe, use_full=False, use_fresh=True):
|
|
248
248
|
"""Refresh the IDS data (indicator Data Service)."""
|
|
249
|
-
use_fresh_arg = '
|
|
250
|
-
use_full_arg = '
|
|
251
|
-
subprocess.run([
|
|
249
|
+
use_fresh_arg = '--fresh' if use_fresh else '-old'
|
|
250
|
+
use_full_arg = '-uf' if use_full else '-nf'
|
|
251
|
+
subprocess.run([
|
|
252
|
+
IDSCLI_PROG_NAME,
|
|
253
|
+
'-i', instrument,
|
|
254
|
+
'-t', timeframe,
|
|
255
|
+
use_full_arg,
|
|
256
|
+
use_fresh_arg,
|
|
257
|
+
], check=True)
|
|
252
258
|
|
|
253
259
|
"""
|
|
254
260
|
fxmvstopgator -tid 68773276 --demo -i AUD/NZD -t H4 --lips
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
JGT Trading System Orchestrator
|
|
5
|
+
|
|
6
|
+
This module orchestrates the complete JGT trading system using the jgtcore timeframe library
|
|
7
|
+
for proper separation between CLI utilities and core logic. It provides both real-time
|
|
8
|
+
scheduling and simulation modes for testing.
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
# Real-time mode
|
|
12
|
+
python trading_orchestrator.py --timeframe H4 --instruments EUR-USD,GBP-USD --demo
|
|
13
|
+
|
|
14
|
+
# Test mode (simulation)
|
|
15
|
+
python trading_orchestrator.py --timeframe H4 --instruments EUR-USD,GBP-USD --demo --test-mode
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
import argparse
|
|
19
|
+
import sys
|
|
20
|
+
import time
|
|
21
|
+
import subprocess
|
|
22
|
+
from typing import List, Optional
|
|
23
|
+
import os
|
|
24
|
+
|
|
25
|
+
# Import jgtcore for timeframe logic
|
|
26
|
+
try:
|
|
27
|
+
import jgtcore
|
|
28
|
+
except ImportError:
|
|
29
|
+
# Add jgtcore to path if not installed
|
|
30
|
+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', 'jgtcore'))
|
|
31
|
+
import jgtcore
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class TradingOrchestrator:
|
|
35
|
+
"""Main trading system orchestrator using jgtcore timeframe library."""
|
|
36
|
+
|
|
37
|
+
def __init__(self, timeframe: str, instruments: List[str],
|
|
38
|
+
quality_threshold: float = 8.0, demo: bool = True, test_mode: bool = False):
|
|
39
|
+
self.timeframe = timeframe
|
|
40
|
+
self.instruments = instruments
|
|
41
|
+
self.quality_threshold = quality_threshold
|
|
42
|
+
self.demo = demo
|
|
43
|
+
self.test_mode = test_mode
|
|
44
|
+
|
|
45
|
+
# Initialize timeframe checker using jgtcore
|
|
46
|
+
self.timeframe_checker = jgtcore.TimeframeChecker(timeframe)
|
|
47
|
+
|
|
48
|
+
print(f"🚀 JGT Trading Orchestrator Initialized")
|
|
49
|
+
print(f"📊 Timeframe: {timeframe} | Instruments: {','.join(instruments)}")
|
|
50
|
+
print(f"🎯 Quality Threshold: {quality_threshold} | Demo: {demo}")
|
|
51
|
+
if test_mode:
|
|
52
|
+
print("⚡ TEST MODE ENABLED - Using simulation")
|
|
53
|
+
|
|
54
|
+
def run_enhanced_trading_analysis(self) -> bool:
|
|
55
|
+
"""Run enhanced trading CLI analysis."""
|
|
56
|
+
try:
|
|
57
|
+
instruments_str = ','.join(self.instruments)
|
|
58
|
+
mode_flag = '--demo' if self.demo else '--real'
|
|
59
|
+
|
|
60
|
+
cmd = [
|
|
61
|
+
'enhancedtradingcli', 'auto',
|
|
62
|
+
'-i', instruments_str,
|
|
63
|
+
mode_flag,
|
|
64
|
+
'--quality-threshold', str(self.quality_threshold)
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
print(f"🔍 Running Enhanced Trading Analysis: {' '.join(cmd)}")
|
|
68
|
+
result = subprocess.run(cmd, capture_output=True, text=True)
|
|
69
|
+
|
|
70
|
+
if result.returncode == 0:
|
|
71
|
+
print("✅ Enhanced trading analysis completed successfully")
|
|
72
|
+
if result.stdout:
|
|
73
|
+
print(f"📋 Output: {result.stdout.strip()}")
|
|
74
|
+
return True
|
|
75
|
+
else:
|
|
76
|
+
print(f"❌ Enhanced trading analysis failed: {result.stderr}")
|
|
77
|
+
return False
|
|
78
|
+
|
|
79
|
+
except Exception as e:
|
|
80
|
+
print(f"❌ Error running enhanced trading analysis: {e}")
|
|
81
|
+
return False
|
|
82
|
+
|
|
83
|
+
def generate_analysis_charts(self) -> bool:
|
|
84
|
+
"""Generate analysis charts for all instruments."""
|
|
85
|
+
success_count = 0
|
|
86
|
+
|
|
87
|
+
for instrument in self.instruments:
|
|
88
|
+
try:
|
|
89
|
+
print(f"📈 Generating chart for {instrument} {self.timeframe}")
|
|
90
|
+
|
|
91
|
+
cmd = [
|
|
92
|
+
'jgtads', '-i', instrument, '-t', self.timeframe,
|
|
93
|
+
'--save_figure', 'charts/',
|
|
94
|
+
'--save_figure_as_timeframe'
|
|
95
|
+
]
|
|
96
|
+
|
|
97
|
+
result = subprocess.run(cmd, capture_output=True, text=True)
|
|
98
|
+
|
|
99
|
+
if result.returncode == 0:
|
|
100
|
+
print(f"✅ Chart generated for {instrument}")
|
|
101
|
+
success_count += 1
|
|
102
|
+
else:
|
|
103
|
+
print(f"⚠️ Chart generation failed for {instrument}: {result.stderr}")
|
|
104
|
+
|
|
105
|
+
except Exception as e:
|
|
106
|
+
print(f"❌ Error generating chart for {instrument}: {e}")
|
|
107
|
+
|
|
108
|
+
return success_count > 0
|
|
109
|
+
|
|
110
|
+
def update_trailing_stops(self) -> bool:
|
|
111
|
+
"""Update trailing stops for active trades."""
|
|
112
|
+
try:
|
|
113
|
+
mode_flag = '--demo' if self.demo else '--real'
|
|
114
|
+
|
|
115
|
+
# Refresh trade data
|
|
116
|
+
cmd_refresh = ['jgtapp', 'fxtr', mode_flag]
|
|
117
|
+
print("🔄 Refreshing trade data...")
|
|
118
|
+
|
|
119
|
+
result = subprocess.run(cmd_refresh, capture_output=True, text=True)
|
|
120
|
+
if result.returncode != 0:
|
|
121
|
+
print("⚠️ No active trades found or trade data unavailable")
|
|
122
|
+
return False
|
|
123
|
+
|
|
124
|
+
print("✅ Trade data refreshed")
|
|
125
|
+
|
|
126
|
+
# Update FDB-based trailing stops with Alligator fallback
|
|
127
|
+
print("🐊 Updating FDB-based trailing stops with Alligator fallback...")
|
|
128
|
+
cmd_stops = ['jgtapp', 'fxmvstopfdb', '-t', self.timeframe, '--lips', mode_flag]
|
|
129
|
+
|
|
130
|
+
result = subprocess.run(cmd_stops, capture_output=True, text=True)
|
|
131
|
+
if result.returncode == 0:
|
|
132
|
+
print("✅ FDB trailing stops updated")
|
|
133
|
+
return True
|
|
134
|
+
else:
|
|
135
|
+
print(f"⚠️ FDB trailing stops update failed: {result.stderr}")
|
|
136
|
+
return False
|
|
137
|
+
|
|
138
|
+
except Exception as e:
|
|
139
|
+
print(f"❌ Error updating trailing stops: {e}")
|
|
140
|
+
return False
|
|
141
|
+
|
|
142
|
+
def quick_monitoring_update(self) -> bool:
|
|
143
|
+
"""Quick chart update for monitoring."""
|
|
144
|
+
try:
|
|
145
|
+
primary_instrument = self.instruments[0] if self.instruments else "EUR-USD"
|
|
146
|
+
|
|
147
|
+
cmd = [
|
|
148
|
+
'jgtads', '-i', primary_instrument, '-t', 'm5',
|
|
149
|
+
'--save_figure', 'charts/', '-tf'
|
|
150
|
+
]
|
|
151
|
+
|
|
152
|
+
print(f"📈 Quick monitoring chart update for {primary_instrument}")
|
|
153
|
+
result = subprocess.run(cmd, capture_output=True, text=True)
|
|
154
|
+
|
|
155
|
+
if result.returncode == 0:
|
|
156
|
+
print("✅ Monitoring chart updated")
|
|
157
|
+
return True
|
|
158
|
+
else:
|
|
159
|
+
print(f"⚠️ Monitoring chart update failed: {result.stderr}")
|
|
160
|
+
return False
|
|
161
|
+
|
|
162
|
+
except Exception as e:
|
|
163
|
+
print(f"❌ Error updating monitoring chart: {e}")
|
|
164
|
+
return False
|
|
165
|
+
|
|
166
|
+
def rapid_trade_status_check(self) -> bool:
|
|
167
|
+
"""Ultra-quick trade status check."""
|
|
168
|
+
try:
|
|
169
|
+
mode_flag = '--demo' if self.demo else '--real'
|
|
170
|
+
cmd = ['jgtapp', 'fxtr', mode_flag, '--nosave']
|
|
171
|
+
|
|
172
|
+
print("⚡ Rapid trade status check...")
|
|
173
|
+
result = subprocess.run(cmd, capture_output=True, text=True)
|
|
174
|
+
|
|
175
|
+
if result.returncode == 0:
|
|
176
|
+
print("✅ Trade status checked")
|
|
177
|
+
return True
|
|
178
|
+
else:
|
|
179
|
+
print("⚠️ Trade status check failed")
|
|
180
|
+
return False
|
|
181
|
+
|
|
182
|
+
except Exception as e:
|
|
183
|
+
print(f"❌ Error checking trade status: {e}")
|
|
184
|
+
return False
|
|
185
|
+
|
|
186
|
+
def process_timeframe_trigger(self) -> bool:
|
|
187
|
+
"""Process actions when timeframe is triggered."""
|
|
188
|
+
print(f"🎯 Processing {self.timeframe} timeframe trigger...")
|
|
189
|
+
|
|
190
|
+
if self.timeframe in ["H4", "H1", "D1"]:
|
|
191
|
+
print("📈 PRIMARY MARKET ANALYSIS MODE")
|
|
192
|
+
|
|
193
|
+
# Step 1: Enhanced trading analysis
|
|
194
|
+
if not self.run_enhanced_trading_analysis():
|
|
195
|
+
return False
|
|
196
|
+
|
|
197
|
+
# Step 2: Generate analysis charts
|
|
198
|
+
if not self.generate_analysis_charts():
|
|
199
|
+
print("⚠️ Chart generation had issues but continuing...")
|
|
200
|
+
|
|
201
|
+
return True
|
|
202
|
+
|
|
203
|
+
elif self.timeframe in ["m15", "m5"]:
|
|
204
|
+
print("🎯 TRADE MANAGEMENT MODE")
|
|
205
|
+
|
|
206
|
+
# Update trailing stops
|
|
207
|
+
self.update_trailing_stops()
|
|
208
|
+
|
|
209
|
+
# Quick monitoring if m5
|
|
210
|
+
if self.timeframe == "m5":
|
|
211
|
+
self.quick_monitoring_update()
|
|
212
|
+
|
|
213
|
+
return True
|
|
214
|
+
|
|
215
|
+
elif self.timeframe == "m1":
|
|
216
|
+
print("⚡ RAPID MONITORING MODE")
|
|
217
|
+
|
|
218
|
+
# Ultra-quick status check
|
|
219
|
+
return self.rapid_trade_status_check()
|
|
220
|
+
|
|
221
|
+
else:
|
|
222
|
+
print(f"❌ Unsupported timeframe: {self.timeframe}")
|
|
223
|
+
return False
|
|
224
|
+
|
|
225
|
+
def run_single_cycle(self) -> bool:
|
|
226
|
+
"""Run a single trading cycle (for testing)."""
|
|
227
|
+
if self.test_mode:
|
|
228
|
+
print(f"🔄 SIMULATION: {self.timeframe} timeframe reached")
|
|
229
|
+
time.sleep(1) # Small delay for realism
|
|
230
|
+
return self.process_timeframe_trigger()
|
|
231
|
+
else:
|
|
232
|
+
# Check if timeframe should trigger now
|
|
233
|
+
if self.timeframe_checker.check_now():
|
|
234
|
+
return self.process_timeframe_trigger()
|
|
235
|
+
else:
|
|
236
|
+
return False
|
|
237
|
+
|
|
238
|
+
def run_continuous(self, max_cycles: Optional[int] = None) -> None:
|
|
239
|
+
"""Run continuous trading orchestration."""
|
|
240
|
+
cycle_count = 0
|
|
241
|
+
|
|
242
|
+
if self.test_mode:
|
|
243
|
+
# In test mode, just run once or a few cycles
|
|
244
|
+
max_cycles = max_cycles or 1
|
|
245
|
+
print(f"🧪 Test mode: Running {max_cycles} cycle(s)")
|
|
246
|
+
|
|
247
|
+
for i in range(max_cycles):
|
|
248
|
+
print(f"\n--- Test Cycle {i+1}/{max_cycles} ---")
|
|
249
|
+
self.run_single_cycle()
|
|
250
|
+
if i < max_cycles - 1:
|
|
251
|
+
time.sleep(2) # Short delay between test cycles
|
|
252
|
+
|
|
253
|
+
print("🎯 Test cycles completed")
|
|
254
|
+
return
|
|
255
|
+
|
|
256
|
+
# Real-time mode
|
|
257
|
+
print(f"🔄 Starting continuous monitoring for {self.timeframe} timeframe...")
|
|
258
|
+
|
|
259
|
+
# Show next trigger time
|
|
260
|
+
next_seconds = self.timeframe_checker.seconds_until_next_trigger()
|
|
261
|
+
if next_seconds:
|
|
262
|
+
minutes = next_seconds // 60
|
|
263
|
+
seconds = next_seconds % 60
|
|
264
|
+
print(f"⏰ Next {self.timeframe} trigger in: {minutes}m {seconds}s")
|
|
265
|
+
|
|
266
|
+
try:
|
|
267
|
+
while True:
|
|
268
|
+
if self.run_single_cycle():
|
|
269
|
+
cycle_count += 1
|
|
270
|
+
print(f"✅ Cycle {cycle_count} completed")
|
|
271
|
+
|
|
272
|
+
if max_cycles and cycle_count >= max_cycles:
|
|
273
|
+
print(f"🏁 Reached maximum cycles ({max_cycles})")
|
|
274
|
+
break
|
|
275
|
+
|
|
276
|
+
# Sleep appropriate amount for timeframe
|
|
277
|
+
if self.timeframe == "m1":
|
|
278
|
+
time.sleep(2)
|
|
279
|
+
elif self.timeframe in ["m5", "m15"]:
|
|
280
|
+
time.sleep(30)
|
|
281
|
+
else:
|
|
282
|
+
time.sleep(60)
|
|
283
|
+
|
|
284
|
+
except KeyboardInterrupt:
|
|
285
|
+
print("\n🛑 Trading orchestrator stopped by user")
|
|
286
|
+
except Exception as e:
|
|
287
|
+
print(f"\n❌ Trading orchestrator error: {e}")
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def main():
|
|
291
|
+
"""Main entry point."""
|
|
292
|
+
parser = argparse.ArgumentParser(
|
|
293
|
+
description="JGT Trading System Orchestrator",
|
|
294
|
+
epilog="Example: python trading_orchestrator.py --timeframe H4 --instruments EUR-USD,GBP-USD --demo --test-mode"
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
parser.add_argument(
|
|
298
|
+
'--timeframe', '-t',
|
|
299
|
+
default='H4',
|
|
300
|
+
help='Trading timeframe (m1, m5, m15, H1, H4, D1)'
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
parser.add_argument(
|
|
304
|
+
'--instruments', '-i',
|
|
305
|
+
default='EUR-USD,GBP-USD,XAU-USD',
|
|
306
|
+
help='Comma-separated list of instruments'
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
parser.add_argument(
|
|
310
|
+
'--quality-threshold', '-q',
|
|
311
|
+
type=float, default=8.0,
|
|
312
|
+
help='Quality threshold for trading signals'
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
parser.add_argument(
|
|
316
|
+
'--demo', action='store_true', default=True,
|
|
317
|
+
help='Use demo account (default: True)'
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
parser.add_argument(
|
|
321
|
+
'--real', action='store_true',
|
|
322
|
+
help='Use real account (overrides --demo)'
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
parser.add_argument(
|
|
326
|
+
'--test-mode', action='store_true',
|
|
327
|
+
help='Enable test mode (simulation without real timeframe waiting)'
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
parser.add_argument(
|
|
331
|
+
'--max-cycles', type=int,
|
|
332
|
+
help='Maximum number of cycles to run (useful for testing)'
|
|
333
|
+
)
|
|
334
|
+
|
|
335
|
+
args = parser.parse_args()
|
|
336
|
+
|
|
337
|
+
# Parse instruments
|
|
338
|
+
instruments = [inst.strip() for inst in args.instruments.split(',')]
|
|
339
|
+
|
|
340
|
+
# Determine demo mode
|
|
341
|
+
demo_mode = not args.real # Default to demo unless --real is specified
|
|
342
|
+
|
|
343
|
+
# Create and run orchestrator
|
|
344
|
+
orchestrator = TradingOrchestrator(
|
|
345
|
+
timeframe=args.timeframe,
|
|
346
|
+
instruments=instruments,
|
|
347
|
+
quality_threshold=args.quality_threshold,
|
|
348
|
+
demo=demo_mode,
|
|
349
|
+
test_mode=args.test_mode
|
|
350
|
+
)
|
|
351
|
+
|
|
352
|
+
if args.test_mode or args.max_cycles:
|
|
353
|
+
orchestrator.run_continuous(max_cycles=args.max_cycles)
|
|
354
|
+
else:
|
|
355
|
+
orchestrator.run_continuous()
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
if __name__ == "__main__":
|
|
359
|
+
main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|