buy-and-hold¶
Buy, then never ever sell, until the end date :)
In [1]:
import datetime
import pandas as pd
import pinkfish as pf
# Format price data.
pd.options.display.float_format = '{:0.2f}'.format
Some global data
In [2]:
symbol = 'SPY'
capital = 10000
start = datetime.datetime(1900, 1, 1)
end = datetime.datetime.now()
Timeseries
In [3]:
# Fetch timeseries, select, finalize.
ts = pf.fetch_timeseries(symbol)
ts = pf.select_tradeperiod(ts, start, end, use_adj=True)
ts, start = pf.finalize_timeseries(ts, start)
# Create tradelog and daily balance objects.
tlog = pf.TradeLog(symbol)
dbal = pf.DailyBal()
Algorithm
In [4]:
pf.TradeLog.cash = capital
# Loop through timeseries.
for i, row in enumerate(ts.itertuples()):
date = row.Index.to_pydatetime()
end_flag = pf.is_last_row(ts, i)
# Buy.
if tlog.shares == 0:
tlog.buy(date, row.close)
# Sell.
elif end_flag:
tlog.sell(date, row.close)
# Record daily balance.
dbal.append(date, row.close)
Retrieve logs
In [5]:
tlog = tlog.get_log()
dbal = dbal.get_log(tlog)
In [6]:
tlog.tail()
Out[6]:
entry_date | entry_price | exit_date | exit_price | pl_points | pl_cash | qty | cumul_total | direction | symbol | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 1993-01-29 | 24.84 | 2023-12-21 | 471.23 | 446.39 | 179450.51 | 402 | 179450.51 | LONG | SPY |
Get stats
In [7]:
stats = pf.stats(ts, tlog, dbal, capital)
Summary
In [8]:
pf.summary(stats)
Out[8]:
strategy | |
---|---|
annual_return_rate | 9.99 |
max_closed_out_drawdown | -55.17 |
best_month | 23.60 |
worst_month | -30.98 |
sharpe_ratio | 0.60 |
sortino_ratio | 0.77 |
monthly_std | 4.48 |
annual_std | 17.01 |
In [ ]: