mirror of
https://github.com/wassname/pandas-ta.git
synced 2026-08-03 13:00: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 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.32b0 To install the Latest Version: $ pip install -U git+https://github.com/twopirllc/pandas-ta
In [53]:
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 [53]:
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 [54]:
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, timed=True)[i] Downloading: SPY, QQQ [+] yf | SPY(7310, 7): 6015.8232 ms (6.0158 s) [+] SPY(7310, 7) Monday February 7, 2022, NYSE: 5:58:00 [+] yf | QQQ(5768, 7): 4612.5752 ms (4.6126 s) [+] QQQ(5768, 7) Monday February 7, 2022, NYSE: 5:58:04 [*] Download Complete
In [7]:
assets = dl(asset_tickers, timed=True)[i] Downloading: AAPL, TSLA, TWTR [+] yf | AAPL(10377, 7): 4302.5109 ms (4.3025 s) [+] AAPL(10377, 7) Monday February 7, 2022, NYSE: 5:58:09 [+] yf | TSLA(2924, 7): 4379.0780 ms (4.3791 s) [+] TSLA(2924, 7) Monday February 7, 2022, NYSE: 5:58:13 [+] yf | TWTR(2077, 7): 4289.1730 ms (4.2892 s) [+] TWTR(2077, 7) Monday February 7, 2022, NYSE: 5:58:17 [*] Download Complete
In [55]:
start_date = datetime(2005, 1, 1) # Adjust as needed
end_date = datetime(2010, 1, 1) # Adjust as neededIn [56]:
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 [57]:
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 [58]:
benchmarkdfOut [58]:
| Open | High | Low | Close | Volume | Dividends | Stock Splits | |
|---|---|---|---|---|---|---|---|
| Date | |||||||
| 2005-01-03 | 87.761711 | 87.906107 | 86.563257 | 86.852043 | 55748000 | 0.0 | 0 |
| 2005-01-04 | 86.967560 | 87.025318 | 85.509199 | 85.790764 | 69167600 | 0.0 | 0 |
| 2005-01-05 | 85.725790 | 86.093993 | 85.191540 | 85.198761 | 65667300 | 0.0 | 0 |
| 2005-01-06 | 85.509188 | 86.021780 | 85.379234 | 85.631920 | 47814700 | 0.0 | 0 |
| 2005-01-07 | 85.891825 | 86.079536 | 85.285374 | 85.509186 | 55847700 | 0.0 | 0 |
| ... | ... | ... | ... | ... | ... | ... | ... |
| 2009-12-24 | 89.583749 | 89.911131 | 89.432032 | 89.815315 | 39677500 | 0.0 | 0 |
| 2009-12-28 | 90.150658 | 90.222520 | 89.687526 | 90.006927 | 87508500 | 0.0 | 0 |
| 2009-12-29 | 90.238441 | 90.254408 | 89.871132 | 89.879112 | 80572500 | 0.0 | 0 |
| 2009-12-30 | 89.615662 | 89.951030 | 89.567748 | 89.847221 | 73138400 | 0.0 | 0 |
| 2009-12-31 | 90.046848 | 90.070809 | 88.944921 | 88.984848 | 90637900 | 0.0 | 0 |
1259 rows × 7 columns
In [59]:
assetdfOut [59]:
| 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.997712 | 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.058875 | 2227450400 | 0.0 | 0.0 |
| ... | ... | ... | ... | ... | ... | ... | ... |
| 2009-12-24 | 6.224808 | 6.402179 | 6.218691 | 6.392698 | 500889200 | 0.0 | 0.0 |
| 2009-12-28 | 6.474655 | 6.542851 | 6.410128 | 6.471291 | 644565600 | 0.0 | 0.0 |
| 2009-12-29 | 6.502485 | 6.505238 | 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.517775 | 6.524503 | 6.439181 | 6.444380 | 352410800 | 0.0 | 0.0 |
1259 rows × 7 columns
In [60]:
# 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 [61]:
trend_kwargs = {"mamode": "sma", "fast": 50, "slow": 200}In [62]:
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).axhline(0, color="black")Out [62]:
<matplotlib.lines.Line2D at 0x157858640>
In [63]:
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).axhline(0, color="black")Out [63]:
<matplotlib.lines.Line2D at 0x15797e220>
In [64]:
# 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 [64]:
| 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 [65]:
asset_signals = assetdf.ta.tsignals(asset_trends, asbool=True, trade_offset=LIVE, append=True)
asset_signals.tail()Out [65]:
| 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 [66]:
# 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 [66]:
Last 1 of 1 Trades
status direction size entry_price exit_price return \
0 0 0 1145.647991 87.069173 88.984848 0.019502
pnl entry_fees exit_fees
0 1945.312385 249.376559 0.0
None
Run Time Monday February 7, 2022, NYSE: 6:05:12 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.312385 Total Return [%] 1.945312 Benchmark Return [%] 2.455676 Max Gross Exposure [%] 100.0 Total Fees Paid 249.376559 Max Drawdown [%] 55.189433 Max Drawdown Duration 562 days 00:00:00 Total Trades 1 Total Closed Trades 0 Total Open Trades 1 Open Trade PnL 1945.312385 Sharpe Ratio 0.163326 Calmar Ratio 0.010149 Omega Ratio 1.028442 Sortino Ratio 0.231223 Annualized Return [%] 0.560118 Annualized Volatility [%] 28.894487 Skew 0.426802 Kurtosis 14.956002 Tail Ratio 0.881919 Common Sense Ratio 0.886859 Value at Risk -0.02229 Alpha -0.001443 Beta 1.000002 dtype: object
In [67]:
# 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 [67]:
Last 1 of 1 Trades
status direction size entry_price exit_price return \
0 0 0 102818.436141 0.970163 6.44438 5.640076
pnl entry_fees exit_fees
0 562601.053608 249.376559 0.0
None
Run Time Monday February 7, 2022, NYSE: 6:05:13 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.053608 Total Return [%] 562.601054 Benchmark Return [%] 565.9182 Max Gross Exposure [%] 100.0 Total Fees Paid 249.376559 Max Drawdown [%] 60.866743 Max Drawdown Duration 456 days 00:00:00 Total Trades 1 Total Closed Trades 0 Total Open Trades 1 Open Trade PnL 562601.053608 Sharpe Ratio 1.329386 Calmar Ratio 1.199638 Omega Ratio 1.209774 Sortino Ratio 1.982724 Annualized Return [%] 73.01803 Annualized Volatility [%] 51.088476 Skew -0.037597 Kurtosis 3.435256 Tail Ratio 1.037879 Common Sense Ratio 1.795718 Value at Risk -0.041247 Alpha -0.00145 Beta 1.00001 dtype: object
In [68]:
# 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 [68]:
Last 5 of 5 Trades
status direction size entry_price exit_price return \
0 1 0 1143.067726 87.265716 93.604879 0.067460
1 1 1 1137.366640 93.604879 96.985603 -0.041207
2 1 0 1052.599067 96.985603 111.975205 0.149169
3 1 1 1047.349196 111.975205 72.667880 0.346914
4 0 0 2172.358822 72.667880 88.984848 0.222042
pnl entry_fees exit_fees
0 6729.224173 249.376559 267.491790
1 -4387.051303 266.157666 275.770474
2 15228.160409 255.217389 294.662489
3 40685.029757 293.192851 190.271616
4 35051.656621 394.651778 0.000000
Run Time Monday February 7, 2022, NYSE: 6:05:16 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 193307.019656 Total Return [%] 93.30702 Benchmark Return [%] 2.455676 Max Gross Exposure [%] 100.0 Total Fees Paid 2486.792612 Max Drawdown [%] 15.56369 Max Drawdown Duration 152 days 00:00:00 Total Trades 5 Total Closed Trades 4 Total Open Trades 1 Open Trade PnL 35051.656621 Win Rate [%] 75.0 Best Trade [%] 34.691356 Worst Trade [%] -4.120726 Avg Winning Trade [%] 18.784752 Avg Losing Trade [%] -4.120726 Avg Winning Trade Duration 299 days 08:00:00 Avg Losing Trade Duration 25 days 00:00:00 Profit Factor 14.278934 Expectancy 14563.840759 Sharpe Ratio 1.128019 Calmar Ratio 1.352901 Omega Ratio 1.199806 Sortino Ratio 1.653528 Annualized Return [%] 21.056134 Annualized Volatility [%] 18.452631 Skew -0.067306 Kurtosis 4.86452 Tail Ratio 1.074084 Common Sense Ratio 1.300244 Value at Risk -0.015183 Alpha 0.244574 Beta -0.220209 dtype: object
In [69]:
# 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 [69]:
Last 5 of 7 Trades
status direction size entry_price exit_price return \
2 1 0 31274.951777 2.322318 3.688941 0.582002
3 1 1 31118.966980 3.688941 5.751994 -0.565651
4 1 0 8696.711793 5.751994 3.869225 -0.331506
5 1 1 8653.336672 3.869225 3.663285 0.048358
6 0 0 9580.683873 3.663285 6.444380 0.756681
pnl entry_fees exit_fees
2 42271.062627 181.575975 288.428643
3 -64934.539698 286.990096 447.490244
4 -16583.080760 125.058576 84.123830
5 1619.110776 83.704260 79.249099
6 26557.046830 87.741942 0.000000
Run Time Monday February 7, 2022, NYSE: 6:05:16 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 61741.565685 Total Return [%] -38.258434 Benchmark Return [%] 565.9182 Max Gross Exposure [%] 100.0 Total Fees Paid 2801.433663 Max Drawdown [%] 83.338227 Max Drawdown Duration 506 days 00:00:00 Total Trades 7 Total Closed Trades 6 Total Open Trades 1 Open Trade PnL 26557.04683 Win Rate [%] 50.0 Best Trade [%] 58.200242 Worst Trade [%] -56.56514 Avg Winning Trade [%] 23.415908 Avg Losing Trade [%] -40.623448 Avg Winning Trade Duration 231 days 00:00:00 Avg Losing Trade Duration 68 days 08:00:00 Profit Factor 0.440761 Expectancy -10802.580191 Sharpe Ratio -0.071065 Calmar Ratio -0.156552 Omega Ratio 0.988973 Sortino Ratio -0.099881 Annualized Return [%] -13.046751 Annualized Volatility [%] 46.262996 Skew 0.150873 Kurtosis 4.766433 Tail Ratio 0.945783 Common Sense Ratio 0.822389 Value at Risk -0.039647 Alpha -0.137603 Beta 0.169161 dtype: object
In [ ]:
In [ ]:
In [70]:
vbt.settings.set_theme("seaborn")In [71]:
benchmarkpf_bnh.trades.plot(title=f"{benchmarkdf.name} | Trades", height=cheight, width=cwidth).show_png()In [72]:
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 [73]:
benchmarkpf_bnh.drawdown().vbt.plot(title=f"{benchmarkdf.name} | Drawdown", trace_kwargs=dict(name="%"), height=cheight // 2, width=cwidth).show_png()In [74]:
benchmarkpf_bnh.trades.plot_pnl(title=f"{benchmarkdf.name} | PnL", height=cheight // 2, width=cwidth).show_png()In [75]:
benchmarkpf_bnh.asset_returns().vbt.plot(title=f"{benchmarkdf.name} | Asset Returns", trace_kwargs=dict(name="%"), height=cheight // 2, width=cwidth).show_png()In [76]:
benchmarkpf_bnh.cash().vbt.plot(title=f"{benchmarkdf.name} | Cash", trace_kwargs=dict(name=u"\u00A4"), height=cheight // 2, width=cwidth).show_png()In [77]:
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 [78]:
assetpf_bnh.trades.plot(title=f"{assetdf.name} | Trades", height=cheight, width=cwidth).show_png()In [79]:
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 [80]:
assetpf_bnh.drawdown().vbt.plot(title=f"{assetdf.name} | Drawdown", trace_kwargs=dict(name="%"), height=cheight // 2, width=cwidth).show_png()In [81]:
assetpf_bnh.trades.plot_pnl(title=f"{assetdf.name} | PnL", height=cheight // 2, width=cwidth).show_png()In [82]:
assetpf_bnh.asset_returns().vbt.plot(title=f"{assetdf.name} | Asset Returns", trace_kwargs=dict(name="%"), height=cheight // 2, width=cwidth).show_png()In [83]:
assetpf_bnh.cash().vbt.plot(title=f"{assetdf.name} | Cash", trace_kwargs=dict(name=u"\u00A4"), height=cheight // 2, width=cwidth).show_png()In [84]:
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 [85]:
vbt.settings.set_theme("dark")In [86]:
benchmarkpf_signals.trades.plot(title=f"{benchmarkdf.name} | Trades", height=cheight, width=cwidth).show_png()In [87]:
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 [88]:
benchmarkpf_signals.drawdown().vbt.plot(title=f"{benchmarkdf.name} | Drawdown", trace_kwargs=dict(name="%"), height=cheight // 2, width=cwidth).show_png()In [89]:
benchmarkpf_signals.trades.plot_pnl(title=f"{benchmarkdf.name} | PnL", height=cheight // 2, width=cwidth).show_png()In [90]:
benchmarkpf_signals.asset_returns().vbt.plot(title=f"{benchmarkdf.name} | Asset Returns", trace_kwargs=dict(name="%"), height=cheight // 2, width=cwidth).show_png()In [91]:
benchmarkpf_signals.cash().vbt.plot(title=f"{benchmarkdf.name} | Cash", trace_kwargs=dict(name=u"\u00A4"), height=cheight // 2, width=cwidth).show_png()In [92]:
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 [93]:
assetpf_signals.trades.plot(title=f"{assetdf.name} | Trades", height=cheight, width=cwidth).show_png()In [94]:
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 [95]:
assetpf_signals.drawdown().vbt.plot(title=f"{assetdf.name} | Drawdown", trace_kwargs=dict(name="%"), height=cheight // 2, width=cwidth).show_png()In [96]:
assetpf_signals.trades.plot_pnl(title=f"{assetdf.name} | PnL", height=cheight // 2, width=cwidth).show_png()In [97]:
assetpf_signals.asset_returns().vbt.plot(title=f"{assetdf.name} | Asset Returns", trace_kwargs=dict(name="%"), height=cheight // 2, width=cwidth).show_png()In [98]:
assetpf_signals.cash().vbt.plot(title=f"{assetdf.name} | Cash", trace_kwargs=dict(name=u"\u00A4"), height=cheight // 2, width=cwidth).show_png()In [99]:
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 [ ]: