mirror of
https://github.com/wassname/pandas-ta.git
synced 2026-07-20 12:30:43 +08:00
1.3 MiB
1.3 MiB
In [1]:
import asyncio
import itertools
from datetime import datetime
from IPython import display
import numpy as np
import pandas as pd
import pandas_ta as ta
import vectorbt as vbt
import plotly.graph_objects as go
print("Package Versions:")
print(f"Numpy v{np.__version__}")
print(f"Pandas v{pd.__version__}")
print(f"vectorbt >= v0.18.1")
print(f"\nPandas TA v{ta.version}\nTo install the Latest Version:\n$ pip install -U git+https://github.com/twopirllc/pandas-ta\n")
%matplotlib inlinePackage Versions: Numpy v1.20.2 Pandas v1.2.4 vectorbt >= v0.18.1 Pandas TA v0.2.89b0 To install the Latest Version: $ pip install -U git+https://github.com/twopirllc/pandas-ta
In [2]:
cheight, cwidth = 500, 1000 # Adjust as needed for Chart Height and Width
vbt.settings.set_theme("dark") # Options: "light" (Default), "dark" (my fav), "seaborn"
# Must be set
vbt.settings.portfolio["freq"] = "1D" # Daily
# Predefine vectorbt Portfolio settings
# vbt.settings.portfolio["init_cash"] = 100
vbt.settings.portfolio["fees"] = 0.0025 # 0.25%
vbt.settings.portfolio["slippage"] = 0.0025 # 0.25%
# vbt.settings.portfolio["size"] = 100
# vbt.settings.portfolio["accumulate"] = False
vbt.settings.portfolio["allow_partial"] = False
pf_settings = pd.DataFrame(vbt.settings.portfolio.items(), columns=["Option", "Value"])
pf_settings.set_index("Option", inplace=True)
print(f"Portfolio Settings [Initial]")
pf_settingsOut [2]:
Portfolio Settings [Initial]
| Value | |
|---|---|
| Option | |
| call_seq | default |
| init_cash | 100.0 |
| size | inf |
| size_type | shares |
| signal_size_type | shares |
| fees | 0.0025 |
| fixed_fees | 0.0 |
| slippage | 0.0025 |
| reject_prob | 0.0 |
| min_size | 0.0 |
| max_size | inf |
| allow_partial | False |
| raise_reject | False |
| close_first | False |
| accumulate | False |
| log | False |
| conflict_mode | ignore |
| signal_direction | longonly |
| order_direction | all |
| cash_sharing | False |
| row_wise | False |
| use_numba | True |
| seed | None |
| freq | 1D |
| incl_unrealized | False |
| use_filled_close | True |
| subplots | [orders, trade_returns, cum_returns] |
In [3]:
def combine_stats(pf: vbt.portfolio.base.Portfolio, ticker: str, strategy: str, mode: int = 0):
header = pd.Series({
"Run Time": ta.get_time(full=False, to_string=True),
"Mode": "LIVE" if mode else "TEST",
"Strategy": strategy,
"Direction": vbt.settings.portfolio["signal_direction"],
"Symbol": ticker.upper(),
"Fees [%]": 100 * vbt.settings.portfolio["fees"],
"Slippage [%]": 100 * vbt.settings.portfolio["slippage"],
"Accumulate": vbt.settings.portfolio["accumulate"],
})
rstats = pf.returns_stats().dropna(axis=0).T
stats = pf.stats().dropna(axis=0).T
joint = pd.concat([header, stats, rstats])
return joint[~joint.index.duplicated(keep="first")]
def earliest_common_index(d: dict):
"""Returns index of the earliest common index of all DataFrames in the dict"""
min_date = None
for df in d.values():
if min_date is None:
min_date = df.index[0]
elif min_date < df.index[0]:
min_date = df.index[0]
return min_date
def dl(tickers: list, same_start: bool = False, **kwargs):
if isinstance(tickers, str):
tickers = [tickers]
if not isinstance(tickers, list) or len(tickers) == 0:
print("Must be a non-empty list of tickers or symbols")
return
if "limit" in kwargs and kwargs["limit"] and len(tickers) > kwargs["limit"]:
from itertools import islice
tickers = list(islice(tickers, kwargs["limit"]))
print(f"[!] Too many assets to compare. Using the first {kwargs['limit']}: {', '.join(tickers)}")
print(f"[i] Downloading: {', '.join(tickers)}")
received = {}
if len(tickers):
_df = pd.DataFrame()
for ticker in tickers:
received[ticker] = _df.ta.ticker(ticker, **kwargs)
print(f"[+] {ticker}{received[ticker].shape} {ta.get_time(full=False, to_string=True)}")
if same_start and len(tickers) > 1:
earliestci = earliest_common_index(received)
print(f"[i] Earliest Common Date: {earliestci}")
result = {ticker:df[df.index > earliestci].copy() for ticker,df in received.items()}
else:
result = received
print(f"[*] Download Complete\n")
return result
def dtmask(df: pd.DataFrame, start: datetime, end: datetime):
return df.loc[(df.index >= start) & (df.index <= end), :].copy()
def show_data(d: dict):
[print(f"{t}[{df.index[0]} - {df.index[-1]}]: {df.shape} {df.ta.time_range:.2f} years") for t,df in d.items()]
def trade_table(pf: vbt.portfolio.base.Portfolio, k: int = 1, total_fees: bool = False):
if not isinstance(pf, vbt.portfolio.base.Portfolio): return
k = int(k) if isinstance(k, int) and k > 0 else 1
df = pf.trades.records[["status", "direction", "size", "entry_price", "exit_price", "return", "pnl", "entry_fees", "exit_fees"]]
if total_fees:
df["total_fees"] = df["entry_fees"] + df["exit_fees"]
print(f"\nLast {k} of {df.shape[0]} Trades\n{df.tail(k)}\n")In [4]:
benchmark_tickers = ["SPY", "QQQ"]
asset_tickers = ["AAPL", "TSLA", "TWTR"]
all_tickers = benchmark_tickers + asset_tickers
print("Tickers by index #")
print("="*100)
print(f"Benchmarks: {', '.join([f'{k}: {v}' for k,v in enumerate(benchmark_tickers)])}")
print(f" Assets: {', '.join([f'{k}: {v}' for k,v in enumerate(asset_tickers)])}")
print(f" All: {', '.join([f'{k}: {v}' for k,v in enumerate(all_tickers)])}")Tickers by index #
====================================================================================================
Benchmarks: 0: SPY, 1: QQQ
Assets: 0: AAPL, 1: TSLA, 2: TWTR
All: 0: SPY, 1: QQQ, 2: AAPL, 3: TSLA, 4: TWTR
In [5]:
benchmark = benchmark_tickers[0] # Change index for different benchmark
asset = asset_tickers[2] # Change index for different symbol
print(f"Selected Benchmark | Asset: {benchmark} | {asset}")Selected Benchmark | Asset: SPY | TWTR
In [6]:
benchmarks = dl(benchmark_tickers, lc_cols=True)[i] Downloading: SPY, QQQ [+] SPY(7149, 7) Saturday June 19, 2021, NYSE: 7:58:24 [+] QQQ(5607, 7) Saturday June 19, 2021, NYSE: 7:58:27 [*] Download Complete
In [7]:
assets = dl(asset_tickers, lc_cols=True)[i] Downloading: AAPL, TSLA, TWTR [+] AAPL(10216, 7) Saturday June 19, 2021, NYSE: 7:58:30 [+] TSLA(2763, 7) Saturday June 19, 2021, NYSE: 7:58:32 [+] TWTR(1916, 7) Saturday June 19, 2021, NYSE: 7:58:34 [*] Download Complete
In [8]:
start_date = datetime(2005, 1, 1) # Adjust as needed
end_date = datetime(2010, 1, 1) # Adjust as neededIn [9]:
print("Available Data:")
print("="*100)
print(f"Benchmarks: {', '.join(benchmarks.keys())}")
print(f"Assets: {', '.join(assets.keys())}")Available Data: ==================================================================================================== Benchmarks: SPY, QQQ Assets: AAPL, TSLA, TWTR
In [10]:
benchmark_name = "SPY" # Select a Benchmark
asset_name = "AAPL" # Select an Asset
benchmarkdf = benchmarks[benchmark_name]
assetdf = assets[asset_name]
# Set True if you want to constrain Data between start_date & end_date
common_range = True
if common_range:
crs = f" from {start_date} to {end_date}"
benchmarkdf = dtmask(benchmarkdf, start_date, end_date)
assetdf = dtmask(assetdf, start_date, end_date)
# Update DataFrame names
benchmarkdf.name = benchmark_name
assetdf.name = asset_name
print(f"Analysis of: {benchmarkdf.name} and {assetdf.name}{crs if common_range else ''}")Analysis of: SPY and AAPL from 2005-01-01 00:00:00 to 2010-01-01 00:00:00
In [11]:
benchmarkdfOut [11]:
| open | high | low | close | volume | dividends | stock splits | |
|---|---|---|---|---|---|---|---|
| date | |||||||
| 2005-01-03 | 88.048860 | 88.193728 | 86.846484 | 87.136215 | 55748000 | 0.0 | 0 |
| 2005-01-04 | 87.252088 | 87.310035 | 85.788956 | 86.071442 | 69167600 | 0.0 | 0 |
| 2005-01-05 | 86.006247 | 86.375654 | 85.470248 | 85.477493 | 65667300 | 0.0 | 0 |
| 2005-01-06 | 85.788945 | 86.303215 | 85.658567 | 85.912079 | 47814700 | 0.0 | 0 |
| 2005-01-07 | 86.172847 | 86.361172 | 85.564411 | 85.788956 | 55847700 | 0.0 | 0 |
| ... | ... | ... | ... | ... | ... | ... | ... |
| 2009-12-24 | 89.876815 | 90.205268 | 89.724602 | 90.109138 | 39677500 | 0.0 | 0 |
| 2009-12-28 | 90.445592 | 90.517689 | 89.980945 | 90.301392 | 87508500 | 0.0 | 0 |
| 2009-12-29 | 90.533684 | 90.549703 | 90.165173 | 90.173180 | 80572500 | 0.0 | 0 |
| 2009-12-30 | 89.908834 | 90.245300 | 89.860763 | 90.141151 | 73138400 | 0.0 | 0 |
| 2009-12-31 | 90.341438 | 90.365476 | 89.235905 | 89.275963 | 90637900 | 0.0 | 0 |
1259 rows × 7 columns
In [12]:
assetdfOut [12]:
| open | high | low | close | volume | dividends | stock splits | |
|---|---|---|---|---|---|---|---|
| date | |||||||
| 2005-01-03 | 0.994723 | 0.999791 | 0.961248 | 0.971844 | 691992000 | 0.0 | 0.0 |
| 2005-01-04 | 0.979521 | 1.005318 | 0.966930 | 0.981825 | 1096810400 | 0.0 | 0.0 |
| 2005-01-05 | 0.989809 | 1.001940 | 0.983514 | 0.990424 | 680433600 | 0.0 | 0.0 |
| 2005-01-06 | 0.993034 | 0.996720 | 0.972458 | 0.991192 | 705555200 | 0.0 | 0.0 |
| 2005-01-07 | 0.998101 | 1.069197 | 0.994263 | 1.063362 | 2227450400 | 0.0 | 0.0 |
| ... | ... | ... | ... | ... | ... | ... | ... |
| 2009-12-24 | 6.251186 | 6.429309 | 6.245044 | 6.419788 | 500889200 | 0.0 | 0.0 |
| 2009-12-28 | 6.502094 | 6.570578 | 6.437294 | 6.498715 | 644565600 | 0.0 | 0.0 |
| 2009-12-29 | 6.530040 | 6.532804 | 6.410268 | 6.421631 | 445205600 | 0.0 | 0.0 |
| 2009-12-30 | 6.413338 | 6.510692 | 6.397369 | 6.499636 | 412084400 | 0.0 | 0.0 |
| 2009-12-31 | 6.545397 | 6.552154 | 6.466470 | 6.471691 | 352410800 | 0.0 | 0.0 |
1259 rows × 7 columns
In [13]:
# Example Long Trends for the selected Asset
# * Uncomment others for exploration or replace them with your own TA Trend Strategy
def trends(df: pd.DataFrame, mamode: str = "sma", fast: int = 50, slow: int = 200):
return ta.ma(mamode, df.close, length=fast) > ta.ma(mamode, df.close, length=slow) # SMA(fast) > SMA(slow) "Golden/Death Cross"
# return ta.increasing(ta.ma(mamode, df.close, length=fast)) # Increasing MA(fast)
# return ta.macd(df.close, fast, slow).iloc[:,1] > 0 # MACD Histogram is positiveIn [14]:
trend_kwargs = {"mamode": "sma", "fast": 50, "slow": 200}In [15]:
benchmark_trends = trends(benchmarkdf, **trend_kwargs)
benchmark_trends.copy().astype(int).plot(figsize=(16, 1), kind="area", color=["green"], alpha=0.45, title=f"{benchmarkdf.name} Trends", grid=True)Out [15]:
<AxesSubplot:title={'center':'SPY Trends'}, xlabel='date'>In [16]:
asset_trends = trends(assetdf, **trend_kwargs)
asset_trends.copy().astype(int).plot(figsize=(16, 1), kind="area", color=["green"], alpha=0.45, title=f"{assetdf.name} Trends", grid=True)Out [16]:
<AxesSubplot:title={'center':'AAPL Trends'}, xlabel='date'>In [17]:
# trade_offset = 0 for Live Signals (close is last price)
# trade_offset = 1 for Backtesting
LIVE = 0
benchmark_signals = assetdf.ta.tsignals(benchmark_trends, asbool=True, trade_offset=LIVE, append=True)
benchmark_signals.tail()Out [17]:
| TS_Trends | TS_Trades | TS_Entries | TS_Exits | |
|---|---|---|---|---|
| date | ||||
| 2009-12-24 | True | 0 | False | False |
| 2009-12-28 | True | 0 | False | False |
| 2009-12-29 | True | 0 | False | False |
| 2009-12-30 | True | 0 | False | False |
| 2009-12-31 | True | 0 | False | False |
In [18]:
asset_signals = assetdf.ta.tsignals(asset_trends, asbool=True, trade_offset=LIVE, append=True)
asset_signals.tail()Out [18]:
| TS_Trends | TS_Trades | TS_Entries | TS_Exits | |
|---|---|---|---|---|
| date | ||||
| 2009-12-24 | True | 0 | False | False |
| 2009-12-28 | True | 0 | False | False |
| 2009-12-29 | True | 0 | False | False |
| 2009-12-30 | True | 0 | False | False |
| 2009-12-31 | True | 0 | False | False |
In [ ]:
In [19]:
# Benchmark Buy and Hold (BnH) Strategy
benchmarkpf_bnh = vbt.Portfolio.from_holding(benchmarkdf.close)
print(trade_table(benchmarkpf_bnh))
combine_stats(benchmarkpf_bnh, benchmarkdf.name, "Buy and Hold", LIVE)Out [19]:
Last 1 of 1 Trades status direction size entry_price exit_price return pnl \ 0 0 0 1.141912 87.354056 89.275963 0.019501 1.945272 entry_fees exit_fees 0 0.249377 0.0 None
/Users/kj/Documents/GitHub/pandas-ta/env/lib/python3.9/site-packages/vectorbt/portfolio/trades.py:252: RuntimeWarning: invalid value encountered in true_divide return self.wrapper.wrap_reduced(win_count / total_count, group_by=group_by, **wrap_kwargs) /Users/kj/Documents/GitHub/pandas-ta/env/lib/python3.9/site-packages/vectorbt/portfolio/trades.py:252: RuntimeWarning: invalid value encountered in true_divide return self.wrapper.wrap_reduced(win_count / total_count, group_by=group_by, **wrap_kwargs)
Run Time Saturday June 19, 2021, NYSE: 7:58:39 Mode TEST Strategy Buy and Hold Direction longonly Symbol SPY Fees [%] 0.25 Slippage [%] 0.25 Accumulate False Start 2005-01-03 00:00:00 End 2009-12-31 00:00:00 Duration 1259 days 00:00:00 Init. Cash 100.0 Total Profit 1.945272 Total Return [%] 1.945272 Benchmark Return [%] 2.455635 Position Coverage [%] 100.0 Max. Drawdown [%] 55.189436 Avg. Drawdown [%] 2.615867 Max. Drawdown Duration 562 days 00:00:00 Avg. Drawdown Duration 24 days 01:55:11.999999999 Num. Trades 0 Gross Exposure 1.0 Sharpe Ratio 0.163325 Sortino Ratio 0.231223 Calmar Ratio 0.010149 Annual Return [%] 0.560106 Annual Volatility [%] 28.894472 Omega Ratio 1.028442 Skew 0.426804 Kurtosis 14.956038 Tail Ratio 0.88191 Common Sense Ratio 0.88685 Value at Risk -0.022291 Alpha -0.001443 Beta 1.000002 dtype: object
In [20]:
# Asset Buy and Hold (BnH) Strategy
assetpf_bnh = vbt.Portfolio.from_holding(assetdf.close)
print(trade_table(assetpf_bnh))
combine_stats(assetpf_bnh, assetdf.name, "Buy and Hold", LIVE)Out [20]:
Last 1 of 1 Trades
status direction size entry_price exit_price return \
0 0 0 102.384595 0.974274 6.471691 5.640079
pnl entry_fees exit_fees
0 562.60143 0.249377 0.0
None
/Users/kj/Documents/GitHub/pandas-ta/env/lib/python3.9/site-packages/vectorbt/portfolio/trades.py:252: RuntimeWarning: invalid value encountered in true_divide return self.wrapper.wrap_reduced(win_count / total_count, group_by=group_by, **wrap_kwargs)
Run Time Saturday June 19, 2021, NYSE: 7:58:52 Mode TEST Strategy Buy and Hold Direction longonly Symbol AAPL Fees [%] 0.25 Slippage [%] 0.25 Accumulate False Start 2005-01-03 00:00:00 End 2009-12-31 00:00:00 Duration 1259 days 00:00:00 Init. Cash 100.0 Total Profit 562.60143 Total Return [%] 562.60143 Benchmark Return [%] 565.918578 Position Coverage [%] 100.0 Max. Drawdown [%] 60.866748 Avg. Drawdown [%] 6.076352 Max. Drawdown Duration 457 days 00:00:00 Avg. Drawdown Duration 22 days 17:32:18.461538461 Num. Trades 0 Gross Exposure 1.0 Sharpe Ratio 1.329387 Sortino Ratio 1.982724 Calmar Ratio 1.199638 Annual Return [%] 73.018058 Annual Volatility [%] 51.088459 Omega Ratio 1.209774 Skew -0.0376 Kurtosis 3.435275 Tail Ratio 1.037861 Common Sense Ratio 1.795687 Value at Risk -0.041247 Alpha -0.00145 Beta 1.00001 dtype: object
In [21]:
# Benchmark Portfolio from Trade Signals
benchmarkpf_signals = vbt.Portfolio.from_signals(
benchmarkdf.close,
entries=benchmark_signals.TS_Entries,
exits=benchmark_signals.TS_Exits,
)
trade_table(benchmarkpf_signals, k=5)
combine_stats(benchmarkpf_signals, benchmarkdf.name, "Long Strategy", LIVE)Out [21]:
Last 5 of 3 Trades status direction size entry_price exit_price return pnl \ 0 1 0 1.139340 87.551210 93.911126 0.067461 6.729240 1 1 0 1.094141 97.302877 112.341527 0.149169 15.880955 2 0 0 1.677572 72.905618 89.275963 0.222042 27.156674 entry_fees exit_fees 0 0.249377 0.267492 1 0.266158 0.307294 2 0.305761 0.000000
Run Time Saturday June 19, 2021, NYSE: 7:58:53 Mode TEST Strategy Long Strategy Direction longonly Symbol SPY Fees [%] 0.25 Slippage [%] 0.25 Accumulate False Start 2005-01-03 00:00:00 End 2009-12-31 00:00:00 Duration 1259 days 00:00:00 Init. Cash 100.0 Total Profit 49.766868 Total Return [%] 49.766868 Benchmark Return [%] 2.455635 Position Coverage [%] 52.819698 Max. Drawdown [%] 10.131765 Avg. Drawdown [%] 1.723872 Max. Drawdown Duration 451 days 00:00:00 Avg. Drawdown Duration 17 days 20:34:17.142857143 Num. Trades 2 Win Rate [%] 100.0 Best Trade [%] 14.916866 Worst Trade [%] 6.746063 Avg. Trade [%] 10.831464 Max. Trade Duration 335 days 00:00:00 Avg. Trade Duration 264 days 00:00:00 Expectancy 11.305097 SQN 2.470596 Gross Exposure 0.528197 Sharpe Ratio 1.009581 Sortino Ratio 1.431911 Calmar Ratio 1.226146 Annual Return [%] 12.423018 Annual Volatility [%] 12.357496 Omega Ratio 1.224227 Skew -0.412954 Kurtosis 6.272176 Tail Ratio 1.032277 Common Sense Ratio 1.160517 Value at Risk -0.010296 Alpha 0.122838 Beta 0.182612 dtype: object
In [22]:
# Asset Portfolio from Trade Signals
assetpf_signals = vbt.Portfolio.from_signals(
assetdf.close,
entries=asset_signals.TS_Entries,
exits=asset_signals.TS_Exits,
)
trade_table(assetpf_signals, k=5)
combine_stats(assetpf_signals, assetdf.name, "Long Strategy", LIVE)Out [22]:
Last 5 of 4 Trades status direction size entry_price exit_price return pnl \ 0 1 0 60.628049 1.645288 1.772486 0.072117 7.193697 1 1 0 45.848650 2.332160 3.704574 0.582002 62.231414 2 1 0 29.257588 5.776368 3.885621 -0.331506 -56.025411 3 0 0 30.748240 3.678809 6.471691 0.756681 85.593399 entry_fees exit_fees 0 0.249377 0.268656 1 0.267316 0.424624 2 0.422507 0.284210 3 0.282792 0.000000
Run Time Saturday June 19, 2021, NYSE: 7:58:54 Mode TEST Strategy Long Strategy Direction longonly Symbol AAPL Fees [%] 0.25 Slippage [%] 0.25 Accumulate False Start 2005-01-03 00:00:00 End 2009-12-31 00:00:00 Duration 1259 days 00:00:00 Init. Cash 100.0 Total Profit 98.993099 Total Return [%] 98.993099 Benchmark Return [%] 565.918578 Position Coverage [%] 62.271644 Max. Drawdown [%] 59.898137 Avg. Drawdown [%] 6.193394 Max. Drawdown Duration 506 days 00:00:00 Avg. Drawdown Duration 32 days 01:30:00 Num. Trades 3 Win Rate [%] 66.666667 Best Trade [%] 58.200243 Worst Trade [%] -33.15062 Avg. Trade [%] 10.753768 Max. Trade Duration 363 days 00:00:00 Avg. Trade Duration 207 days 08:00:00 Expectancy 4.466566 SQN 0.130735 Gross Exposure 0.622716 Sharpe Ratio 0.739016 Sortino Ratio 1.08289 Calmar Ratio 0.36859 Annual Return [%] 22.077862 Annual Volatility [%] 35.543979 Omega Ratio 1.140899 Skew 0.024374 Kurtosis 4.672291 Tail Ratio 1.095481 Common Sense Ratio 1.337339 Value at Risk -0.029217 Alpha -0.063652 Beta 0.482566 dtype: object
In [ ]:
In [ ]:
In [ ]:
In [23]:
vbt.settings.set_theme("seaborn")In [24]:
benchmarkpf_bnh.trades.plot(title=f"{benchmarkdf.name} | Trades", height=cheight, width=cwidth).show_png()In [25]:
benchmarkpf_bnh.value().vbt.plot(title=f"{benchmarkdf.name} | Equity Curve", trace_kwargs=dict(name=u"\u00A4"), height=cheight // 2, width=cwidth).show_png()In [26]:
benchmarkpf_bnh.drawdown().vbt.plot(title=f"{benchmarkdf.name} | Drawdown", trace_kwargs=dict(name="%"), height=cheight // 2, width=cwidth).show_png()In [27]:
benchmarkpf_bnh.trades.plot_pnl(title=f"{benchmarkdf.name} | PnL", height=cheight // 2, width=cwidth).show_png()In [28]:
benchmarkpf_bnh.active_returns().vbt.plot(title=f"{benchmarkdf.name} | Active Returns", trace_kwargs=dict(name="%"), height=cheight // 2, width=cwidth).show_png()In [29]:
benchmarkpf_bnh.cash().vbt.plot(title=f"{benchmarkdf.name} | Cash", trace_kwargs=dict(name=u"\u00A4"), height=cheight // 2, width=cwidth).show_png()In [30]:
total_assetfees = benchmarkpf_bnh.trades.records_readable["Entry Fees"] + benchmarkpf_bnh.trades.records_readable["Exit Fees"]
total_assetfees.vbt.plot(title=f"{benchmarkdf.name} | Total Fees", trace_kwargs=dict(name=u"\u00A4"), height=cheight // 2, width=cwidth).show_png()In [ ]:
In [31]:
assetpf_bnh.trades.plot(title=f"{assetdf.name} | Trades", height=cheight, width=cwidth).show_png()In [32]:
assetpf_bnh.value().vbt.plot(title=f"{assetdf.name} | Equity Curve", trace_kwargs=dict(name=u"\u00A4"), height=cheight // 2, width=cwidth).show_png()In [33]:
assetpf_bnh.drawdown().vbt.plot(title=f"{assetdf.name} | Drawdown", trace_kwargs=dict(name="%"), height=cheight // 2, width=cwidth).show_png()In [34]:
assetpf_bnh.trades.plot_pnl(title=f"{assetdf.name} | PnL", height=cheight // 2, width=cwidth).show_png()In [35]:
assetpf_bnh.active_returns().vbt.plot(title=f"{assetdf.name} | Active Returns", trace_kwargs=dict(name="%"), height=cheight // 2, width=cwidth).show_png()In [36]:
assetpf_bnh.cash().vbt.plot(title=f"{assetdf.name} | Cash", trace_kwargs=dict(name=u"\u00A4"), height=cheight // 2, width=cwidth).show_png()In [37]:
total_assetfees = assetpf_bnh.trades.records_readable["Entry Fees"] + assetpf_bnh.trades.records_readable["Exit Fees"]
total_assetfees.vbt.plot(title=f"{assetdf.name} | Total Fees", trace_kwargs=dict(name=u"\u00A4"), height=cheight // 2, width=cwidth).show_png()In [ ]:
In [ ]:
In [38]:
vbt.settings.set_theme("dark")In [39]:
benchmarkpf_signals.trades.plot(title=f"{benchmarkdf.name} | Trades", height=cheight, width=cwidth).show_png()In [40]:
benchmarkpf_signals.value().vbt.plot(title=f"{benchmarkdf.name} | Equity Curve", trace_kwargs=dict(name=u"\u00A4"), height=cheight // 2, width=cwidth).show_png()In [41]:
benchmarkpf_signals.drawdown().vbt.plot(title=f"{benchmarkdf.name} | Drawdown", trace_kwargs=dict(name="%"), height=cheight // 2, width=cwidth).show_png()In [42]:
benchmarkpf_signals.trades.plot_pnl(title=f"{benchmarkdf.name} | PnL", height=cheight // 2, width=cwidth).show_png()In [43]:
benchmarkpf_signals.active_returns().vbt.plot(title=f"{benchmarkdf.name} | Active Returns", trace_kwargs=dict(name="%"), height=cheight // 2, width=cwidth).show_png()In [44]:
benchmarkpf_signals.cash().vbt.plot(title=f"{benchmarkdf.name} | Cash", trace_kwargs=dict(name=u"\u00A4"), height=cheight // 2, width=cwidth).show_png()In [45]:
total_assetfees = benchmarkpf_signals.trades.records_readable["Entry Fees"] + benchmarkpf_signals.trades.records_readable["Exit Fees"]
total_assetfees.vbt.plot(title=f"{benchmarkdf.name} | Total Fees", trace_kwargs=dict(name=u"\u00A4"), height=cheight // 2, width=cwidth).show_png()In [ ]:
In [46]:
assetpf_signals.trades.plot(title=f"{assetdf.name} | Trades", height=cheight, width=cwidth).show_png()In [47]:
assetpf_signals.value().vbt.plot(title=f"{assetdf.name} | Equity Curve", trace_kwargs=dict(name=u"\u00A4"), height=cheight // 2, width=cwidth).show_png()In [48]:
assetpf_signals.drawdown().vbt.plot(title=f"{assetdf.name} | Drawdown", trace_kwargs=dict(name="%"), height=cheight // 2, width=cwidth).show_png()In [49]:
assetpf_signals.trades.plot_pnl(title=f"{assetdf.name} | PnL", height=cheight // 2, width=cwidth).show_png()In [50]:
assetpf_signals.active_returns().vbt.plot(title=f"{assetdf.name} | Active Returns", trace_kwargs=dict(name="%"), height=cheight // 2, width=cwidth).show_png()In [51]:
assetpf_signals.cash().vbt.plot(title=f"{assetdf.name} | Cash", trace_kwargs=dict(name=u"\u00A4"), height=cheight // 2, width=cwidth).show_png()In [52]:
total_assetfees = assetpf_signals.trades.records_readable["Entry Fees"] + assetpf_signals.trades.records_readable["Exit Fees"]
total_assetfees.vbt.plot(title=f"{assetdf.name} | Total Fees", trace_kwargs=dict(name=u"\u00A4"), height=cheight // 2, width=cwidth).show_png()In [ ]: