### Install Gym Trading Environment Source: https://gym-trading-env.readthedocs.io/en/latest/getting_started Installs the Gym Trading Environment using pip. Ensure you have Python 3.9+ installed. ```bash pip install gym-trading-env ``` -------------------------------- ### Clone Gym Trading Environment Repository Source: https://gym-trading-env.readthedocs.io/en/latest/getting_started Clones the Gym Trading Environment from its GitHub repository. This method is an alternative to pip installation. ```bash git clone https://github.com/ClementPerroud/Gym-Trading-Env ``` -------------------------------- ### Import Gym Trading Environment Source: https://gym-trading-env.readthedocs.io/en/latest/getting_started Imports the Gym Trading Environment library into your Python project. This is the standard way to access the library's functionalities. ```python import gym_trading_env ``` -------------------------------- ### Install Gym Trading Environment Source: https://gym-trading-env.readthedocs.io/en/latest/index Provides instructions for installing the Gym Trading Environment package using pip or by cloning the git repository. Ensures compatibility with Python 3.9+. ```bash pip install gym-trading-env ``` ```bash git clone https://github.com/ClementPerroud/Gym-Trading-Env ``` -------------------------------- ### Running Vectorized Environments Source: https://gym-trading-env.readthedocs.io/en/latest/vectorize_env Provides an example of how to interact with vectorized environments. It shows the process of resetting the environments to get initial observations and info, and then stepping through the environments with a list of actions. ```python observation, info = env.reset() while True: actions = [0, 0, 0] # 3D List as we have 3 simultaneous environments observation, reward, done, truncated, info = env.step(actions) ``` -------------------------------- ### Initialize Trading Environment with Windowed Observations Source: https://gym-trading-env.readthedocs.io/en/latest/environment_desc This snippet shows how to initialize the TradingEnv with the `windows` parameter set to a value greater than 1. This configuration results in the observation being a stack of the last W states. The example initializes the environment with `windows = 3`, resets it, and prints the resulting windowed observation. ```python import pandas as pd import gymnasium # Assuming df is already prepared as in the previous example env = gymnasium.make("TradingEnv", df = df, positions = [-1, 0, 1], initial_position= 1, windows = 3) observation, info = env.reset() print(observation) ``` -------------------------------- ### Dynamic Feature Functions and Environment Initialization Source: https://gym-trading-env.readthedocs.io/en/latest/features Defines example Python functions for dynamic features ('dynamic_feature_last_position_taken', 'dynamic_feature_real_position') and shows how to pass them to the TradingEnv constructor. Dynamic features are computed at each step and appended to the observation. ```python def dynamic_feature_last_position_taken(history): return history['position', -1] def dynamic_feature_real_position(history): return history['real_position', -1] env = gym.make( "TradingEnv", df = df, dynamic_feature_functions = [dynamic_feature_last_position_taken, dynamic_feature_real_position], ... ) ``` -------------------------------- ### Custom Reward Function Example Source: https://gym-trading-env.readthedocs.io/en/latest/customization This snippet demonstrates how to define and use a custom reward function for the Trading Environment. It utilizes the History object to access portfolio valuation at different timesteps. ```python import gymnasium as gym import numpy as np def reward_function(history): return np.log(history["portfolio_valuation", -1] / history["portfolio_valuation", -2]) env = gym.make("TradingEnv", ... reward_function = reward_function ... ) ``` -------------------------------- ### TradingEnv Action Space Explanation Source: https://gym-trading-env.readthedocs.io/en/latest/environment_desc Explains the action space of the TradingEnv, which is defined by a list of user-specified positions. Each position represents the ratio of portfolio valuation engaged in a trade. Positive values indicate betting on a rise, while negative values indicate betting on a decrease. The example illustrates how different position values translate to portfolio allocations and leverage strategies (shorting or margin trading). ```APIDOC TradingEnv Action Space: - Type: Discrete(number_of_positions) - Description: A list of positions provided by the user. Each position is a number representing the ratio of the portfolio valuation engaged in the position. - Positive values (> 0): Bet on the rise. - Negative values (< 0): Bet on the decrease. Position Examples: - Position 0: No action (e.g., 100% USDT). - Position 1: 100% in the asset (e.g., 100% BTC). - Position 0.5: 50% in the asset, 50% in stablecoin (e.g., 50% BTC, 50% USDT). - Position 2: Margin trading (e.g., 200% BTC, implies borrowing 100% USDT). - Position -1: Shorting (e.g., borrowing 100% USDT to buy BTC, effectively shorting BTC). Action Interpretation: - If position < 0: Performs a SHORT (borrows USDT, buys BTC). - If position > 1: Uses MARGIN trading (borrows BTC, sells it for USDT). ``` -------------------------------- ### TradingEnv Documentation Source: https://gym-trading-env.readthedocs.io/en/latest/rl_tutorial Provides documentation for the TradingEnv class within the gym_trading_env library, detailing its parameters and usage. ```APIDOC gym_trading_env.environments.TradingEnv Parameters: name (str): Name of the environment (e.g., 'BTCUSD'). df (pd.DataFrame): DataFrame containing the trading data. Must include columns like 'open', 'high', 'low', 'close', 'volume', and any custom features. positions (list): A list of possible trading positions (e.g., [-1, 0, 1] for SHORT, OUT, LONG). trading_fees (float): The fee applied per stock buy/sell transaction. borrow_interest_rate (float): The interest rate charged per timestep for borrowing assets. ``` -------------------------------- ### Environment Creation with Preprocessing Source: https://gym-trading-env.readthedocs.io/en/latest/documentation Demonstrates how to create a trading environment using `gym.make`. It specifies the dataset directory and passes a custom preprocessing function (`preprocess`) to the environment constructor. This allows for customized data handling during environment initialization. ```python import gym env = gym.make( "MultiDatasetTradingEnv", dataset_dir= 'examples/data/*.pkl', preprocess= preprocess, ) ``` -------------------------------- ### Download Crypto Data Source: https://gym-trading-env.readthedocs.io/en/latest/rl_tutorial Downloads historical cryptocurrency data from specified exchanges and symbols, saving it as .pkl files for efficient loading. It supports various timeframes and allows specifying a date range. ```python from gym_trading_env.downloader import download import datetime import pandas as pd # Download BTC/USDT historical data from Binance and stores it to directory ./data/binance-BTCUSDT-1h.pkl download(exchange_names = ["binance"], symbols= ["BTC/USDT"], timeframe= "1h", dir = "data", since= datetime.datetime(year= 2020, month= 1, day=1), ) # Import your fresh data df = pd.read_pickle("./data/binance-BTCUSDT-1h.pkl") ``` -------------------------------- ### Create Trading Environment Source: https://gym-trading-env.readthedocs.io/en/latest/rl_tutorial Instantiates the Gym Trading Environment with a provided DataFrame, defining trading positions, fees, and borrow interest rates. The environment is configured for a specific trading pair like 'BTCUSD'. ```python import gymnasium as gym import gym_trading_env env = gym.make("TradingEnv", name= "BTCUSD", df = df, # Your dataset with your custom features positions = [ -1, 0, 1], # -1 (=SHORT), 0(=OUT), +1 (=LONG) trading_fees = 0.01/100, # 0.01% per stock buy / sell (Binance fees) borrow_interest_rate= 0.0003/100, # 0.0003% per timestep (one timestep = 1h here) ) ``` -------------------------------- ### Understanding Action Space in Gym Trading Environment Source: https://gym-trading-env.readthedocs.io/en/latest/rl_tutorial Explains how the Gym Trading Environment represents actions as positions, ranging from converting the entire portfolio to one asset (e.g., BUY ALL, SELL ALL) to complex leveraged positions. It highlights that using positions simplifies the action space for RL agents. ```python 1: All of our portfolio is converted into BTC. (=BUY ALL) 0: All of our portfolio is converted into USD. (=SELL ALL) 0.5: 50% in BTC & 50% in USD 0.1: 10% in BTC & 90% in USD … -1: Bet 100% of the portfolio value on the decline of BTC (=SHORT). +2: Bet 100% of the portfolio value on the rise of BTC. ``` -------------------------------- ### Initialize and Run Renderer Source: https://gym-trading-env.readthedocs.io/en/latest/render Initializes the Renderer with logs from a directory and runs the web application to display the visualizations. The renderer uses Flask and pyecharts. ```python from gym_trading_env.renderer import Renderer renderer = Renderer(render_logs_dir="render_logs") renderer.run() ``` -------------------------------- ### Import Custom Dataset Source: https://gym-trading-env.readthedocs.io/en/latest/rl_tutorial Loads a custom dataset from a URL, ensuring it's sorted by date and has a DatetimeIndex. Requires a 'close' price column and optionally 'open', 'high', 'low', 'volume' for rendering. ```python import pandas as pd # Available in the github repo : examples/data/BTC_USD-Hourly.csv url = "https://raw.githubusercontent.com/ClementPerroud/Gym-Trading-Env/main/examples/data/BTC_USD-Hourly.csv" df = pd.read_csv(url, parse_dates=["date"], index_col= "date") df.sort_index(inplace= True) df.dropna(inplace= True) df.drop_duplicates(inplace=True) ``` -------------------------------- ### Prepare DataFrame and Initialize Trading Environment Source: https://gym-trading-env.readthedocs.io/en/latest/environment_desc This snippet demonstrates how to prepare a pandas DataFrame by adding feature columns like percentage change, high-to-close ratio, and low-to-close ratio. It then initializes the TradingEnv from the gymnasium library with the prepared DataFrame, defined positions, and an initial position. Finally, it resets the environment and displays the initial observation. ```python import pandas as pd import gymnasium df["feature_pct_change"] = df["close"].pct_change() df["feature_high"] = df["high"] / df["close"] - 1 df["feature_low"] = df["low"] / df["close"] - 1 df.dropna(inplace= True) env = gymnasium.make("TradingEnv", df = df, positions = [-1, 0, 1], initial_position= 1) observation, info = env.reset() print(observation) ``` -------------------------------- ### MultiDatasetTradingEnv Parameters Source: https://gym-trading-env.readthedocs.io/en/latest/documentation Details the parameters for initializing the MultiDatasetTradingEnv class. It requires a dataset directory and allows for a preprocessing function to ensure datasets meet the TradingEnv requirements. ```APIDOC gym_trading_env.environments.MultiDatasetTradingEnv(_dataset_dir_ , _*args_ , preprocess= >_, episodes_between_dataset_switch=1_ , _**kwargs_) (Inherits from TradingEnv) Parameters: * **dataset_dir** (_str_) – A [glob path](https://docs.python.org/3.6/library/glob.html) that needs to match your datasets. All of your datasets needs to match the dataset requirements (see docs from TradingEnv). If it is not the case, you can use the `preprocess` param to make your datasets match the requirements. * **preprocess** (_function pandas.DataFrame>_) – This function takes a pandas.DataFrame and returns a pandas.DataFrame. This function is applied to each dataset before being used in the environment. For example, imagine you have a folder named ‘data’ with several datasets (formatted as .pkl) ``` import pandas as pd import numpy as np import gymnasium as gym from gym_trading_env ``` ``` -------------------------------- ### MultiDatasetTradingEnv Usage Source: https://gym-trading-env.readthedocs.io/en/latest/multi_datasets Demonstrates how to instantiate the MultiDatasetTradingEnv by providing a glob path to a directory containing multiple preprocessed datasets. This environment automatically switches between datasets at the end of each episode. ```python import gymnasium as gym import gym_trading_env env = gym.make('MultiDatasetTradingEnv', dataset_dir = 'preprocessed_data/*.pkl', ) ``` -------------------------------- ### Gym Trading Environment Import and Parameters Source: https://gym-trading-env.readthedocs.io/en/latest/environment_desc Demonstrates how to import the TradingEnv from the gym-trading-env library and specifies the required and optional parameters for its initialization. The `df` parameter is mandatory and must be a pandas DataFrame with a 'close' column and a DatetimeIndex. For rendering, 'open', 'low', and 'high' columns are also needed. The `positions` parameter allows customization of the agent's possible actions. ```python import gymnasium # Required: DataFrame with 'close' and DatetimeIndex # For render: DataFrame also needs 'open', 'low', 'high' df = ... # Optional: List of positions (e.g., [-1, 0, 1]) positions = [-1, 0, 1] env = gymnasium.make("TradingEnv", df=df, positions=positions) ``` -------------------------------- ### Add Support for New Exchanges Source: https://gym-trading-env.readthedocs.io/en/latest/download Demonstrates how to add support for new cryptocurrency exchanges by configuring their API rate limits. This involves setting 'limit', 'pause_every', and 'pause' parameters for the exchange in the EXCHANGE_LIMIT_RATES dictionary. This allows for customized data downloading from exchanges not initially supported. ```python from gym_trading_env.downloader import download, EXCHANGE_LIMIT_RATES import datetime EXCHANGE_LIMIT_RATES["bybit"] = { "limit" : 200, # One request will query 200 data points (aka candlesticks). "pause_every" : 120, # it will pause every 120 requests. "pause" : 2, # the pause will last 2 seconds. } download( exchange_names = ["binance", "bitfinex2", "huobi", "bybit"], symbols= ["BTC/USDT", "ETH/USDT"], timeframe= "1h", dir = "examples/data", since= datetime.datetime(year= 2023, month= 1, day=1), ) ``` -------------------------------- ### Run Trading Environment Episode Source: https://gym-trading-env.readthedocs.io/en/latest/rl_tutorial This code snippet demonstrates how to run a single episode of the trading environment. It resets the environment, then enters a loop that continues until the episode is done or truncated. Inside the loop, a random action (position index) is sampled and applied to the environment using env.step(). The observation, reward, done, truncated, and info are updated after each step. ```python done, truncated = False, False observation, info = env.reset() while not done and not truncated: # Pick a position by its index in your position list (=[-1, 0, 1])....usually something like : position_index = your_policy(observation) position_index = env.action_space.sample() # At every timestep, pick a random position index from your position list (=[-1, 0, 1]) observation, reward, done, truncated, info = env.step(position_index) ``` -------------------------------- ### TradingEnv Parameters Source: https://gym-trading-env.readthedocs.io/en/latest/documentation Details the parameters for initializing the TradingEnv class. These include the market DataFrame (df), allowed positions, dynamic feature functions, reward function, trading fees, initial portfolio value, and episode duration settings. ```APIDOC gym_trading_env.environments.TradingEnv(_df: ~pandas.core.frame.DataFrame, positions: list = [0, 1], dynamic_feature_functions=[, ], reward_function=, windows=None, trading_fees=0, borrow_interest_rate=0, portfolio_initial_value=1000, initial_position='random', max_episode_duration='max', verbose=1, name='Stock', render_mode='logs') Parameters: * **df** (_pandas.DataFrame_) – The market DataFrame. It must contain ‘open’, ‘high’, ‘low’, ‘close’. Index must be DatetimeIndex. Your desired inputs need to contain ‘feature’ in their column name : this way, they will be returned as observation at each step. * **positions** (_optional - list_ _[__int_ _or_ _float_ _]_) – List of the positions allowed by the environment. * **dynamic_feature_functions** (_optional - list_) – The list of the dynamic features functions. By default, two dynamic features are added : the last position taken by the agent and the real position of the portfolio. * **reward_function** (_optional - function float>_) – Take the History object of the environment and must return a float. * **windows** (_optional - None_ _or_ _int_) – Default is None. If it is set to an int: N, every step observation will return the past N observations. It is recommended for Recurrent Neural Network based Agents. * **trading_fees** (_optional - float_) – Transaction trading fees (buy and sell operations). eg: 0.01 corresponds to 1% fees * **borrow_interest_rate** (_optional - float_) – Borrow interest rate per step (only when position < 0 or position > 1). eg: 0.01 corresponds to 1% borrow interest rate per STEP. * **portfolio_initial_value** (_float_ _or_ _int_) – Initial valuation of the portfolio. * **initial_position** (_optional - float_ _or_ _int_) – You can specify the initial position of the environment or set it to ‘random’. It must contained in the list parameter ‘positions’. * **max_episode_duration** (_optional - int_ _or_ _'max'_) – If a integer value is used, each episode will be truncated after reaching the desired max duration in steps. When using a max duration, each episode will start at a random starting point. * **verbose** (_optional - int_) – If 0, no log is outputted. If 1, the env send episode result logs. * **name** (_optional - str_) – The name of the environment (eg. ‘BTC/USDT’) ``` -------------------------------- ### Run MultiDatasetTradingEnv Episodes Source: https://gym-trading-env.readthedocs.io/en/latest/multi_datasets Demonstrates how to run multiple episodes using the MultiDatasetTradingEnv. The environment automatically selects a new dataset for each episode. The step function takes a sampled action from the action space. ```python # Run 100 episodes for _ in range(100): # At every episode, the env will pick a new dataset. done, truncated = False, False observation, info = env.reset() while not done and not truncated: position_index = env.action_space.sample() # Pick random position index observation, reward, done, truncated, info = env.step(position_index) ``` -------------------------------- ### Create Trading Features Source: https://gym-trading-env.readthedocs.io/en/latest/rl_tutorial Generates various features from raw price and volume data, such as price change percentage, price ratios, and normalized volume. These features serve as inputs for the RL agent. The environment recognizes columns containing 'feature' in their name. ```python # df is a DataFrame with columns : "open", "high", "low", "close", "Volume USD" # Create the feature : ( close[t] - close[t-1] )/ close[t-1] df["feature_close"] = df["close"].pct_change() # Create the feature : open[t] / close[t] df["feature_open"] = df["open"]/df["close"] # Create the feature : high[t] / close[t] df["feature_high"] = df["high"]/df["close"] # Create the feature : low[t] / close[t] df["feature_low"] = df["low"]/df["close"] # Create the feature : volume[t] / max(*volume[t-7*24:t+1]) df["feature_volume"] = df["Volume USD"] / df["Volume USD"].rolling(7*24).max() df.dropna(inplace= True) # Clean again ! # Eatch step, the environment will return 5 inputs : "feature_close", "feature_open", "feature_high", "feature_low", "feature_volume" ``` -------------------------------- ### TradingEnv Parameters Source: https://gym-trading-env.readthedocs.io/en/latest/environment_desc Detailed description of the parameters for the TradingEnv class. This includes data input requirements, allowed positions, dynamic feature functions, reward function signature, windowing for RNNs, trading fees, borrow interest rates, initial portfolio value, initial position, episode duration control, verbosity, and environment naming. ```APIDOC gym_trading_env.environments.TradingEnv( df: pandas.DataFrame, positions: list = [0, 1], dynamic_feature_functions: list = [, ], reward_function: function = , windows: Optional[int] = None, trading_fees: float = 0, borrow_interest_rate: float = 0, portfolio_initial_value: Union[float, int] = 1000, initial_position: Union[float, int, str] = 'random', max_episode_duration: Union[int, str] = 'max', verbose: int = 1, name: str = 'Stock', render_mode: str = 'logs' ) Parameters: df (pandas.DataFrame): The market DataFrame. Must contain 'open', 'high', 'low', 'close'. Index must be DatetimeIndex. Input columns must contain 'feature' to be included in observations. positions (list, optional): List of allowed positions. Defaults to [0, 1]. dynamic_feature_functions (list, optional): List of dynamic feature functions. Defaults to functions for last position taken and real portfolio position. reward_function (function, optional): Function that takes the environment's History object and returns a float reward. Defaults to basic_reward_function. windows (int, optional): If set, observation will include the past N observations. Recommended for RNNs. Defaults to None. trading_fees (float, optional): Transaction fees for buy/sell operations (e.g., 0.01 for 1%). Defaults to 0. borrow_interest_rate (float, optional): Borrow interest rate per step (for negative positions). E.g., 0.01 for 1% per step. Defaults to 0. portfolio_initial_value (Union[float, int], optional): Initial portfolio valuation. Defaults to 1000. initial_position (Union[float, int, str], optional): Initial position, can be 'random' or a value within 'positions'. Defaults to 'random'. max_episode_duration (Union[int, str], optional): Max steps per episode. If int, episodes truncate and start at random points. Defaults to 'max'. verbose (int, optional): Logging level. 0 for no logs, 1 for episode result logs. Defaults to 1. name (str, optional): Name of the environment (e.g., 'BTC/USDT'). Defaults to 'Stock'. render_mode (str, optional): Rendering mode. Defaults to 'logs'. ``` -------------------------------- ### MultiDatasetTradingEnv Class Initialization Source: https://gym-trading-env.readthedocs.io/en/latest/documentation Initializes the MultiDatasetTradingEnv class, which inherits from TradingEnv and handles multiple datasets. It automatically switches datasets at the end of an episode, which can help avoid overfitting. ```python import gymnasium as gym import gym_trading_env env = gym.make('MultiDatasetTradingEnv', dataset_dir = 'data/*.pkl', ... ) ``` -------------------------------- ### Download Crypto Market Data Source: https://gym-trading-env.readthedocs.io/en/latest/download Downloads market data for specified symbols and timeframes from multiple cryptocurrency exchanges. It saves the data in pickle format. Dependencies include the 'gym-trading-env' library and 'datetime'. ```python from gym_trading_env.downloader import download import datetime download( exchange_names = ["binance", "bitfinex2", "huobi"], symbols= ["BTC/USDT", "ETH/USDT"], timeframe= "1h", dir = "data", since= datetime.datetime(year= 2019, month= 1, day=1), until = datetime.datetime(year= 2023, month= 1, day=1), ) ``` -------------------------------- ### TradingEnv Class Initialization Source: https://gym-trading-env.readthedocs.io/en/latest/environment_desc Initializes the TradingEnv environment for OpenAI gym. It requires a pandas DataFrame with market data and allows customization of positions, dynamic features, reward functions, trading fees, and episode duration. ```python import gymnasium as gym import gym_trading_env env = gym.make('TradingEnv', df=_df, positions=[0, 1], dynamic_feature_functions=[dynamic_feature_last_position_taken, dynamic_feature_real_position], reward_function=basic_reward_function, windows=None, trading_fees=0, borrow_interest_rate=0, portfolio_initial_value=1000, initial_position='random', max_episode_duration='max', verbose=1, name='Stock', render_mode='logs' ) ``` -------------------------------- ### Special Cases for Jupyter Notebooks Source: https://gym-trading-env.readthedocs.io/en/latest/vectorize_env Demonstrates how to use `SyncVectorEnv` from the gym library to avoid crashes in environments like Jupyter Notebooks. It sets up a trading environment and creates a vectorized version with multiple instances. ```python import gymnasium as gym import gym_trading_env def make_env(): env = gym.make( "MultiDatasetTradingEnv", dataset_dir= "preprocessed_data", ) return env envs = gym.vector.SyncVectorEnv([lambda: make_env() for _ in range(3)]) ``` -------------------------------- ### TradingEnv Class Initialization Source: https://gym-trading-env.readthedocs.io/en/latest/documentation Initializes the TradingEnv class, a trading environment for OpenAI Gym. It requires a pandas DataFrame with market data and allows customization of positions, reward functions, trading fees, and more. ```python import gymnasium as gym import gym_trading_env env = gym.make('TradingEnv', ...) ``` -------------------------------- ### Create and Reset Vectorized Environment Source: https://gym-trading-env.readthedocs.io/en/latest/vectorize_env This snippet demonstrates how to create a vectorized version of the MultiDatasetTradingEnv using `gym.vector.make`. It specifies the dataset directory and the number of parallel environments. The `envs.reset()` method is then called to initialize these environments, returning the initial observations and auxiliary information. ```python import gymnasium as gym import gym_trading_env if __name__ == "__main__": envs = gym.vector.make( "MultiDatasetTradingEnv", dataset_dir = "preprocessed_data", num_envs = 3) print(envs.reset()) ``` -------------------------------- ### gym.make Parameters Source: https://gym-trading-env.readthedocs.io/en/latest/documentation Details a parameter for the `gym.make` function when creating a trading environment. Specifically, it describes `episodes_between_dataset_switch`, an optional integer that controls how many times a dataset is used before switching to another. This can impact performance, especially with low `max_episode_duration`. ```APIDOC episodes_between_dataset_switch: type: int description: Number of times a dataset is used to create an episode, before moving on to another dataset. It can be useful for performances when max_episode_duration is low. optional: true ``` -------------------------------- ### History Object Access and Content Source: https://gym-trading-env.readthedocs.io/en/latest/history Demonstrates how to access data within the History object at a specific timestep and lists the types of information stored, including training metrics, original data columns, and portfolio details. ```python >>> history[33091] { # Training info 'step': 33091, #Step = t. 'date': numpy.datetime64('2022-03-01T00:00:00.000000000'), #Date at step t, datetime. 'position_index': 2, #Index of the position at step t among your position list. 'position': 1, # Last position taken by the agent. 'real_position': 1.09848, # Real portfolio position = (asset owned - asset borrowed - asset interests) * current price / portfolio valuation 'reward': 0.0028838985262525257, #Reward at step t. Obviously, you can not be used inside a custom reward function (the value is always 0 as it as not been computed yet). # DataFrame info : Every column (except features) of your initial DataFrame preceded by 'data_' 'data_symbol': 'BTC/USD', 'data_volume': 52.05632, 'data_Volume USD': 2254677.3870464, 'data_high': 43626.49, 'data_open': 43221.71, 'data_close': 43312.27, 'data_unix': 1646092800, 'data_low': 43185.48, # Portfolio info : Distribution of the portfolio 'portfolio_valuation': 45.3857471834205, #Global valuation of the portfolio 'portfolio_distribution_asset': 0.001047869568779473, #the amount of owned BTC 'portfolio_distribution_fiat': 0.0001374956603967803, #the amount of owned USD 'portfolio_distribution_borrowed_asset': 0, #the amount of borrowed BTC (when position < 0 = SHORT) 'portfolio_distribution_borrowed_fiat': 0, #the amount of borrowed USD (when position > 1) 'portfolio_distribution_interest_asset': 0.0, #the cumalated interest generated by the borrowed BTC 'portfolio_distribution_interest_fiat': 0.0, #the cumalated interest generated by the borrowed USD } ``` -------------------------------- ### Create Static Features Source: https://gym-trading-env.readthedocs.io/en/latest/features Demonstrates how to create static features by adding new columns to a pandas DataFrame. These features are calculated once and used as observations by the trading environment. The environment identifies features by the keyword 'feature' in their column names. It also shows how to clean up NaN values after feature creation. ```python # df is a DataFrame with columns : "open", "high", "low", "close", "Volume USD" # Create the feature : ( close[t] - close[t-1] )/ close[t-1] df["feature_close"] = df["close"].pct_change() # Create the feature : open[t] / close[t] df["feature_open"] = df["open"]/df["close"] # Create the feature : high[t] / close[t] df["feature_high"] = df["high"]/df["close"] # Create the feature : low[t] / close[t] df["feature_low"] = df["low"]/df["close"] # Create the feature : volume[t] / max(*volume[t-7*24:t+1]) df["feature_volume"] = df["Volume USD"] / df["Volume USD"].rolling(7*24).max() df.dropna(inplace= True) # Clean again ! # Eatch step, the environment will return 5 static inputs : "feature_close", "feature_open", "feature_high", "feature_low", "feature_volume" env = gym.make('TradingEnv', df = df, .... ) ``` -------------------------------- ### Add Custom Metrics (Annualized Returns) Source: https://gym-trading-env.readthedocs.io/en/latest/render Demonstrates how to add custom metrics for 'Annual Market Return' and 'Annual Portfolio Return' using lambda functions. These functions calculate annualized returns based on historical data provided as a DataFrame. ```python renderer.add_metric( name = "Annual Market Return", function = lambda df : f"{ ((df['close'].iloc[-1] / df['close'].iloc[0])**(pd.Timedelta(days=365)/(df.index.values[-1] - df.index.values[0]))-1)*100:0.2f}%" ) renderer.add_metric( name = "Annual Portfolio Return", function = lambda df : f"{((df['portfolio_valuation'].iloc[-1] / df['portfolio_valuation'].iloc[0])**(pd.Timedelta(days=365)/(df.index.values[-1] - df.index.values[0]))-1)*100:0.2f}%" ) renderer.run() ``` -------------------------------- ### Retrieve Metrics Source: https://gym-trading-env.readthedocs.io/en/latest/customization After an episode concludes, you can access the calculated custom metrics using the `env.get_metrics()` method. This method returns a dictionary containing the names and values of all added metrics. ```python metrics = env.get_metrics() # Example output: {"Market Return": "25.30%", "Portfolio Return": "45.24%", "Position Changes": 28417, "Episode Length": 33087} ``` -------------------------------- ### Save Render Logs Source: https://gym-trading-env.readthedocs.io/en/latest/render Saves the environment's render logs to a specified directory at the end of an episode. This is necessary for later visualization. ```python env.save_for_render(dir = "render_logs") ``` -------------------------------- ### Easy Preprocessing Function Source: https://gym-trading-env.readthedocs.io/en/latest/multi_datasets Defines a custom preprocessing function that takes a pandas DataFrame, performs feature engineering, and returns the processed DataFrame. This function is applied to each dataset before it's used in the MultiDatasetTradingEnv. ```python import pandas as pd import gym def preprocess(df : pd.DataFrame): # Preprocess df["date"] = pd.to_datetime(df["timestamp"], unit= "ms") df.set_index("date", inplace = True) # Create your features df["feature_close"] = df["close"].pct_change() df["feature_open"] = df["open"]/df["close"] df["feature_high"] = df["high"]/df["close"] df["feature_low"] = df["low"]/df["close"] df["feature_volume"] = df["volume"] / df["volume"].rolling(7*24).max() df.dropna(inplace= True) return df env = gym.make( "MultiDatasetTradingEnv", dataset_dir= 'raw_data/*.pkl', preprocess= preprocess, ) ``` -------------------------------- ### renderer.add_metric Function Signature Source: https://gym-trading-env.readthedocs.io/en/latest/render Explains the `add_metric` function used for adding custom metrics to the renderer. It details the required parameters: `name` for the metric's display name and `function` which processes the episode's history DataFrame. ```APIDOC renderer.add_metric(name, function) Parameters: name (str): The name of the metrics to be displayed. function (callable): A function that takes the History object (converted into a DataFrame) of the episode as a parameter and must return a string representing the metric's value. ``` -------------------------------- ### Adding Custom Logs/Metrics Source: https://gym-trading-env.readthedocs.io/en/latest/customization This snippet shows how to add custom metrics to the Trading Environment's logs. Custom metrics can be defined using lambda functions that operate on the History object. ```python env = gym.make("TradingEnv", ... ) env.add_metric('Position Changes', lambda history : np.sum(np.diff(history['position']) != 0) ) env.add_metric('Episode Length', lambda history : len(history['position']) ) ``` -------------------------------- ### Add Custom Metric Source: https://gym-trading-env.readthedocs.io/en/latest/customization The `.add_metric` method allows you to define and add custom metrics to your trading environment. It takes a name for the metric and a function that calculates its value using the History object. ```python env.add_metric(name="Market Return", function=lambda history: history.market_return) env.add_metric(name="Portfolio Return", function=lambda history: history.portfolio_return) env.add_metric(name="Position Changes", function=lambda history: history.position_changes) env.add_metric(name="Episode Length", function=lambda history: history.episode_length) ``` -------------------------------- ### Data Preprocessing Function Source: https://gym-trading-env.readthedocs.io/en/latest/documentation Defines a function to preprocess a pandas DataFrame for the trading environment. It calculates several features based on 'close', 'open', 'high', 'low', and 'volume' data, then removes rows with NaN values. This function is designed to be passed to the trading environment for data transformation. ```python import pandas as pd def preprocess(df : pd.DataFrame): # You can easily change your inputs this way df["feature_close"] = df["close"].pct_change() df["feature_open"] = df["open"]/df["close"] df["feature_high"] = df["high"]/df["close"] df["feature_low"] = df["low"]/df["close"] df["feature_volume"] = df["volume"] / df["volume"].rolling(7*24).max() df.dropna(inplace= True) return df ``` -------------------------------- ### Add Custom Lines to Render Source: https://gym-trading-env.readthedocs.io/en/latest/render Adds custom lines to the render visualization, such as moving averages. The function parameter takes the episode's history DataFrame and returns a Series for plotting. Line appearance can be customized. ```python renderer = Renderer(render_logs_dir="render_logs") # Add Custom Lines (Simple Moving Average) renderer.add_line( name= "sma10", function= lambda df : df["close"].rolling(10).mean(), line_options ={"width" : 1, "color": "purple"}) renderer.add_line( name= "sma20", function= lambda df : df["close"].rolling(20).mean(), line_options ={"width" : 1, "color": "blue"}) renderer.run() ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.