mirror of
https://github.com/wassname/pandas-ta.git
synced 2026-08-04 13:03:59 +08:00
1.4 MiB
1.4 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 v{vbt.__version__}")
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.3 Pandas v1.3.0 vectorbt v0.23.1 Pandas TA v0.3.54b0 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_000
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
vbt.settings.portfolio["signal_direction"] = "both"
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 | 100000 |
| size | inf |
| size_type | amount |
| fees | 0.0025 |
| fixed_fees | 0.0 |
| slippage | 0.0025 |
| reject_prob | 0.0 |
| min_size | 0.0 |
| max_size | inf |
| size_granularity | NaN |
| lock_cash | False |
| allow_partial | False |
| raise_reject | False |
| val_price | inf |
| accumulate | False |
| sl_stop | NaN |
| sl_trail | False |
| tp_stop | NaN |
| stop_entry_price | close |
| stop_exit_price | stoplimit |
| stop_conflict_mode | exit |
| upon_stop_exit | close |
| upon_stop_update | override |
| use_stops | None |
| log | False |
| upon_long_conflict | ignore |
| upon_short_conflict | ignore |
| upon_dir_conflict | ignore |
| upon_opposite_entry | reversereduce |
| signal_direction | both |
| order_direction | both |
| cash_sharing | False |
| call_pre_segment | False |
| call_post_segment | False |
| ffill_val_price | True |
| update_value | False |
| fill_pos_record | True |
| row_wise | False |
| flexible | False |
| use_numba | True |
| seed | None |
| freq | 1D |
| attach_call_seq | False |
| fillna_close | True |
| trades_type | exittrades |
| stats | {'filters': {'has_year_freq': {'filter_func': ... |
| plots | {'subplots': ['orders', 'trade_pnl', 'cum_retu... |
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"[+] {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, timed=True)[i] Downloading: SPY, QQQ [+] yf | SPY(7343, 7): 3510.6075 ms (3.5106 s) [+] Friday March 25, 2022, NYSE: 4:33:29 [+] yf | QQQ(5801, 7): 2978.0290 ms (2.9780 s) [+] Friday March 25, 2022, NYSE: 4:33:32 [*] Download Complete
In [7]:
assets = dl(asset_tickers, timed=True)[i] Downloading: AAPL, TSLA, TWTR [+] yf | AAPL(10410, 7): 3208.4925 ms (3.2085 s) [+] Friday March 25, 2022, NYSE: 4:33:36 [+] yf | TSLA(2957, 7): 2836.7323 ms (2.8367 s) [+] Friday March 25, 2022, NYSE: 4:33:38 [+] yf | TWTR(2110, 7): 2735.9980 ms (2.7360 s) [+] Friday March 25, 2022, NYSE: 4:33:41 [*] 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 | 86.905246 | 87.048233 | 85.718488 | 86.004456 | 55748000 | 0.0 | 0 |
| 2005-01-04 | 86.118826 | 86.176020 | 84.674697 | 84.953514 | 69167600 | 0.0 | 0 |
| 2005-01-05 | 84.889165 | 85.253774 | 84.360128 | 84.367279 | 65667300 | 0.0 | 0 |
| 2005-01-06 | 84.674684 | 85.182274 | 84.545999 | 84.796219 | 47814700 | 0.0 | 0 |
| 2005-01-07 | 85.053626 | 85.239506 | 84.453093 | 84.674721 | 55847700 | 0.0 | 0 |
| ... | ... | ... | ... | ... | ... | ... | ... |
| 2009-12-24 | 88.709423 | 89.033609 | 88.559186 | 88.938728 | 39677500 | 0.0 | 0 |
| 2009-12-28 | 89.270837 | 89.341998 | 88.812225 | 89.128510 | 87508500 | 0.0 | 0 |
| 2009-12-29 | 89.357798 | 89.373609 | 88.994073 | 89.001976 | 80572500 | 0.0 | 0 |
| 2009-12-30 | 88.741037 | 89.073133 | 88.693591 | 88.970337 | 73138400 | 0.0 | 0 |
| 2009-12-31 | 89.168030 | 89.191756 | 88.076856 | 88.116394 | 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.990526 | 0.995572 | 0.957193 | 0.967744 | 691992000 | 0.0 | 0.0 |
| 2005-01-04 | 0.975388 | 1.001076 | 0.962850 | 0.977682 | 1096810400 | 0.0 | 0.0 |
| 2005-01-05 | 0.985632 | 0.997713 | 0.979364 | 0.986245 | 680433600 | 0.0 | 0.0 |
| 2005-01-06 | 0.988843 | 0.992513 | 0.968354 | 0.987009 | 705555200 | 0.0 | 0.0 |
| 2005-01-07 | 0.993890 | 1.064686 | 0.990067 | 1.058875 | 2227450400 | 0.0 | 0.0 |
| ... | ... | ... | ... | ... | ... | ... | ... |
| 2009-12-24 | 6.224809 | 6.402181 | 6.218693 | 6.392700 | 500889200 | 0.0 | 0.0 |
| 2009-12-28 | 6.474657 | 6.542852 | 6.410130 | 6.471292 | 644565600 | 0.0 | 0.0 |
| 2009-12-29 | 6.502488 | 6.505240 | 6.383221 | 6.394536 | 445205600 | 0.0 | 0.0 |
| 2009-12-30 | 6.386277 | 6.483220 | 6.370375 | 6.472210 | 412084400 | 0.0 | 0.0 |
| 2009-12-31 | 6.517778 | 6.524506 | 6.439184 | 6.444382 | 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": "ema", "fast": 20, "slow": 50}In [15]:
benchmark_trends = trends(benchmarkdf, **trend_kwargs)
benchmark_trends.copy().astype(int).plot(figsize=(16, 1), kind="area", color=["limegreen"], alpha=0.9, title=f"{benchmarkdf.name} Trends", grid=True).axhline(0, color="black")Out [15]:
<matplotlib.lines.Line2D at 0x157decf40>
In [16]:
asset_trends = trends(assetdf, **trend_kwargs)
asset_trends.copy().astype(int).plot(figsize=(16, 1), kind="area", color=["limegreen"], alpha=0.98, title=f"{assetdf.name} Trends", grid=True).axhline(0, color="black")Out [16]:
<matplotlib.lines.Line2D at 0x158255ee0>
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 \
0 0 0 1156.938534 86.219467 88.116394 0.019501
pnl entry_fees exit_fees
0 1945.251775 249.376559 0.0
None
Run Time Friday March 25, 2022, NYSE: 4:33:45 Mode TEST Strategy Buy and Hold Direction both Symbol SPY Fees [%] 0.25 Slippage [%] 0.25 Accumulate False Start 2005-01-03 00:00:00 End 2009-12-31 00:00:00 Period 1259 days 00:00:00 Start Value 100000.0 End Value 101945.251775 Total Return [%] 1.945252 Benchmark Return [%] 2.455615 Max Gross Exposure [%] 100.0 Total Fees Paid 249.376559 Max Drawdown [%] 55.189449 Max Drawdown Duration 562 days 00:00:00 Total Trades 1 Total Closed Trades 0 Total Open Trades 1 Open Trade PnL 1945.251775 Sharpe Ratio 0.163325 Calmar Ratio 0.010149 Omega Ratio 1.028442 Sortino Ratio 0.231222 Annualized Return [%] 0.560101 Annualized Volatility [%] 28.894507 Skew 0.426795 Kurtosis 14.955978 Tail Ratio 0.881912 Common Sense Ratio 0.886852 Value at Risk -0.02229 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 102818.423476 0.970163 6.444382 5.640077
pnl entry_fees exit_fees
0 562601.217125 249.376559 0.0
None
Run Time Friday March 25, 2022, NYSE: 4:33:46 Mode TEST Strategy Buy and Hold Direction both Symbol AAPL Fees [%] 0.25 Slippage [%] 0.25 Accumulate False Start 2005-01-03 00:00:00 End 2009-12-31 00:00:00 Period 1259 days 00:00:00 Start Value 100000.0 End Value 662601.217125 Total Return [%] 562.601217 Benchmark Return [%] 565.918364 Max Gross Exposure [%] 100.0 Total Fees Paid 249.376559 Max Drawdown [%] 60.86673 Max Drawdown Duration 456 days 00:00:00 Total Trades 1 Total Closed Trades 0 Total Open Trades 1 Open Trade PnL 562601.217125 Sharpe Ratio 1.329387 Calmar Ratio 1.199638 Omega Ratio 1.209774 Sortino Ratio 1.982726 Annualized Return [%] 73.018042 Annualized Volatility [%] 51.088429 Skew -0.037597 Kurtosis 3.435264 Tail Ratio 1.037885 Common Sense Ratio 1.795729 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 15 Trades
status direction size entry_price exit_price return \
10 1 0 797.772784 114.865412 108.679654 -0.058718
11 1 1 793.793867 108.679654 105.284153 0.026321
12 1 0 840.908131 105.284153 101.710419 -0.038859
13 1 1 836.714076 101.710419 63.710985 0.369538
14 0 0 1828.142319 63.710985 88.116394 0.380564
pnl entry_fees exit_fees
10 -5380.674590 229.091248 216.754175
11 2270.720055 215.673107 208.934787
12 -3440.340619 221.335750 213.822795
13 31448.634826 212.756347 133.269695
14 44325.378834 291.181871 0.000000
Run Time Friday March 25, 2022, NYSE: 4:33:49 Mode TEST Strategy Long Strategy Direction both Symbol SPY Fees [%] 0.25 Slippage [%] 0.25 Accumulate False Start 2005-01-03 00:00:00 End 2009-12-31 00:00:00 Period 1259 days 00:00:00 Start Value 100000.0 End Value 161089.308979 Total Return [%] 61.089309 Benchmark Return [%] 2.455615 Max Gross Exposure [%] 100.0 Total Fees Paid 6786.609621 Max Drawdown [%] 21.642405 Max Drawdown Duration 411 days 00:00:00 Total Trades 15 Total Closed Trades 14 Total Open Trades 1 Open Trade PnL 44325.378834 Win Rate [%] 35.714286 Best Trade [%] 36.953815 Worst Trade [%] -5.871759 Avg Winning Trade [%] 10.694648 Avg Losing Trade [%] -3.476746 Avg Winning Trade Duration 136 days 14:24:00 Avg Losing Trade Duration 37 days 18:40:00 Profit Factor 1.564796 Expectancy 1197.423582 Sharpe Ratio 0.762857 Calmar Ratio 0.684934 Omega Ratio 1.124146 Sortino Ratio 1.111308 Annualized Return [%] 14.823626 Annualized Volatility [%] 21.015085 Skew 0.013953 Kurtosis 4.710095 Tail Ratio 1.023207 Common Sense Ratio 1.174883 Value at Risk -0.017307 Alpha 0.191161 Beta -0.301323 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 19 Trades
status direction size entry_price exit_price return \
14 1 0 29355.575610 5.320026 4.917980 -0.080383
15 1 1 29209.163761 4.917980 3.043387 0.377124
16 1 0 64956.862336 3.043387 2.652390 -0.133153
17 1 1 64632.887961 2.652390 3.112368 -0.178854
18 0 0 45253.957674 3.112368 6.444382 1.068072
pnl entry_fees exit_fees
14 -12553.649891 390.431047 360.925314
15 54173.913870 359.125187 222.236997
16 -26322.878669 494.222229 430.727407
17 -30661.152430 428.579140 502.903315
18 150434.715996 352.117414 0.000000
Run Time Friday March 25, 2022, NYSE: 4:33:50 Mode TEST Strategy Long Strategy Direction both Symbol AAPL Fees [%] 0.25 Slippage [%] 0.25 Accumulate False Start 2005-01-03 00:00:00 End 2009-12-31 00:00:00 Period 1259 days 00:00:00 Start Value 100000.0 End Value 291633.798892 Total Return [%] 191.633799 Benchmark Return [%] 565.918364 Max Gross Exposure [%] 100.0 Total Fees Paid 10631.095277 Max Drawdown [%] 46.10598 Max Drawdown Duration 368 days 00:00:00 Total Trades 19 Total Closed Trades 18 Total Open Trades 1 Open Trade PnL 150434.715996 Win Rate [%] 33.333333 Best Trade [%] 78.771745 Worst Trade [%] -17.88535 Avg Winning Trade [%] 34.908001 Avg Losing Trade [%] -10.451626 Avg Winning Trade Duration 124 days 12:00:00 Avg Losing Trade Duration 21 days 20:00:00 Profit Factor 1.281501 Expectancy 2288.837939 Sharpe Ratio 0.926133 Calmar Ratio 0.789131 Omega Ratio 1.141239 Sortino Ratio 1.339789 Annualized Return [%] 36.383667 Annualized Volatility [%] 43.942033 Skew -0.036485 Kurtosis 1.988366 Tail Ratio 0.968342 Common Sense Ratio 1.32066 Value at Risk -0.038211 Alpha 0.353839 Beta 0.152645 dtype: object
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.asset_returns().vbt.plot(title=f"{benchmarkdf.name} | Asset 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.asset_returns().vbt.plot(title=f"{assetdf.name} | Asset 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.asset_returns().vbt.plot(title=f"{benchmarkdf.name} | Asset 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.asset_returns().vbt.plot(title=f"{assetdf.name} | Asset 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()