algorembrant commited on
Commit
6043bea
·
verified ·
1 Parent(s): 0c2dea8

Upload 4 files

Browse files
.gitattributes CHANGED
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ no-HH-LL/market_representation_M3_high_res.png filter=lfs diff=lfs merge=lfs -text
37
+ with-HH-LL/market_representation_M3_high_res.png filter=lfs diff=lfs merge=lfs -text
no-HH-LL/market_representation_M3_high_res.png ADDED

Git LFS Details

  • SHA256: e4cad76d47dc903effe0d530c827b4564113b929fffa72e5ad0dc07015dc7d37
  • Pointer size: 133 Bytes
  • Size of remote file: 10.3 MB
no-HH-LL/no_highest-high_no_lowest-low.py ADDED
@@ -0,0 +1,203 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # !pip install pandas numpy matplotlib
2
+
3
+ import pandas as pd
4
+ import numpy as np
5
+ import matplotlib.pyplot as plt
6
+ from matplotlib.collections import LineCollection, PolyCollection
7
+ import time
8
+
9
+ class MarketRepresentation:
10
+ def __init__(self, gap, premarket, daytime, nighttime):
11
+ self.current_time_gap = gap
12
+ self.current_premarket_session = premarket
13
+ self.current_daytime_session = daytime
14
+ self.current_nighttime_session = nighttime
15
+
16
+ def to_dataframe(self):
17
+ """Reconstruct the active time session."""
18
+ return pd.concat([
19
+ self.current_premarket_session,
20
+ self.current_daytime_session,
21
+ self.current_nighttime_session
22
+ ])
23
+
24
+ def run_market_representation_pipeline(csv_path):
25
+ print("="*55)
26
+ print("1. LOADING DATA")
27
+ print("="*55)
28
+ start_time = time.time()
29
+
30
+ df = pd.read_csv(csv_path)
31
+ # Optimized datetime parsing
32
+ df['datetime'] = pd.to_datetime(df['datetime'], format='%Y-%m-%d %H:%M:%S')
33
+ df = df.sort_values('datetime').reset_index(drop=True)
34
+
35
+ print(f"[✔] Data loaded in {time.time() - start_time:.2f} seconds.")
36
+ print(f"[i] Total records: {len(df):,}")
37
+
38
+ print("\n" + "="*55)
39
+ print("2. EXTRACTING COMPLETE DAILY REPRESENTATIONS")
40
+ print("="*55)
41
+ extract_start = time.time()
42
+
43
+ # 45 mins threshold robustly captures the standard 1-hour daily break and 48-hour weekend gap
44
+ gap_threshold = pd.Timedelta(minutes=45)
45
+
46
+ df['time_diff'] = df['datetime'].diff()
47
+ is_gap = df['time_diff'] > gap_threshold
48
+ df['session_id'] = is_gap.cumsum()
49
+
50
+ representations = []
51
+
52
+ grouped = df.groupby('session_id')
53
+ for sid, group in grouped:
54
+ # 1. current_time_gap
55
+ current_time_gap = group['time_diff'].iloc[0] if sid > 0 else pd.Timedelta(seconds=0)
56
+
57
+ # Determine reference date for 0:00 UTC
58
+ zero_hour_rows = group[group['datetime'].dt.hour == 0]
59
+ if len(zero_hour_rows) > 0:
60
+ ref_date = zero_hour_rows['datetime'].dt.floor('D').iloc[0]
61
+ else:
62
+ # Fallback for sessions that skip exactly 0:00 but span across it
63
+ ref_date = group['datetime'].iloc[len(group)//2].floor('D')
64
+
65
+ group = group.copy()
66
+
67
+ # Relative time in hours (0:00 UTC is exactly 0.0)
68
+ group['rel_time_hours'] = (group['datetime'] - ref_date).dt.total_seconds() / 3600.0
69
+
70
+ # Align all candle_open at 0:00 UTC to Y=0
71
+ idx_closest_to_zero = group['rel_time_hours'].abs().idxmin()
72
+ ref_price = group.loc[idx_closest_to_zero, 'open']
73
+
74
+ group['open'] -= ref_price
75
+ group['high'] -= ref_price
76
+ group['low'] -= ref_price
77
+ group['close'] -= ref_price
78
+
79
+ # Slicing sessions based on precise UTC constraints
80
+ # 2. current_premarket_session
81
+ current_premarket_session = group[group['rel_time_hours'] < 0.0]
82
+ # 3. current_daytime_session
83
+ current_daytime_session = group[(group['rel_time_hours'] >= 0.0) & (group['rel_time_hours'] < 12.0)]
84
+ # 4. current_nighttime_session
85
+ current_nighttime_session = group[group['rel_time_hours'] >= 12.0]
86
+
87
+ # Keep only structurally complete representations
88
+ if not current_premarket_session.empty and not current_daytime_session.empty and not current_nighttime_session.empty:
89
+ rep = MarketRepresentation(
90
+ current_time_gap,
91
+ current_premarket_session,
92
+ current_daytime_session,
93
+ current_nighttime_session
94
+ )
95
+ representations.append(rep)
96
+
97
+ print(f"[✔] Extraction complete in {time.time() - extract_start:.2f} seconds.")
98
+ print(f"[i] Found {len(representations):,} complete daily market representations.")
99
+
100
+ if len(representations) == 0:
101
+ print("[!] No complete sessions found. Exiting.")
102
+ return
103
+
104
+ print("\n" + "="*55)
105
+ print("3. GENERATING VECTORIZED OVERLAY PLOT")
106
+ print("="*55)
107
+ plot_start = time.time()
108
+
109
+ # Fast merge of validated data structures
110
+ valid_sessions_dfs = [rep.to_dataframe() for rep in representations]
111
+ df_aligned = pd.concat(valid_sessions_dfs, ignore_index=True)
112
+
113
+ up = df_aligned['close'] >= df_aligned['open']
114
+ down = ~up
115
+
116
+ # Render width parameters UPDATED FOR M3 (3 minutes)
117
+ width = (3.0 / 60.0) * 0.8 # 80% width of a 3-minute period mapped in hours
118
+ w = width / 2
119
+
120
+ x = df_aligned['rel_time_hours'].values
121
+ o = df_aligned['open'].values
122
+ c = df_aligned['close'].values
123
+ h = df_aligned['high'].values
124
+ l = df_aligned['low'].values
125
+
126
+ x_up, o_up, c_up, h_up, l_up = x[up], o[up], c[up], h[up], l[up]
127
+ x_down, o_down, c_down, h_down, l_down = x[down], o[down], c[down], h[down], l[down]
128
+
129
+ # Memory-efficient vectorized polygon coordinate mapping
130
+ wicks_up = np.empty((len(x_up), 2, 2))
131
+ wicks_up[:, 0, 0] = x_up; wicks_up[:, 0, 1] = l_up
132
+ wicks_up[:, 1, 0] = x_up; wicks_up[:, 1, 1] = h_up
133
+
134
+ wicks_down = np.empty((len(x_down), 2, 2))
135
+ wicks_down[:, 0, 0] = x_down; wicks_down[:, 0, 1] = l_down
136
+ wicks_down[:, 1, 0] = x_down; wicks_down[:, 1, 1] = h_down
137
+
138
+ boxes_up = np.empty((len(x_up), 4, 2))
139
+ boxes_up[:, 0, 0] = x_up - w; boxes_up[:, 0, 1] = o_up
140
+ boxes_up[:, 1, 0] = x_up + w; boxes_up[:, 1, 1] = o_up
141
+ boxes_up[:, 2, 0] = x_up + w; boxes_up[:, 2, 1] = c_up
142
+ boxes_up[:, 3, 0] = x_up - w; boxes_up[:, 3, 1] = c_up
143
+
144
+ boxes_down = np.empty((len(x_down), 4, 2))
145
+ boxes_down[:, 0, 0] = x_down - w; boxes_down[:, 0, 1] = o_down
146
+ boxes_down[:, 1, 0] = x_down + w; boxes_down[:, 1, 1] = o_down
147
+ boxes_down[:, 2, 0] = x_down + w; boxes_down[:, 2, 1] = c_down
148
+ boxes_down[:, 3, 0] = x_down - w; boxes_down[:, 3, 1] = c_down
149
+
150
+ # White-themed rendering (Massive Canvas for 1200 DPI Detail)
151
+ plt.style.use('default')
152
+ fig, ax = plt.subplots(figsize=(30, 15), facecolor='white')
153
+ ax.set_facecolor('white')
154
+
155
+ up_color = '#26a69a'
156
+ down_color = '#ef5350'
157
+ alpha_val = 0.1 # Exactly 10% opacity
158
+
159
+ # Hardware-accelerated GPU/CPU rendering using Collections
160
+ lc_up = LineCollection(wicks_up, colors=up_color, linewidths=0.5, alpha=alpha_val)
161
+ lc_down = LineCollection(wicks_down, colors=down_color, linewidths=0.5, alpha=alpha_val)
162
+ pc_up = PolyCollection(boxes_up, facecolors=up_color, edgecolors='none', alpha=alpha_val)
163
+ pc_down = PolyCollection(boxes_down, facecolors=down_color, edgecolors='none', alpha=alpha_val)
164
+
165
+ ax.add_collection(lc_up)
166
+ ax.add_collection(lc_down)
167
+ ax.add_collection(pc_up)
168
+ ax.add_collection(pc_down)
169
+
170
+ ax.autoscale_view()
171
+
172
+ # Annotations & Formatting
173
+ ax.set_title("Complete Daily Market Representation Overlay (M3 Timeframe)\nAligned at 0:00 UTC", fontsize=20, fontweight='bold', pad=15)
174
+ ax.set_xlabel("Hours Relative to 0:00 UTC", fontsize=16, labelpad=10)
175
+ ax.set_ylabel("Price Deviation from 0:00 UTC Open", fontsize=16, labelpad=10)
176
+
177
+ min_x, max_x = ax.get_xlim()
178
+ ax.set_xticks(np.arange(np.floor(min_x), np.ceil(max_x)+1, 2))
179
+
180
+ # Segment shading
181
+ ax.axvspan(min_x, 0, color='#e3f2fd', alpha=0.3, label='Premarket (< 0:00)')
182
+ ax.axvspan(0, 12, color='#fff3e0', alpha=0.3, label='Daytime (0:00 - 12:00)')
183
+ ax.axvspan(12, max_x, color='#f3e5f5', alpha=0.3, label='Nighttime (> 12:00)')
184
+
185
+ ax.grid(True, linestyle='--', alpha=0.5)
186
+ ax.axvline(0, color='black', linestyle='-', linewidth=2.0, alpha=0.8, label='0:00 UTC Alignment')
187
+ ax.axhline(0, color='black', linestyle='-', linewidth=2.0, alpha=0.8)
188
+
189
+ ax.legend(loc='upper left', fontsize=14)
190
+ plt.tight_layout()
191
+
192
+ # High Resolution Export Setup
193
+ export_path = 'market_representation_M3_high_res.png'
194
+ print(f"[✔] Exporting Extreme-Res image (1200 DPI) to {export_path}...")
195
+ plt.savefig(export_path, dpi=1200, bbox_inches='tight')
196
+ print(f"[✔] Plot generated and saved in {time.time() - plot_start:.2f} seconds.")
197
+ print("="*55)
198
+ plt.show()
199
+
200
+ # Execution Call
201
+ # Upload your M3 file to Colab and update the path accordingly.
202
+ csv_path = '/content/XAUUSDc_M3_2014-01-14_to_2026-04-29_1060828records_88092KB.csv'
203
+ run_market_representation_pipeline(csv_path)
with-HH-LL/market_representation_M3_high_res.png ADDED

Git LFS Details

  • SHA256: c2dfb25c9de4afc16a2040f103e756eeeb106aee200f301e30e5deb5bc67616f
  • Pointer size: 133 Bytes
  • Size of remote file: 22.5 MB
with-HH-LL/wtih_highest-high_no_lowest-low.py ADDED
@@ -0,0 +1,241 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # !pip install pandas numpy matplotlib
2
+
3
+ import pandas as pd
4
+ import numpy as np
5
+ import matplotlib.pyplot as plt
6
+ from matplotlib.collections import LineCollection, PolyCollection
7
+ import time
8
+
9
+ class MarketRepresentation:
10
+ def __init__(self, gap, premarket, daytime, nighttime, extremes=None):
11
+ self.current_time_gap = gap
12
+ self.current_premarket_session = premarket
13
+ self.current_daytime_session = daytime
14
+ self.current_nighttime_session = nighttime
15
+ self.extremes = extremes
16
+
17
+ def to_dataframe(self):
18
+ """Reconstruct the active time session."""
19
+ return pd.concat([
20
+ self.current_premarket_session,
21
+ self.current_daytime_session,
22
+ self.current_nighttime_session
23
+ ])
24
+
25
+ def run_market_representation_pipeline(csv_path):
26
+ print("="*55)
27
+ print("1. LOADING DATA")
28
+ print("="*55)
29
+ start_time = time.time()
30
+
31
+ df = pd.read_csv(csv_path)
32
+ # Optimized datetime parsing
33
+ df['datetime'] = pd.to_datetime(df['datetime'], format='%Y-%m-%d %H:%M:%S')
34
+ df = df.sort_values('datetime').reset_index(drop=True)
35
+
36
+ print(f"[✔] Data loaded in {time.time() - start_time:.2f} seconds.")
37
+ print(f"[i] Total records: {len(df):,}")
38
+
39
+ print("\n" + "="*55)
40
+ print("2. EXTRACTING COMPLETE DAILY REPRESENTATIONS")
41
+ print("="*55)
42
+ extract_start = time.time()
43
+
44
+ # 45 mins threshold robustly captures the standard 1-hour daily break and 48-hour weekend gap
45
+ gap_threshold = pd.Timedelta(minutes=45)
46
+
47
+ df['time_diff'] = df['datetime'].diff()
48
+ is_gap = df['time_diff'] > gap_threshold
49
+ df['session_id'] = is_gap.cumsum()
50
+
51
+ representations = []
52
+
53
+ grouped = df.groupby('session_id')
54
+ for sid, group in grouped:
55
+ # 1. current_time_gap
56
+ current_time_gap = group['time_diff'].iloc[0] if sid > 0 else pd.Timedelta(seconds=0)
57
+
58
+ # Determine reference date for 0:00 UTC
59
+ zero_hour_rows = group[group['datetime'].dt.hour == 0]
60
+ if len(zero_hour_rows) > 0:
61
+ ref_date = zero_hour_rows['datetime'].dt.floor('D').iloc[0]
62
+ else:
63
+ # Fallback for sessions that skip exactly 0:00 but span across it
64
+ ref_date = group['datetime'].iloc[len(group)//2].floor('D')
65
+
66
+ group = group.copy()
67
+
68
+ # Relative time in hours (0:00 UTC is exactly 0.0)
69
+ group['rel_time_hours'] = (group['datetime'] - ref_date).dt.total_seconds() / 3600.0
70
+
71
+ # Align all candle_open at 0:00 UTC to Y=0
72
+ idx_closest_to_zero = group['rel_time_hours'].abs().idxmin()
73
+ ref_price = group.loc[idx_closest_to_zero, 'open']
74
+
75
+ group['open'] -= ref_price
76
+ group['high'] -= ref_price
77
+ group['low'] -= ref_price
78
+ group['close'] -= ref_price
79
+
80
+ # Slicing sessions based on precise UTC constraints
81
+ # 2. current_premarket_session
82
+ current_premarket_session = group[group['rel_time_hours'] < 0.0]
83
+ # 3. current_daytime_session
84
+ current_daytime_session = group[(group['rel_time_hours'] >= 0.0) & (group['rel_time_hours'] < 12.0)]
85
+ # 4. current_nighttime_session
86
+ current_nighttime_session = group[group['rel_time_hours'] >= 12.0]
87
+
88
+ # Keep only structurally complete representations
89
+ if not current_premarket_session.empty and not current_daytime_session.empty and not current_nighttime_session.empty:
90
+
91
+ # Find extreme points
92
+ pre_hh_idx = current_premarket_session['high'].idxmax()
93
+ pre_ll_idx = current_premarket_session['low'].idxmin()
94
+
95
+ day_hh_idx = current_daytime_session['high'].idxmax()
96
+ day_ll_idx = current_daytime_session['low'].idxmin()
97
+
98
+ night_hh_idx = current_nighttime_session['high'].idxmax()
99
+ night_ll_idx = current_nighttime_session['low'].idxmin()
100
+
101
+ extremes = {
102
+ 'pre_hh': (current_premarket_session.loc[pre_hh_idx, 'rel_time_hours'], current_premarket_session.loc[pre_hh_idx, 'high']),
103
+ 'pre_ll': (current_premarket_session.loc[pre_ll_idx, 'rel_time_hours'], current_premarket_session.loc[pre_ll_idx, 'low']),
104
+ 'day_hh': (current_daytime_session.loc[day_hh_idx, 'rel_time_hours'], current_daytime_session.loc[day_hh_idx, 'high']),
105
+ 'day_ll': (current_daytime_session.loc[day_ll_idx, 'rel_time_hours'], current_daytime_session.loc[day_ll_idx, 'low']),
106
+ 'night_hh': (current_nighttime_session.loc[night_hh_idx, 'rel_time_hours'], current_nighttime_session.loc[night_hh_idx, 'high']),
107
+ 'night_ll': (current_nighttime_session.loc[night_ll_idx, 'rel_time_hours'], current_nighttime_session.loc[night_ll_idx, 'low'])
108
+ }
109
+
110
+ rep = MarketRepresentation(
111
+ current_time_gap,
112
+ current_premarket_session,
113
+ current_daytime_session,
114
+ current_nighttime_session,
115
+ extremes
116
+ )
117
+ representations.append(rep)
118
+
119
+ print(f"[✔] Extraction complete in {time.time() - extract_start:.2f} seconds.")
120
+ print(f"[i] Found {len(representations):,} complete daily market representations.")
121
+
122
+ if len(representations) == 0:
123
+ print("[!] No complete sessions found. Exiting.")
124
+ return
125
+
126
+ print("\n" + "="*55)
127
+ print("3. GENERATING VECTORIZED OVERLAY PLOT")
128
+ print("="*55)
129
+ plot_start = time.time()
130
+
131
+ # Fast merge of validated data structures
132
+ valid_sessions_dfs = [rep.to_dataframe() for rep in representations]
133
+ df_aligned = pd.concat(valid_sessions_dfs, ignore_index=True)
134
+
135
+ up = df_aligned['close'] >= df_aligned['open']
136
+ down = ~up
137
+
138
+ # Render width parameters UPDATED FOR M3 (3 minutes)
139
+ width = (3.0 / 60.0) * 0.8 # 80% width of a 3-minute period mapped in hours
140
+ w = width / 2
141
+
142
+ x = df_aligned['rel_time_hours'].values
143
+ o = df_aligned['open'].values
144
+ c = df_aligned['close'].values
145
+ h = df_aligned['high'].values
146
+ l = df_aligned['low'].values
147
+
148
+ x_up, o_up, c_up, h_up, l_up = x[up], o[up], c[up], h[up], l[up]
149
+ x_down, o_down, c_down, h_down, l_down = x[down], o[down], c[down], h[down], l[down]
150
+
151
+ # Memory-efficient vectorized polygon coordinate mapping
152
+ wicks_up = np.empty((len(x_up), 2, 2))
153
+ wicks_up[:, 0, 0] = x_up; wicks_up[:, 0, 1] = l_up
154
+ wicks_up[:, 1, 0] = x_up; wicks_up[:, 1, 1] = h_up
155
+
156
+ wicks_down = np.empty((len(x_down), 2, 2))
157
+ wicks_down[:, 0, 0] = x_down; wicks_down[:, 0, 1] = l_down
158
+ wicks_down[:, 1, 0] = x_down; wicks_down[:, 1, 1] = h_down
159
+
160
+ boxes_up = np.empty((len(x_up), 4, 2))
161
+ boxes_up[:, 0, 0] = x_up - w; boxes_up[:, 0, 1] = o_up
162
+ boxes_up[:, 1, 0] = x_up + w; boxes_up[:, 1, 1] = o_up
163
+ boxes_up[:, 2, 0] = x_up + w; boxes_up[:, 2, 1] = c_up
164
+ boxes_up[:, 3, 0] = x_up - w; boxes_up[:, 3, 1] = c_up
165
+
166
+ boxes_down = np.empty((len(x_down), 4, 2))
167
+ boxes_down[:, 0, 0] = x_down - w; boxes_down[:, 0, 1] = o_down
168
+ boxes_down[:, 1, 0] = x_down + w; boxes_down[:, 1, 1] = o_down
169
+ boxes_down[:, 2, 0] = x_down + w; boxes_down[:, 2, 1] = c_down
170
+ boxes_down[:, 3, 0] = x_down - w; boxes_down[:, 3, 1] = c_down
171
+
172
+ # White-themed rendering (Massive Canvas for 1200 DPI Detail)
173
+ plt.style.use('default')
174
+ fig, ax = plt.subplots(figsize=(30, 15), facecolor='white')
175
+ ax.set_facecolor('white')
176
+
177
+ up_color = '#26a69a'
178
+ down_color = '#ef5350'
179
+ alpha_val = 0.1 # Exactly 10% opacity
180
+
181
+ # Hardware-accelerated GPU/CPU rendering using Collections
182
+ lc_up = LineCollection(wicks_up, colors=up_color, linewidths=0.5, alpha=alpha_val)
183
+ lc_down = LineCollection(wicks_down, colors=down_color, linewidths=0.5, alpha=alpha_val)
184
+ pc_up = PolyCollection(boxes_up, facecolors=up_color, edgecolors='none', alpha=alpha_val)
185
+ pc_down = PolyCollection(boxes_down, facecolors=down_color, edgecolors='none', alpha=alpha_val)
186
+
187
+ ax.add_collection(lc_up)
188
+ ax.add_collection(lc_down)
189
+ ax.add_collection(pc_up)
190
+ ax.add_collection(pc_down)
191
+
192
+ # Plot extreme points
193
+ hh_x, hh_y = [], []
194
+ ll_x, ll_y = [], []
195
+
196
+ for rep in representations:
197
+ if rep.extremes:
198
+ ext = rep.extremes
199
+ hh_x.extend([ext['pre_hh'][0], ext['day_hh'][0], ext['night_hh'][0]])
200
+ hh_y.extend([ext['pre_hh'][1], ext['day_hh'][1], ext['night_hh'][1]])
201
+
202
+ ll_x.extend([ext['pre_ll'][0], ext['day_ll'][0], ext['night_ll'][0]])
203
+ ll_y.extend([ext['pre_ll'][1], ext['day_ll'][1], ext['night_ll'][1]])
204
+
205
+ ax.scatter(hh_x, hh_y, color='blue', s=15, alpha=0.6, label='Highest Highs', zorder=5)
206
+ ax.scatter(ll_x, ll_y, color='red', s=15, alpha=0.6, label='Lowest Lows', zorder=5)
207
+
208
+ ax.autoscale_view()
209
+
210
+ # Annotations & Formatting
211
+ ax.set_title("Complete Daily Market Representation Overlay (M3 Timeframe)\nAligned at 0:00 UTC", fontsize=20, fontweight='bold', pad=15)
212
+ ax.set_xlabel("Hours Relative to 0:00 UTC", fontsize=16, labelpad=10)
213
+ ax.set_ylabel("Price Deviation from 0:00 UTC Open", fontsize=16, labelpad=10)
214
+
215
+ min_x, max_x = ax.get_xlim()
216
+ ax.set_xticks(np.arange(np.floor(min_x), np.ceil(max_x)+1, 2))
217
+
218
+ # Segment shading
219
+ ax.axvspan(min_x, 0, color='#e3f2fd', alpha=0.3, label='Premarket (< 0:00)')
220
+ ax.axvspan(0, 12, color='#fff3e0', alpha=0.3, label='Daytime (0:00 - 12:00)')
221
+ ax.axvspan(12, max_x, color='#f3e5f5', alpha=0.3, label='Nighttime (> 12:00)')
222
+
223
+ ax.grid(True, linestyle='--', alpha=0.5)
224
+ ax.axvline(0, color='black', linestyle='-', linewidth=2.0, alpha=0.8, label='0:00 UTC Alignment')
225
+ ax.axhline(0, color='black', linestyle='-', linewidth=2.0, alpha=0.8)
226
+
227
+ ax.legend(loc='upper left', fontsize=14)
228
+ plt.tight_layout()
229
+
230
+ # High Resolution Export Setup
231
+ export_path = 'market_representation_M3_high_res.png'
232
+ print(f"[✔] Exporting Extreme-Res image (1200 DPI) to {export_path}...")
233
+ plt.savefig(export_path, dpi=1200, bbox_inches='tight')
234
+ print(f"[✔] Plot generated and saved in {time.time() - plot_start:.2f} seconds.")
235
+ print("="*55)
236
+ plt.show()
237
+
238
+ # Execution Call
239
+ # Upload your M3 file to Colab and update the path accordingly.
240
+ csv_path = '/content/XAUUSDc_M3_2014-01-14_to_2026-04-29_1060828records_88092KB.csv'
241
+ run_market_representation_pipeline(csv_path)