Yvictor/TradingGym

Trading and Backtesting environment for training reinforcement learning agent or simple rule base algo.

Python

1,924

47 commits

updated Feb 11, 2024

See the code

README

TradingGym

Build Status

TradingGym is a toolkit for training and backtesting the reinforcement learning algorithms. This was inspired by OpenAI Gym and imitated the framework form. Not only traning env but also has backtesting and in the future will implement realtime trading env with Interactivate Broker API and so on.

This training env originally design for tickdata, but also support for ohlc data format. WIP.

Installation

git clone https://github.com/Yvictor/TradingGym.git
cd TradingGym
python setup.py install

Getting Started

import random
import numpy as np
import pandas as pd
import trading_env

df = pd.read_hdf('dataset/SGXTW.h5', 'STW')

env = trading_env.make(env_id='training_v1', obs_data_len=256, step_len=128,
                       df=df, fee=0.1, max_position=5, deal_col_name='Price', 
                       feature_names=['Price', 'Volume', 
                                      'Ask_price','Bid_price', 
                                      'Ask_deal_vol','Bid_deal_vol',
                                      'Bid/Ask_deal', 'Updown'])

env.reset()
env.render()

state, reward, done, info = env.step(random.randrange(3))

### randow choice action and show the transaction detail
for i in range(500):
    print(i)
    state, reward, done, info = env.step(random.randrange(3))
    print(state, reward)
    env.render()
    if done:
        break
env.transaction_details
  • obs_data_len: observation data length
  • step_len: when call step rolling windows will + step_len
  • df exmaple
indexdatetimebidaskpricevolumeserial_numberdealin
02010-05-25 08:45:007188.07188.07188.0527.00.00.0
12010-05-25 08:45:007188.07189.07189.01.01.01.0
22010-05-25 08:45:007188.07189.07188.01.02.0-1.0
32010-05-25 08:45:007188.07189.07188.04.03.0-1.0
42010-05-25 08:45:007188.07189.07188.02.04.0-1.0
  • df: dataframe that contain data for trading

serial_number -> serial num of deal at each day recalculating

  • fee: when each deal will pay the fee, set with your product.
  • max_position: the max market position for you trading share.
  • deal_col_name: the column name for cucalate reward used.
  • feature_names: list contain the feature columns to use in trading status.

gif

Training

simple dqn

  • WIP

policy gradient

  • WIP

actor-critic

  • WIP

A3C with RNN

  • WIP

Backtesting

  • loading env just like training
env = trading_env.make(env_id='backtest_v1', obs_data_len=1024, step_len=512,
                       df=df, fee=0.1, max_position=5, deal_col_name='Price', 
                        feature_names=['Price', 'Volume', 
                                       'Ask_price','Bid_price', 
                                       'Ask_deal_vol','Bid_deal_vol',
                                       'Bid/Ask_deal', 'Updown'])
  • load your own agent
class YourAgent:
    def __init__(self):
        # build your network and so on
        pass
    def choice_action(self, state):
        ## your rule base conditon or your max Qvalue action or Policy Gradient action
         # action=0 -> do nothing
         # action=1 -> buy 1 share
         # action=2 -> sell 1 share
        ## in this testing case we just build a simple random policy 
        return np.random.randint(3)
  • start to backtest
agent = YourAgent()

transactions = []
while not env.backtest_done:
    state = env.backtest()
    done = False
    while not done:
        state, reward, done, info = env.step(agent.choice_action(state))
        #print(state, reward)
        #env.render()
        if done:
            transactions.append(info)
            break
transaction = pd.concate(transactions)
transaction
stepdatetimetransacttransact_typepriceshareprice_meanpositionreward_flucrewardreward_sumcolorrotation
215372013-04-09 10:58:45Buynew277.11.0277.1000001.00.000000e+000.000000e+000.00000011
530732013-04-09 11:47:26Sellcover276.8-1.0277.1000000.0-4.000000e-01-4.000000e-01-0.40000022
1056332013-04-09 13:23:40Sellnew276.9-1.0276.900000-1.00.000000e+000.000000e+00-0.40000021
1161452013-04-09 13:30:36Sellnew276.7-1.0276.800000-2.01.000000e-010.000000e+00-0.40000021
..........................................
2111085452013-04-19 13:18:32Sellnew286.7-1.0286.525000-2.0-4.500000e-010.000000e+0030.65000021
2161111052013-04-19 16:02:01Sellnew289.2-1.0287.416667-3.0-5.550000e+000.000000e+0030.65000021
2171116172013-04-19 17:54:29Sellnew289.2-1.0287.862500-4.0-5.650000e+000.000000e+0030.65000021
2181121292013-04-19 21:36:21Sellnew288.0-1.0287.890000-5.0-9.500000e-010.000000e+0030.65000021
2191121292013-04-19 21:36:21Buycover288.05.0287.8900000.00.000000e+00-1.050000e+0029.60000012

128 rows × 13 columns

exmaple of rule base usage

  • ma crossover and crossunder
env = trading_env.make(env_id='backtest_v1', obs_data_len=10, step_len=1,
                       df=df, fee=0.1, max_position=5, deal_col_name='Price', 
                       feature_names=['Price', 'MA'])
class MaAgent:
    def __init__(self):
        pass
        
    def choice_action(self, state):
        if state[-1][0] > state[-1][1] and state[-2][0] <= state[-2][1]:
            return 1
        elif state[-1][0] < state[-1][1] and state[-2][0] >= state[-2][1]:
            return 2
        else:
            return 0
# then same as above
backtest
backtesting-trading-strategies
python
reinforcement-learning
trading
trading-api
trading-bot
trading-platform
trading-simulator
trading-strategies

Yvictor/TradingGym

Trading and Backtesting environment for training reinforcement learning agent or simple rule base algo.

Python

1,924

47 commits

updated Feb 11, 2024

See the code

README

TradingGym

Build Status

TradingGym is a toolkit for training and backtesting the reinforcement learning algorithms. This was inspired by OpenAI Gym and imitated the framework form. Not only traning env but also has backtesting and in the future will implement realtime trading env with Interactivate Broker API and so on.

This training env originally design for tickdata, but also support for ohlc data format. WIP.

Installation

git clone https://github.com/Yvictor/TradingGym.git
cd TradingGym
python setup.py install

Getting Started

import random
import numpy as np
import pandas as pd
import trading_env

df = pd.read_hdf('dataset/SGXTW.h5', 'STW')

env = trading_env.make(env_id='training_v1', obs_data_len=256, step_len=128,
                       df=df, fee=0.1, max_position=5, deal_col_name='Price', 
                       feature_names=['Price', 'Volume', 
                                      'Ask_price','Bid_price', 
                                      'Ask_deal_vol','Bid_deal_vol',
                                      'Bid/Ask_deal', 'Updown'])

env.reset()
env.render()

state, reward, done, info = env.step(random.randrange(3))

### randow choice action and show the transaction detail
for i in range(500):
    print(i)
    state, reward, done, info = env.step(random.randrange(3))
    print(state, reward)
    env.render()
    if done:
        break
env.transaction_details
  • obs_data_len: observation data length
  • step_len: when call step rolling windows will + step_len
  • df exmaple
indexdatetimebidaskpricevolumeserial_numberdealin
02010-05-25 08:45:007188.07188.07188.0527.00.00.0
12010-05-25 08:45:007188.07189.07189.01.01.01.0
22010-05-25 08:45:007188.07189.07188.01.02.0-1.0
32010-05-25 08:45:007188.07189.07188.04.03.0-1.0
42010-05-25 08:45:007188.07189.07188.02.04.0-1.0
  • df: dataframe that contain data for trading

serial_number -> serial num of deal at each day recalculating

  • fee: when each deal will pay the fee, set with your product.
  • max_position: the max market position for you trading share.
  • deal_col_name: the column name for cucalate reward used.
  • feature_names: list contain the feature columns to use in trading status.

gif

Training

simple dqn

  • WIP

policy gradient

  • WIP

actor-critic

  • WIP

A3C with RNN

  • WIP

Backtesting

  • loading env just like training
env = trading_env.make(env_id='backtest_v1', obs_data_len=1024, step_len=512,
                       df=df, fee=0.1, max_position=5, deal_col_name='Price', 
                        feature_names=['Price', 'Volume', 
                                       'Ask_price','Bid_price', 
                                       'Ask_deal_vol','Bid_deal_vol',
                                       'Bid/Ask_deal', 'Updown'])
  • load your own agent
class YourAgent:
    def __init__(self):
        # build your network and so on
        pass
    def choice_action(self, state):
        ## your rule base conditon or your max Qvalue action or Policy Gradient action
         # action=0 -> do nothing
         # action=1 -> buy 1 share
         # action=2 -> sell 1 share
        ## in this testing case we just build a simple random policy 
        return np.random.randint(3)
  • start to backtest
agent = YourAgent()

transactions = []
while not env.backtest_done:
    state = env.backtest()
    done = False
    while not done:
        state, reward, done, info = env.step(agent.choice_action(state))
        #print(state, reward)
        #env.render()
        if done:
            transactions.append(info)
            break
transaction = pd.concate(transactions)
transaction
stepdatetimetransacttransact_typepriceshareprice_meanpositionreward_flucrewardreward_sumcolorrotation
215372013-04-09 10:58:45Buynew277.11.0277.1000001.00.000000e+000.000000e+000.00000011
530732013-04-09 11:47:26Sellcover276.8-1.0277.1000000.0-4.000000e-01-4.000000e-01-0.40000022
1056332013-04-09 13:23:40Sellnew276.9-1.0276.900000-1.00.000000e+000.000000e+00-0.40000021
1161452013-04-09 13:30:36Sellnew276.7-1.0276.800000-2.01.000000e-010.000000e+00-0.40000021
..........................................
2111085452013-04-19 13:18:32Sellnew286.7-1.0286.525000-2.0-4.500000e-010.000000e+0030.65000021
2161111052013-04-19 16:02:01Sellnew289.2-1.0287.416667-3.0-5.550000e+000.000000e+0030.65000021
2171116172013-04-19 17:54:29Sellnew289.2-1.0287.862500-4.0-5.650000e+000.000000e+0030.65000021
2181121292013-04-19 21:36:21Sellnew288.0-1.0287.890000-5.0-9.500000e-010.000000e+0030.65000021
2191121292013-04-19 21:36:21Buycover288.05.0287.8900000.00.000000e+00-1.050000e+0029.60000012

128 rows × 13 columns

exmaple of rule base usage

  • ma crossover and crossunder
env = trading_env.make(env_id='backtest_v1', obs_data_len=10, step_len=1,
                       df=df, fee=0.1, max_position=5, deal_col_name='Price', 
                       feature_names=['Price', 'MA'])
class MaAgent:
    def __init__(self):
        pass
        
    def choice_action(self, state):
        if state[-1][0] > state[-1][1] and state[-2][0] <= state[-2][1]:
            return 1
        elif state[-1][0] < state[-1][1] and state[-2][0] >= state[-2][1]:
            return 2
        else:
            return 0
# then same as above
backtest
backtesting-trading-strategies
python
reinforcement-learning
trading
trading-api
trading-bot
trading-platform
trading-simulator
trading-strategies

Significant stargazers

Weston Platter

175 followers · starred Aug 2023

Ruben Fonseca

174 followers · starred Nov 2020

NotMoni

75 followers · starred Mar 2023

Kris Wu

54 followers · starred Oct 2019