# coin-test
[![Tests](https://github.com/coin-test/coin-test/workflows/Tests/badge.svg)](https://github.com/coin-test/coin-test/actions?workflow=Tests)
[![Codecov](https://codecov.io/gh/coin-test/coin-test/branch/main/graph/badge.svg)](https://codecov.io/gh/coin-test/coin-test)
Coin-test is a backtesting library designed for cryptocurrency trading. It supports trading strategies across multiple currencies and advanced configurations of tests, including cron-based scheduled execution of strategies, synthetic data generation, slippage modeling, and trading fees.
## Quick Start
Coin-test runs on Python 3.10 or higher. Install the package via pip:
```sh
pip3 install coin-test
```
To run a backtest, import the coin-test library. Then define your data source, strategy, and test settings to run the analysis.
```python
import datetime as dt
import os
import pandas as pd
from coin_test.backtest import Portfolio, Strategy, MarketTradeRequest
from coin_test.data import CustomDataset
from coin_test.util import AssetPair, Ticker, Money, Side
```
Then, import data from a CSV or another source to load
into the backtest.
```python
dataset_file = "data/ETHUSDT-1h-monthly/BTCUSDT-1h-2017-08.csv"
header = ["Open Time", "Open", "High", "Low", "Close", "Volume", "Close Time",
"Quote asset volume", "Number of trades", "Taker buy base asset volume",
"Taker buy quote asset volume", "Ignore"
]
df = pd.read_csv(dataset_file, names=header)
df = df.drop(columns=["Close Time", "Quote asset volume", "Number of trades",
"Taker buy base asset volume",
"Taker buy quote asset volume", "Ignore"])
df["Open Time"] //= 1000 # To seconds
df = df.sort_values(by=["Open Time"])
# define dataset metadata
usdt = Ticker("USDT")
btc = Ticker("BTC")
asset_pair = AssetPair(btc, usdt)
freq = "H"
dataset = CustomDataset(df, freq, asset_pair)
```
Strategies are stored in classes as shown below. Each strategy
should have a schedule, which is a cron string representing
when this strategy is run, a lookback, which is how much
data is accessed in the strategy, and a `__call__` method
which returns a list of TradeRequest objects, which represent
trades the strategy wants to make.
```python
class MACD(Strategy):
def __init__(self, asset_pair) -> None:
"""Initialize a MACD object."""
super().__init__(
name="MACD",
asset_pairs=[asset_pair],
schedule="0 9 * * *",
lookback=dt.timedelta(days=26),
)
self.perc = 0.2
def __call__(self, time, portfolio, lookback_data):
"""Execute test strategy."""
asset_pair = self.asset_pairs[0]
exp1 = lookback_data[asset_pair]["Close"].ewm(span=12 * 24, adjust=False).mean()
exp2 = lookback_data[asset_pair]["Close"].ewm(span=26 * 24, adjust=False).mean()
macd = exp1 - exp2
exp3 = macd.ewm(span=9 * 24, adjust=False).mean()
if macd.iloc[-1] > exp3.iloc[-1]:
return [MarketTradeRequest(
asset_pair,
Side.BUY,
notional=portfolio.available_assets(usdt).qty * self.perc,
)]
elif macd.iloc[-1] < exp3.iloc[-1]:
return [MarketTradeRequest(
asset_pair,
Side.SELL,
qty=portfolio.available_assets(btc).qty * self.perc,
)]
return []
```
This package supports multiple strategies, train-test splits
for historical data, synthetic data, and further customization.
To run the backtest, define the datasets
```python
from coin_test.backtest import ConstantSlippage, ConstantTransactionFeeCalculator
sc = ConstantSlippage(50)
tc = ConstantTransactionFeeCalculator(50)
datasets = [dataset]
strategies = [MACD]
results = coin_test.run(datasets, strategies, sc, tc,
portfolio, pd.Timedelta(days=90),
n_parallel=8)
```
Raw data
{
"_id": null,
"home_page": "https://github.com/coin-test/coin-test",
"name": "coin-test",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.10,<3.11",
"maintainer_email": "",
"keywords": "cryptocurrency,backtesting",
"author": "Eamon Ito-Fisher",
"author_email": "eamon@itofisher.com",
"download_url": "https://files.pythonhosted.org/packages/00/87/244bfa811303a6d2329c3f64760840d1d7e2476c976b2755598ffb766e88/coin_test-0.1.0.tar.gz",
"platform": null,
"description": "# coin-test\n\n[![Tests](https://github.com/coin-test/coin-test/workflows/Tests/badge.svg)](https://github.com/coin-test/coin-test/actions?workflow=Tests)\n[![Codecov](https://codecov.io/gh/coin-test/coin-test/branch/main/graph/badge.svg)](https://codecov.io/gh/coin-test/coin-test)\n\nCoin-test is a backtesting library designed for cryptocurrency trading. It supports trading strategies across multiple currencies and advanced configurations of tests, including cron-based scheduled execution of strategies, synthetic data generation, slippage modeling, and trading fees.\n\n## Quick Start\n\nCoin-test runs on Python 3.10 or higher. Install the package via pip:\n\n```sh\npip3 install coin-test\n```\n\nTo run a backtest, import the coin-test library. Then define your data source, strategy, and test settings to run the analysis.\n\n```python\nimport datetime as dt\nimport os\nimport pandas as pd\n\nfrom coin_test.backtest import Portfolio, Strategy, MarketTradeRequest\nfrom coin_test.data import CustomDataset\nfrom coin_test.util import AssetPair, Ticker, Money, Side\n```\nThen, import data from a CSV or another source to load\ninto the backtest.\n```python\ndataset_file = \"data/ETHUSDT-1h-monthly/BTCUSDT-1h-2017-08.csv\"\nheader = [\"Open Time\", \"Open\", \"High\", \"Low\", \"Close\", \"Volume\", \"Close Time\",\n \"Quote asset volume\", \"Number of trades\", \"Taker buy base asset volume\",\n \"Taker buy quote asset volume\", \"Ignore\"\n]\ndf = pd.read_csv(dataset_file, names=header)\ndf = df.drop(columns=[\"Close Time\", \"Quote asset volume\", \"Number of trades\",\n \"Taker buy base asset volume\",\n \"Taker buy quote asset volume\", \"Ignore\"])\ndf[\"Open Time\"] //= 1000 # To seconds\ndf = df.sort_values(by=[\"Open Time\"])\n\n# define dataset metadata\nusdt = Ticker(\"USDT\")\nbtc = Ticker(\"BTC\")\nasset_pair = AssetPair(btc, usdt)\nfreq = \"H\"\n\ndataset = CustomDataset(df, freq, asset_pair)\n```\n\nStrategies are stored in classes as shown below. Each strategy\nshould have a schedule, which is a cron string representing\nwhen this strategy is run, a lookback, which is how much\ndata is accessed in the strategy, and a `__call__` method\nwhich returns a list of TradeRequest objects, which represent\ntrades the strategy wants to make.\n\n```python\nclass MACD(Strategy):\n def __init__(self, asset_pair) -> None:\n \"\"\"Initialize a MACD object.\"\"\"\n super().__init__(\n name=\"MACD\",\n asset_pairs=[asset_pair],\n schedule=\"0 9 * * *\",\n lookback=dt.timedelta(days=26),\n )\n self.perc = 0.2\n\n def __call__(self, time, portfolio, lookback_data):\n \"\"\"Execute test strategy.\"\"\"\n asset_pair = self.asset_pairs[0]\n exp1 = lookback_data[asset_pair][\"Close\"].ewm(span=12 * 24, adjust=False).mean()\n exp2 = lookback_data[asset_pair][\"Close\"].ewm(span=26 * 24, adjust=False).mean()\n macd = exp1 - exp2\n exp3 = macd.ewm(span=9 * 24, adjust=False).mean()\n\n if macd.iloc[-1] > exp3.iloc[-1]:\n return [MarketTradeRequest(\n asset_pair,\n Side.BUY,\n notional=portfolio.available_assets(usdt).qty * self.perc,\n )]\n elif macd.iloc[-1] < exp3.iloc[-1]:\n return [MarketTradeRequest(\n asset_pair,\n Side.SELL,\n qty=portfolio.available_assets(btc).qty * self.perc,\n )]\n return []\n```\n\nThis package supports multiple strategies, train-test splits\nfor historical data, synthetic data, and further customization.\nTo run the backtest, define the datasets\n\n```python\nfrom coin_test.backtest import ConstantSlippage, ConstantTransactionFeeCalculator\nsc = ConstantSlippage(50)\ntc = ConstantTransactionFeeCalculator(50)\n\ndatasets = [dataset]\nstrategies = [MACD]\n\nresults = coin_test.run(datasets, strategies, sc, tc,\n portfolio, pd.Timedelta(days=90),\n n_parallel=8)\n```\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Robust and rigorous backtesting framework for cryptocurrencies.",
"version": "0.1.0",
"split_keywords": [
"cryptocurrency",
"backtesting"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "22da50d6740738e138718c27ec1ed9c8f256880dde01df72e916b920b2676e46",
"md5": "7c87ab54ef13f43cb142f300f52734bc",
"sha256": "2478b9e9434dc28382a6276d83cf7bcf928e76c2970e44f4c275e9d4f6cdbf08"
},
"downloads": -1,
"filename": "coin_test-0.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "7c87ab54ef13f43cb142f300f52734bc",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10,<3.11",
"size": 27540,
"upload_time": "2023-03-22T19:28:10",
"upload_time_iso_8601": "2023-03-22T19:28:10.635023Z",
"url": "https://files.pythonhosted.org/packages/22/da/50d6740738e138718c27ec1ed9c8f256880dde01df72e916b920b2676e46/coin_test-0.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "0087244bfa811303a6d2329c3f64760840d1d7e2476c976b2755598ffb766e88",
"md5": "5a107cce2308fb9f3723fbeefc27cb10",
"sha256": "8b8811e49d43ad0f53c04a8f3c6b63bc0c60fa7f48197da08ca24c063479e1e6"
},
"downloads": -1,
"filename": "coin_test-0.1.0.tar.gz",
"has_sig": false,
"md5_digest": "5a107cce2308fb9f3723fbeefc27cb10",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10,<3.11",
"size": 22010,
"upload_time": "2023-03-22T19:28:11",
"upload_time_iso_8601": "2023-03-22T19:28:11.945609Z",
"url": "https://files.pythonhosted.org/packages/00/87/244bfa811303a6d2329c3f64760840d1d7e2476c976b2755598ffb766e88/coin_test-0.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-03-22 19:28:11",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "coin-test",
"github_project": "coin-test",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "coin-test"
}