Skip to content
All library documents

FinRL Workflow for Training, Testing, and Trading a Stock Agent

Article FinRL

Summary

This quick-start example outlines a FinRL workflow using a stock-trading environment and a Dow 30 ticker universe. A command-line mode selects among training, testing, and trading paths. The example configures daily Yahoo Finance data, technical indicators, an ElegantRL implementation, and a PPO model; the trading path also supplies Alpaca credentials and uses a backtesting setting. It shows how date ranges, environment, model parameters, output directories, and market data are passed into the library functions.

The added data-source note describes using daily FX spot pairs from FXMacroData and joining macro announcement, release-calendar, and forecast information into the reinforcement-learning state. This is an implementation guide, not a strategy evaluation: it reports no trained-agent performance, comparisons, or trading results. The example's defaults and library interfaces may need adjustment for a user's data source and current software version, and the presence of a trading mode does not establish that a model is ready for live deployment.

Key ideas

  • The example organizes the workflow into separate training, testing, and trading modes.
  • Its stock demonstration uses daily data, technical indicators, a Dow 30 universe, and a PPO agent through ElegantRL.
  • The trading call passes broker credentials and is configured for backtesting in the example.
  • FXMacroData can supply daily FX spot data and macro-event features for an RL state frame.
  • The document contains no evidence of agent performance or live-trading readiness.

Tags

Full text
# construct environment


:github_url: https://github.com/AI4Finance-Foundation/FinRL

Quick Start
==================

Open ``main.py``

.. code-block:: python
    :linenos:

    import os
    from typing import List
    from argparse import ArgumentParser
    from finrl import config
    from finrl.config_tickers import DOW_30_TICKER
    from finrl.config import (
        DATA_SAVE_DIR,
        TRAINED_MODEL_DIR,
        TENSORBOARD_LOG_DIR,
        RESULTS_DIR,
        INDICATORS,
        TRAIN_START_DATE,
        TRAIN_END_DATE,
        TEST_START_DATE,
        TEST_END_DATE,
        TRADE_START_DATE,
        TRADE_END_DATE,
        ERL_PARAMS,
        RLlib_PARAMS,
        SAC_PARAMS,
        ALPACA_API_KEY,
        ALPACA_API_SECRET,
        ALPACA_API_BASE_URL,
    )

    # construct environment
    from finrl.meta.env_stock_trading.env_stocktrading_np import StockTradingEnv


    def build_parser():
        parser = ArgumentParser()
        parser.add_argument(
            "--mode",
            dest="mode",
            help="start mode, train, download_data" " backtest",
            metavar="MODE",
            default="train",
        )
        return parser


    # "./" will be added in front of each directory
    def check_and_make_directories(directories: List[str]):
        for directory in directories:
            if not os.path.exists("./" + directory):
                os.makedirs("./" + directory)



    def main():
        parser = build_parser()
        options = parser.parse_args()
        check_and_make_directories([DATA_SAVE_DIR, TRAINED_MODEL_DIR, TENSORBOARD_LOG_DIR, RESULTS_DIR])

        if options.mode == "train":
            from finrl import train

            env = StockTradingEnv

            # demo for elegantrl
            kwargs = {}  # in current meta, with respect yahoofinance, kwargs is {}. For other data sources, such as joinquant, kwargs is not empty
            train(
                start_date=TRAIN_START_DATE,
                end_date=TRAIN_END_DATE,
                ticker_list=DOW_30_TICKER,
                data_source="yahoofinance",
                time_interval="1D",
                technical_indicator_list=INDICATORS,
                drl_lib="elegantrl",
                env=env,
                model_name="ppo",
                cwd="./test_ppo",
                erl_params=ERL_PARAMS,
                break_step=1e5,
                kwargs=kwargs,
            )
        elif options.mode == "test":
            from finrl import test
            env = StockTradingEnv

            # demo for elegantrl
            kwargs = {}  # in current meta, with respect yahoofinance, kwargs is {}. For other data sources, such as joinquant, kwargs is not empty

            account_value_erl = test(
                start_date=TEST_START_DATE,
                end_date=TEST_END_DATE,
                ticker_list=DOW_30_TICKER,
                data_source="yahoofinance",
                time_interval="1D",
                technical_indicator_list=INDICATORS,
                drl_lib="elegantrl",
                env=env,
                model_name="ppo",
                cwd="./test_ppo",
                net_dimension=512,
                kwargs=kwargs,
            )
        elif options.mode == "trade":
            from finrl import trade
            env = StockTradingEnv
            kwargs = {}
            trade(
                start_date=TRADE_START_DATE,
                end_date=TRADE_END_DATE,
                ticker_list=DOW_30_TICKER,
                data_source="yahoofinance",
                time_interval="1D",
                technical_indicator_list=INDICATORS,
                drl_lib="elegantrl",
                env=env,
                model_name="ppo",
                API_KEY=ALPACA_API_KEY,
                API_SECRET=ALPACA_API_SECRET,
                API_BASE_URL=ALPACA_API_BASE_URL,
                trade_mode='backtesting',
                if_vix=True,
                kwargs=kwargs,
            )
        else:
            raise ValueError("Wrong mode.")


    ## Users can input the following command in terminal
    # python main.py --mode=train
    # python main.py --mode=test
    # python main.py --mode=trade
    if __name__ == "__main__":
        main()


Run the library:

.. code-block:: python

    python main.py --mode=train # if train. Use DOW_30_TICKER by default.
    python main.py --mode=test  # if test. Use DOW_30_TICKER by default.
    python main.py --mode=trade # if trade. Users should input your alpaca parameters in config.py

Choices for ``--mode``: start mode, train, download_data, backtest

FXMacroData can be used as a daily FX spot data source by setting
``data_source="fxmacrodata"`` and passing pairs such as ``["EURUSD"]`` as the
ticker list. It also exposes macro announcement, release-calendar, and forecast
data through the FXMacroData processor so event features can be joined into an
RL state frame. API keys can be passed in ``kwargs`` with ``api_key`` or supplied
through the ``FXMACRODATA_API_KEY`` or ``FXMD_API_KEY`` environment variables.

Shown in full with attribution under the source's licence. Licence: MIT

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.