Skip to main content

Investate

Overview

A collection of tools to find the value over time of various investments. Initially motivated by investing in the real estate market, thus its name, the package has since grown to include tools to develop and backtest investment strategies for various investments.

Intro

"How much would I have if I invest every month $10 on a bank account at a yearly rate of 5%" Basic calculus offers a simple formula to answer the question above. If more realistically, we invest a different amount every month, and the rate is changing over time, there is no algebraic shortcut to get an answer. Instead you can use the function values_of_series_of_invest to get an answer:

from investate.series_utils import values_of_series_of_invest

values_of_series_of_invest(rate_between_period=[0.01, 0.005, 0.011], 
                           invest_values=[10, 12, 5])

27.292549999999995

Backtesting

Investate contains simple yet flexible tools to backtest strategies. Below is an example based on the standard crossing averages buy/sell signal.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# We choose a series of value of an investment over time, eth_series, the value of Ethereum
# over time
import pandas as pd
eth_series = pd.read_csv('test_dfs/eth.csv')['Last']
plt.plot(eth_series)

alt text

We set our moving average parameters, namely the size of windows (which we call chunks here) used for the rolling means

chk_size_1 = 10
chk_size_2 = 30

We can use get_comp_ma to get a dictionary containing the aligned numpy series of the moving averages along with the original series, all appropriately cut off as to be time aligned.

from investate.moving_average import get_comp_ma

stat_dict = get_comp_ma(eth_series, chk_size_1=chk_size_1, chk_size_2=chk_size_2)
stat_series_1, stat_series_2, cut_series = stat_dict['stat_series_1'], stat_dict['stat_series_2'], stat_dict[
    'cut_series']

fig, ax = plot_mas(**stat_dict)

alt text

We determine the daily growth of eth over the last 471 days (500 original minus the 30-1 days lost due to the largest of the two chunk size).

from investate.series_utils import values_to_percent_growth

period_rate_A = values_to_percent_growth(cut_series)

For the demo here, we will assume that the alternative investment is cash, and that cash does not yield any interest. We represent its growth with the series of its daily returns, all zeros per assumption.

# get the growth over time of the alternative investment, here we choose holding cash at 0% APR
period_rate_B = [0] * len(cut_series)

Our strategy is the classical "sma cross over", namely, we devest from ethereum anytime the fast moving average falls bellow the slow moving average. Conversely, we re-invest anytime the trend reverses. The logic of the strategy is coded in the function invest_with_sma.

from investate.backtesting_examples import invest_with_sma
invest_func = invest_with_sma(chk_size_1=chk_size_1, chk_size_2=chk_size_2)

Invest_with_sma applied to eth_series provides a series of 0/1 determining whether to invest in ethereum for each period. A 1 means "at the corresponding time, invest all availalbe in A", while a 0 means "invest all available in B".

invest_period = np.array(list(invest_func(eth_series)))
plt.plot(invest_period)

alt text

The user can provide any alternative function, as long as the function takes the original series as an input and return a series of values a_i/b_i where a_i and b_i belong to the interval [0,1] and a_i + b_i = 1. The meaning of a_i/b_i is that at period i, we will invest a_i * T_i in investment A and b_i * T_i on investment B, where T_i is the total available at time i.

Finally, the function investment_over_period allows to track the value of each investment over time, using the series of 0/1 (invest/devest) generated by our strategy. Here we will assume we start with an investment of 1 dollars in ethereum, 0 in cash and that the cost of buying/selling ethereum is 0. (as specified by the fact that we set the fees_func_AB to None)

val_A, val_B = investment_over_period(period_rates_A=period_rate_A,
                                      period_rates_B=period_rate_B,
                                      fees_func_AB=None,
                                      period_end_balance=invest_period,
                                      initial_investment_A=1,
                                      initial_investment_B=0)

plt.plot(val_A)
plt.plot(val_B)
plt.show()
plt.plot(cut_series / cut_series[0])
plt.show()

alt text

We can easily determine the final and total value of our investements

total = np.array(val_A) + np.array(val_B)
print(total)
15.55

and we can compare it to holding 1$ in ethereum over the same period of time

print(cut_series[-1] / cut_series[0])
15.94

The function provide a convenient way to compare and visualize the return of any sma crossover strategy for any pair of fast/short moving average. We just need to specify the maximum size of each window, we chose 30 below.

mean_return, mat = parameter_grid_search(eth_series, 30)
plot_mat(mat)

alt text

Real estate investment

A streamlit app is provided to evaluate a real estate investment and it compare it to the same initial amount invested in a something like say the index 500. The app can be accessed by running streamlit_house_app.py or alternatively use the url below: https://investest.herokuapp.com

Note that the heroku version above may not be the latest. Below is a screenshot of the app. The parameters meaning should be clear from context. alt text

Release files for investate 0.1.11

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for investate 0.1.11
File Size Uploaded
investate-0.1.11.tar.gz 26.1 kB Details

Release files / investate-0.1.11.tar.gz

Download URL investate-0.1.11.tar.gz
Size 26.1 kB
Tags Source
SHA-256 checksum
How to use checksums
539c68dc7a54947fd02174081b777d6344be2f2676a1bbac2082d348fa2a1527
BLAKE2b-256 checksum
How to use checksums
6882c767629e9ab86268539f11d5b74c76ebf5afd0163c6cf176dc97655bd0eb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.0 CPython/3.8.12

Release history Release notifications | RSS feed

This release

0.1.11 This release

1 release file

0.1.10

1 release file

0.1.9

1 release file

0.1.8

1 release file

0.1.7

1 release file

0.1.6

1 release file

0.1.5

1 release file

0.1.4

1 release file

0.1.3

1 release file

0.1.2

1 release file

0.1.1

1 release file

0.1.0

1 release file

0.0.5

2 release files

0.0.4

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page