Skip to main content

BackTest and Run CryptoCurrency Trading Strategies

Project description

btrccts

BackTest and Run CryptoCurrency Trading Strategies

Install - Usage - Manual - Development

This library provides an easy way to backtest trading strategies and run them live with ccxt. The purpose of this library is to provide a framework and an backtest exchange with the same interface than ccxt - nothing less and nothing more. If you want an library to compute performance metrics out of trades/orders, you need an additional library.

Install

The easiest way to install the BTRCCTS library is to use a package manager:

The python package hashes can be found in the version_hashes.txt.

You can also clone the repository, see Development

Usage

For example algorithms see in Examples

from btrccts import parse_params_and_execute_algorithm, AlgorithmBase


class Algorithm(AlgorithmBase):

    @staticmethod
    def configure_argparser(argparser):
        # Here you can add additional arguments to the argparser
        argparser.add_argument('--pyramiding', default=1, type=int)

    def __init__(self, context, args):
        # Context is used to create exchanges or get the current time
        self._context = context
        self._args = args

        # This will create a kraken exchange instance
        # The interface in backtesting and live mode is identical to CCXT.
        # See: [CCXT](https://github.com/ccxt/ccxt/wiki)
        # In live mode, this will be a plain ccxt instance of the exchange
        # The exchange keys will be read from the config directory (see --help)
        # You can create sync or async versions of the exchange.
        # If ccxtpro is available in your python environment, the async
        # call will create a ccxtpro instance.
        self._kraken = context.create_exchange('kraken', async_ccxt=True)

        # You can access your own defined parameters
        print('Pyramiding:', args.pyramiding)

        # You can access predefined parameters like exchanges and symbols
        print('Exchanges:', args.exchanges)
        print('Symbols:', args.symbols)

    async def next_iteration(self):
        # This method is executed each time interval
        # This method can be async or a normal method.

        # This is the current context date:
        print('context date', self._context.date())

        # In live mode, markets are not loaded by the library
        # If you need access to the exchanges market object, you need
        # to load them first
        await self._kraken.load_markets()
        # Use the exchange to load OHLCV data
        ohlcv_len = 10
        ohlcv_offset = ohlcv_len * 60 * 1000
        ohlcv_start = int(self._context.date().value / 1000000 - ohlcv_offset)
        print(await self._kraken.fetch_ohlcv(
            'BTC/USD', '1m', ohlcv_start, ohlcv_len))

        # Use the exchange to create a market order
        self._order_id = await self._kraken.create_order(
            type='market', side='buy', symbol='BTC/USD', amount=0.1)

        # If you want to stop the algorithm in context or live mode, you can
        # do this:
        self._context.stop('stop message')

    async def handle_exception(self, e):
        # This method is called, when next_iteration raises an exception, e.g.
        # because of an exchange error or a programming error.
        # If this method raises an exception, the algorithm will stop with
        # reason EXCEPTION
        # This method can be async or a normal method.
        # If you are not in live mode, it is advisable to rethrow the
        # exception to fix the programming error.
        print(e)
        if not self._args.live:
            raise e

    async def exit(self, reason):
        # This method is called, when the algorithm exits and should be used
        # to cleanup (e.g. cancel open orders).
        # This method can be async or a normal method.
        # reason contains information on why the algorithm exits.
        # e.g. STOPPED, EXCEPTION, FINISHED
        print("Done", reason)
        self.closed_orders = await self._kraken.fetch_closed_orders()
        # Async versions of an exchange needs to be closed, because
        # btrccts will close the asyncio loop after the run.
        await self._kraken.close()


# This method parses commandline parameters (see --help)
# and runs the Algorithm according to the parameters
result = parse_params_and_execute_algorithm(Algorithm)
# The result is an instance of Algorithm, you can now use saved
# information. If you used a sync version of the exchange you can
# still use them. For async exchanges the asyncio loop is already
# destroyed.
print(result.closed_orders)

To run this algorithm, just execute the file with python. e.g.

.venv/bin/python examples/algo_readme.py --start-date 2017-12-01 --end-date 2017-12-02 --interval 1h \
                                         --exchanges kraken --symbols BTC/USD \
                                         --start-balances '{"kraken": {"USD": 10000}}'

To execute orders in exchanges, you can run the algorithm in live mode with the command-line parameter --live. For other parameters, see .venv/bin/python examples/algo_readme.py --help.

If you dont want the function to parse commandline parameters for you, you can use

from btrccts.run import execute_algorithm
execute_algorithm(...)

Manual

Data and directories

Run your algorithm with --help to see the path to your config and data directories.

The data directory contains the ohlcv data: data_directory/ohlcv/EXCHANGE/BASE/QUOTE.csv e.g. data_directory/ohlcv/binance/BTC/USD.csv

Data files are in the following format (readable with pandas.read_csv)

,open,high,low,close,volume
2019-10-01 10:10:00+00:00,200,300,100,300,1000
2019-10-01 10:11:00+00:00,300,400,200,400,2000
2019-10-01 10:12:00+00:00,400,500,300,500,3000

The data files are not yet provided with this library. You have to provide them yourself. The data file needs to cover the complete period (you want to run the bot) in 1 minute interval. You can specify the period with --start-date and --end-date.

The config directory contains exchange keys. e.g. config_directory/binance.json:

{
    "apiKey": "key material",
    "secret": "secret stuff"
}

If an alias is provided (e.g. --auth-aliases '{"kraken": "kraken_wma"}', the file config_directory/kraken_wma.json is used.

Differences between live and backtesting mode

  • In backtesting mode the markets from the exchanges are loaded upon exchange creation. This needs to be done, because market information is needed for order handling. In live mode, the markets are not loaded via the library, because the library does not know how you want to handle e.g. errors or reloading the market.

How orders get filled

  • Market order

Market orders are executed immediately with a price a little worse than current low/high. Since we only have ohlcv data, we cannot use the next data, because this would introduce a look-ahead bias Some other backtesting libraries would wait until the next round to fill market orders, but this is not what is happening in the real world (executing market orders immediately).

  • Limit order

Limit orders are filled, when the price is reached. Limit orders get filled all at once, there is no volume calculation yet. If your bot uses huge limit orders, keep in mind that the behavior on the exchange can be a partiall fill and leaving the order open until filled.

When next round is initiated in live mode / How interval is handled in live mode

When the algorithm is started, it will immediately execute next_iteration. Now the library waits until the next time interval and executes next_iteration. If the next_iteration call takes longer than the interval, next_iteration is called immediately again. If next_iteration takes longer than multiple intervals, only the last interval is rescheduled.

Development

Setup a virtualenv:

git clone git@github.com:btrccts/btrccts.git
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
.venv/bin/pip install -e . --no-deps

Run tests

Install the dev dependencies:

.venv/bin/pip install -e .[dev]

Run the tests:

.venv/bin/python -m unittest tests/unit/tests.py
.venv/bin/python -m unittest tests/integration/tests.py

Contact us

btrccts@e.email

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

btrccts-0.1.4.tar.gz (19.0 kB view details)

Uploaded Source

Built Distribution

btrccts-0.1.4-py3-none-any.whl (19.8 kB view details)

Uploaded Python 3

File details

Details for the file btrccts-0.1.4.tar.gz.

File metadata

  • Download URL: btrccts-0.1.4.tar.gz
  • Upload date:
  • Size: 19.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.2

File hashes

Hashes for btrccts-0.1.4.tar.gz
Algorithm Hash digest
SHA256 f9fa663156119efdcdfa07c7413f5bf32d22ebe6a1632daae2069aabbcdc50e9
MD5 3616852fff2e7e653606f26a3ea42054
BLAKE2b-256 7251102a3506a631dabc39c60465abe54b3844aaef635557d45d821a8145b470

See more details on using hashes here.

File details

Details for the file btrccts-0.1.4-py3-none-any.whl.

File metadata

  • Download URL: btrccts-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 19.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.2

File hashes

Hashes for btrccts-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 bb4472f3159438711f75fae49a1c07ae3c05e4232e3401c05dfe2f3f4beedce6
MD5 46b5834a7896f21f2507baf3b81603d8
BLAKE2b-256 3245611be6757ddb489b38ed0f7f5a2d067f0a963b5978dbee81850f95a89c33

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page