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

Performance #116

Open
wants to merge 3 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
Binary file not shown.
Binary file removed data/params.db
Binary file not shown.
39 changes: 39 additions & 0 deletions lib/data/features/transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,42 @@ def difference(iterable: Iterable, inplace: bool = True, columns: List[str] = No

def log_and_difference(iterable: Iterable, inplace: bool = True, columns: List[str] = None):
return transform(iterable, inplace, columns, lambda t_iterable: np.log(t_iterable) - np.log(t_iterable).shift(1))


class FastTransform:

MIN="min"
MAX="max"

def __init__(self):
self.cached_min_max = dict()

def max_min_normalize(self, iterable: Iterable, inplace: bool = True, columns: List[str] = None):
columns = iterable.columns if columns is None else columns

if iterable.empty:
return iterable

for column in columns:
cached_min = self.cached_min_max[FastTransform.MIN + column] if FastTransform.MIN + column in self.cached_min_max else np.min(iterable[column])
cached_max = self.cached_min_max[FastTransform.MAX + column] if FastTransform.MAX + column in self.cached_min_max else np.max(iterable[column])

new_min = min(cached_min, iterable.iloc[-1][column])
new_max = max(cached_max, iterable.iloc[-1][column])

iterable.iloc[-1][column] = (iterable.iloc[-1][column] - new_min) / (new_max - new_min)

self._update_cache(column, new_min, new_max)

return iterable

def _update_cache(self,column, min, max):
#don't want to save nan's as it will force recalculation on the next iteration
if not np.isnan(min):
self.cached_min_max[FastTransform.MIN + column] = min

if not np.isnan(max):
self.cached_min_max[FastTransform.MAX + column] = max

def _get_cached(self, column):
return self.cached_min_max[FastTransform.MIN + column], self.cached_min_max[FastTransform.MAX + column]
67 changes: 37 additions & 30 deletions lib/env/TradingEnv.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from lib.env.render import TradingChart
from lib.env.reward import BaseRewardStrategy, IncrementalProfit
from lib.data.providers import BaseDataProvider
from lib.data.features.transform import max_min_normalize, mean_normalize, log_and_difference, difference
from lib.data.features.transform import max_min_normalize, log_and_difference, FastTransform, difference
from lib.util.logger import init_logger


Expand Down Expand Up @@ -58,6 +58,10 @@ def __init__(self,
self.observation_space = spaces.Box(low=0, high=1, shape=self.obs_shape, dtype=np.float16)

self.observations = pd.DataFrame(None, columns=self.data_provider.columns)
self.fast_transform_observations = FastTransform()
self.fast_transform_account_history = FastTransform()

self.fast_log_observation = self.observations

def _current_price(self, ohlcv_key: str = 'Close'):
return float(self.current_ohlcv[ohlcv_key])
Expand Down Expand Up @@ -97,6 +101,38 @@ def _make_trade(self, action: int, current_price: float):

return asset_bought, asset_sold, cost_of_asset, revenue_from_sold

def _next_observation(self):
self.current_ohlcv = self.data_provider.next_ohlcv()
self.observations = self.observations.append(self.current_ohlcv, ignore_index=True)

if self.stationarize_obs:
log_observation = log_and_difference(self.observations.tail(2), inplace=False)
self.fast_log_observation = self.fast_log_observation.append(log_observation.tail(1), ignore_index=True)
observations = self.fast_log_observation
else:
observations = self.observations

if self.normalize_obs:
observations = self.fast_transform_observations.max_min_normalize(observations)

obs = observations.values[-1]

if self.stationarize_obs:
scaled_history = log_and_difference(self.account_history, inplace=False)
else:
scaled_history = self.account_history

if self.normalize_obs:
scaled_history = self.fast_transform_account_history.max_min_normalize(self.account_history)

obs = np.insert(obs, len(obs), scaled_history.values[-1], axis=0)

obs = np.reshape(obs.astype('float16'), self.obs_shape)
obs[np.bitwise_not(np.isfinite(obs))] = 0

return obs


def _take_action(self, action: int):
current_price = self._current_price()

Expand Down Expand Up @@ -143,35 +179,6 @@ def _reward(self):

return float(rewards[-1])

def _next_observation(self):
self.current_ohlcv = self.data_provider.next_ohlcv()
self.observations = self.observations.append(self.current_ohlcv, ignore_index=True)

if self.stationarize_obs:
observations = log_and_difference(self.observations, inplace=False)
else:
observations = self.observations

if self.normalize_obs:
observations = max_min_normalize(observations)

obs = observations.values[-1]

if self.stationarize_obs:
scaled_history = log_and_difference(self.account_history, inplace=False)
else:
scaled_history = self.account_history

if self.normalize_obs:
scaled_history = max_min_normalize(scaled_history, inplace=False)

obs = np.insert(obs, len(obs), scaled_history.values[-1], axis=0)

obs = np.reshape(obs.astype('float16'), self.obs_shape)
obs[np.bitwise_not(np.isfinite(obs))] = 0

return obs

def reset(self):
self.data_provider.reset_ohlcv_index()

Expand Down