panelbeater 0.0.2__tar.gz → 0.0.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of panelbeater might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: panelbeater
3
- Version: 0.0.2
3
+ Version: 0.0.3
4
4
  Summary: A CLI for finding mispriced options.
5
5
  Home-page: https://github.com/8W9aG/panelbeater
6
6
  Author: Will Sackfield
@@ -1,3 +1,3 @@
1
1
  """panelbeater initialisation."""
2
2
 
3
- __VERSION__ = "0.0.2"
3
+ __VERSION__ = "0.0.3"
@@ -3,11 +3,12 @@
3
3
  import datetime
4
4
 
5
5
  import requests_cache
6
+ import tqdm
6
7
  import wavetrainer as wt
7
8
 
8
9
  from .download import download
9
10
  from .features import features
10
- from .normalizer import normalize
11
+ from .normalizer import denormalize, normalize
11
12
 
12
13
  _TICKERS = [
13
14
  # Equities
@@ -46,6 +47,7 @@ _WINDOWS = [
46
47
  200,
47
48
  ]
48
49
  _LAGS = [1, 3, 5, 10, 20, 30]
50
+ _DAYS_OUT = 30
49
51
 
50
52
 
51
53
  def main() -> None:
@@ -61,8 +63,13 @@ def main() -> None:
61
63
  )
62
64
  df_y = download(tickers=_TICKERS, macros=_MACROS, session=session)
63
65
  df_x = features(df=df_y.copy(), windows=_WINDOWS, lags=_LAGS)
64
- df_y = normalize(df=df_y)
65
- wavetrainer.fit(df_x, y=df_y)
66
+ df_y_norm = normalize(df=df_y.copy())
67
+ for _ in tqdm.tqdm(range(_DAYS_OUT), desc="Running t+X simulation"):
68
+ wavetrainer.fit(df_x, y=df_y_norm)
69
+ df_next = wavetrainer.transform(df_y_norm)
70
+ df_next = denormalize(df_next)
71
+ df_x = features(df=df_next.copy(), windows=_WINDOWS, lags=_LAGS)
72
+ df_y_norm = normalize(df=df_next.copy())
66
73
 
67
74
 
68
75
  if __name__ == "__main__":
@@ -63,8 +63,4 @@ def download(
63
63
  levels = pd.concat(
64
64
  [prices.add_prefix("PX_"), macro.add_prefix("MACRO_")], axis=1
65
65
  ).ffill()
66
- return (
67
- levels.replace([np.inf, -np.inf], np.nan)
68
- .pct_change(fill_method=None)
69
- .replace([np.inf, -np.inf], np.nan)
70
- )
66
+ return levels.replace([np.inf, -np.inf], np.nan)
@@ -36,7 +36,6 @@ def _meta_ticker_feature(
36
36
  for window in tqdm.tqdm(windows, desc="Generating window features"):
37
37
  dfs.append(df.rolling(window).mean().add_suffix(f"_rmean{window}")) # type: ignore
38
38
  dfs.append(df.rolling(window).std().add_suffix(f"_rstd{window}")) # type: ignore
39
- dfs.append(df.diff().add_suffix("_diff1"))
40
39
  return pd.concat(dfs, axis=1).replace([np.inf, -np.inf], np.nan)
41
40
 
42
41
 
@@ -0,0 +1,59 @@
1
+ """Normalize the Y targets to standard deviations."""
2
+
3
+ # pylint: disable=too-many-locals
4
+
5
+ import math
6
+
7
+ import numpy as np
8
+ import pandas as pd
9
+ import tqdm
10
+ from wavetrainer.model.model import PROBABILITY_COLUMN_PREFIX
11
+
12
+
13
+ def normalize(df: pd.DataFrame) -> pd.DataFrame:
14
+ """Normalize the dataframe per column by z-score bucketing."""
15
+ df = df.pct_change(fill_method=None).replace([np.inf, -np.inf], np.nan)
16
+ mu = df.rolling(365).mean()
17
+ sigma = df.rolling(365).std()
18
+ df = ((((df - mu) / sigma) * 2.0).round() / 2.0).clip(-3, 3)
19
+ dfs = []
20
+ for col in tqdm.tqdm(df.columns, desc="Normalising targets"):
21
+ for unique_val in df[col].unique():
22
+ if math.isnan(unique_val):
23
+ continue
24
+ s = (df[col] == unique_val).rename(f"{col}_{unique_val}")
25
+ dfs.append(s)
26
+ return pd.concat(dfs, axis=1)
27
+
28
+
29
+ def denormalize(df: pd.DataFrame) -> pd.DataFrame:
30
+ """Denormalize the dataframe back to a total value."""
31
+ date_to_add = df.index[-1] + pd.Timedelta(days=1)
32
+
33
+ cols = set(df.columns.values.tolist())
34
+ target_cols = {x for x in cols if "_".join(x.split("_")[:-1])}
35
+ for col in target_cols:
36
+ df[col] = None
37
+
38
+ # Find the standard deviations
39
+ z_cols = {x for x in cols if x.startswith(col)}
40
+ stds = sorted([float(x.replace(col, "").split("_")[1]) for x in z_cols])
41
+
42
+ # Find the highest probability standard deviation
43
+ highest_std_value = 0.0
44
+ highest_std = None
45
+ for std in stds:
46
+ std_suffix = f"{col}_{std}_{PROBABILITY_COLUMN_PREFIX}"
47
+ std_true_col = sorted([x for x in cols if x.startswith(std_suffix)])[-1]
48
+ std_value = df[std_true_col].iloc[-1]
49
+ if std_value > highest_std_value:
50
+ highest_std_value = std_value
51
+ highest_std = std
52
+
53
+ # Convert the standard deviation back to a value
54
+ mu = df[col].rolling(365).mean()
55
+ sigma = df[col].rolling(365).std()
56
+ value = (highest_std * sigma) + mu
57
+ df.loc[date_to_add, col] = value
58
+
59
+ return df.drop(columns=list(cols))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: panelbeater
3
- Version: 0.0.2
3
+ Version: 0.0.3
4
4
  Summary: A CLI for finding mispriced options.
5
5
  Home-page: https://github.com/8W9aG/panelbeater
6
6
  Author: Will Sackfield
@@ -23,7 +23,7 @@ def install_requires() -> typing.List[str]:
23
23
 
24
24
  setup(
25
25
  name='panelbeater',
26
- version='0.0.2',
26
+ version='0.0.3',
27
27
  description='A CLI for finding mispriced options.',
28
28
  long_description=long_description,
29
29
  long_description_content_type='text/markdown',
@@ -1,21 +0,0 @@
1
- """Normalize the Y targets to standard deviations."""
2
-
3
- import math
4
-
5
- import pandas as pd
6
- import tqdm
7
-
8
-
9
- def normalize(df: pd.DataFrame) -> pd.DataFrame:
10
- """Normalize the dataframe per column by z-score bucketing."""
11
- mu = df.rolling(365).mean()
12
- sigma = df.rolling(365).std()
13
- df = ((((df - mu) / sigma) * 2.0).round() / 2.0).clip(-3, 3)
14
- dfs = []
15
- for col in tqdm.tqdm(df.columns, desc="Normalising targets"):
16
- for unique_val in df[col].unique():
17
- if math.isnan(unique_val):
18
- continue
19
- s = (df[col] == unique_val).rename(f"{col}_{unique_val}")
20
- dfs.append(s)
21
- return pd.concat(dfs, axis=1)
File without changes
File without changes
File without changes
File without changes