EDCA, results relative to DCA, histogram

master
Dmitry Maylarov 4 years ago
parent e7e58a60d2
commit 4781836ea1

@ -141,9 +141,15 @@ class FormulaInvesting(Investing):
def notify_timer(self, timer, when, *args):
super().notify_timer(timer, when, *args)
self.formula()
self.prev_value = self.broker.get_value()
class VA(FormulaInvesting):
"""
When market is down, buy
When up, sell. Shitty strategy: https://en.wikipedia.org/wiki/Value_averaging
"""
def formula(self):
target_value = (
min(
@ -156,25 +162,65 @@ class VA(FormulaInvesting):
# self.broker.set_cash(self.broker.get_cash() * self.monthly_params["t_rate"])
class QVA(VA):
"""
Same but quarterly
"""
def formula(self):
if not self.months % 3:
super().formula()
class DCA(FormulaInvesting):
"""
Buy everything monthly
"""
def formula(self):
target_value = self.broker.get_value() - reserve
self.order_target_value(target=target_value)
class QVA(VA):
class QDCA(DCA):
"""
Buy everything quarterly
"""
def formula(self):
if not self.months % 3:
super().formula()
class QDCA(DCA):
def formula(self):
if not self.months % 3:
super().formula()
class EDCA(Investing):
"""
When market is down, BUY THE DIP
When up, leave some cash
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.prev_value = 0
def notify_timer(self, timer, when, *args):
self.months += 1
if self.prev_value >= self.broker.get_value():
self.broker.add_cash(1.1 * self.monthly_cash)
else:
self.broker.add_cash(0.9 * self.monthly_cash)
target_value = self.broker.get_value()
self.order_target_value(target=target_value - reserve)
self.prev_value = self.broker.get_value()
class SmaCross(Investing):
"""
Buy when fast moving average crosses slow upwards
"""
params = dict(
pfast=8, # period for the fast moving average
pslow=17, # period for the slow moving average
@ -191,13 +237,3 @@ class SmaCross(Investing):
self.order_target_value(
target=self.broker.get_value() - reserve
) # enter long
class SmaVA(SmaCross):
def next(self):
if not self.position: # not in the market
if self.crossover > 0: # if fast crosses slow to the upside
self.order_target_value(target=self.broker.get_cash()) # enter long
elif self.crossover < 0: # in the market & cross to the downside
self.order_target_value(target=self.broker.get_value() / 2) # close half

@ -6,13 +6,13 @@ import pandas as pd
if __name__ == "__main__":
stockList = ["^GSPC"]
monthly_params = dict(sum=1000, coef=1, t_rate=1 + 0.02 / 12)
monthly_params = dict(sum=100000, coef=1, t_rate=1 + 0.02 / 12)
# startDate = datetime.datetime.fromisoformat("2000-01-01")
# endDate = datetime.datetime.fromisoformat("2022-01-01")
print(stockList[0])
stockData = lib.get_data(stockList[0])
start_date = stockData.index[0]
year_step = 5
year_step = 1
label_string = "Investing to {} monthly over {} years, increasing {:.2f}%, starting from ${}".format(
stockList[0],
year_step,
@ -21,15 +21,20 @@ if __name__ == "__main__":
)
print(label_string)
plot_param = "annual%"
strategies = (
st.DCA,
_strategies = (
st.QDCA,
st.EDCA,
st.SmaCross,
)
strategies = (st.DCA,) + _strategies
df_comp = pd.DataFrame(index=list(st.__name__ for st in strategies))
df_vwr = pd.DataFrame(index=list(st.__name__ for st in strategies))
for start_year in range(start_date.year, datetime.datetime.today().year, year_step):
df_rel_to_dca = pd.DataFrame(index=list(st.__name__ for st in _strategies))
for start_year in range(
start_date.year, datetime.datetime.today().year - year_step + 1, year_step
):
start_date = datetime.date(start_year, 1, 1)
end_date = datetime.date(start_year + year_step - 1, 12, 31)
if (today := datetime.date.today()) < end_date:
@ -50,12 +55,19 @@ if __name__ == "__main__":
]
)
print(newdf.to_string())
df_rel_to_dca[start_year] = list(
newdf.loc[s.__name__][plot_param] - newdf.loc[st.DCA.__name__][plot_param]
for s in _strategies
)
df_comp[start_year] = newdf[plot_param].values
# print(df[["annual%", "froi%", "cost", "total_value", "max_dd%", "max_md"]])
# print(newdf["annual%"])
print(df_comp.to_string())
print(df_rel_to_dca.to_string())
df_comp.T.plot()
for index, s in df_rel_to_dca.iterrows():
print("{}: avg {:.3f} dev {:.3f}".format(index, s.mean(), s.std()))
df_rel_to_dca.T.hist(bins=20)
plt.grid()
plt.title(label_string)
plt.ylabel(plot_param)

Loading…
Cancel
Save