diff --git a/README.md b/README.md index 496f60ded8..c2c13a1308 100755 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ image -# FinRL: Financial Reinforcement Learning → FinRL-X +# FinRL: Financial Reinforcement Learning → FinRL-X
@@ -24,7 +24,7 @@ > [!IMPORTANT] > **FinRL-X** is the next-generation evolution of FinRL, designed for AI-native, modular, and production-oriented quantitative trading. -> +> > - **This repository (`FinRL`)** preserves the original end-to-end educational and research framework. > - **For the latest architecture, live trading deployment, and production-focused development, please use [`FinRL-X / FinRL-Trading`](https://github.com/AI4Finance-Foundation/FinRL-Trading).** @@ -87,7 +87,7 @@ Key contributors include: - [**Hongyang (Bruce) Yang**](https://www.linkedin.com/in/brucehy/) – research and development on financial reinforcement learning frameworks, market environments, and quantitative trading applications - [other contributors…] - + ## Overview FinRL is the original open-source framework for financial reinforcement learning, organized around three core layers: diff --git a/examples/FinRL_StockTrading_2026_1_data.py b/examples/FinRL_StockTrading_2026_1_data.py index b40f165ac4..7c0ca5e01c 100644 --- a/examples/FinRL_StockTrading_2026_1_data.py +++ b/examples/FinRL_StockTrading_2026_1_data.py @@ -6,14 +6,21 @@ Introduce how to use FinRL to fetch and process data that we need for ML/RL trading. """ +from __future__ import annotations + import itertools import pandas as pd import yfinance as yf from finrl import config_tickers -from finrl.config import INDICATORS, TRAIN_START_DATE, TRAIN_END_DATE, TRADE_START_DATE, TRADE_END_DATE -from finrl.meta.preprocessor.preprocessors import FeatureEngineer, data_split +from finrl.config import INDICATORS +from finrl.config import TRADE_END_DATE +from finrl.config import TRADE_START_DATE +from finrl.config import TRAIN_END_DATE +from finrl.config import TRAIN_START_DATE +from finrl.meta.preprocessor.preprocessors import data_split +from finrl.meta.preprocessor.preprocessors import FeatureEngineer from finrl.meta.preprocessor.yahoodownloader import YahooDownloader # %% Part 1. Fetch data - Single ticker diff --git a/examples/FinRL_StockTrading_2026_2_train.py b/examples/FinRL_StockTrading_2026_2_train.py index 457a2b3223..c03d7a5401 100644 --- a/examples/FinRL_StockTrading_2026_2_train.py +++ b/examples/FinRL_StockTrading_2026_2_train.py @@ -7,11 +7,15 @@ Introduce how to use FinRL to make data into the gym form environment, and train DRL agents on it. """ +from __future__ import annotations + import pandas as pd from stable_baselines3.common.logger import configure from finrl.agents.stablebaselines3.models import DRLAgent -from finrl.config import INDICATORS, TRAINED_MODEL_DIR, RESULTS_DIR +from finrl.config import INDICATORS +from finrl.config import RESULTS_DIR +from finrl.config import TRAINED_MODEL_DIR from finrl.main import check_and_make_directories from finrl.meta.env_stock_trading.env_stocktrading import StockTradingEnv diff --git a/examples/FinRL_StockTrading_2026_3_Backtest.py b/examples/FinRL_StockTrading_2026_3_Backtest.py index 63a64bda68..f3e8b25c34 100644 --- a/examples/FinRL_StockTrading_2026_3_Backtest.py +++ b/examples/FinRL_StockTrading_2026_3_Backtest.py @@ -8,7 +8,10 @@ Mean Variance Optimization and DJIA index. """ +from __future__ import annotations + import matplotlib + matplotlib.use("Agg") import matplotlib.pyplot as plt import numpy as np diff --git a/finrl/config_tickers.py b/finrl/config_tickers.py index f90efb8b68..60fd2514ed 100644 --- a/finrl/config_tickers.py +++ b/finrl/config_tickers.py @@ -140,7 +140,7 @@ "TRI", "WBD", "WMT", - "ZS" + "ZS", ] # SP 500 constituents at 2019 diff --git a/finrl/meta/env_stock_trading/env_stocktrading.py b/finrl/meta/env_stock_trading/env_stocktrading.py index 2fb3a69c84..6516e29d24 100644 --- a/finrl/meta/env_stock_trading/env_stocktrading.py +++ b/finrl/meta/env_stock_trading/env_stocktrading.py @@ -28,6 +28,9 @@ class StockTradingEnv(gym.Env): sell_cost_pct (float, array): Cost for selling shares, each index corresponds to each asset turbulence_threshold (float): Maximum turbulence allowed in market for purchases to occur. If exceeded, positions are liquidated print_verbosity(int): When iterating (step), how often to print stats about state of env + allow_short_selling (bool): If False, the agent cannot take short + positions. The action space is restricted to [0, 1] and negative + actions are clipped. Default is True for backward compatibility. """ metadata = {"render.modes": ["human"]} @@ -55,6 +58,7 @@ def __init__( model_name="", mode="", iteration="", + allow_short_selling: bool = True, ): self.day = day self.df = df @@ -68,7 +72,10 @@ def __init__( self.state_space = state_space self.action_space = action_space self.tech_indicator_list = tech_indicator_list - self.action_space = spaces.Box(low=-1, high=1, shape=(self.action_space,)) + if self.allow_short_selling: + self.action_space = spaces.Box(low=-1, high=1, shape=(self.action_space,)) + else: + self.action_space = spaces.Box(low=0, high=1, shape=(self.action_space,)) self.observation_space = spaces.Box( low=-np.inf, high=np.inf, shape=(self.state_space,) ) @@ -83,6 +90,7 @@ def __init__( self.model_name = model_name self.mode = mode self.iteration = iteration + self.allow_short_selling = allow_short_selling # initalize state self.state = self._initiate_state() @@ -315,6 +323,9 @@ def step(self, actions): actions = actions.astype( int ) # convert into integer because we can't by fraction of shares + # Prevent short selling: clip negative actions to 0 + if not self.allow_short_selling: + actions = np.where(actions < 0, 0, actions) if self.turbulence_threshold is not None: if self.turbulence >= self.turbulence_threshold: actions = np.array([-self.hmax] * self.stock_dim)