mirror of
https://github.com/wassname/pandas-ta.git
synced 2026-08-14 12:40:48 +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.63b0 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(7367, 7): 3810.4675 ms (3.8105 s) [+] Sunday May 1, 2022, NYSE: 14:17:10 [+] yf | QQQ(5825, 7): 3371.7531 ms (3.3718 s) [+] Sunday May 1, 2022, NYSE: 14:17:14 [*] Download Complete
In [7]:
assets = dl(asset_tickers, timed=True)[i] Downloading: AAPL, TSLA, TWTR [+] yf | AAPL(10434, 7): 3390.6886 ms (3.3907 s) [+] Sunday May 1, 2022, NYSE: 14:17:17 [+] yf | TSLA(2981, 7): 3219.1295 ms (3.2191 s) [+] Sunday May 1, 2022, NYSE: 14:17:20 [+] yf | TWTR(2134, 7): 3016.2403 ms (3.0162 s) [+] Sunday May 1, 2022, NYSE: 14:17:23 [*] 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.905223 | 87.048210 | 85.718465 | 86.004433 | 55748000 | 0.0 | 0 |
| 2005-01-04 | 86.118795 | 86.175989 | 84.674667 | 84.953484 | 69167600 | 0.0 | 0 |
| 2005-01-05 | 84.889173 | 85.253781 | 84.360136 | 84.367287 | 65667300 | 0.0 | 0 |
| 2005-01-06 | 84.674677 | 85.182267 | 84.545992 | 84.796211 | 47814700 | 0.0 | 0 |
| 2005-01-07 | 85.053580 | 85.239459 | 84.453047 | 84.674675 | 55847700 | 0.0 | 0 |
| ... | ... | ... | ... | ... | ... | ... | ... |
| 2009-12-24 | 88.709400 | 89.033586 | 88.559164 | 88.938705 | 39677500 | 0.0 | 0 |
| 2009-12-28 | 89.270845 | 89.342005 | 88.812233 | 89.128517 | 87508500 | 0.0 | 0 |
| 2009-12-29 | 89.357828 | 89.373640 | 88.994104 | 89.002007 | 80572500 | 0.0 | 0 |
| 2009-12-30 | 88.741052 | 89.073148 | 88.693606 | 88.970352 | 73138400 | 0.0 | 0 |
| 2009-12-31 | 89.168022 | 89.191748 | 88.076849 | 88.116386 | 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.957192 | 0.967743 | 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.979363 | 0.986244 | 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.993889 | 1.064685 | 0.990067 | 1.058874 | 2227450400 | 0.0 | 0.0 |
| ... | ... | ... | ... | ... | ... | ... | ... |
| 2009-12-24 | 6.224809 | 6.402180 | 6.218692 | 6.392699 | 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.502485 | 6.505237 | 6.383218 | 6.394533 | 445205600 | 0.0 | 0.0 |
| 2009-12-30 | 6.386275 | 6.483218 | 6.370373 | 6.472208 | 412084400 | 0.0 | 0.0 |
| 2009-12-31 | 6.517777 | 6.524505 | 6.439183 | 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 0x156c5ab50>
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 0x157201400>
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]:
tsignals
| 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]:
tsignals
| 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.938842 86.219444 88.116386 0.019501
pnl entry_fees exit_fees
0 1945.270079 249.376559 0.0
None
Run Time Sunday May 1, 2022, NYSE: 14:17:27 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.270079 Total Return [%] 1.94527 Benchmark Return [%] 2.455634 Max Gross Exposure [%] 100.0 Total Fees Paid 249.376559 Max Drawdown [%] 55.189427 Max Drawdown Duration 562 days 00:00:00 Total Trades 1 Total Closed Trades 0 Total Open Trades 1 Open Trade PnL 1945.270079 Sharpe Ratio 0.163325 Calmar Ratio 0.010149 Omega Ratio 1.028442 Sortino Ratio 0.231223 Annualized Return [%] 0.560106 Annualized Volatility [%] 28.894497 Skew 0.426797 Kurtosis 14.955984 Tail Ratio 0.881903 Common Sense Ratio 0.886842 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.493136 0.970162 6.444382 5.640081
pnl entry_fees exit_fees
0 562601.617014 249.376559 0.0
None
Run Time Sunday May 1, 2022, NYSE: 14:17:28 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.617014 Total Return [%] 562.601617 Benchmark Return [%] 565.918766 Max Gross Exposure [%] 100.0 Total Fees Paid 249.376559 Max Drawdown [%] 60.866735 Max Drawdown Duration 456 days 00:00:00 Total Trades 1 Total Closed Trades 0 Total Open Trades 1 Open Trade PnL 562601.617014 Sharpe Ratio 1.329387 Calmar Ratio 1.199638 Omega Ratio 1.209774 Sortino Ratio 1.982725 Annualized Return [%] 73.018072 Annualized Volatility [%] 51.088458 Skew -0.037599 Kurtosis 3.43526 Tail Ratio 1.03789 Common Sense Ratio 1.795738 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.770311 114.865419 108.679631 -0.058718
11 1 1 793.791407 108.679631 105.284168 0.026321
12 1 0 840.904944 105.284168 101.710388 -0.038859
13 1 1 836.710904 101.710388 63.711012 0.369538
14 0 0 1828.133472 63.711012 88.116386 0.380564
pnl entry_fees exit_fees
10 -5380.682196 229.090553 216.753458
11 2270.682765 215.672393 208.934170
12 -3440.366007 221.334944 213.821921
13 31448.467750 212.755477 133.269246
14 44325.101312 291.180584 0.000000
Run Time Sunday May 1, 2022, NYSE: 14:17:31 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 161088.515438 Total Return [%] 61.088515 Benchmark Return [%] 2.455634 Max Gross Exposure [%] 100.0 Total Fees Paid 6786.593906 Max Drawdown [%] 21.642411 Max Drawdown Duration 411 days 00:00:00 Total Trades 15 Total Closed Trades 14 Total Open Trades 1 Open Trade PnL 44325.101312 Win Rate [%] 35.714286 Best Trade [%] 36.95377 Worst Trade [%] -5.871785 Avg Winning Trade [%] 10.694623 Avg Losing Trade [%] -3.476782 Avg Winning Trade Duration 136 days 14:24:00 Avg Losing Trade Duration 37 days 18:40:00 Profit Factor 1.564774 Expectancy 1197.386723 Sharpe Ratio 0.76285 Calmar Ratio 0.684927 Omega Ratio 1.124145 Sortino Ratio 1.111297 Annualized Return [%] 14.823462 Annualized Volatility [%] 21.015086 Skew 0.013949 Kurtosis 4.710068 Tail Ratio 1.023206 Common Sense Ratio 1.174881 Value at Risk -0.017307 Alpha 0.191159 Beta -0.301324 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.566042 5.320024 4.917979 -0.080383
15 1 1 29209.154242 4.917979 3.043387 0.377124
16 1 0 64956.830347 3.043387 2.652390 -0.133153
17 1 1 64632.856130 2.652390 3.112366 -0.178853
18 0 0 45253.946608 3.112366 6.444382 1.068073
pnl entry_fees exit_fees
14 -12553.631451 390.430815 360.925126
15 54173.875496 359.125001 222.236907
16 -26322.911779 494.221947 430.727040
17 -30661.105740 428.578776 502.902836
18 150434.722694 352.117165 0.000000
Run Time Sunday May 1, 2022, NYSE: 14:17:32 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.706004 Total Return [%] 191.633706 Benchmark Return [%] 565.918766 Max Gross Exposure [%] 100.0 Total Fees Paid 10631.091236 Max Drawdown [%] 46.106062 Max Drawdown Duration 368 days 00:00:00 Total Trades 19 Total Closed Trades 18 Total Open Trades 1 Open Trade PnL 150434.722694 Win Rate [%] 33.333333 Best Trade [%] 78.771666 Worst Trade [%] -17.885338 Avg Winning Trade [%] 34.907989 Avg Losing Trade [%] -10.451628 Avg Winning Trade Duration 124 days 12:00:00 Avg Losing Trade Duration 21 days 20:00:00 Profit Factor 1.2815 Expectancy 2288.832406 Sharpe Ratio 0.926132 Calmar Ratio 0.78913 Omega Ratio 1.141239 Sortino Ratio 1.339789 Annualized Return [%] 36.383655 Annualized Volatility [%] 43.942062 Skew -0.036486 Kurtosis 1.988356 Tail Ratio 0.968328 Common Sense Ratio 1.320641 Value at Risk -0.038211 Alpha 0.353838 Beta 0.152646 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()