im trying to refine the reward routine : import numpy as np
import pandas as pd
import gym
from gym import spaces

class FinancialEnv(gym.Env):
    def __init__(self, df):
        super(FinancialEnv, self).__init__()

        self.df = df
        self.current_step = 0
        self.cash = 10000  # Initial cash
        self.shares = 0
        self.total_value = self.cash
        self.action_space = spaces.Discrete(7)  # Seven possible actions
        self.columns = list(df.columns)
        self.observation_space = spaces.Box(low=0, high=1, shape=(len(self.columns),), dtype=np.float32)

    def reset(self):
        self.current_step = 0
        self.cash = 10000
        self.shares = 0
        self.total_value = self.cash
        return self._next_observation()

    def _next_observation(self):
        return self.df.iloc[self.current_step].values

    def step(self, action):
        current_price = self.df.iloc[self.current_step]['close']
        reward = 0

        if action == 0:  # Hold
            reward = 0
        elif action == 1:  # Buy 25%
            buy_amount = self.cash * 0.25
            self.shares += buy_amount / current_price
            self.cash -= buy_amount
        elif action == 2:  # Buy 50%
            buy_amount = self.cash * 0.5
            self.shares += buy_amount / current_price
            self.cash -= buy_amount
        elif action == 3:  # Buy 100%
            self.shares += self.cash / current_price
            self.cash = 0
        elif action == 4:  # Sell 25%
            sell_amount = self.shares * 0.25
            self.cash += sell_amount * current_price
            self.shares -= sell_amount
        elif action == 5:  # Sell 50%
            sell_amount = self.shares * 0.5
            self.cash += sell_amount * current_price
            self.shares -= sell_amount
        elif action == 6:  # Sell 100%
            self.cash += self.shares * current_price
            self.shares = 0

        self.total_value = self.cash + self.shares * current_price
        reward += self._calculate_reward(action, current_price)

        self.current_step += 1
        done = self.current_step >= len(self.df) - 1
        obs = self._next_observation() if not done else None

        return obs, reward, done, {}

    def _calculate_reward(self, action, current_price):
        """
        Reward is calculated using the current state and indicators.
        Includes interpretation of all available indicators and candle stats.
        """
        reward = 0

        # RSI Interpretation
        rsi = self.df.iloc[self.current_step]['rsi']
        if rsi > 70 and action in [4, 5, 6]:  # Overbought -> Sell actions
            reward += 1
        elif rsi < 30 and action in [1, 2, 3]:  # Oversold -> Buy actions
            reward += 1

        # MACD Interpretation
        macd = self.df.iloc[self.current_step]['macd']
        macd_signal = self.df.iloc[self.current_step]['macd_signal']
        if macd > macd_signal and action in [1, 2, 3]:  # Positive crossover -> Buy
            reward += 1
        elif macd < macd_signal and action in [4, 5, 6]:  # Negative crossover -> Sell
            reward += 1

        # Bollinger Bands
        close = self.df.iloc[self.current_step]['close']
        bb_upper = self.df.iloc[self.current_step]['bb_upper']
        bb_lower = self.df.iloc[self.current_step]['bb_lower']
        if close > bb_upper and action in [4, 5, 6]:  # Price above upper band -> Sell
            reward += 1
        elif close < bb_lower and action in [1, 2, 3]:  # Price below lower band -> Buy
            reward += 1

        # ATR (Volatility Measure)
        atr = self.df.iloc[self.current_step]['atr']
        if atr > 0.01 and action == 0:  # High volatility and Hold action -> Penalize
            reward -= 1

        # Volume Analysis
        volume = self.df.iloc[self.current_step]['volume']
        vpt = self.df.iloc[self.current_step]['vpt']
        if volume > 0.7 and vpt > 0.5 and action in [1, 2, 3]:  # High volume & positive VPT -> Buy
            reward += 1
        elif volume < 0.3 and vpt < 0 and action in [4, 5, 6]:  # Low volume & negative VPT -> Sell
            reward += 1

        # Reward based on overall portfolio performance
        portfolio_change = self.total_value - self.cash - self.shares * current_price
        reward += portfolio_change / self.total_value

        return reward

    def render(self, mode='human'):
        profit = self.total_value - 10000
        print(f'Step: {self.current_step}, Cash: {self.cash}, Shares: {self.shares}, Total Value: {self.total_value}, Profit: {profit}')
  by using this implementation : Objective of the New Reward Routine
The goal of the updated reward routine is to improve the performance and learning capability of the trading model within the financial environment. Specifically, we aim to:

Encourage Learning from Indicators and Candle Data:

Utilize technical indicators (e.g., RSI, MACD, Bollinger Bands, ATR) and price data (open, high, low, close, volume) to help the model recognize meaningful patterns in the market.
Train the model to use these indicators and candle statistics to identify high-probability trading opportunities.
Align Model Actions with Market Context:

Teach the model to take actions that are contextually relevant based on the current state of the market. For example:
Overbought or oversold conditions (via RSI): Prompt sell or buy actions, respectively.
Trend reversals or momentum signals (via MACD): Act accordingly based on positive or negative crossovers.
Support and resistance levels (via Bollinger Bands and Fibonacci retracements): React appropriately when prices reach critical levels.
Balance Risk and Reward:

Integrate risk measures such as ATR (volatility) into the reward system to avoid unnecessary trading during high-risk periods or to capitalize on volatility when conditions are favorable.
Penalize actions that lead to higher drawdowns or misaligned trades with respect to the indicators.
Reward Strategic Actions:

Reward the model for:
Buying low and selling high: Encourage actions that maximize profit potential.
Holding during uncertainty: Avoid frequent, unnecessary trades that incur transaction costs.
Penalize:
Actions that go against indicator signals (e.g., buying in overbought conditions or selling in oversold conditions).
Holding during periods of high volatility without strong market context.
Incorporate Portfolio Performance into Rewards:

Include portfolio metrics like total value, profit, and relative changes to measure the success of actions over time.
Reward the model for improving the portfolio's total value compared to a baseline.
Support Diverse Trading Strategies:

Expand the model's decision-making capability to include seven discrete actions:
Hold, Buy 25%, Buy 50%, Buy 100%, Sell 25%, Sell 50%, Sell 100%.
Provide flexibility in trading decisions to allow the model to scale positions or exit gradually based on market conditions.
Improve Generalization Across Market Scenarios:

Train the model to adapt to various market conditions, such as trending, sideways, and volatile markets, by leveraging the dynamic relationship between price movements and indicator values.
Build a robust policy that performs well across different time periods and financial instruments.
Desired Outcome
By implementing the new reward routine, we aim to build a model that:

Learns to identify and act on profitable market patterns effectively.
Minimizes risk and transaction costs while maximizing long-term portfolio growth.
Demonstrates improved decision-making through alignment with technical analysis principles.
Adapts dynamically to changing market conditions using the full range of available data and indicators.
This holistic approach should result in a more intelligent and profitable trading strategy that aligns with real-world trading dynamics.  the dataset looks like this  , each row as a candle of 5min information open low high close volume elapsed_time and all of the indicators. we need to use all of them into the rewards routine : Objective of the New Reward Routine
The goal of the updated reward routine is to improve the performance and learning capability of the trading model within the financial environment. Specifically, we aim to:

Encourage Learning from Indicators and Candle Data:

Utilize technical indicators (e.g., RSI, MACD, Bollinger Bands, ATR) and price data (open, high, low, close, volume) to help the model recognize meaningful patterns in the market.
Train the model to use these indicators and candle statistics to identify high-probability trading opportunities.
Align Model Actions with Market Context:

Teach the model to take actions that are contextually relevant based on the current state of the market. For example:
Overbought or oversold conditions (via RSI): Prompt sell or buy actions, respectively.
Trend reversals or momentum signals (via MACD): Act accordingly based on positive or negative crossovers.
Support and resistance levels (via Bollinger Bands and Fibonacci retracements): React appropriately when prices reach critical levels.
Balance Risk and Reward:

Integrate risk measures such as ATR (volatility) into the reward system to avoid unnecessary trading during high-risk periods or to capitalize on volatility when conditions are favorable.
Penalize actions that lead to higher drawdowns or misaligned trades with respect to the indicators.
Reward Strategic Actions:

Reward the model for:
Buying low and selling high: Encourage actions that maximize profit potential.
Holding during uncertainty: Avoid frequent, unnecessary trades that incur transaction costs.
Penalize:
Actions that go against indicator signals (e.g., buying in overbought conditions or selling in oversold conditions).
Holding during periods of high volatility without strong market context.
Incorporate Portfolio Performance into Rewards:

Include portfolio metrics like total value, profit, and relative changes to measure the success of actions over time.
Reward the model for improving the portfolio's total value compared to a baseline.
Support Diverse Trading Strategies:

Expand the model's decision-making capability to include seven discrete actions:
Hold, Buy 25%, Buy 50%, Buy 100%, Sell 25%, Sell 50%, Sell 100%.
Provide flexibility in trading decisions to allow the model to scale positions or exit gradually based on market conditions.
Improve Generalization Across Market Scenarios:

Train the model to adapt to various market conditions, such as trending, sideways, and volatile markets, by leveraging the dynamic relationship between price movements and indicator values.
Build a robust policy that performs well across different time periods and financial instruments.
Desired Outcome
By implementing the new reward routine, we aim to build a model that:

Learns to identify and act on profitable market patterns effectively.
Minimizes risk and transaction costs while maximizing long-term portfolio growth.
Demonstrates improved decision-making through alignment with technical analysis principles.
Adapts dynamically to changing market conditions using the full range of available data and indicators.
This holistic approach should result in a more intelligent and profitable trading strategy that aligns with real-world trading dynamics.     datasets header columns : open	high	low	volume	close	elapsed_time	rsi	adx	roc	stochastic_k	stochastic_d	macd	macd_signal	macd_hist	mfi	bb_upper	bb_middle	bb_lower	kc_upper	kc_lower	dc_upper	dc_lower	atr	pivot	fibonacci_23	fibonacci_38	fibonacci_50	fibonacci_61	vpt	cmf	obv	supertrend
write me an updated version of the scripts.  copy the whole scripts here so i can copy it