improving shift ans scale

This commit is contained in:
wassname
2017-07-15 10:58:10 +08:00
parent 835b9e3682
commit c7d80187f2
4 changed files with 39 additions and 15 deletions
+1 -2
View File
@@ -7,8 +7,7 @@ def random_shift(x, fraction):
"""Apply a random shift to a pandas series."""
min_x, max_x = np.min(x), np.max(x)
m = np.random.uniform(-fraction, fraction, size=x.shape) + 1
c = np.random.uniform(-fraction, fraction, size=x.shape) * x.std()
return np.clip(x * m + c, min_x, max_x)
return np.clip(x * m, min_x, max_x)
def normalize(x):
+9 -5
View File
@@ -24,22 +24,24 @@ class DataSrc(object):
self.augument = augument
self.scale = scale
df = df.copy()
# add return/y1 as last col
pairs = df.columns.levels[0]
for pair in pairs:
x = df[pair].close
df[pair, "return"] = (x + eps*2) / (x.shift() + eps)
df[pair, "return"] = (x + eps) / (x.shift() + eps)
df = df[1:]
# data processing
if scale:
# df = (df - df.mean(0) + eps) / (df.max(0) - df.min(0) + eps)
df = df.apply(lambda x: normalize(x))
# don't normalize return
df = df.apply(
lambda x: normalize(x) if x.name[1] != 'return' else x)
# get rid of NaN's
df = df.fillna(method="pad")
df.replace(np.nan, 0, inplace=True)
df = df.fillna(method="pad")
self._data = df.copy()
self.asset_names = self._data.columns.levels[0].tolist()
@@ -64,8 +66,10 @@ class DataSrc(object):
data = self._data[self.idx:self.idx + self.steps].copy()
# scale each run to the begining of the episode so they look the same
# but not return
if self.scale:
data = data.apply(lambda x: scale_to_start(x))
data = data.apply(
lambda x: scale_to_start(x) if x.name[1] != 'return' else x)
# augument data to prevent overfitting
data = data.apply(lambda x: random_shift(x, self.augument))
+26 -5
View File
@@ -6,19 +6,29 @@ from src.environments.portfolio import PortfolioEnv
def test_portfolio_env():
df = pd.read_hdf('./data/poliniex_30m.hf', key='train')
asset_names = df.columns.levels[0]
# action
w = np.random.random((len(asset_names)))
w /= w.sum()
np.random.seed(0)
env = PortfolioEnv(df=df)
env.reset()
obs, reward, done, info = env.step(w)
obs = env.reset()
for _ in range(20):
w = np.random.random((len(asset_names)))
w /= w.sum()
obs, reward, done, info = env.step(w)
assert not done
df_info = pd.DataFrame(info)
final_value = df_info.portfolio_value.iloc[-1]
assert final_value > 0.75, 'should retain most value with 20 random steps'
def test_portfolio_env_hold():
df = pd.read_hdf('./data/poliniex_30m.hf', key='train')
asset_names = df.columns.levels[0]
np.random.seed(0)
env = PortfolioEnv(df=df)
env.reset()
for _ in range(5):
@@ -27,3 +37,14 @@ def test_portfolio_env_hold():
df = pd.DataFrame(info)
assert df.portfolio_value.iloc[-1] > 0.9999, 'portfolio should retain value if holding bitcoin'
def test_return_not_scaled():
df = pd.read_hdf('./data/poliniex_30m.hf', key='train')
np.random.seed(0)
env1 = PortfolioEnv(df=df, scale=True)
np.random.seed(0)
env0 = PortfolioEnv(df=df, scale=False)
a = env0.src._data.xs('return', axis=1, level='Price').tail(5)
b = env1.src._data.xs('return', axis=1, level='Price').tail(5)
assert (a == b).all().all(), 'returns should not be scaled'
+3 -3
View File
@@ -10,9 +10,9 @@ def test_random_shift():
assert (s == s1).all(), 'should not do anything if given 0'
s2 = random_shift(s.copy(), 0.05)
assert (s2 / s).max() > 1.0, 'should shift more than 0.00 given 0.05'
assert (s2 / s).max() < 1.1, 'should shift less than 0.10 given 0.05'
np.testing.assert_almost_equal((s2 / s).mean(), 1.00, 2)
shift = (s2 / s)
np.testing.assert_almost_equal(shift.mean(), 1.00, 2)
np.testing.assert_almost_equal(shift.max(), 1.05, 2)
def test_normalize():