pwb-toolbox 0.1.9__tar.gz → 0.1.10__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.
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/PKG-INFO +1 -1
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/pwb_toolbox/backtest/__init__.py +2 -0
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/pwb_toolbox/backtest/engine.py +1 -1
- pwb_toolbox-0.1.10/pwb_toolbox/backtest/portfolio.py +30 -0
- pwb_toolbox-0.1.10/pwb_toolbox/backtest/universe.py +37 -0
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/pwb_toolbox.egg-info/PKG-INFO +1 -1
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/pwb_toolbox.egg-info/SOURCES.txt +2 -0
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/setup.cfg +1 -1
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/LICENSE.txt +0 -0
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/README.md +0 -0
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/pwb_toolbox/__init__.py +0 -0
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/pwb_toolbox/backtest/base_strategy.py +0 -0
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/pwb_toolbox/backtest/ib_connector.py +0 -0
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/pwb_toolbox/datasets/__init__.py +0 -0
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/pwb_toolbox/performance/__init__.py +0 -0
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/pwb_toolbox/performance/metrics.py +0 -0
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/pwb_toolbox/performance/plots.py +0 -0
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/pwb_toolbox/performance/trade_stats.py +0 -0
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/pwb_toolbox.egg-info/dependency_links.txt +0 -0
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/pwb_toolbox.egg-info/requires.txt +0 -0
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/pwb_toolbox.egg-info/top_level.txt +0 -0
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/pyproject.toml +0 -0
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/tests/test_backtest.py +0 -0
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/tests/test_execution_models.py +0 -0
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/tests/test_hf_token.py +0 -0
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/tests/test_ib_connector.py +0 -0
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/tests/test_portfolio_models.py +0 -0
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/tests/test_risk_models.py +0 -0
- {pwb_toolbox-0.1.9 → pwb_toolbox-0.1.10}/tests/test_universe_models.py +0 -0
@@ -18,7 +18,7 @@ def run_strategy(signal, signal_kwargs, portfolio, symbols, start_date, leverage
|
|
18
18
|
pivot_df.ffill(inplace=True) # forward-fill holidays
|
19
19
|
pivot_df.bfill(inplace=True) # back-fill leading IPO gaps
|
20
20
|
cerebro = bt.Cerebro()
|
21
|
-
for symbol in
|
21
|
+
for symbol in pivot_df.columns.levels[0]:
|
22
22
|
data = bt.feeds.PandasData(dataname=pivot_df[symbol].copy())
|
23
23
|
cerebro.adddata(data, name=symbol)
|
24
24
|
cerebro.addstrategy(
|
@@ -0,0 +1,30 @@
|
|
1
|
+
from .base_strategy import BaseStrategy
|
2
|
+
|
3
|
+
|
4
|
+
class MonthlyEqualWeightPortfolio(BaseStrategy):
|
5
|
+
params = (
|
6
|
+
("leverage", 0.9),
|
7
|
+
("signal_cls", None),
|
8
|
+
("signal_kwargs", {}),
|
9
|
+
)
|
10
|
+
|
11
|
+
def __init__(self):
|
12
|
+
super().__init__()
|
13
|
+
self.sig = {
|
14
|
+
d._name: self.p.signal_cls(d, **self.p.signal_kwargs) for d in self.datas
|
15
|
+
}
|
16
|
+
self.last_month = -1
|
17
|
+
|
18
|
+
def next(self):
|
19
|
+
"""Rebalance portfolio at the start of each month."""
|
20
|
+
super().next()
|
21
|
+
today = self.datas[0].datetime.date(0)
|
22
|
+
if today.month == self.last_month:
|
23
|
+
return
|
24
|
+
self.last_month = today.month
|
25
|
+
longs = [
|
26
|
+
d for d in self.datas if self.is_tradable(d) and self.sig[d._name][0] == 1
|
27
|
+
]
|
28
|
+
wt = (self.p.leverage / len(longs)) if longs else 0.0
|
29
|
+
for d in self.datas:
|
30
|
+
self.order_target_percent(d, target=wt if d in longs else 0)
|
@@ -0,0 +1,37 @@
|
|
1
|
+
from typing import List
|
2
|
+
import pandas as pd
|
3
|
+
import pwb_toolbox.datasets as pwb_ds
|
4
|
+
|
5
|
+
|
6
|
+
def get_most_liquid_symbols(n: int = 1_200) -> List[str]:
|
7
|
+
"""Return the `n` most liquid stock symbols (volume × price on last bar)."""
|
8
|
+
df = pwb_ds.load_dataset("Stocks-Daily-Price", adjust=True, extend=True)
|
9
|
+
last_date = df["date"].max()
|
10
|
+
today = df[df["date"] == last_date].copy()
|
11
|
+
today["liquidity"] = today["volume"] * today["close"]
|
12
|
+
liquid = today.sort_values("liquidity", ascending=False)
|
13
|
+
return liquid["symbol"].tolist()[:n]
|
14
|
+
|
15
|
+
|
16
|
+
def get_least_volatile_symbols(symbols=["sp500"], start="1990-01-01") -> List[str]:
|
17
|
+
pivot = pwb_ds.get_pricing(
|
18
|
+
symbol_list=symbols,
|
19
|
+
fields=["open", "high", "low", "close"],
|
20
|
+
start_date=start,
|
21
|
+
extend=True,
|
22
|
+
)
|
23
|
+
td = pd.bdate_range(pivot.index.min(), pivot.index.max())
|
24
|
+
pivot = pivot.reindex(td).ffill().bfill()
|
25
|
+
symbols = []
|
26
|
+
for sym in pivot.columns.levels[0]:
|
27
|
+
df = (
|
28
|
+
pivot[sym]
|
29
|
+
.copy()
|
30
|
+
.reset_index()
|
31
|
+
.rename(columns={"index": "date"})
|
32
|
+
.set_index("date")
|
33
|
+
)
|
34
|
+
if df.close.pct_change().abs().max() > 3: # same volatility filter
|
35
|
+
continue
|
36
|
+
symbols.append(sym)
|
37
|
+
return symbols
|
@@ -12,6 +12,8 @@ pwb_toolbox/backtest/__init__.py
|
|
12
12
|
pwb_toolbox/backtest/base_strategy.py
|
13
13
|
pwb_toolbox/backtest/engine.py
|
14
14
|
pwb_toolbox/backtest/ib_connector.py
|
15
|
+
pwb_toolbox/backtest/portfolio.py
|
16
|
+
pwb_toolbox/backtest/universe.py
|
15
17
|
pwb_toolbox/datasets/__init__.py
|
16
18
|
pwb_toolbox/performance/__init__.py
|
17
19
|
pwb_toolbox/performance/metrics.py
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|