mirror of
https://github.com/wassname/pandas-ta.git
synced 2026-08-19 12:30:41 +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(7328, 7): 3297.1998 ms (3.2972 s) [+] Friday March 4, 2022, NYSE: 4:13:28 [+] yf | QQQ(5786, 7): 3182.5192 ms (3.1825 s) [+] Friday March 4, 2022, NYSE: 4:13:31 [*] Download Complete
In [7]:
assets = dl(asset_tickers, timed=True)[i] Downloading: AAPL, TSLA, TWTR [+] yf | AAPL(10395, 7): 2928.4840 ms (2.9285 s) [+] Friday March 4, 2022, NYSE: 4:13:34 [+] yf | TSLA(2942, 7): 2660.0862 ms (2.6601 s) [+] Friday March 4, 2022, NYSE: 4:13:37 [+] yf | TWTR(2095, 7): 2686.0984 ms (2.6861 s) [+] Friday March 4, 2022, NYSE: 4:13:40 [*] 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 | 87.175188 | 87.318618 | 85.984743 | 86.271599 | 55748000 | 0.0 | 0 |
| 2005-01-04 | 86.386323 | 86.443696 | 84.937709 | 85.217392 | 69167600 | 0.0 | 0 |
| 2005-01-05 | 85.152863 | 85.518605 | 84.622183 | 84.629356 | 65667300 | 0.0 | 0 |
| 2005-01-06 | 84.937742 | 85.446909 | 84.808657 | 85.059654 | 47814700 | 0.0 | 0 |
| 2005-01-07 | 85.317803 | 85.504260 | 84.715405 | 84.937721 | 55847700 | 0.0 | 0 |
| ... | ... | ... | ... | ... | ... | ... | ... |
| 2009-12-24 | 88.984994 | 89.310187 | 88.834291 | 89.215012 | 39677500 | 0.0 | 0 |
| 2009-12-28 | 89.548150 | 89.619532 | 89.088114 | 89.405380 | 87508500 | 0.0 | 0 |
| 2009-12-29 | 89.635408 | 89.651268 | 89.270553 | 89.278481 | 80572500 | 0.0 | 0 |
| 2009-12-30 | 89.016730 | 89.349857 | 88.969136 | 89.246742 | 73138400 | 0.0 | 0 |
| 2009-12-31 | 89.445055 | 89.468855 | 88.350491 | 88.390152 | 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.962849 | 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.993889 | 1.064685 | 0.990067 | 1.058874 | 2227450400 | 0.0 | 0.0 |
| ... | ... | ... | ... | ... | ... | ... | ... |
| 2009-12-24 | 6.224808 | 6.402180 | 6.218692 | 6.392699 | 500889200 | 0.0 | 0.0 |
| 2009-12-28 | 6.474656 | 6.542852 | 6.410129 | 6.471292 | 644565600 | 0.0 | 0.0 |
| 2009-12-29 | 6.502484 | 6.505237 | 6.383217 | 6.394532 | 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.517776 | 6.524504 | 6.439182 | 6.444380 | 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 0x1560f43d0>
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 0x1564f0af0>
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 1153.356031 86.487278 88.390152 0.019502
pnl entry_fees exit_fees
0 1945.314835 249.376559 0.0
None
Run Time Friday March 4, 2022, NYSE: 4:13:43 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.314835 Total Return [%] 1.945315 Benchmark Return [%] 2.455679 Max Gross Exposure [%] 100.0 Total Fees Paid 249.376559 Max Drawdown [%] 55.189444 Max Drawdown Duration 562 days 00:00:00 Total Trades 1 Total Closed Trades 0 Total Open Trades 1 Open Trade PnL 1945.314835 Sharpe Ratio 0.163326 Calmar Ratio 0.010149 Omega Ratio 1.028442 Sortino Ratio 0.231223 Annualized Return [%] 0.560119 Annualized Volatility [%] 28.894491 Skew 0.426808 Kurtosis 14.956064 Tail Ratio 0.881911 Common Sense Ratio 0.886851 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.467805 0.970163 6.44438 5.640078
pnl entry_fees exit_fees
0 562601.306688 249.376559 0.0
None
Run Time Friday March 4, 2022, NYSE: 4:13:45 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.306688 Total Return [%] 562.601307 Benchmark Return [%] 565.918454 Max Gross Exposure [%] 100.0 Total Fees Paid 249.376559 Max Drawdown [%] 60.866741 Max Drawdown Duration 456 days 00:00:00 Total Trades 1 Total Closed Trades 0 Total Open Trades 1 Open Trade PnL 562601.306688 Sharpe Ratio 1.329387 Calmar Ratio 1.199638 Omega Ratio 1.209774 Sortino Ratio 1.982725 Annualized Return [%] 73.018049 Annualized Volatility [%] 51.088448 Skew -0.037599 Kurtosis 3.435268 Tail Ratio 1.037877 Common Sense Ratio 1.795715 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 795.303054 115.222213 109.017225 -0.058718
11 1 1 791.336455 109.017225 105.611285 0.026320
12 1 0 838.303190 105.611285 102.026354 -0.038860
13 1 1 834.122127 102.026354 63.908901 0.369538
14 0 0 1822.478518 63.908901 88.390152 0.380565
pnl entry_fees exit_fees
10 -5380.691483 229.091444 216.754330
11 2270.635665 215.673261 208.935151
12 -3440.418062 221.335694 213.822544
13 31448.585118 212.756098 133.269571
14 44325.372865 291.181497 0.000000
Run Time Friday March 4, 2022, NYSE: 4:13:47 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.153138 Total Return [%] 61.089153 Benchmark Return [%] 2.455679 Max Gross Exposure [%] 100.0 Total Fees Paid 6786.610242 Max Drawdown [%] 21.642453 Max Drawdown Duration 411 days 00:00:00 Total Trades 15 Total Closed Trades 14 Total Open Trades 1 Open Trade PnL 44325.372865 Win Rate [%] 35.714286 Best Trade [%] 36.9538 Worst Trade [%] -5.871773 Avg Winning Trade [%] 10.694638 Avg Losing Trade [%] -3.476755 Avg Winning Trade Duration 136 days 14:24:00 Avg Losing Trade Duration 37 days 18:40:00 Profit Factor 1.564789 Expectancy 1197.412877 Sharpe Ratio 0.762856 Calmar Ratio 0.684931 Omega Ratio 1.124146 Sortino Ratio 1.111307 Annualized Return [%] 14.823594 Annualized Volatility [%] 21.015065 Skew 0.01395 Kurtosis 4.71009 Tail Ratio 1.023224 Common Sense Ratio 1.174903 Value at Risk -0.017307 Alpha 0.191161 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.475854 5.320027 4.917979 -0.080384
15 1 1 29209.064503 4.917979 3.043388 0.377124
16 1 0 64956.602912 3.043388 2.652390 -0.133154
17 1 1 64632.629830 2.652390 3.112366 -0.178853
18 0 0 45253.806451 3.112366 6.444380 1.068073
pnl entry_fees exit_fees
14 -12553.649294 390.429791 360.924052
15 54173.687923 359.123932 222.236312
16 -26322.882027 494.220411 430.725571
17 -30660.967566 428.577314 502.901037
18 150434.202886 352.116048 0.000000
Run Time Friday March 4, 2022, NYSE: 4:13:48 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 291632.738041 Total Return [%] 191.632738 Benchmark Return [%] 565.918454 Max Gross Exposure [%] 100.0 Total Fees Paid 10631.077665 Max Drawdown [%] 46.105984 Max Drawdown Duration 368 days 00:00:00 Total Trades 19 Total Closed Trades 18 Total Open Trades 1 Open Trade PnL 150434.202886 Win Rate [%] 33.333333 Best Trade [%] 78.771593 Worst Trade [%] -17.885319 Avg Winning Trade [%] 34.907941 Avg Losing Trade [%] -10.451635 Avg Winning Trade Duration 124 days 12:00:00 Avg Losing Trade Duration 21 days 20:00:00 Profit Factor 1.281497 Expectancy 2288.807509 Sharpe Ratio 0.92613 Calmar Ratio 0.789128 Omega Ratio 1.141238 Sortino Ratio 1.339786 Annualized Return [%] 36.383524 Annualized Volatility [%] 43.942042 Skew -0.036484 Kurtosis 1.988354 Tail Ratio 0.968337 Common Sense Ratio 1.320653 Value at Risk -0.038211 Alpha 0.353838 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()