{"id":13449729,"url":"https://github.com/Yvictor/TradingGym","last_synced_at":"2025-03-22T22:33:57.409Z","repository":{"id":41142941,"uuid":"89928104","full_name":"Yvictor/TradingGym","owner":"Yvictor","description":"Trading and Backtesting environment for training reinforcement learning agent or simple rule base algo.","archived":false,"fork":false,"pushed_at":"2024-02-11T11:53:21.000Z","size":17812,"stargazers_count":1650,"open_issues_count":12,"forks_count":355,"subscribers_count":105,"default_branch":"master","last_synced_at":"2025-03-17T19:11:50.779Z","etag":null,"topics":["backtest","backtesting-trading-strategies","python","reinforcement-learning","trading","trading-api","trading-bot","trading-platform","trading-simulator","trading-strategies"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Yvictor.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-01T13:53:32.000Z","updated_at":"2025-03-17T15:07:43.000Z","dependencies_parsed_at":"2022-09-03T13:00:46.806Z","dependency_job_id":"f6302653-e1bd-457f-8678-e3f1499d94d7","html_url":"https://github.com/Yvictor/TradingGym","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Yvictor%2FTradingGym","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Yvictor%2FTradingGym/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Yvictor%2FTradingGym/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Yvictor%2FTradingGym/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Yvictor","download_url":"https://codeload.github.com/Yvictor/TradingGym/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245029313,"owners_count":20549684,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backtest","backtesting-trading-strategies","python","reinforcement-learning","trading","trading-api","trading-bot","trading-platform","trading-simulator","trading-strategies"],"created_at":"2024-07-31T06:00:52.623Z","updated_at":"2025-03-22T22:33:53.054Z","avatar_url":"https://github.com/Yvictor.png","language":"Python","funding_links":[],"categories":["Machine Learning","Exchange API","Backtest + live trading","By Industry","Finance","Python","Reinforcement Learning environments","Social Processing"],"sub_categories":["Cryptocurrencies","GYM Environment","Machine Learning / Reinforcement Learning Focused","Finance","Rendering Tools","Events \u0026 Sentiment trading","Sentiment Analysis"],"readme":"# TradingGym\n\n[![Build Status](https://travis-ci.org/Yvictor/TradingGym.svg?branch=master)](https://travis-ci.org/Yvictor/TradingGym)\n\nTradingGym 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.\n\nThis training env originally design for tickdata, but also support for ohlc data format. WIP.\n\n### Installation\n```\ngit clone https://github.com/Yvictor/TradingGym.git\ncd TradingGym\npython setup.py install\n```\n\n### Getting Started\n``` python\nimport random\nimport numpy as np\nimport pandas as pd\nimport trading_env\n\ndf = pd.read_hdf('dataset/SGXTW.h5', 'STW')\n\nenv = trading_env.make(env_id='training_v1', obs_data_len=256, step_len=128,\n                       df=df, fee=0.1, max_position=5, deal_col_name='Price', \n                       feature_names=['Price', 'Volume', \n                                      'Ask_price','Bid_price', \n                                      'Ask_deal_vol','Bid_deal_vol',\n                                      'Bid/Ask_deal', 'Updown'])\n\nenv.reset()\nenv.render()\n\nstate, reward, done, info = env.step(random.randrange(3))\n\n### randow choice action and show the transaction detail\nfor i in range(500):\n    print(i)\n    state, reward, done, info = env.step(random.randrange(3))\n    print(state, reward)\n    env.render()\n    if done:\n        break\nenv.transaction_details\n```\n- obs_data_len: observation data length\n- step_len: when call step rolling windows will + step_len\n- df exmaple\n\u003e|index|datetime|bid|ask|price|volume|serial_number|dealin|\n\u003e|-----|--------|---|---|-----|------|-------------|------|\n\u003e|0|2010-05-25 08:45:00|7188.0|7188.0|7188.0|527.0|0.0|0.0|\n\u003e|1|2010-05-25 08:45:00|7188.0|7189.0|7189.0|1.0|1.0|1.0|\n\u003e|2|2010-05-25 08:45:00|7188.0|7189.0|7188.0|1.0|2.0|-1.0|\n\u003e|3|2010-05-25 08:45:00|7188.0|7189.0|7188.0|4.0|3.0|-1.0|\n\u003e|4|2010-05-25 08:45:00|7188.0|7189.0|7188.0|2.0|4.0|-1.0|\n\n- df: dataframe that contain data for trading \n\u003e serial_number -\u003e serial num of deal at each day recalculating\n\n- fee: when each deal will pay the fee, set with your product. \n- max_position: the max market position for you trading share.\n- deal_col_name: the column name for cucalate reward used.\n- feature_names: list contain the feature columns to use in trading status.\n\n![gif](fig/render.gif)\n\n### Training\n\n#### simple dqn\n- WIP\n#### policy gradient\n- WIP\n#### actor-critic\n- WIP\n#### A3C with RNN\n- WIP\n\n### Backtesting\n\n - loading env just like training\n``` python\nenv = trading_env.make(env_id='backtest_v1', obs_data_len=1024, step_len=512,\n                       df=df, fee=0.1, max_position=5, deal_col_name='Price', \n                        feature_names=['Price', 'Volume', \n                                       'Ask_price','Bid_price', \n                                       'Ask_deal_vol','Bid_deal_vol',\n                                       'Bid/Ask_deal', 'Updown'])\n```\n- load your own agent\n\n``` python \nclass YourAgent:\n    def __init__(self):\n        # build your network and so on\n        pass\n    def choice_action(self, state):\n        ## your rule base conditon or your max Qvalue action or Policy Gradient action\n         # action=0 -\u003e do nothing\n         # action=1 -\u003e buy 1 share\n         # action=2 -\u003e sell 1 share\n        ## in this testing case we just build a simple random policy \n        return np.random.randint(3)\n```\n- start to backtest\n``` python\nagent = YourAgent()\n\ntransactions = []\nwhile not env.backtest_done:\n    state = env.backtest()\n    done = False\n    while not done:\n        state, reward, done, info = env.step(agent.choice_action(state))\n        #print(state, reward)\n        #env.render()\n        if done:\n            transactions.append(info)\n            break\ntransaction = pd.concate(transactions)\ntransaction\n```\n\n\u003cdiv\u003e\n\u003ctable border=\"1\" class=\"dataframe\"\u003e\n  \u003cthead\u003e\n    \u003ctr style=\"text-align: right;\"\u003e\n      \u003cth\u003e\u003c/th\u003e\n      \u003cth\u003estep\u003c/th\u003e\n      \u003cth\u003edatetime\u003c/th\u003e\n      \u003cth\u003etransact\u003c/th\u003e\n      \u003cth\u003etransact_type\u003c/th\u003e\n      \u003cth\u003eprice\u003c/th\u003e\n      \u003cth\u003eshare\u003c/th\u003e\n      \u003cth\u003eprice_mean\u003c/th\u003e\n      \u003cth\u003eposition\u003c/th\u003e\n      \u003cth\u003ereward_fluc\u003c/th\u003e\n      \u003cth\u003ereward\u003c/th\u003e\n      \u003cth\u003ereward_sum\u003c/th\u003e\n      \u003cth\u003ecolor\u003c/th\u003e\n      \u003cth\u003erotation\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003e2\u003c/th\u003e\n      \u003ctd\u003e1537\u003c/td\u003e\n      \u003ctd\u003e2013-04-09 10:58:45\u003c/td\u003e\n      \u003ctd\u003eBuy\u003c/td\u003e\n      \u003ctd\u003enew\u003c/td\u003e\n      \u003ctd\u003e277.1\u003c/td\u003e\n      \u003ctd\u003e1.0\u003c/td\u003e\n      \u003ctd\u003e277.100000\u003c/td\u003e\n      \u003ctd\u003e1.0\u003c/td\u003e\n      \u003ctd\u003e0.000000e+00\u003c/td\u003e\n      \u003ctd\u003e0.000000e+00\u003c/td\u003e\n      \u003ctd\u003e0.000000\u003c/td\u003e\n      \u003ctd\u003e1\u003c/td\u003e\n      \u003ctd\u003e1\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003cth\u003e5\u003c/th\u003e\n      \u003ctd\u003e3073\u003c/td\u003e\n      \u003ctd\u003e2013-04-09 11:47:26\u003c/td\u003e\n      \u003ctd\u003eSell\u003c/td\u003e\n      \u003ctd\u003ecover\u003c/td\u003e\n      \u003ctd\u003e276.8\u003c/td\u003e\n      \u003ctd\u003e-1.0\u003c/td\u003e\n      \u003ctd\u003e277.100000\u003c/td\u003e\n      \u003ctd\u003e0.0\u003c/td\u003e\n      \u003ctd\u003e-4.000000e-01\u003c/td\u003e\n      \u003ctd\u003e-4.000000e-01\u003c/td\u003e\n      \u003ctd\u003e-0.400000\u003c/td\u003e\n      \u003ctd\u003e2\u003c/td\u003e\n      \u003ctd\u003e2\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003cth\u003e10\u003c/th\u003e\n      \u003ctd\u003e5633\u003c/td\u003e\n      \u003ctd\u003e2013-04-09 13:23:40\u003c/td\u003e\n      \u003ctd\u003eSell\u003c/td\u003e\n      \u003ctd\u003enew\u003c/td\u003e\n      \u003ctd\u003e276.9\u003c/td\u003e\n      \u003ctd\u003e-1.0\u003c/td\u003e\n      \u003ctd\u003e276.900000\u003c/td\u003e\n      \u003ctd\u003e-1.0\u003c/td\u003e\n      \u003ctd\u003e0.000000e+00\u003c/td\u003e\n      \u003ctd\u003e0.000000e+00\u003c/td\u003e\n      \u003ctd\u003e-0.400000\u003c/td\u003e\n      \u003ctd\u003e2\u003c/td\u003e\n      \u003ctd\u003e1\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003cth\u003e11\u003c/th\u003e\n      \u003ctd\u003e6145\u003c/td\u003e\n      \u003ctd\u003e2013-04-09 13:30:36\u003c/td\u003e\n      \u003ctd\u003eSell\u003c/td\u003e\n      \u003ctd\u003enew\u003c/td\u003e\n      \u003ctd\u003e276.7\u003c/td\u003e\n      \u003ctd\u003e-1.0\u003c/td\u003e\n      \u003ctd\u003e276.800000\u003c/td\u003e\n      \u003ctd\u003e-2.0\u003c/td\u003e\n      \u003ctd\u003e1.000000e-01\u003c/td\u003e\n      \u003ctd\u003e0.000000e+00\u003c/td\u003e\n      \u003ctd\u003e-0.400000\u003c/td\u003e\n      \u003ctd\u003e2\u003c/td\u003e\n      \u003ctd\u003e1\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003cth\u003e...\u003c/th\u003e\n      \u003ctd\u003e...\u003c/td\u003e\n      \u003ctd\u003e...\u003c/td\u003e\n      \u003ctd\u003e...\u003c/td\u003e\n      \u003ctd\u003e...\u003c/td\u003e\n      \u003ctd\u003e...\u003c/td\u003e\n      \u003ctd\u003e...\u003c/td\u003e\n      \u003ctd\u003e...\u003c/td\u003e\n      \u003ctd\u003e...\u003c/td\u003e\n      \u003ctd\u003e...\u003c/td\u003e\n      \u003ctd\u003e...\u003c/td\u003e\n      \u003ctd\u003e...\u003c/td\u003e\n      \u003ctd\u003e...\u003c/td\u003e\n      \u003ctd\u003e...\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003cth\u003e211\u003c/th\u003e\n      \u003ctd\u003e108545\u003c/td\u003e\n      \u003ctd\u003e2013-04-19 13:18:32\u003c/td\u003e\n      \u003ctd\u003eSell\u003c/td\u003e\n      \u003ctd\u003enew\u003c/td\u003e\n      \u003ctd\u003e286.7\u003c/td\u003e\n      \u003ctd\u003e-1.0\u003c/td\u003e\n      \u003ctd\u003e286.525000\u003c/td\u003e\n      \u003ctd\u003e-2.0\u003c/td\u003e\n      \u003ctd\u003e-4.500000e-01\u003c/td\u003e\n      \u003ctd\u003e0.000000e+00\u003c/td\u003e\n      \u003ctd\u003e30.650000\u003c/td\u003e\n      \u003ctd\u003e2\u003c/td\u003e\n      \u003ctd\u003e1\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003cth\u003e216\u003c/th\u003e\n      \u003ctd\u003e111105\u003c/td\u003e\n      \u003ctd\u003e2013-04-19 16:02:01\u003c/td\u003e\n      \u003ctd\u003eSell\u003c/td\u003e\n      \u003ctd\u003enew\u003c/td\u003e\n      \u003ctd\u003e289.2\u003c/td\u003e\n      \u003ctd\u003e-1.0\u003c/td\u003e\n      \u003ctd\u003e287.416667\u003c/td\u003e\n      \u003ctd\u003e-3.0\u003c/td\u003e\n      \u003ctd\u003e-5.550000e+00\u003c/td\u003e\n      \u003ctd\u003e0.000000e+00\u003c/td\u003e\n      \u003ctd\u003e30.650000\u003c/td\u003e\n      \u003ctd\u003e2\u003c/td\u003e\n      \u003ctd\u003e1\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003cth\u003e217\u003c/th\u003e\n      \u003ctd\u003e111617\u003c/td\u003e\n      \u003ctd\u003e2013-04-19 17:54:29\u003c/td\u003e\n      \u003ctd\u003eSell\u003c/td\u003e\n      \u003ctd\u003enew\u003c/td\u003e\n      \u003ctd\u003e289.2\u003c/td\u003e\n      \u003ctd\u003e-1.0\u003c/td\u003e\n      \u003ctd\u003e287.862500\u003c/td\u003e\n      \u003ctd\u003e-4.0\u003c/td\u003e\n      \u003ctd\u003e-5.650000e+00\u003c/td\u003e\n      \u003ctd\u003e0.000000e+00\u003c/td\u003e\n      \u003ctd\u003e30.650000\u003c/td\u003e\n      \u003ctd\u003e2\u003c/td\u003e\n      \u003ctd\u003e1\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003cth\u003e218\u003c/th\u003e\n      \u003ctd\u003e112129\u003c/td\u003e\n      \u003ctd\u003e2013-04-19 21:36:21\u003c/td\u003e\n      \u003ctd\u003eSell\u003c/td\u003e\n      \u003ctd\u003enew\u003c/td\u003e\n      \u003ctd\u003e288.0\u003c/td\u003e\n      \u003ctd\u003e-1.0\u003c/td\u003e\n      \u003ctd\u003e287.890000\u003c/td\u003e\n      \u003ctd\u003e-5.0\u003c/td\u003e\n      \u003ctd\u003e-9.500000e-01\u003c/td\u003e\n      \u003ctd\u003e0.000000e+00\u003c/td\u003e\n      \u003ctd\u003e30.650000\u003c/td\u003e\n      \u003ctd\u003e2\u003c/td\u003e\n      \u003ctd\u003e1\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003cth\u003e219\u003c/th\u003e\n      \u003ctd\u003e112129\u003c/td\u003e\n      \u003ctd\u003e2013-04-19 21:36:21\u003c/td\u003e\n      \u003ctd\u003eBuy\u003c/td\u003e\n      \u003ctd\u003ecover\u003c/td\u003e\n      \u003ctd\u003e288.0\u003c/td\u003e\n      \u003ctd\u003e5.0\u003c/td\u003e\n      \u003ctd\u003e287.890000\u003c/td\u003e\n      \u003ctd\u003e0.0\u003c/td\u003e\n      \u003ctd\u003e0.000000e+00\u003c/td\u003e\n      \u003ctd\u003e-1.050000e+00\u003c/td\u003e\n      \u003ctd\u003e29.600000\u003c/td\u003e\n      \u003ctd\u003e1\u003c/td\u003e\n      \u003ctd\u003e2\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003e128 rows × 13 columns\u003c/p\u003e\n\u003c/div\u003e\n\n\n\n#### exmaple of rule base usage\n- ma crossover and crossunder\n\n``` python\nenv = trading_env.make(env_id='backtest_v1', obs_data_len=10, step_len=1,\n                       df=df, fee=0.1, max_position=5, deal_col_name='Price', \n                       feature_names=['Price', 'MA'])\nclass MaAgent:\n    def __init__(self):\n        pass\n        \n    def choice_action(self, state):\n        if state[-1][0] \u003e state[-1][1] and state[-2][0] \u003c= state[-2][1]:\n            return 1\n        elif state[-1][0] \u003c state[-1][1] and state[-2][0] \u003e= state[-2][1]:\n            return 2\n        else:\n            return 0\n# then same as above\n```\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FYvictor%2FTradingGym","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FYvictor%2FTradingGym","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FYvictor%2FTradingGym/lists"}