All Projects → epymetheus → epymetheus

epymetheus / epymetheus

Licence: BSD-3-Clause license
Multi-asset backtesting framework. An intuitive API lets analysts try out their strategies right away. Fast execution of profit-take/loss-cut orders is built-in. Seamless with Pandas.

Programming Languages

python
139335 projects - #7 most used programming language
Makefile
30231 projects

Projects that are alternatives of or similar to epymetheus

Stocksharp
Algorithmic trading and quantitative trading open source platform to develop trading robots (stock markets, forex, crypto, bitcoins, and options).
Stars: ✭ 4,601 (+15765.52%)
Mutual labels:  finance, backtesting
simple portfolio
Export trades from Robinhood and run basic reporting on portfolio performance
Stars: ✭ 17 (-41.38%)
Mutual labels:  finance
ap-monorepo
Monorepo containing all packages related to the ACTUS Protocol
Stars: ✭ 15 (-48.28%)
Mutual labels:  finance
AlphaVantage.Net
.Net client library for Alpha Vantage API
Stars: ✭ 65 (+124.14%)
Mutual labels:  finance
awesome-open-finance
A curated list of open finance and open banking resources
Stars: ✭ 92 (+217.24%)
Mutual labels:  finance
ProjectReward
A software to shortlist and find the best options spread available for a given stock and help it visualise using payoff graphs.
Stars: ✭ 57 (+96.55%)
Mutual labels:  finance
66DaysOfData
#66DaysOfData challenge in Financial Machine Learning and NLP
Stars: ✭ 21 (-27.59%)
Mutual labels:  finance
pytr
Use TradeRepublic in terminal and mass download all documents
Stars: ✭ 141 (+386.21%)
Mutual labels:  finance
modeltime.resample
Resampling Tools for Time Series Forecasting with Modeltime
Stars: ✭ 12 (-58.62%)
Mutual labels:  backtesting
MLiFC
Course Material for the machine learning in financial context bootcamp
Stars: ✭ 102 (+251.72%)
Mutual labels:  finance
knut
knut is an efficient plain text accounting tool with support for multiple currencies and valuation.
Stars: ✭ 40 (+37.93%)
Mutual labels:  finance
pybacen
This library was developed for economic analysis in the Brazilian scenario (Investments, micro and macroeconomic indicators)
Stars: ✭ 40 (+37.93%)
Mutual labels:  finance
node-yahoo-finance2
Unofficial API for Yahoo Finance
Stars: ✭ 155 (+434.48%)
Mutual labels:  finance
ark-invest-api
📈 API for tracking holdings and trades of ARK Invest funds
Stars: ✭ 49 (+68.97%)
Mutual labels:  finance
cash
Home Bookkeeping on ExtJS 4, PHP 5, SQLite 3
Stars: ✭ 37 (+27.59%)
Mutual labels:  finance
fints-institute-db
Database of German Banks and their HBCI / FinTS endpoints
Stars: ✭ 28 (-3.45%)
Mutual labels:  finance
priceR
Economics and Pricing in R
Stars: ✭ 32 (+10.34%)
Mutual labels:  finance
financisto
Financisto - open-source personal finance tracker for Android
Stars: ✭ 116 (+300%)
Mutual labels:  finance
open-climate-investing
Application and data for analyzing and structuring portfolios for climate investing.
Stars: ✭ 20 (-31.03%)
Mutual labels:  finance
Ostia
Ostia is a cryptocurrency trading platform that allows you to run algorithmic trading strategies across all major exchanges.
Stars: ✭ 61 (+110.34%)
Mutual labels:  finance

Epymetheus

Epymetheus: Multi-asset Backtesting Framework

python versions version CI codecov dl Code style: black

Documentation

Epymetheus is a multi-asset backtesting framework. It features an intuitive user API that lets analysts try out their trade strategies right away.

wealth

Installation

$ pip install epymetheus

Features

  1. Intuitive and Pythonic API
    • Epymetheus designs Pythonic API that lets you code your idea intuitively without any fuss.
    • Trading strategies can be readily coded as ordinary functions and then you can run() and score() it right away.
  2. Blazingly Fast Computation
    • Backtesting is boosted by NumPy and so you can give your own idea a quick try.
    • Executions of profit-taking and stop-loss orders are built-in.
  3. Seamless Connection with Pandas
    • You can use pandas.DataFrame of historical prices as the target of backtesting.
    • You can view the result of backtesting in Pandas format so that you can analyze and plot it using the familiar Pandas methods.
  4. Full Test Coverage:

Integrations

Your trading strategy may incorporate various libraries out there, for instance,

How to use

Open In Colab

Create strategy

Let's construct your trading strategy. The following "dumb strategy" will,

  • target a set of stocks whose DataFrame of historical prices is given by universe.
  • buy the cheapest stock with your monthly allowance $100, and
  • place a profit-taking order when your profit exceeds $profit_take and place a stop-loss order when your loss exceeds $stop_loss.

Here in the function dumb_strategy, the first argument universe is mandatory while the other arguments are parameters that you can define freely.

import pandas as pd
import epymetheus as ep


def dumb_strategy(universe: pd.DataFrame, profit_take, stop_loss):
    # I get $100 allowance on the first business day of each month
    allowance = 100

    for date in pd.date_range(universe.index[0], universe.index[-1], freq="BMS"):
        cheapest_stock = universe.loc[date].idxmin()

        # Find the maximum number of shares that I can buy with my allowance
        n_shares = allowance // universe.at[date, cheapest_stock]

        trade = n_shares * ep.trade(cheapest_stock, date, take=profit_take, stop=stop_loss)
        yield trade

You can now create your strategy with specific parameters as:

my_strategy = ep.create_strategy(dumb_strategy, profit_take=20.0, stop_loss=-10.0)

Run strategy

Now you can backtest your strategy with any universe, for instance, US stocks.

from epymetheus.datasets import fetch_usstocks

universe = fetch_usstocks()
universe.head()
#                 AAPL       MSFT     AMZN  BRK-A        JPM        JNJ        WMT        BAC         PG        XOM
# 2000-01-01  0.785456  37.162327  76.1250  56100  27.773939  27.289129  46.962898  14.527933  31.304089  21.492596
# 2000-01-02  0.785456  37.162327  76.1250  56100  27.773939  27.289129  46.962898  14.527933  31.304089  21.492596
# 2000-01-03  0.855168  37.102634  89.3750  54800  26.053429  26.978193  45.391777  14.021359  30.625511  20.892334
# 2000-01-04  0.783068  35.849308  81.9375  52000  25.481777  25.990519  43.693306  13.189125  30.036228  20.492161
# 2000-01-05  0.794528  36.227283  69.7500  53200  25.324482  26.264877  42.801613  13.333860  29.464787  21.609318
my_strategy.run(universe)
# 240 trades returned: trade(['BAC'], lot=[3.], entry=2019-12-02 00:00:00, take=20.0, stop=-10.0) ... Done. (Runtume: 0.1034 sec)
# 240 trades executed: trade(['BAC'], lot=[3.], entry=2019-12-02 00:00:00, take=20.0, stop=-10.0) ... Done. (Runtime: 0.2304 sec)
# Done. (Runtime: 0.3338 sec)

Trade history and wealth

Trade history can be viewed as:

df_history = my_strategy.history()
df_history.head()
#    trade_id asset    lot      entry      close  exit  take  stop        pnl
# 0         0  AAPL  115.0 2000-01-03 2005-01-07  None  20.0 -10.0  23.527901
# 1         1  AAPL  129.0 2000-02-01 2000-09-29  None  20.0 -10.0 -48.437450
# 2         2  AAPL   99.0 2000-03-01 2005-07-14  None  20.0 -10.0  24.924913
# 3         3  AAPL   97.0 2000-04-03 2005-07-14  None  20.0 -10.0  22.180065
# 4         4  AAPL  104.0 2000-05-01 2005-05-19  None  20.0 -10.0  20.736752

The time-series of wealth can be viewed as:

series_wealth = my_strategy.wealth()
series_wealth.head()
# 2000-01-01    0.000000
# 2000-01-02    0.000000
# 2000-01-03    0.000000
# 2000-01-04   -8.363557
# 2000-01-05   -7.034265
# Freq: D, dtype: float64

wealth

Scores

You can quickly score() the metrics of the strategy.

my_strategy.score("final_wealth")
# 3216.74
my_strategy.score("max_drawdown")
# -989.19

You may compute various time-series.

drawdown = my_strategy.drawdown()
exposure = my_strategy.net_exposure()

drawdown net_exposure

More examples

Optimization

You may optimize the parameters of your strategy using Optuna for example.

Remember that optimization for backtesting is dangerous.

import optuna


def objective(trial):
    profit_take = trial.suggest_int("profit_take", 10, 100)
    stop_loss = trial.suggest_int("stop_loss", -100, -10)

    my_strategy = ep.create_strategy(
        dumb_strategy,
        profit_take=profit_take,
        stop_loss=stop_loss,
    ).run(universe, verbose=False)

    return my_strategy.score("final_wealth")


study = optuna.create_study(direction="maximize")
study.optimize(objective, n_trials=100)

study.best_params
# {'profit_take': 100, 'stop_loss': -42}

Pair trading

Trade can include multiple stocks.

Profit-take and stop-loss will be executed when the total profit/loss exceed thresholds.

def pair_trading_strategy(universe, param_1, ...):
    ...
    # Buy 1 share of "BULLISH_STOCK" and sell 2 shares of "BEARISH_STOCK".
    yield [1, -2] * ep.trade(["BULLISH_STOCK", "BEARISH_STOCK"], stop=-100.0)

Contributing

Any contributions are more than welcome.

The maintainer (simaki) is not making further enhancements and appreciates pull requests to make them. See Issue for proposed features. Please take a look at CONTRIBUTING.md before creating a pull request.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].