Code Monkey home page Code Monkey logo

finlab_crypto's Introduction

Build Status PyPI version codecov

Develop and verify crypto trading strategies at a glance.

Key Features

Installation

pip install finlab_crypto

Colab Example

Usage

Setup Research Environment (Recommend)

Create directory ./history/ for saving historical data. If Colab notebook is detected, it creates GoogleDrive/crypto_workspace/history and link the folder to ./history/.

import finlab_crypto
finlab_crypto.setup()

Get Historical Price

ohlcv = finlab_crypto.crawler.get_all_binance('BTCUSDT', '4h')
ohlcv.head()

'dataframe'

Trading Strategy

@finlab_crypto.Strategy(n1=20, n2=60)
def sma_strategy(ohlcv):
  n1 = sma_strategy.n1
  n2 = sma_strategy.n2
  
  sma1 = ohlcv.close.rolling(int(n1)).mean()
  sma2 = ohlcv.close.rolling(int(n2)).mean()
  return (sma1 > sma2), (sma1 < sma2)

Backtest

# default fee and slipagge are 0.1% and 0.1%

vars =  {'n1': 20, 'n2': 60}
portfolio = sma_strategy.backtest(ohlcv, vars, freq='4h', plot=True)

image

Optimization

import numpy as np
vars = {
  'n1': np.arange(10, 100, 5), 
  'n2': np.arange(10, 100, 5)
}
portfolio = sma_strategy.backtest(ohlcv, vars, freq='4h', plot=True)

cumulative returns parameter performance parameter range view

Live Trading

To perform live trading of a strategy, the following 3 sections should be executed when any candle is complete.

1. Create TradingMethods

First, we need to encapsulate a strategy into TradingMethod

from finlab_crypto.online import TradingMethod, TradingPortfolio, render_html

# create TradingMethod for live trading
tm_sma = TradingMethod(
    name='live-strategy-sma'
    symbols=['ADAUSDT', 'DOTBTC', 'ETHBTC'], freq='4h', lookback=1200,
    strategy=sma_strategy,
    variables=dict(n1 = 35, n2 = 105,),
    weight=5000,
    weight_unit='USDT',
    execution_price='close' # trade at close or open price
)

2. register TradingMethods to TradingPortfolio

A TradingPortfolio can sync the virtual portfolio to your Binance trading account. A TradingPortfolio contains many TradingMethods, which should be executed whenever any new candle is (going to) closed. You can decide when to rebalance the portfolio by giving execute_before_candle_complete when creating the TradingPortfolio:

  • execute_before_candle_complete=True: rebalance right before a candle is closed (i.e. setting xx:59 for 1h frequency strategy), so you can execute orders faster then others. However, signal hazards may occur due to incomplete candles.
  • execute_before_candle_complete=False (default): rebalance right after a candle is closed (i.e. setting xx:00 for 1h frequency strategy)

The above information is crucial to help TradingPortfolio decide whether to remove incomplete candles when generating trading signals or not. However, Tradingportfolio will not execute periodically for you. So, you should set up a crontab or cloud function to execute it. We recommend you run the code by yourself before setting the crontab or cloud function.

# setup portftolio
BINANCE_KEY = '' # Enter your key and secret here!
BINANCE_SECRET = ''

tp = TradingPortfolio(BINANCE_KEY, BINANCE_SECRET, execute_before_candle_complete=False)
tp.register(tm0)

# additional trading methods can be registered
# tp.register(tm1)

3. view and execute orders

Finally, we could call tp.get_ohlcvs() to get history data of all trading assets and call tp.get_latest_signals to calculate the trading signals. The aggregate information is created using tp.calculate_position_size. All the information can be viewed by tp.render_html.

ohlcvs = tp.get_ohlcvs()
signals = tp.get_latest_signals(ohlcvs)
position, position_btc, new_orders = tp.calculate_position_size(signals)

render_html(signals, position, position_btc, new_orders, order_results)

If the result makes sense, use tp.execute_orders to sync the position of your real account. Please make an issue if there is any bug:

# (order) mode can be either 'TEST', 'MARKET', 'LIMIT'
# TEST mode will show orders without real executions.
order_results = tp.execute_orders(new_orders, mode='TEST') 

Testing

The following script runs all test cases on your local environment. Creating an isolated python environment is recommended. To test crawler functions, please provide Binance API's key and secret by setting environment variables BINANCE_KEY and BINANCE_SECRET, respectively.

git clone https://github.com/finlab-python/finlab_crypto.git
cd finlab_crypto
pip install requirements.txt
pip install coverage
BINANCE_KEY=<<YOUR_BINANCE_KEY>> BINANCE_SECRET=<<YOUR_BINANCE_SECRET>> coverage run -m unittest discover --pattern *_test.py

Updates

Version 0.2.27

  • support new version of pandas 3.8
  • support 3.8 syntax

Version 0.2.26

  • fix dependency of python 3.10

Version 0.2.25 Version 0.2.24

  • fix dependency in colab

Version 0.2.23

  • fix binance min_notional not found

Version 0.2.22

  • fix compatability of seaborn in cscv algorithm plotting

Version 0.2.21

  • fix pyecharts compatibility
  • set the default argument client of get_nbars_binance

Version 0.2.20

  • fix get_all_binance last candle not updated

Version 0.2.19

  • fix bar color

Verison 0.2.18

  • fix stop loss and take profit and add them into tests

Verison 0.2.17

  • update vectorbt version

Version 0.2.16

  • update pandas version

Version 0.2.15

  • fix tp.portfolio_backtest

Version 0.2.14

  • add execute_before_candle_complete
  • add weight and weight_unit for TradingMethod

Version 0.2.12

  • fix numba version

Version 0.2.11 Version 0.2.10

  • fix numpy version

Version 0.2.8

  • merge transactions to reduce fees

Version 0.2.7

  • fix test error (request binance api too fast)
  • add USDC as base stable coin (tp.set_default_stable_coin('USDC'))

Version 0.2.6

  • fix version of pandas==1.1.5, since pandas==1.2.0 is not compatable with vectorbt
  • fix show_parameters function in Strategy and Filter

Version 0.2.5

  • fix weight_btc error
  • fix strategy mutable input

Verison 0.2.4

  • fix entry price online.py

Version 0.2.3

  • fix execution price issue

Version 0.2.2: not stable

  • improve syntax
  • add execution price for the strategy

Version 0.2.1

  • fix vectorbt version

Version 0.2.0

  • update vectorbt to 0.14.4

Version 0.1.19

  • refactor(strategy.py): refactor strategy
  • refactor(cscv.py): refactor cscv
  • add cscv_nbins and cscv_objective to strategy.backtest
  • add bitmex support

Version 0.1.18

  • fix(crawler): get_n_bars
  • fix(TradingPortfolio): get_ohlcv
  • fix(TradingPortfolio): portfolio_backtest

Version 0.1.17

  • fix error for latest_signal asset_btc_value
  • add unittest for latest_signal

Version 0.1.16

  • fix web page error
  • fix error for zero orders

Version 0.1.15

  • fix web page error

Version 0.1.14

  • refine render_html function

Version 0.1.13

  • refine display html for TradingPortfolio

Version 0.1.12

  • add delay when portfolio backtesting
  • fix colab compatability
  • improve interface of TradingPortfolio

Version 0.1.11

  • fix portfolio backtest error
  • add last date equity for backtest

Version 0.1.10

  • add portfolio backtest
  • rename online.py functions
  • refactor error tolerance of different position in online.py functions
  • set usdt to excluded asset when calculate position size

Version 0.1.9

  • set 'filters' as an optional argument on TradingMethod
  • set plot range dynamically
  • portfolio backtest

Version 0.1.8

  • fix talib parameter type incompatable issue

Version 0.1.7

  • fix talib parameter type incompatable issue

Version 0.1.6

  • fix talib-binary compatable issue using talib_strategy or talib_filter

Version 0.1.5

  • add filters to online.py
  • add lambda argument options to talib_filter
  • move talib_filter to finlab_crypto package

Version 0.1.4

  • fix talib filter and strategy pandas import error
  • fix talib import error in indicators, talib_strategy, and talib_filter

Version 0.1.3

  • remove progress bar when only single strategy is backtested
  • adjust online portfolio to support leaverge
  • new theme for overfitting plots
  • fix online order with zero order amount
  • fix SD2 for overfitting plots

Version 0.1.2

  • fix strategy variables

Version 0.1.1

  • fix talib error
  • add filters folder
  • add excluded assets when sync portfolio
  • add filter folder to setup
  • fix variable eval failure

Version 0.1.0

  • add filter interface
  • add talib strategy wrapper
  • add talib filter wrapper

Version 0.0.9.dev1

  • vectorbt heatmap redesign
  • improve optimization plots
  • redesign strategy interface
  • add new function setup, to replace setup_colab

Version 0.0.8.dev1

  • fix transaction duplicate bug

Version 0.0.7.dev1

  • fix bugs of zero transaction

Version 0.0.6.dev1

  • fix latest signal
  • rename strategy.recent_signal
  • restructure rebalance function in online.py

Version 0.0.5.dev1

  • add init module
  • add colab setup function
  • set vectorbt default
  • fix crawler duplicated index

Version 0.0.4.dev1

  • add seaborn to dependencies
  • remove talib-binary from dependencies
  • fix padding style

Version 0.0.3.dev1

  • remove logs when calculating portfolio
  • add render html to show final portfolio changes
  • add button in html to place real trade with google cloud function

Version 0.0.2.dev1

  • skip heatmap if it is broken
  • add portfolio strategies
  • add talib dependency

finlab_crypto's People

Contributors

benbilly3 avatar finlab-python avatar jrycw avatar koreal6803 avatar minggnim avatar yaotechuang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

finlab_crypto's Issues

Stocks support

Stumbled upon this while researching vectorbt. I have few questions. hope you can answer

  1. can this be used for stocks
  2. How easy or difficult it is to integrate with alpaca for live trading

can u please give some guidance for me to code alpaca brokerage for stocks

Cannot Install as conflicting dependencies

ERROR: Cannot install finlab-crypto==0.1.0, finlab-crypto==0.1.1, finlab-crypto==0.1.10, finlab-crypto==0.1.11, finlab-crypto==0.1.12, finlab-crypto==0.1.13, finlab-crypto==0.1.14, finlab-crypto==0.1.15, finlab-crypto==0.1.16, finlab-crypto==0.1.17, finlab-crypto==0.1.18, finlab-crypto==0.1.19, finlab-crypto==0.1.2, finlab-crypto==0.1.3, finlab-crypto==0.1.4, finlab-crypto==0.1.5, finlab-crypto==0.1.6, finlab-crypto==0.1.7, finlab-crypto==0.1.8, finlab-crypto==0.1.9, finlab-crypto==0.2.0, finlab-crypto==0.2.1, finlab-crypto==0.2.10, finlab-crypto==0.2.11, finlab-crypto==0.2.12, finlab-crypto==0.2.13, finlab-crypto==0.2.14, finlab-crypto==0.2.15, finlab-crypto==0.2.16, finlab-crypto==0.2.17, finlab-crypto==0.2.18, finlab-crypto==0.2.19, finlab-crypto==0.2.2, finlab-crypto==0.2.20, finlab-crypto==0.2.21, finlab-crypto==0.2.22, finlab-crypto==0.2.23, finlab-crypto==0.2.3, finlab-crypto==0.2.4, finlab-crypto==0.2.5, finlab-crypto==0.2.6, finlab-crypto==0.2.7, finlab-crypto==0.2.8 and finlab-crypto==0.2.9 because these package versions have conflicting dependencies.
ERROR: ResolutionImpossible: for help visit https://pip.pypa.io/en/latest/topics/dependency-resolution/#dealing-with-dependency-conflicts

vectorbt upgrade

Thanks for sharing this great repo!

I can't help but notice that the version of vectorbt is a bit outdated. I think it'd be very helpful to upgrade it to the latest 0.21.0, which offers enhanced stats and pnl analysis, and many more new features. I've created a pr #16 to support this. Hopefully you also find it useful. Thanks!

[Feature request] Support for cctx

Great project!. A feature suggestion/request: cctx already standardizes data from many exchanges. Would be great to be able to use that data in order to have access to instruments supported on different exchanges (ex: futures, deribit options).

stop loss example

could you please provide an example how to use stop loss and trailing stop with backtest

Args in def get_nbars_binance(...)

in function defined in crawler.py file row 100
get_nbars_binance(symbol, interval, nbars, client):
...
client (Binance.Client) (optional): Binance Client object.

It is not optional.
I've fixed with this: get_nbars_binance(symbol, interval, nbars, client=Client()):

Include a .gitignore file

I would like to suggest including a .gitignore file in the repo.
We could use the template that github provided and modify it in the future if needed.

Mutable default arguments

class Strategy(object):

    def backtest(self, ohlcv, variables=dict(),
                         filters=dict(), lookback=None, plot=False,
                         signals=False, side='long', cscv_nbins=10,
                         cscv_objective=lambda r: r.mean(), html=None, compounded=True, execution_price='close', **args):

There might be a potential issue if using dictionary as the default argument for variables and filters, since dictionary is mutable.

I will argue that using None as the default argument might be a safer approach.

objective function set up as lambda r: r.mean()

In DH Bailey's paper "The probability of backtest overfitting", they used sharpe ratio as their default objective function.
However, in fin_crypto library, objective function was set up as objective=lambda r: r.mean().
Just want to clarify, needn't the default of objective function be set as objective=lambda r: sharpe_ratio(r)?

TypeError: add_yaxis() in utility.py:171

167 figures['entries & exits'] = pd.DataFrame(
168     {'entries':entries.squeeze(), 'exits': exits.squeeze()})
169 figures['performance'] = portfolio.cumulative_returns()

--> 171 c, info = chart.chart(ohlcv, overlaps=overlaps,
172 figures=figures, markerlines=mark_lines,
173 start_date=ohlcv.index[-min(1000, len(ohlcv))], end_date=ohlcv.index[-1], k_colors=k_colors)
174 c.load_javascript()
175 if html is not None:
...
161 # indicators
162 #################
164 def is_item(item):

TypeError: add_yaxis() got an unexpected keyword argument 'yaxis_data'

seems due to pyecharts library, you need to update your utility.py file to the new pyecharts version that receive 'y_axis' instead of 'yaxis_data'

There are some similar code in Strategy and Filter

__init__, __call__ , set_parameters and show_parameters methods looks similar in Strategy and Filter.
My suggestion is using Inheritance to refractor the code as following:

class BaseDec:

    delattr_clsname = {'Strategy'}

    def __init__(self, **default_parameters):
        self.func = None
        self._variables = None
        self.filters = {}
        self._default_parameters = default_parameters
        self.set_parameters(default_parameters)

    def __call__(self, func):
        self.func = func
        return self

    def set_parameters(self, variables):
        if type(self).__name__ in self.delattr_clsname:
          stop_vars = ['sl_stop', 'tp_stop', 'ts_stop']
          for svar in stop_vars:
              if hasattr(self, svar):
                  delattr(self, svar)

        if variables:
            for key, val in variables.items():
                setattr(self, key, val)

        self._variables = variables

    def show_parameters(self):
        print(self._variables)

class Filter(BaseDec):
    ...

class Strategy(BaseDec):
    ...

Unable to draw candlestick chart

Hello,

I am currently using Python 3.8.4 to run the tutorial with the finlab_crypto version 0.2.27.
I have encountered an issue where candlestick charts are not being displayed during the test.
image
Additionally, when running the optimization process, I encountered a TypeError: "pivot() takes 1 positional argument but 3 were given."
image
As a newcomer to Python, I would appreciate guidance on whether I need to install any additional dependencies or provide additional information to help identify the cause of these issues.

Thank you for your assistance.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.