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 [ ]: