Files
2026-06-17 17:12:19 -04:00

141 lines
4.8 KiB
Python

"""Raw 5-minute OHLCV loading and cleaning."""
import numpy as np
import pandas as pd
class GoldDataProcessor:
"""
Data processor for 5-minute gold price data.
Handles data loading, cleaning, and preprocessing.
"""
def __init__(self, fill_gaps=True, remove_outliers=True, handle_after_hours=True):
self.fill_gaps = fill_gaps
self.remove_outliers = remove_outliers
self.handle_after_hours = handle_after_hours
def load_data(self, file_path):
"""
Load data from CSV file and set appropriate index
"""
# Load data from CSV
data = pd.read_csv(file_path)
# Ensure timestamp column exists
if 'timestamp' not in data.columns:
raise ValueError("CSV must contain a 'timestamp' column")
# Convert timestamp to datetime and set as index
data['timestamp'] = pd.to_datetime(data['timestamp'])
data = data.drop_duplicates(subset=['timestamp'])
data.set_index('timestamp', inplace=True)
# Ensure all necessary columns exist
required_columns = ['open', 'high', 'low', 'close', 'volume']
missing_columns = [col for col in required_columns if col not in data.columns]
if missing_columns:
raise ValueError(f"Missing required columns: {missing_columns}")
# Make column names lowercase if they aren't already
data.columns = [col.lower() for col in data.columns]
return self._preprocess_data(data)
def _preprocess_data(self, data):
"""
Apply preprocessing steps to clean and prepare the data
"""
# Sort data by timestamp to ensure chronological order
data = data.sort_index()
# Fill gaps in 5-minute data
if self.fill_gaps:
data = self._fill_time_gaps(data)
# Remove outliers
if self.remove_outliers:
data = self._remove_price_outliers(data)
# Handle after-hours and weekend data
if self.handle_after_hours:
data = self._handle_after_hours_data(data)
return data
def _fill_time_gaps(self, data):
"""
Fill gaps in 5-minute data by reindexing with complete 5-minute intervals
during trading hours
"""
# Create complete 5-minute intervals
start_date = data.index.min()
end_date = data.index.max()
full_range = pd.date_range(start=start_date, end=end_date, freq='5min')
# Reindex the data
reindexed_data = data.reindex(full_range)
# Forward fill price data (OHLC)
for col in ['open', 'high', 'low', 'close']:
reindexed_data[col] = reindexed_data[col].ffill()
# Fill volume with zeros
reindexed_data['volume'] = reindexed_data['volume'].fillna(0)
return reindexed_data
def _remove_price_outliers(self, data, z_threshold=10):
"""
Remove extreme price outliers based on z-score of returns
"""
# Calculate returns
returns = data['close'].pct_change()
# Calculate rolling z-score (20 periods ~ 100 minutes)
rolling_mean = returns.rolling(window=20).mean()
rolling_std = returns.rolling(window=20).std()
z_scores = (returns - rolling_mean) / rolling_std
# Identify outliers
outliers = abs(z_scores) > z_threshold
if outliers.sum() > 0:
print(f"Identified {outliers.sum()} outliers out of {len(data)} records")
# Replace outlier prices with interpolated values
clean_data = data.copy()
outlier_indices = outliers[outliers].index
for col in ['open', 'high', 'low', 'close']:
clean_data.loc[outlier_indices, col] = np.nan
clean_data[col] = clean_data[col].interpolate(method='linear')
return clean_data
return data
def _handle_after_hours_data(self, data):
"""
Handle after-hours and weekend data in gold trading
"""
# Create day of week and hour features
data['day_of_week'] = data.index.dayofweek
data['hour'] = data.index.hour
# Filter out weekends (Saturday and Sunday)
# For gold, market typically closes Friday ~5PM ET and opens Sunday ~6PM ET
weekend_mask = (data['day_of_week'] == 5) & (data['hour'] >= 17) # After Friday 5PM
weekend_mask |= (data['day_of_week'] == 6) # All of Saturday
weekend_mask |= (data['day_of_week'] == 0) & (data['hour'] < 18) # Before Sunday 6PM
# Mark weekend data
data['is_weekend'] = weekend_mask
# Forward fill prices for weekend gaps
# We don't remove weekend data to maintain continuity
# but we mark it so we can filter it later if needed
# Remove temporary columns if needed
data = data.drop(['day_of_week', 'hour'], axis=1)
return data