Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

python 3.x #12

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Trading Gym
# Trading Gym (Python 3.x)

Trading Gym is an open-source project for the development of reinforcement learning algorithms in the context of trading.
It is currently composed of a single environment and implements a generic way of feeding this trading environment different type of price data.
Expand All @@ -7,6 +7,10 @@ It is currently composed of a single environment and implements a generic way of

`pip install tgym`

if you clone the project to local, run

`python setup.py install`

We strongly recommend using virtual environments. A very good guide can be found at http://python-guide-pt-br.readthedocs.io/en/latest/dev/virtualenvs/.

## The trading environment: `SpreadTrading`
Expand All @@ -28,3 +32,16 @@ Our environments API is strongly inspired by OpenAI Gym. We aim to entirely base
Some examples are available in `tgym/examples/`

To run the `dqn_agent.py` example, you will need to also install keras with `pip install keras`. By default, the backend will be set to Theano. You can also run it with Tensorflow by installing it with `pip install tensorflow`. You then need to edit `~/.keras/keras.json` and make sure `"backend": "tensorflow"` is specified.

## To Do List
1. Python 3
- [x] a. print issue
- [x] b. module import (need to python setup.py install/develop)
- [x] c. class iter issue (__next(self)__, change next(obj))
- [x] d. testing coverage
2. Add more features
- [ ] a. pips (%)
- [ ] b. limit order
- [ ] c. sl, pt, holding postion value
- [ ] d. on-line data feeder
- [ ] e. realtime feed
7 changes: 4 additions & 3 deletions examples/csv_streamer.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from tgym.envs import SpreadTrading
from tgym.gens import CSVStreamer
from __future__ import absolute_import
from tgym.envs.trading_spread import SpreadTrading
from tgym.gens.csvstream import CSVStreamer

generator = CSVStreamer(filename='./examples/price_2.csv')

Expand All @@ -11,7 +12,7 @@

environment.render()
while True:
action = raw_input("Action: Buy (b) / Sell (s) / Hold (enter): ")
action = input("Action: Buy (b) / Sell (s) / Hold (enter): ")
if action == 'b':
action = [0, 1, 0]
elif action == 's':
Expand Down
36 changes: 31 additions & 5 deletions examples/dqn_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from keras.layers import Dense
from keras.models import Sequential
from keras.optimizers import Adam
from tgym.envs import SpreadTrading
from tgym.envs.trading_spread import SpreadTrading


class DQNAgent:
Expand Down Expand Up @@ -110,16 +110,42 @@ def _get_batches(self):
if __name__ == "__main__":
import matplotlib.pyplot as plt

from tgym.envs import SpreadTrading
from tgym.gens.deterministic import WavySignal
from tgym.envs.trading_spread import SpreadTrading
from tgym.gens.deterministic import WavySignal,RandomGenerator
from tgym.gens.csvstream import CSVStreamer
from tgym.envs.trading_tick import TickTrading
# Instantiating the environmnent
generator = WavySignal(period_1=25, period_2=50, epsilon=-0.5)
gen_type = 'C'
if gen_type == 'W':
generator = WavySignal(period_1=25, period_2=50, epsilon=-0.5,ba_spread = 0.0001 )
elif gen_type == 'R':
generator = RandomGenerator(spread = 0.0001,range_low =1.0,range_high=2.0)
elif gen_type == 'C':
filename = r'./examples/price_usdeur.csv'
generator = CSVStreamer(filename=filename)

episodes = 50
episode_length = 400
trading_fee = .2
time_fee = 0
history_length = 2
environment = SpreadTrading(spread_coefficients=[1],
episode_length = 200000

# history_length number of historical states in the observation vector.
profit_taken = 10
stop_loss = -5
render_show = False
trading_type = 'T'
if trading_type == 'T':
environment = TickTrading( data_generator=generator,
trading_fee=trading_fee,
time_fee=time_fee,
history_length=history_length,
episode_length=episode_length,
profit_taken = profit_taken,
stop_loss = stop_loss)
else:
environment = SpreadTrading(spread_coefficients=[1],
data_generator=generator,
trading_fee=trading_fee,
time_fee=time_fee,
Expand Down
6 changes: 6 additions & 0 deletions examples/price_2.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
10.0,21.0,11.0,22.0
12.0,22.0,12.0,24.0
12.0,22.0,13.0,24.0
12.1,22.1,15.1,27.1
12.5,22.5,16.1,26.1
11.5,21.5,17.1,21.1
23 changes: 10 additions & 13 deletions examples/random_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,17 @@
In this example we show how a random generator is coded.
All generators inherit from the DataGenerator class
The class yields tuple (bid_price,ask_price)
spread = ask_price - bid_price
limit range between range_low, range_high
better format for return value
"""
from __future__ import absolute_import
import numpy as np
from tgym.core import DataGenerator
from tgym.gens.deterministic import RandomGenerator


class RandomGenerator(DataGenerator):
@staticmethod
def _generator(ba_spread=0):
while True:
val = np.random.randn()
yield val, val + ba_spread


time_series_length = 10
mygen = RandomGenerator()
prices_time_series = [mygen.next() for _ in range(time_series_length)]
print prices_time_series
if __name__ == "__main__":
time_series_length = 100
mygen = RandomGenerator(spread = 0.01,range_low =1.0,range_high=2.0)
prices_time_series = [next(mygen) for _ in range(time_series_length)]
print (prices_time_series)
46 changes: 46 additions & 0 deletions examples/testing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
def add_position(action,pr,ls):
if action in ('b','s'):
bt = (action,(_tick_buy if action == 'b' else _tick_sell), pr, ls)
_holding_position.append(bt)

def close_position(position):
if position[0] == 'b':
pr = (_tick_buy - position[1]) * 10000.0
st = (position[1] - _tick_sell) * 10000.0
elif position[0] == 's':
pr = (position[1] - _tick_sell ) * 10000.0
st = (_tick_buy - position[1] ) * 10000.0

if pr >= position[2]:
print(position, pr, 'pr')
return pr, True
elif st <= position[3]:
print(position, st,'st')
return st, True
else :
print(position, 'nothing')
return 0, False



def calculate_position():
rewards = 0
result = []
for position in _holding_position:
reward, remove = close_position(position)
rewards += reward
if remove:
result.append(position)
return rewards, result


#testing script
_tick_buy = 1.3330
_tick_sell = 1.3329
_holding_position = [('b',1.3333,100,50),('b',1.3343,300,600),('b',1.3383,90,20),('s',1.3333,100,50)]
add_position('s',100,501)
add_position('b',100,502)
rewards, new_position = calculate_position()

print (rewards)
print (new_position)
35 changes: 0 additions & 35 deletions examples/trading_environment.py

This file was deleted.

52 changes: 52 additions & 0 deletions examples/trading_spread_env.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""
The aim of this file is to give a standalone example of how an environment runs.
"""
import os
import numpy as np
from tgym.core import DataGenerator
from tgym.envs.trading_tick import TickTrading
from tgym.gens.deterministic import WavySignal, RandomGenerator


gen_type = 'W'
if gen_type == 'W':
generator = WavySignal(period_1=25, period_2=50, epsilon=-0.5,ba_spread = 0.0001 )
elif gen_type == 'R':
generator = RandomGenerator(spread = 0.0001,range_low =1.0,range_high=2.0)


episode_length = 200
trading_fee = 0.2
time_fee = 0
# history_length number of historical states in the observation vector.
history_length = 2
profit_taken = 6000
stop_loss = -7000

environment = TickTrading( data_generator=generator,
trading_fee=trading_fee,
time_fee=time_fee,
history_length=history_length,
episode_length=episode_length,
profit_taken = profit_taken,
stop_loss = stop_loss)

environment.render()
i = 0
while True:
#action = input("Action: Buy (b) / Sell (s) / Hold (enter): ")

# if action == 'b':
# action = [0, 1, 0]
# elif action == 's':
# action = [0, 0, 1]
# else:
# action = [1, 0, 0]
'''
kind of random action
'''
action = [0, 1, 0] if i%7 == 0 else ([0, 0, 1] if i%13 == 0 else [1, 0, 0])

environment.step(action)
environment.render()
i += 1
56 changes: 56 additions & 0 deletions examples/trading_tick_env.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
"""
The aim of this file is to give a standalone example of how an environment runs.
"""
import os
import numpy as np
from tgym.core import DataGenerator
from tgym.envs.trading_tick import TickTrading
from tgym.gens.deterministic import WavySignal, RandomGenerator
from tgym.gens.csvstream import CSVStreamer

gen_type = 'C'
if gen_type == 'W':
generator = WavySignal(period_1=25, period_2=50, epsilon=-0.5,ba_spread = 0.0001 )
elif gen_type == 'R':
generator = RandomGenerator(spread = 0.0001,range_low =1.0,range_high=2.0)
elif gen_type == 'C':
filename = r'./examples/price_usdeur.csv'
generator = CSVStreamer(filename=filename)

episode_length = 200000
trading_fee = 0.2
time_fee = 0
# history_length number of historical states in the observation vector.
history_length = 2
profit_taken = 10
stop_loss = -5
render_show = False
environment = TickTrading( data_generator=generator,
trading_fee=trading_fee,
time_fee=time_fee,
history_length=history_length,
episode_length=episode_length,
profit_taken = profit_taken,
stop_loss = stop_loss)

if render_show :
environment.render()
i = 0
while True:
#action = input("Action: Buy (b) / Sell (s) / Hold (enter): ")

# if action == 'b':
# action = [0, 1, 0]
# elif action == 's':
# action = [0, 0, 1]
# else:
# action = [1, 0, 0]
'''
kind of random action
'''
action = [0, 1, 0] if i%7 == 0 else ([0, 0, 1] if i%13 == 0 else [1, 0, 0])

environment.step(action)
if render_show :
environment.render()
i += 1
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
url='https://github.com/prediction-machines/tgym',
packages=find_packages(),
install_requires=[
'matplotlib==2.0.2'
#'matplotlib>=2.0.2'
],
license="MIT license",
zip_safe=False,
Expand Down
4 changes: 2 additions & 2 deletions tests/envs/test_trading.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import numpy as np
from tgym.envs import SpreadTrading
from tgym.gens import WavySignal
from tgym.envs.trading import SpreadTrading
from tgym.gens.deterministic import WavySignal


class TestSpreadTrading(object):
Expand Down
3 changes: 1 addition & 2 deletions tests/gens/test_csvstream.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import csv

import numpy as np
from tgym.gens import CSVStreamer

from tgym.gens.csvstream import CSVStreamer

def test_csv_streamer():
with open('test.csv', 'w+') as csvfile:
Expand Down
2 changes: 1 addition & 1 deletion tests/gens/test_random.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import numpy as np
from tgym.gens import AR1, RandomWalk
from tgym.gens.random import AR1, RandomWalk


def test_random_walk():
Expand Down
Loading