RL training in NN working

This commit is contained in:
Dobromir Popov
2025-03-31 11:12:45 +03:00
parent 4eac14022c
commit 0ad9484d56
3 changed files with 449 additions and 167 deletions

View File

@ -303,6 +303,76 @@ class DataInterface:
"""
return len(self.timeframes) * 5 # OHLCV features for each timeframe
def get_features(self, timeframe, n_candles=1000):
"""
Get feature data with technical indicators for a specific timeframe.
Args:
timeframe (str): Timeframe to get features for ('1m', '5m', etc.)
n_candles (int): Number of candles to get
Returns:
np.ndarray: Array of feature data including technical indicators
and the close price as the last column
"""
# Get historical data
df = self.get_historical_data(timeframe=timeframe, n_candles=n_candles)
if df is None or df.empty:
logger.error(f"No data available for {self.symbol} {timeframe}")
return None
# Add technical indicators
df = self.add_technical_indicators(df)
# Drop NaN values that might have been introduced by indicators
df = df.dropna()
# Extract features (all columns except timestamp)
features = df.drop('timestamp', axis=1).values
logger.info(f"Prepared {len(features)} {timeframe} feature rows with {features.shape[1]} features")
return features
def add_technical_indicators(self, df):
"""
Add technical indicators to the dataframe.
Args:
df (pd.DataFrame): DataFrame with OHLCV data
Returns:
pd.DataFrame: DataFrame with added technical indicators
"""
# Make a copy to avoid modifying the original
df_copy = df.copy()
# Basic price indicators
df_copy['returns'] = df_copy['close'].pct_change()
df_copy['log_returns'] = np.log(df_copy['close']/df_copy['close'].shift(1))
# Moving Averages
df_copy['sma_7'] = ta.trend.sma_indicator(df_copy['close'], window=7)
df_copy['sma_25'] = ta.trend.sma_indicator(df_copy['close'], window=25)
df_copy['sma_99'] = ta.trend.sma_indicator(df_copy['close'], window=99)
# MACD
macd = ta.trend.MACD(df_copy['close'])
df_copy['macd'] = macd.macd()
df_copy['macd_signal'] = macd.macd_signal()
df_copy['macd_diff'] = macd.macd_diff()
# RSI
df_copy['rsi'] = ta.momentum.rsi(df_copy['close'], window=14)
# Bollinger Bands
bollinger = ta.volatility.BollingerBands(df_copy['close'])
df_copy['bb_high'] = bollinger.bollinger_hband()
df_copy['bb_low'] = bollinger.bollinger_lband()
df_copy['bb_pct'] = bollinger.bollinger_pband()
return df_copy
def calculate_pnl(self, predictions, actual_prices, position_size=1.0):
"""
Robust PnL calculator that handles:
@ -557,33 +627,33 @@ class DataInterface:
# Calculate technical indicators
try:
# Add RSI (14)
df['rsi'] = ta.rsi(df['close'], length=14)
df['rsi'] = ta.momentum.rsi(df['close'], window=14)
# Add MACD
macd = ta.macd(df['close'])
df['macd'] = macd['MACD_12_26_9']
df['macd_signal'] = macd['MACDs_12_26_9']
df['macd_hist'] = macd['MACDh_12_26_9']
macd = ta.trend.MACD(df['close'])
df['macd'] = macd.macd()
df['macd_signal'] = macd.macd_signal()
df['macd_hist'] = macd.macd_diff()
# Add Bollinger Bands
bbands = ta.bbands(df['close'], length=20)
df['bb_upper'] = bbands['BBU_20_2.0']
df['bb_middle'] = bbands['BBM_20_2.0']
df['bb_lower'] = bbands['BBL_20_2.0']
bbands = ta.volatility.BollingerBands(df['close'])
df['bb_upper'] = bbands.bollinger_hband()
df['bb_middle'] = bbands.bollinger_mavg()
df['bb_lower'] = bbands.bollinger_lband()
# Add ATR (Average True Range)
df['atr'] = ta.atr(df['high'], df['low'], df['close'], length=14)
df['atr'] = ta.volatility.average_true_range(df['high'], df['low'], df['close'], window=14)
# Add moving averages
df['sma_20'] = ta.sma(df['close'], length=20)
df['sma_50'] = ta.sma(df['close'], length=50)
df['ema_20'] = ta.ema(df['close'], length=20)
df['sma_20'] = ta.trend.sma_indicator(df['close'], window=20)
df['sma_50'] = ta.trend.sma_indicator(df['close'], window=50)
df['ema_20'] = ta.trend.ema_indicator(df['close'], window=20)
# Add OBV (On-Balance Volume)
df['obv'] = ta.obv(df['close'], df['volume'])
df['obv'] = ta.volume.on_balance_volume(df['close'], df['volume'])
# Add momentum indicators
df['mom'] = ta.mom(df['close'], length=10)
df['mom'] = ta.momentum.roc(df['close'], window=10)
# Normalize price to previous close
df['close_norm'] = df['close'] / df['close'].shift(1) - 1