# market-break
> a set of utilities for backtesting vectorized trading algorithms, high-frequency trading strategies and investing strategies.
## Installation
_______
````
pip install python-market-break
````
Connect to a live database for real-time data.
```python
from sqlalchemy import create_engine
engine = create_engine('sqlite:///database/2024-06-14.sqlite')
```
Extract The data from the database into a DataFrame.
```python
from cryptocore.market.database import extract_dataframe, table_name
EXCHANGE = "binance"
SYMBOL = "ETH/USDT"
df = extract_dataframe(engine, table_name(exchange=EXCHANGE, symbol=SYMBOL))
df = df.iloc[3500:7000].reset_index()
```
```python
df
```
<div>
<style scoped>
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
</style>
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>index</th>
<th>exchange</th>
<th>symbol</th>
<th>timestamp</th>
<th>datetime</th>
<th>received_datetime</th>
<th>open</th>
<th>high</th>
<th>low</th>
<th>close</th>
<th>bid</th>
<th>ask</th>
<th>bid_volume</th>
<th>ask_volume</th>
<th>side</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>3500</td>
<td>binance</td>
<td>ETH/USDT</td>
<td>1.718353e+12</td>
<td>2024-06-14 11:19:38.208</td>
<td>2024-06-14 08:19:38.156</td>
<td>3510.78</td>
<td>3539.83</td>
<td>3428.0</td>
<td>3521.99</td>
<td>3521.98</td>
<td>3521.99</td>
<td>59.7590</td>
<td>21.0623</td>
<td>buy</td>
</tr>
<tr>
<th>1</th>
<td>3501</td>
<td>binance</td>
<td>ETH/USDT</td>
<td>1.718353e+12</td>
<td>2024-06-14 11:19:39.031</td>
<td>2024-06-14 08:19:39.155</td>
<td>3510.78</td>
<td>3539.83</td>
<td>3428.0</td>
<td>3521.98</td>
<td>3521.98</td>
<td>3521.99</td>
<td>58.2914</td>
<td>28.2213</td>
<td>sell</td>
</tr>
<tr>
<th>2</th>
<td>3502</td>
<td>binance</td>
<td>ETH/USDT</td>
<td>1.718353e+12</td>
<td>2024-06-14 11:19:39.857</td>
<td>2024-06-14 08:19:40.158</td>
<td>3510.78</td>
<td>3539.83</td>
<td>3428.0</td>
<td>3521.99</td>
<td>3521.98</td>
<td>3521.99</td>
<td>58.2418</td>
<td>24.8653</td>
<td>buy</td>
</tr>
<tr>
<th>3</th>
<td>3503</td>
<td>binance</td>
<td>ETH/USDT</td>
<td>1.718353e+12</td>
<td>2024-06-14 11:19:40.574</td>
<td>2024-06-14 08:19:41.179</td>
<td>3510.78</td>
<td>3539.83</td>
<td>3428.0</td>
<td>3521.99</td>
<td>3521.98</td>
<td>3521.99</td>
<td>63.9093</td>
<td>24.8653</td>
<td>buy</td>
</tr>
<tr>
<th>4</th>
<td>3504</td>
<td>binance</td>
<td>ETH/USDT</td>
<td>1.718353e+12</td>
<td>2024-06-14 11:19:42.080</td>
<td>2024-06-14 08:19:42.161</td>
<td>3510.78</td>
<td>3539.83</td>
<td>3428.0</td>
<td>3521.99</td>
<td>3521.98</td>
<td>3521.99</td>
<td>64.6069</td>
<td>14.6805</td>
<td>buy</td>
</tr>
<tr>
<th>...</th>
<td>...</td>
<td>...</td>
<td>...</td>
<td>...</td>
<td>...</td>
<td>...</td>
<td>...</td>
<td>...</td>
<td>...</td>
<td>...</td>
<td>...</td>
<td>...</td>
<td>...</td>
<td>...</td>
<td>...</td>
</tr>
<tr>
<th>3495</th>
<td>6995</td>
<td>binance</td>
<td>ETH/USDT</td>
<td>1.718357e+12</td>
<td>2024-06-14 12:17:55.995</td>
<td>2024-06-14 09:17:55.971</td>
<td>3493.19</td>
<td>3539.83</td>
<td>3428.0</td>
<td>3518.19</td>
<td>3518.19</td>
<td>3518.20</td>
<td>125.1496</td>
<td>5.5759</td>
<td>sell</td>
</tr>
<tr>
<th>3496</th>
<td>6996</td>
<td>binance</td>
<td>ETH/USDT</td>
<td>1.718357e+12</td>
<td>2024-06-14 12:17:56.069</td>
<td>2024-06-14 09:17:56.976</td>
<td>3493.19</td>
<td>3539.83</td>
<td>3428.0</td>
<td>3518.20</td>
<td>3518.19</td>
<td>3518.20</td>
<td>125.1496</td>
<td>5.5728</td>
<td>buy</td>
</tr>
<tr>
<th>3497</th>
<td>6997</td>
<td>binance</td>
<td>ETH/USDT</td>
<td>1.718357e+12</td>
<td>2024-06-14 12:17:57.779</td>
<td>2024-06-14 09:17:58.075</td>
<td>3492.59</td>
<td>3539.83</td>
<td>3428.0</td>
<td>3518.20</td>
<td>3518.19</td>
<td>3518.20</td>
<td>121.2325</td>
<td>7.5728</td>
<td>buy</td>
</tr>
<tr>
<th>3498</th>
<td>6998</td>
<td>binance</td>
<td>ETH/USDT</td>
<td>1.718357e+12</td>
<td>2024-06-14 12:17:58.886</td>
<td>2024-06-14 09:17:58.973</td>
<td>3492.59</td>
<td>3539.83</td>
<td>3428.0</td>
<td>3518.20</td>
<td>3518.19</td>
<td>3518.20</td>
<td>83.2826</td>
<td>7.7234</td>
<td>buy</td>
</tr>
<tr>
<th>3499</th>
<td>6999</td>
<td>binance</td>
<td>ETH/USDT</td>
<td>1.718357e+12</td>
<td>2024-06-14 12:18:00.028</td>
<td>2024-06-14 09:17:59.973</td>
<td>3492.60</td>
<td>3539.83</td>
<td>3428.0</td>
<td>3518.20</td>
<td>3518.19</td>
<td>3518.20</td>
<td>75.6586</td>
<td>9.3705</td>
<td>buy</td>
</tr>
</tbody>
</table>
<p>3500 rows × 15 columns</p>
</div>
Import column names to handle the data.
```python
from market_break.labels import BID, ASK, DATETIME, ENTRY, EXIT, TYPE, LONG
```
Import a class of backtesting functions.
```python
from market_break.backtest import Trades
```
Generate trades record, both short and long as a DataFrame, from definition of up-trends and down-trends.
```python
trades = Trades.generate(
up=df[ASK] > df[ASK].shift(1),
down=df[BID] < df[BID].shift(1),
adjust=True
)
```
Process the results of the generated trades.
```python
FEE = 0.001
returns = Trades.returns(trades, bid=df[BID], ask=df[ASK], fee=FEE)
```
Imports a class of Plotting trading results.
```python
from market_break.backtest import Plot
```
Plot a histogram of the trades returns.
```python
Plot.returns_histogram(returns, bins=35)
```
![png](media/output_8_0.png)
Plot a graph of the trades returns.
```python
Plot.returns_signals(returns, index=df[DATETIME].iloc)
```
![png](media/output_9_0.png)
Plot pie graphs of the winning and losing trades and their profits and losses.
```python
Plot.returns_pie(returns)
```
![png](media/output_10_0.png)
Plot the signals for long and short entries and exits, with the bid-ask spread.
Also plotting The balance, profits and losses.
```python
long_trades = trades[trades[TYPE] == LONG]
Plot.price_signals(
bid=df[BID], ask=df[ASK], index=df[DATETIME].iloc,
long=long_trades[ENTRY], short=long_trades[EXIT]
)
Plot.returns_balance(returns, index=df[DATETIME].iloc)
```
![png](media/output_11_0.png)
![png](media/output_11_1.png)
Import a class for generating a report from the results.
```python
from market_break.backtest import Report
```
Generating and displaying the results with the report.
```python
report = Report.generate(
index=df[DATETIME], returns=returns,
long=trades[EXIT].values, short=trades[EXIT].values
)
print(Report.repr(report))
```
[Index]
start 2024-06-14 11:19:38.20
end 2024-06-14 12:18:00.02
total duration 0 days 00:58:21.82
min. tick duration 0:00:00.06
max. tick duration 0:00:01.90
avg. tick duration 0:00:01.00
ticks 3500
[Trades]
long trades 125
short trades 125
min. TUW 0:0
max. TUW 0:0
avg. TUW 0:0
[Gains]
[%] min. gain 0.0003
[%] max. gain 0.1482
[%] avg. gain 0.0291
[%] total gains 2.4411
winning trades 84
[Losses]
[%] min. loss -0.0003
[%] max. loss -0.017
[%] avg. loss -0.0063
[%] total losses -0.2383
losing trades 38
[Performance]
PnL factor 10.245
avg. profit factor 1.0002
[%] win rate 67.2
[%] total profit 2.2029
Raw data
{
"_id": null,
"home_page": "https://github.com/Shahaf-F-S/market-break",
"name": "python-market-break",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": null,
"author": "Shahaf Frank-Shapir",
"author_email": "shahaffrs@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/39/51/040c3adba9eb8cc3f5e4c65044baa754f0508fcf2da5f0f947e7c59e5d71/python_market_break-3.2.2.tar.gz",
"platform": null,
"description": "# market-break\r\n\r\n> a set of utilities for backtesting vectorized trading algorithms, high-frequency trading strategies and investing strategies.\r\n\r\n## Installation\r\n_______\r\n\r\n````\r\npip install python-market-break\r\n````\r\n\r\nConnect to a live database for real-time data.\r\n\r\n```python\r\nfrom sqlalchemy import create_engine\r\n\r\nengine = create_engine('sqlite:///database/2024-06-14.sqlite')\r\n```\r\n\r\nExtract The data from the database into a DataFrame.\r\n\r\n```python\r\nfrom cryptocore.market.database import extract_dataframe, table_name\r\n\r\nEXCHANGE = \"binance\"\r\nSYMBOL = \"ETH/USDT\"\r\n\r\ndf = extract_dataframe(engine, table_name(exchange=EXCHANGE, symbol=SYMBOL))\r\ndf = df.iloc[3500:7000].reset_index()\r\n```\r\n\r\n\r\n```python\r\ndf\r\n```\r\n\r\n\r\n\r\n\r\n<div>\r\n<style scoped>\r\n .dataframe tbody tr th:only-of-type {\r\n vertical-align: middle;\r\n }\r\n\r\n .dataframe tbody tr th {\r\n vertical-align: top;\r\n }\r\n\r\n .dataframe thead th {\r\n text-align: right;\r\n }\r\n</style>\r\n<table border=\"1\" class=\"dataframe\">\r\n <thead>\r\n <tr style=\"text-align: right;\">\r\n <th></th>\r\n <th>index</th>\r\n <th>exchange</th>\r\n <th>symbol</th>\r\n <th>timestamp</th>\r\n <th>datetime</th>\r\n <th>received_datetime</th>\r\n <th>open</th>\r\n <th>high</th>\r\n <th>low</th>\r\n <th>close</th>\r\n <th>bid</th>\r\n <th>ask</th>\r\n <th>bid_volume</th>\r\n <th>ask_volume</th>\r\n <th>side</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr>\r\n <th>0</th>\r\n <td>3500</td>\r\n <td>binance</td>\r\n <td>ETH/USDT</td>\r\n <td>1.718353e+12</td>\r\n <td>2024-06-14 11:19:38.208</td>\r\n <td>2024-06-14 08:19:38.156</td>\r\n <td>3510.78</td>\r\n <td>3539.83</td>\r\n <td>3428.0</td>\r\n <td>3521.99</td>\r\n <td>3521.98</td>\r\n <td>3521.99</td>\r\n <td>59.7590</td>\r\n <td>21.0623</td>\r\n <td>buy</td>\r\n </tr>\r\n <tr>\r\n <th>1</th>\r\n <td>3501</td>\r\n <td>binance</td>\r\n <td>ETH/USDT</td>\r\n <td>1.718353e+12</td>\r\n <td>2024-06-14 11:19:39.031</td>\r\n <td>2024-06-14 08:19:39.155</td>\r\n <td>3510.78</td>\r\n <td>3539.83</td>\r\n <td>3428.0</td>\r\n <td>3521.98</td>\r\n <td>3521.98</td>\r\n <td>3521.99</td>\r\n <td>58.2914</td>\r\n <td>28.2213</td>\r\n <td>sell</td>\r\n </tr>\r\n <tr>\r\n <th>2</th>\r\n <td>3502</td>\r\n <td>binance</td>\r\n <td>ETH/USDT</td>\r\n <td>1.718353e+12</td>\r\n <td>2024-06-14 11:19:39.857</td>\r\n <td>2024-06-14 08:19:40.158</td>\r\n <td>3510.78</td>\r\n <td>3539.83</td>\r\n <td>3428.0</td>\r\n <td>3521.99</td>\r\n <td>3521.98</td>\r\n <td>3521.99</td>\r\n <td>58.2418</td>\r\n <td>24.8653</td>\r\n <td>buy</td>\r\n </tr>\r\n <tr>\r\n <th>3</th>\r\n <td>3503</td>\r\n <td>binance</td>\r\n <td>ETH/USDT</td>\r\n <td>1.718353e+12</td>\r\n <td>2024-06-14 11:19:40.574</td>\r\n <td>2024-06-14 08:19:41.179</td>\r\n <td>3510.78</td>\r\n <td>3539.83</td>\r\n <td>3428.0</td>\r\n <td>3521.99</td>\r\n <td>3521.98</td>\r\n <td>3521.99</td>\r\n <td>63.9093</td>\r\n <td>24.8653</td>\r\n <td>buy</td>\r\n </tr>\r\n <tr>\r\n <th>4</th>\r\n <td>3504</td>\r\n <td>binance</td>\r\n <td>ETH/USDT</td>\r\n <td>1.718353e+12</td>\r\n <td>2024-06-14 11:19:42.080</td>\r\n <td>2024-06-14 08:19:42.161</td>\r\n <td>3510.78</td>\r\n <td>3539.83</td>\r\n <td>3428.0</td>\r\n <td>3521.99</td>\r\n <td>3521.98</td>\r\n <td>3521.99</td>\r\n <td>64.6069</td>\r\n <td>14.6805</td>\r\n <td>buy</td>\r\n </tr>\r\n <tr>\r\n <th>...</th>\r\n <td>...</td>\r\n <td>...</td>\r\n <td>...</td>\r\n <td>...</td>\r\n <td>...</td>\r\n <td>...</td>\r\n <td>...</td>\r\n <td>...</td>\r\n <td>...</td>\r\n <td>...</td>\r\n <td>...</td>\r\n <td>...</td>\r\n <td>...</td>\r\n <td>...</td>\r\n <td>...</td>\r\n </tr>\r\n <tr>\r\n <th>3495</th>\r\n <td>6995</td>\r\n <td>binance</td>\r\n <td>ETH/USDT</td>\r\n <td>1.718357e+12</td>\r\n <td>2024-06-14 12:17:55.995</td>\r\n <td>2024-06-14 09:17:55.971</td>\r\n <td>3493.19</td>\r\n <td>3539.83</td>\r\n <td>3428.0</td>\r\n <td>3518.19</td>\r\n <td>3518.19</td>\r\n <td>3518.20</td>\r\n <td>125.1496</td>\r\n <td>5.5759</td>\r\n <td>sell</td>\r\n </tr>\r\n <tr>\r\n <th>3496</th>\r\n <td>6996</td>\r\n <td>binance</td>\r\n <td>ETH/USDT</td>\r\n <td>1.718357e+12</td>\r\n <td>2024-06-14 12:17:56.069</td>\r\n <td>2024-06-14 09:17:56.976</td>\r\n <td>3493.19</td>\r\n <td>3539.83</td>\r\n <td>3428.0</td>\r\n <td>3518.20</td>\r\n <td>3518.19</td>\r\n <td>3518.20</td>\r\n <td>125.1496</td>\r\n <td>5.5728</td>\r\n <td>buy</td>\r\n </tr>\r\n <tr>\r\n <th>3497</th>\r\n <td>6997</td>\r\n <td>binance</td>\r\n <td>ETH/USDT</td>\r\n <td>1.718357e+12</td>\r\n <td>2024-06-14 12:17:57.779</td>\r\n <td>2024-06-14 09:17:58.075</td>\r\n <td>3492.59</td>\r\n <td>3539.83</td>\r\n <td>3428.0</td>\r\n <td>3518.20</td>\r\n <td>3518.19</td>\r\n <td>3518.20</td>\r\n <td>121.2325</td>\r\n <td>7.5728</td>\r\n <td>buy</td>\r\n </tr>\r\n <tr>\r\n <th>3498</th>\r\n <td>6998</td>\r\n <td>binance</td>\r\n <td>ETH/USDT</td>\r\n <td>1.718357e+12</td>\r\n <td>2024-06-14 12:17:58.886</td>\r\n <td>2024-06-14 09:17:58.973</td>\r\n <td>3492.59</td>\r\n <td>3539.83</td>\r\n <td>3428.0</td>\r\n <td>3518.20</td>\r\n <td>3518.19</td>\r\n <td>3518.20</td>\r\n <td>83.2826</td>\r\n <td>7.7234</td>\r\n <td>buy</td>\r\n </tr>\r\n <tr>\r\n <th>3499</th>\r\n <td>6999</td>\r\n <td>binance</td>\r\n <td>ETH/USDT</td>\r\n <td>1.718357e+12</td>\r\n <td>2024-06-14 12:18:00.028</td>\r\n <td>2024-06-14 09:17:59.973</td>\r\n <td>3492.60</td>\r\n <td>3539.83</td>\r\n <td>3428.0</td>\r\n <td>3518.20</td>\r\n <td>3518.19</td>\r\n <td>3518.20</td>\r\n <td>75.6586</td>\r\n <td>9.3705</td>\r\n <td>buy</td>\r\n </tr>\r\n </tbody>\r\n</table>\r\n<p>3500 rows \u00c3\u2014 15 columns</p>\r\n</div>\r\n\r\n\r\nImport column names to handle the data.\r\n\r\n```python\r\nfrom market_break.labels import BID, ASK, DATETIME, ENTRY, EXIT, TYPE, LONG\r\n```\r\n\r\nImport a class of backtesting functions.\r\n\r\n```python\r\nfrom market_break.backtest import Trades\r\n```\r\n\r\nGenerate trades record, both short and long as a DataFrame, from definition of up-trends and down-trends.\r\n\r\n```python\r\ntrades = Trades.generate(\r\n up=df[ASK] > df[ASK].shift(1),\r\n down=df[BID] < df[BID].shift(1),\r\n adjust=True\r\n)\r\n```\r\n\r\nProcess the results of the generated trades.\r\n\r\n```python\r\nFEE = 0.001\r\n\r\nreturns = Trades.returns(trades, bid=df[BID], ask=df[ASK], fee=FEE)\r\n```\r\n\r\nImports a class of Plotting trading results.\r\n\r\n```python\r\nfrom market_break.backtest import Plot\r\n```\r\n\r\nPlot a histogram of the trades returns.\r\n\r\n```python\r\nPlot.returns_histogram(returns, bins=35)\r\n```\r\n\r\n\r\n\r\n![png](media/output_8_0.png)\r\n\r\n\r\nPlot a graph of the trades returns.\r\n\r\n```python\r\nPlot.returns_signals(returns, index=df[DATETIME].iloc)\r\n```\r\n\r\n\r\n\r\n![png](media/output_9_0.png)\r\n\r\n\r\nPlot pie graphs of the winning and losing trades and their profits and losses.\r\n\r\n```python\r\nPlot.returns_pie(returns)\r\n```\r\n\r\n\r\n\r\n![png](media/output_10_0.png)\r\n\r\n\r\nPlot the signals for long and short entries and exits, with the bid-ask spread.\r\nAlso plotting The balance, profits and losses.\r\n\r\n```python\r\nlong_trades = trades[trades[TYPE] == LONG]\r\n\r\nPlot.price_signals(\r\n bid=df[BID], ask=df[ASK], index=df[DATETIME].iloc,\r\n long=long_trades[ENTRY], short=long_trades[EXIT]\r\n)\r\nPlot.returns_balance(returns, index=df[DATETIME].iloc)\r\n```\r\n\r\n\r\n\r\n![png](media/output_11_0.png)\r\n\r\n\r\n\r\n\r\n\r\n![png](media/output_11_1.png)\r\n\r\n\r\nImport a class for generating a report from the results.\r\n\r\n```python\r\nfrom market_break.backtest import Report\r\n```\r\n\r\nGenerating and displaying the results with the report.\r\n\r\n```python\r\nreport = Report.generate(\r\n index=df[DATETIME], returns=returns, \r\n long=trades[EXIT].values, short=trades[EXIT].values\r\n)\r\n\r\nprint(Report.repr(report))\r\n```\r\n\r\n [Index]\r\n start 2024-06-14 11:19:38.20\r\n end 2024-06-14 12:18:00.02\r\n total duration 0 days 00:58:21.82\r\n min. tick duration 0:00:00.06\r\n max. tick duration 0:00:01.90\r\n avg. tick duration 0:00:01.00\r\n ticks 3500\r\n \r\n [Trades]\r\n long trades 125\r\n short trades 125\r\n min. TUW 0:0\r\n max. TUW 0:0\r\n avg. TUW 0:0\r\n \r\n [Gains]\r\n [%] min. gain 0.0003\r\n [%] max. gain 0.1482\r\n [%] avg. gain 0.0291\r\n [%] total gains 2.4411\r\n winning trades 84\r\n \r\n [Losses]\r\n [%] min. loss -0.0003\r\n [%] max. loss -0.017\r\n [%] avg. loss -0.0063\r\n [%] total losses -0.2383\r\n losing trades 38\r\n \r\n [Performance]\r\n PnL factor 10.245\r\n avg. profit factor 1.0002\r\n [%] win rate 67.2\r\n [%] total profit 2.2029\r\n \r\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A set of tools to help create algorithmic trading strategies and test them, in a vectorized way.",
"version": "3.2.2",
"project_urls": {
"Homepage": "https://github.com/Shahaf-F-S/market-break"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "3951040c3adba9eb8cc3f5e4c65044baa754f0508fcf2da5f0f947e7c59e5d71",
"md5": "a3fdeeb985d2eb7bdfebe4fd6833b07e",
"sha256": "f6f408b0a9bb9a78d5d211a7ddd4a888fd9cb1317117a913c183596a55b5d7c6"
},
"downloads": -1,
"filename": "python_market_break-3.2.2.tar.gz",
"has_sig": false,
"md5_digest": "a3fdeeb985d2eb7bdfebe4fd6833b07e",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 21255,
"upload_time": "2024-11-05T19:31:58",
"upload_time_iso_8601": "2024-11-05T19:31:58.916047Z",
"url": "https://files.pythonhosted.org/packages/39/51/040c3adba9eb8cc3f5e4c65044baa754f0508fcf2da5f0f947e7c59e5d71/python_market_break-3.2.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-05 19:31:58",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Shahaf-F-S",
"github_project": "market-break",
"github_not_found": true,
"lcname": "python-market-break"
}