Skip to content

Commit

Permalink
made strat work with float allocation and fixed bugs in back test
Browse files Browse the repository at this point in the history
  • Loading branch information
AxelGard committed Jun 14, 2024
1 parent c154fec commit 6250988
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 18 deletions.
42 changes: 36 additions & 6 deletions cira/strategy.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,19 @@ def load(cls, file_path):


class Randomness(Strategy):
def __init__(self, lower: int = -1, upper: int = 1, seed=0) -> None:
def __init__(
self,
lower: float | int = -1,
upper: float | int = 1,
seed=0,
use_float: bool = False,
) -> None:
super().__init__(name="Randomness")
random.seed(seed)
self.a = lower
self.b = upper
self.allocation = []
self.use_float = use_float

def iterate(
self,
Expand All @@ -61,8 +68,31 @@ def iterate(
cash=float,
) -> np.ndarray:
al = np.array(
[random.randint(self.a, self.b) for _ in range(len(prices.keys()))]
[
random.uniform(float(self.a), float(self.b))
for _ in range(len(prices.keys()))
]
)
if not self.use_float:
al = al.astype(int)
self.allocation.append(al)
return al


class DollarCostAveraging(Strategy):
def __init__(self, amount: int | float = 1) -> None:
super().__init__(name="DollarCostAveraging")
self.amount = amount
self.allocation = []

def iterate(
self,
feature_data: pd.DataFrame,
prices: pd.DataFrame,
portfolio: np.ndarray,
cash=float,
) -> np.ndarray:
al = np.array([self.amount for _ in range(len(prices.keys()))])
self.allocation.append(al)
return al

Expand Down Expand Up @@ -117,11 +147,11 @@ def back_test(
}
assert len(feature_data) == len(asset_prices)
total_value = capital
nr_of_asset = np.zeros([len(asset_prices.keys())], int)
nr_of_asset = np.zeros([len(asset_prices.keys())], float)
i = 0
for t, cur_price in asset_prices.iterrows():
if len(asset_prices) == i + 1:
break
# if len(asset_prices) == i + 1:
# break
if total_value > 0:
f_data = feature_data.iloc[: i + 1]
p_data = asset_prices.iloc[: i + 1]
Expand All @@ -138,7 +168,7 @@ def back_test(
np.matmul(cur_price.values.T, allocation)
+ use_fees * fees(cur_price.values, allocation)
) # - capital)
if asking < capital:
if asking <= capital:
capital -= asking
nr_of_asset += allocation
total_value = np.matmul(cur_price.values.T, nr_of_asset) + capital
Expand Down
41 changes: 29 additions & 12 deletions tests/test_strategy.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import cira
from . import util
import os
import numpy as np


def test_iterate():
feature_data = util.stock_data
strat = cira.strategy.Randomness(seed=2**12)
strat = cira.strategy.DollarCostAveraging(amount=1)
prices = feature_data["close"].to_frame()
change_in_portfolio = strat.iterate(feature_data, prices.iloc[-1], 10_000)
assert change_in_portfolio.tolist() == [1]
Expand All @@ -26,20 +27,36 @@ def test_storing_strategy():

def test_backtest():
feature_data = util.stock_data
strat = cira.strategy.Randomness(seed=2**14)
strat = cira.strategy.DollarCostAveraging(amount=1)
prices = feature_data["close"].to_frame()
prices["close"] = [10, 100, 10_000, 100, 10]
prices["close"] = [10, 10, 5, 20, 10]

resutlt = cira.strategy.back_test_against_buy_and_hold(strat, feature_data, prices, 10_000)
resutlt = resutlt.dropna()
resutlt = cira.strategy.back_test(strat, feature_data, prices, 20, use_fees=False)

res = resutlt[strat.name].values.tolist()
res = [int(r) for r in res]
res = resutlt[strat.name].values.astype(int).tolist()
assert res == [20, 20, 10, 40, 20]

assert res == [9999, 10089, 20029, 20029]

s = cira.strategy.ByAndHold()
res = resutlt[s.name].values.tolist()
res = [int(r) for r in res]
def test_backtest_float():
feature_data = util.stock_data
strat = cira.strategy.DollarCostAveraging(amount=0.5)
prices = feature_data["close"].to_frame()
prices["close"] = [10, 10, 5, 20, 10]

resutlt = cira.strategy.back_test(strat, feature_data, prices, 10, use_fees=False)

res = resutlt[strat.name].values.astype(int).tolist()
assert res == [10, 10, 5, 20, 10]


def test_backtest_fees():
feature_data = util.stock_data
strat = cira.strategy.DollarCostAveraging(amount=1)
prices = feature_data["close"].to_frame()
prices["close"] = [10, 10, 10, 10, 10]

cira.strategy.FEE_RATE = 0.1
resutlt = cira.strategy.back_test(strat, feature_data, prices, 100, use_fees=True)

assert res == [9961, 96361, 9600361, 96361]
res = resutlt[strat.name].values.astype(int).tolist()
assert res == [99, 98, 97, 96, 95]

0 comments on commit 6250988

Please sign in to comment.