Synthetic data backtesting example#
This is an example notebook how to create and run backtests with tradeexecutor
framework.
Some highlights of this notebook:
Runs everything within a single notebook
The backtest code and charts are self-contained in a single file
The example code is easy to read
Easy to test different functionalities of
tradeexecutor
library
Uses generated, synthetic, random price data
Notebook runs offline
No downloads needed
No API keys needed
Running the notebook completes quickly, making it suitable for low powered devices and demos
Set up#
Set up strategy paramets that will decide its behavior
[1]:
import datetime
import logging
import pandas as pd
from tradingstrategy.chain import ChainId
from tradingstrategy.timebucket import TimeBucket
from tradeexecutor.strategy.cycle import CycleDuration
from tradeexecutor.strategy.strategy_module import TradeRouting, ReserveCurrency
trading_strategy_cycle = CycleDuration.cycle_1d
# Strategy keeps its cash in BUSD
reserve_currency = ReserveCurrency.busd
# How much of the cash to put on a single trade
position_size = 0.10
#
# Strategy thinking specific parameter
#
slow_ema_candle_count = 20
fast_ema_candle_count = 5
# How many candles to extract from the dataset once
batch_size = 90
# Range of backtesting and synthetic data generation.
# Because we are using synthetic data actual dates do not really matter -
# only the duration
start_at = datetime.datetime(2021, 6, 1)
start_at_data = datetime.datetime(2021, 1, 1)
end_at = datetime.datetime(2022, 1, 1)
Strategy logic and trade decisions#
decide_trades
function decide what trades to take. In this example, we calculate two exponential moving averages (EMAs) and make decisions based on those.
[2]:
from typing import List, Dict
from pandas_ta.overlap import ema
from tradingstrategy.universe import Universe
from tradeexecutor.state.visualisation import PlotKind
from tradeexecutor.state.trade import TradeExecution
from tradeexecutor.strategy.pricing_model import PricingModel
from tradeexecutor.strategy.pandas_trader.position_manager import PositionManager
from tradeexecutor.state.state import State
def decide_trades(
timestamp: pd.Timestamp,
universe: Universe,
state: State,
pricing_model: PricingModel,
cycle_debug_data: Dict) -> List[TradeExecution]:
"""The brain function to decide the trades on each trading strategy cycle."""
# The pair we are trading
pair = universe.pairs.get_single()
# How much cash we have in the hand
cash = state.portfolio.get_current_cash()
# Get OHLCV candles for our trading pair as Pandas Dataframe.
# We could have candles for multiple trading pairs in a different strategy,
# but this strategy only operates on single pair candle.
# We also limit our sample size to N latest candles to speed up calculations.
candles: pd.DataFrame = universe.candles.get_single_pair_data(timestamp, sample_count=batch_size)
# We have data for open, high, close, etc.
# We only operate using candle close values in this strategy.
close = candles["close"]
# Calculate exponential moving averages based on slow and fast sample numbers.
# https://github.com/twopirllc/pandas-ta
# https://github.com/twopirllc/pandas-ta/blob/bc3b292bf1cc1d5f2aba50bb750a75209d655b37/pandas_ta/overlap/ema.py#L7
slow_ema_series = ema(close, length=slow_ema_candle_count)
fast_ema_series = ema(close, length=fast_ema_candle_count)
if slow_ema_series is None or fast_ema_series is None:
# Cannot calculate EMA, because
# not enough samples in backtesting
return []
slow_ema = slow_ema_series.iloc[-1]
fast_ema = fast_ema_series.iloc[-1]
# Get the last close price from close time series
# that's Pandas's Series object
# https://pandas.pydata.org/docs/reference/api/pandas.Series.iat.html
current_price = close.iloc[-1]
# List of any trades we decide on this cycle.
# Because the strategy is simple, there can be
# only zero (do nothing) or 1 (open or close) trades
# decides
trades = []
# Create a position manager helper class that allows us easily to create
# opening/closing trades for different positions
position_manager = PositionManager(timestamp, universe, state, pricing_model)
if not position_manager.is_any_open():
if current_price >= slow_ema:
# Entry condition:
# Close price is higher than the slow EMA
buy_amount = cash * position_size
trades += position_manager.open_1x_long(pair, buy_amount)
else:
if fast_ema >= slow_ema:
# Exit condition:
# Fast EMA crosses slow EMA
trades += position_manager.close_all()
# Visualize strategy
# See available Plotly colours here
# https://community.plotly.com/t/plotly-colours-list/11730/3?u=miohtama
visualisation = state.visualisation
visualisation.plot_indicator(timestamp, "Slow EMA", PlotKind.technical_indicator_on_price, slow_ema, colour="darkblue")
visualisation.plot_indicator(timestamp, "Fast EMA", PlotKind.technical_indicator_on_price, fast_ema, colour="#003300")
return trades
Defining trading universe#
We create a trading universe with a single blockchain, exchange and trading pair. For the sake of easier understanding the code, we name this “Uniswap v2” like exchange with a single ETH-USDC trading pair.
The trading pair contains generated noise-like OHLCV trading data.
[3]:
import random
from tradeexecutor.state.identifier import AssetIdentifier, TradingPairIdentifier
from tradingstrategy.candle import GroupedCandleUniverse
from tradeexecutor.testing.synthetic_ethereum_data import generate_random_ethereum_address
from tradeexecutor.testing.synthetic_exchange_data import generate_exchange
from tradeexecutor.testing.synthetic_price_data import generate_ohlcv_candles
from tradeexecutor.strategy.trading_strategy_universe import TradingStrategyUniverse, \
create_pair_universe_from_code
def create_trading_universe() -> TradingStrategyUniverse:
# Set up fake assets
mock_chain_id = ChainId.ethereum
mock_exchange = generate_exchange(
exchange_id=random.randint(1, 1000),
chain_id=mock_chain_id,
address=generate_random_ethereum_address())
usdc = AssetIdentifier(ChainId.ethereum.value, generate_random_ethereum_address(), "USDC", 6, 1)
weth = AssetIdentifier(ChainId.ethereum.value, generate_random_ethereum_address(), "WETH", 18, 2)
weth_usdc = TradingPairIdentifier(
weth,
usdc,
generate_random_ethereum_address(),
mock_exchange.address,
internal_id=random.randint(1, 1000),
internal_exchange_id=mock_exchange.exchange_id,
fee=0.0005
)
time_bucket = TimeBucket.d1
pair_universe = create_pair_universe_from_code(mock_chain_id, [weth_usdc])
candles = generate_ohlcv_candles(time_bucket, start_at_data, end_at, pair_id=weth_usdc.internal_id)
candle_universe = GroupedCandleUniverse.create_from_single_pair_dataframe(candles)
universe = Universe(
time_bucket=time_bucket,
chains={mock_chain_id},
exchanges={mock_exchange},
pairs=pair_universe,
candles=candle_universe,
liquidity=None
)
return TradingStrategyUniverse(universe=universe, reserve_assets=[usdc])
Running the backtest#
Run backtest using giving trading universe and strategy function.
Running the backtest outputs state
object that contains all the information on the backtesting position and trades.
[4]:
from tradeexecutor.testing.synthetic_exchange_data import generate_simple_routing_model
from tradeexecutor.backtest.backtest_runner import run_backtest_inline
universe = create_trading_universe()
start_candle, end_candle = universe.universe.candles.get_timestamp_range()
print(f"Our universe has synthetic candle data for the period {start_candle} - {end_candle}")
# This function set ups trade routing for our synthetic trading universe.
# Because we have only one trading pair, there is no complicated
# routing needed
routing_model = generate_simple_routing_model(universe)
state, universe, debug_dump = run_backtest_inline(
name="Synthetic random data backtest",
start_at=start_at,
end_at=end_at,
client=None, # None of downloads needed, because we are using synthetic data
cycle_duration=trading_strategy_cycle,
decide_trades=decide_trades,
universe=universe,
initial_deposit=10_000,
reserve_currency=ReserveCurrency.busd,
trade_routing=TradeRouting.user_supplied_routing_model,
routing_model=routing_model,
log_level=logging.WARNING,
)
Our universe has synthetic candle data for the period 2021-01-01 00:00:00 - 2021-12-31 00:00:00
Examine backtest results#
Examine state
that contains all actions the trade executor took.
We plot out a chart that shows - The price action - When the strategy made buys or sells
[5]:
print(f"Positions taken: {len(list(state.portfolio.get_all_positions()))}")
print(f"Trades made: {len(list(state.portfolio.get_all_trades()))}")
Positions taken: 82
Trades made: 163
[6]:
from tradeexecutor.visual.single_pair import visualise_single_pair
figure = visualise_single_pair(state, universe.universe.candles)
figure.show()
Equity curve and drawdown#
Visualise equity curve and related performnace over time.
Returns
Drawdown
Daily returns
[7]:
# Set Jupyter Notebook output mode parameters
# Used to avoid warnings
from tradeexecutor.backtest.notebook import setup_charting_and_output
setup_charting_and_output()
# Needed to improve the resolution of matplotlib chart used here
%config InlineBackend.figure_format = 'svg'
from tradeexecutor.visual.equity_curve import calculate_equity_curve, calculate_returns
from tradeexecutor.visual.equity_curve import visualise_equity_curve
curve = calculate_equity_curve(state)
returns = calculate_returns(curve)
visualise_equity_curve(returns)
[7]:
Returns monthly breakdown#
Monthly returns
Best day/week/month/year
[8]:
from tradeexecutor.visual.equity_curve import visualise_returns_over_time
visualise_returns_over_time(returns)
[8]:
Benchmarking the strategy performance#
Here we benchmark the strategy performance against some baseline scenarios.
Buy and hold US dollar
Buy and hold the underlying trading pair base asset
[9]:
close = universe.universe.candles.get_single_pair_data()["close"]
[10]:
from tradeexecutor.visual.benchmark import visualise_benchmark
traded_pair = universe.universe.pairs.get_single()
fig = visualise_benchmark(
state.name,
portfolio_statistics=state.stats.portfolio,
all_cash=state.portfolio.get_initial_deposit(),
buy_and_hold_asset_name=traded_pair.base_token_symbol,
buy_and_hold_price_series=universe.universe.candles.get_single_pair_data()["close"],
)
fig.show()
Analysing the strategy success#
Here we calculate statistics on how well the strategy performed.
Won/lost trades
Timeline of taken positions with color coding of trade performance
[11]:
from tradeexecutor.analysis.trade_analyser import build_trade_analysis
analysis = build_trade_analysis(state.portfolio)
Strategy summary#
Overview of strategy performance
[12]:
from IPython.core.display_functions import display
summary = analysis.calculate_summary_statistics(TimeBucket.d1, state)
with pd.option_context("display.max_row", None):
summary.display()
Returns | |
---|---|
Annualised return % | 5.85% |
Lifetime return % | 3.42% |
Realised PnL | $342.64 |
Trade period | 213 days 0 hours |
Holdings | |
---|---|
Total assets | $10,341.60 |
Cash left | $9,308.37 |
Open position value | $1,033.23 |
Open positions | 1 |
Winning | Losing | Total | |
---|---|---|---|
Closed Positions | |||
Number of positions | 48 | 33 | 81 |
% of total | 59.26% | 40.74% | 100.00% |
Average PnL % | 2.36% | -2.40% | 0.42% |
Median PnL % | 2.37% | -2.08% | 0.50% |
Biggest PnL % | 4.85% | -5.06% | - |
Average duration | 1 bars | 1 bars | 1 bars |
Max consecutive streak | 6 | 4 | - |
Max runup / drawdown | 4.07% | -1.59% | - |
Stop losses | Take profits | |
---|---|---|
Position Exits | ||
Triggered exits | 0 | 0 |
Percent winning | - | - |
Percent losing | - | - |
Percent of total | 0.00% | 0.00% |
Risk Analysis | |
---|---|
Biggest realized risk | 10.00% |
Average realized risk | -0.24% |
Max pullback of capital | -1.07% |
Sharpe Ratio | 179.63% |
Sortino Ratio | 292.29% |
Profit Factor | 140.42% |
Performance metrics#
Here is an example how to use Quantstats library to calculate the tearsheet metrics for the strategy with advanced metrics. The metrics include popular risk-adjusted return comparison metrics.
This includes metrics like:
Sharpe
Sortino
Max drawdown
Note: These metrics are based on equity curve and returns. Analysis here does not go down to the level of an individual trade or a position. Any consecutive wins and losses are measured in days, not in trade or candle counts.
[13]:
from tradeexecutor.visual.equity_curve import calculate_equity_curve, calculate_returns
from tradeexecutor.analysis.advanced_metrics import visualise_advanced_metrics, AdvancedMetricsMode
equity = calculate_equity_curve(state)
returns = calculate_returns(equity)
metrics = visualise_advanced_metrics(returns, mode=AdvancedMetricsMode.full)
with pd.option_context("display.max_row", None):
display(metrics)
Strategy | |
---|---|
Start Period | 2021-06-01 |
End Period | 2021-12-31 |
Risk-Free Rate | 0.0% |
Time in Market | 77.0% |
Cumulative Return | 3.43% |
CAGR﹪ | 5.94% |
Sharpe | 1.8 |
Prob. Sharpe Ratio | 91.8% |
Smart Sharpe | 1.76 |
Sortino | 2.92 |
Smart Sortino | 2.86 |
Sortino/√2 | 2.07 |
Smart Sortino/√2 | 2.02 |
Omega | 1.4 |
Max Drawdown | -1.59% |
Longest DD Days | 62 |
Volatility (ann.) | 3.23% |
Calmar | 3.73 |
Skew | 0.31 |
Kurtosis | 1.93 |
Expected Daily | 0.02% |
Expected Monthly | 0.48% |
Expected Yearly | 3.43% |
Kelly Criterion | 8.65% |
Risk of Ruin | 0.0% |
Daily Value-at-Risk | -0.26% |
Expected Shortfall (cVaR) | -0.26% |
Max Consecutive Wins | 2 |
Max Consecutive Losses | 8 |
Gain/Pain Ratio | 0.4 |
Gain/Pain (1M) | 2.87 |
Payoff Ratio | 3.27 |
Profit Factor | 1.4 |
Common Sense Ratio | 1.66 |
CPC Index | 1.38 |
Tail Ratio | 1.18 |
Outlier Win Ratio | 4.09 |
Outlier Loss Ratio | 5.61 |
MTD | 1.45% |
3M | 0.74% |
6M | 3.53% |
YTD | 3.43% |
1Y | 3.43% |
3Y (ann.) | 5.94% |
5Y (ann.) | 5.94% |
10Y (ann.) | 5.94% |
All-time (ann.) | 5.94% |
Best Day | 0.5% |
Worst Day | -0.5% |
Best Month | 1.51% |
Worst Month | -1.18% |
Best Year | 3.43% |
Worst Year | 3.43% |
Avg. Drawdown | -0.3% |
Avg. Drawdown Days | 10 |
Recovery Factor | 2.15 |
Ulcer Index | 0.01 |
Serenity Index | 1.0 |
Avg. Up Month | 0.76% |
Avg. Down Month | -1.18% |
Win Days | 30.06% |
Win Month | 85.71% |
Win Quarter | 100.0% |
Win Year | 100.0% |
Position and trade timeline#
Display all positions and how much profit they made.
[14]:
from tradeexecutor.analysis.trade_analyser import expand_timeline
timeline = analysis.create_timeline()
expanded_timeline, apply_styles = expand_timeline(
universe.universe.exchanges,
universe.universe.pairs,
timeline)
# Do not truncate the row output
with pd.option_context("display.max_row", None):
display(apply_styles(expanded_timeline))
Remarks | Type | Opened at | Duration | Exchange | Base asset | Quote asset | Position max value | PnL USD | PnL % | Open mid price USD | Close mid price USD | Trade count | LP fees |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Long | 2021-06-01 | 1 days | WETH | USDC | $1,000.00 | $-18.44 | -1.84% | $1,693.685824 | $1,662.462170 | 2 | $0.99 | ||
Long | 2021-06-03 | 1 days | WETH | USDC | $998.16 | $-10.15 | -1.02% | $1,740.579395 | $1,722.881327 | 2 | $0.99 | ||
Long | 2021-06-05 | 1 days | WETH | USDC | $997.14 | $-31.89 | -3.20% | $1,681.182338 | $1,627.410345 | 2 | $0.98 | ||
Long | 2021-06-11 | 1 days | WETH | USDC | $993.95 | $34.33 | 3.45% | $1,669.302169 | $1,726.951048 | 2 | $1.01 | ||
Long | 2021-06-13 | 1 days | WETH | USDC | $997.38 | $29.65 | 2.97% | $1,708.497641 | $1,759.282168 | 2 | $1.01 | ||
Long | 2021-06-15 | 1 days | WETH | USDC | $1,000.35 | $46.32 | 4.63% | $1,769.017579 | $1,850.932203 | 2 | $1.02 | ||
Long | 2021-06-17 | 1 days | WETH | USDC | $1,004.98 | $-15.38 | -1.53% | $1,866.231250 | $1,837.671730 | 2 | $1.00 | ||
Long | 2021-06-19 | 1 days | WETH | USDC | $1,003.44 | $-11.09 | -1.10% | $1,828.898982 | $1,808.691165 | 2 | $1.00 | ||
Long | 2021-06-21 | 1 days | WETH | USDC | $1,002.33 | $-30.65 | -3.06% | $1,809.106519 | $1,753.786752 | 2 | $0.99 | ||
Long | 2021-06-23 | 1 days | WETH | USDC | $999.27 | $0.10 | 0.01% | $1,772.774548 | $1,772.943715 | 2 | $1.00 | ||
Long | 2021-06-25 | 1 days | WETH | USDC | $999.28 | $47.68 | 4.77% | $1,834.098439 | $1,921.604989 | 2 | $1.02 | ||
Long | 2021-06-27 | 1 days | WETH | USDC | $1,004.05 | $-50.80 | -5.06% | $1,946.616370 | $1,848.121566 | 2 | $0.98 | ||
Long | 2021-06-29 | 1 days | WETH | USDC | $998.97 | $22.34 | 2.24% | $1,832.442524 | $1,873.416319 | 2 | $1.01 | ||
Long | 2021-07-01 | 1 days | WETH | USDC | $1,001.20 | $13.88 | 1.39% | $1,873.922096 | $1,899.894986 | 2 | $1.01 | ||
Long | 2021-07-03 | 1 days | WETH | USDC | $1,002.59 | $27.29 | 2.72% | $1,926.378830 | $1,978.814159 | 2 | $1.02 | ||
Long | 2021-07-05 | 1 days | WETH | USDC | $1,005.32 | $-24.65 | -2.45% | $2,043.253520 | $1,993.157756 | 2 | $0.99 | ||
Long | 2021-07-07 | 1 days | WETH | USDC | $1,002.85 | $-2.55 | -0.25% | $2,003.979811 | $1,998.882393 | 2 | $1.00 | ||
Long | 2021-07-09 | 1 days | WETH | USDC | $1,002.60 | $-15.51 | -1.55% | $2,002.939367 | $1,971.959315 | 2 | $1.00 | ||
Long | 2021-07-11 | 1 days | WETH | USDC | $1,001.05 | $-10.81 | -1.08% | $1,975.346307 | $1,954.017851 | 2 | $1.00 | ||
Long | 2021-07-17 | 1 days | WETH | USDC | $999.97 | $9.96 | 1.00% | $1,944.127936 | $1,963.484007 | 2 | $1.01 | ||
Long | 2021-07-22 | 1 days | WETH | USDC | $1,000.96 | $-7.82 | -0.78% | $1,983.466912 | $1,967.963901 | 2 | $1.00 | ||
Long | 2021-07-25 | 1 days | WETH | USDC | $1,000.18 | $21.81 | 2.18% | $1,999.143302 | $2,042.729566 | 2 | $1.01 | ||
Long | 2021-07-27 | 1 days | WETH | USDC | $1,002.36 | $20.60 | 2.06% | $2,050.210845 | $2,092.350698 | 2 | $1.01 | ||
Long | 2021-07-29 | 1 days | WETH | USDC | $1,004.42 | $-20.52 | -2.04% | $2,040.091932 | $1,998.411892 | 2 | $0.99 | ||
Long | 2021-07-31 | 1 days | WETH | USDC | $1,002.37 | $-45.53 | -4.54% | $1,998.883289 | $1,908.092508 | 2 | $0.98 | ||
Long | 2021-08-10 | 1 days | WETH | USDC | $997.81 | $34.65 | 3.47% | $1,942.441944 | $2,009.890407 | 2 | $1.02 | ||
Long | 2021-08-12 | 1 days | WETH | USDC | $1,001.28 | $37.01 | 3.70% | $2,028.047567 | $2,103.015426 | 2 | $1.02 | ||
Long | 2021-08-14 | 1 days | WETH | USDC | $1,004.98 | $15.54 | 1.55% | $2,192.204059 | $2,226.106820 | 2 | $1.01 | ||
Long | 2021-08-16 | 1 days | WETH | USDC | $1,006.54 | $39.83 | 3.96% | $2,145.880970 | $2,230.789932 | 2 | $1.03 | ||
Long | 2021-08-18 | 1 days | WETH | USDC | $1,010.52 | $-39.63 | -3.92% | $2,309.083929 | $2,218.527219 | 2 | $0.99 | ||
Long | 2021-08-20 | 1 days | WETH | USDC | $1,006.55 | $33.75 | 3.35% | $2,251.285015 | $2,326.766622 | 2 | $1.02 | ||
Long | 2021-08-22 | 1 days | WETH | USDC | $1,009.93 | $-26.93 | -2.67% | $2,359.620370 | $2,296.701921 | 2 | $1.00 | ||
Long | 2021-08-24 | 1 days | WETH | USDC | $1,007.24 | $5.06 | 0.50% | $2,319.804685 | $2,331.450653 | 2 | $1.01 | ||
Long | 2021-08-26 | 1 days | WETH | USDC | $1,007.74 | $37.26 | 3.70% | $2,299.529762 | $2,384.550348 | 2 | $1.03 | ||
Long | 2021-08-28 | 1 days | WETH | USDC | $1,011.47 | $24.47 | 2.42% | $2,437.908264 | $2,496.896238 | 2 | $1.02 | ||
Long | 2021-08-30 | 1 days | WETH | USDC | $1,013.92 | $34.66 | 3.42% | $2,412.167957 | $2,494.620031 | 2 | $1.03 | ||
Long | 2021-09-01 | 1 days | WETH | USDC | $1,017.38 | $48.25 | 4.74% | $2,575.289561 | $2,697.411858 | 2 | $1.04 | ||
Long | 2021-09-03 | 1 days | WETH | USDC | $1,022.21 | $20.18 | 1.97% | $2,684.814432 | $2,737.824713 | 2 | $1.03 | ||
Long | 2021-09-05 | 1 days | WETH | USDC | $1,024.22 | $-43.41 | -4.24% | $2,747.280908 | $2,630.852321 | 2 | $1.00 | ||
Long | 2021-09-07 | 1 days | WETH | USDC | $1,019.88 | $28.99 | 2.84% | $2,694.740964 | $2,771.347814 | 2 | $1.03 | ||
Long | 2021-09-09 | 1 days | WETH | USDC | $1,022.78 | $4.82 | 0.47% | $2,719.676899 | $2,732.493469 | 2 | $1.03 | ||
Long | 2021-09-11 | 1 days | WETH | USDC | $1,023.27 | $-41.43 | -4.05% | $2,812.804235 | $2,698.910428 | 2 | $1.00 | ||
Long | 2021-09-13 | 1 days | WETH | USDC | $1,019.12 | $19.47 | 1.91% | $2,833.457545 | $2,887.602106 | 2 | $1.03 | ||
Long | 2021-09-15 | 1 days | WETH | USDC | $1,021.07 | $-14.25 | -1.40% | $2,986.344772 | $2,944.681216 | 2 | $1.01 | ||
Long | 2021-09-17 | 1 days | WETH | USDC | $1,019.64 | $31.06 | 3.05% | $2,902.050945 | $2,990.458701 | 2 | $1.04 | ||
Long | 2021-09-19 | 1 days | WETH | USDC | $1,022.75 | $24.37 | 2.38% | $2,933.079037 | $3,002.965624 | 2 | $1.04 | ||
Long | 2021-09-21 | 1 days | WETH | USDC | $1,025.19 | $-18.68 | -1.82% | $2,900.387346 | $2,847.525408 | 2 | $1.02 | ||
Long | 2021-09-23 | 1 days | WETH | USDC | $1,023.32 | $47.00 | 4.59% | $2,844.587483 | $2,975.235865 | 2 | $1.05 | ||
Long | 2021-09-25 | 1 days | WETH | USDC | $1,028.02 | $1.41 | 0.14% | $3,103.979327 | $3,108.229612 | 2 | $1.03 | ||
Long | 2021-09-27 | 1 days | WETH | USDC | $1,028.16 | $-15.25 | -1.48% | $3,199.685428 | $3,152.240849 | 2 | $1.02 | ||
Long | 2021-09-29 | 1 days | WETH | USDC | $1,026.64 | $2.27 | 0.22% | $3,124.653111 | $3,131.558995 | 2 | $1.03 | ||
Long | 2021-10-01 | 1 days | WETH | USDC | $1,026.86 | $-33.38 | -3.25% | $3,193.386784 | $3,089.576353 | 2 | $1.01 | ||
Long | 2021-10-13 | 1 days | WETH | USDC | $1,023.52 | $24.21 | 2.37% | $2,979.384392 | $3,049.859093 | 2 | $1.04 | ||
Long | 2021-10-15 | 1 days | WETH | USDC | $1,025.95 | $29.34 | 2.86% | $3,048.964839 | $3,136.147181 | 2 | $1.04 | ||
Long | 2021-10-17 | 1 days | WETH | USDC | $1,028.88 | $-21.65 | -2.10% | $3,249.518248 | $3,181.135327 | 2 | $1.02 | ||
Long | 2021-10-19 | 1 days | WETH | USDC | $1,026.71 | $24.29 | 2.37% | $3,063.328184 | $3,135.812258 | 2 | $1.04 | ||
Long | 2021-10-21 | 1 days | WETH | USDC | $1,029.14 | $3.29 | 0.32% | $3,161.540103 | $3,171.658153 | 2 | $1.03 | ||
Long | 2021-10-23 | 1 days | WETH | USDC | $1,029.47 | $-21.40 | -2.08% | $3,145.718438 | $3,080.323159 | 2 | $1.02 | ||
Long | 2021-10-25 | 1 days | WETH | USDC | $1,027.33 | $13.00 | 1.27% | $3,098.820342 | $3,138.030588 | 2 | $1.03 | ||
Long | 2021-10-27 | 1 days | WETH | USDC | $1,028.63 | $43.83 | 4.26% | $3,161.873175 | $3,296.597993 | 2 | $1.05 | ||
Long | 2021-10-29 | 1 days | WETH | USDC | $1,033.02 | $-13.06 | -1.26% | $3,431.478907 | $3,388.083641 | 2 | $1.03 | ||
Long | 2021-10-31 | 1 days | WETH | USDC | $1,031.71 | $-17.88 | -1.73% | $3,348.277250 | $3,290.254847 | 2 | $1.02 | ||
Long | 2021-11-02 | 1 days | WETH | USDC | $1,029.92 | $-34.77 | -3.38% | $3,245.624574 | $3,136.054474 | 2 | $1.01 | ||
Long | 2021-11-08 | 1 days | WETH | USDC | $1,026.44 | $-39.02 | -3.80% | $3,293.592632 | $3,168.385216 | 2 | $1.01 | ||
Long | 2021-11-12 | 1 days | WETH | USDC | $1,022.54 | $49.62 | 4.85% | $3,263.466429 | $3,421.840437 | 2 | $1.05 | ||
Long | 2021-11-14 | 1 days | WETH | USDC | $1,027.50 | $-41.76 | -4.06% | $3,372.755562 | $3,235.677157 | 2 | $1.01 | ||
Long | 2021-11-16 | 1 days | WETH | USDC | $1,023.33 | $-23.64 | -2.31% | $3,294.509176 | $3,218.399264 | 2 | $1.01 | ||
Long | 2021-11-18 | 1 days | WETH | USDC | $1,020.96 | $-43.12 | -4.22% | $3,336.904117 | $3,195.956743 | 2 | $1.00 | ||
Long | 2021-11-25 | 1 days | WETH | USDC | $1,016.65 | $25.36 | 2.49% | $3,255.592303 | $3,336.789307 | 2 | $1.03 | ||
Long | 2021-11-28 | 1 days | WETH | USDC | $1,019.19 | $3.11 | 0.31% | $3,311.218522 | $3,321.317890 | 2 | $1.02 | ||
Long | 2021-11-30 | 1 days | WETH | USDC | $1,019.50 | $19.99 | 1.96% | $3,438.471807 | $3,505.886618 | 2 | $1.03 | ||
Long | 2021-12-02 | 1 days | WETH | USDC | $1,021.50 | $45.93 | 4.50% | $3,402.466732 | $3,555.447327 | 2 | $1.04 | ||
Long | 2021-12-04 | 1 days | WETH | USDC | $1,026.09 | $19.01 | 1.85% | $3,434.031800 | $3,497.641234 | 2 | $1.04 | ||
Long | 2021-12-06 | 1 days | WETH | USDC | $1,027.99 | $9.83 | 0.96% | $3,454.815072 | $3,487.853978 | 2 | $1.03 | ||
Long | 2021-12-08 | 1 days | WETH | USDC | $1,028.97 | $-18.91 | -1.84% | $3,559.135471 | $3,493.713416 | 2 | $1.02 | ||
Long | 2021-12-10 | 1 days | WETH | USDC | $1,027.08 | $-1.67 | -0.16% | $3,606.305769 | $3,600.442618 | 2 | $1.03 | ||
Long | 2021-12-12 | 1 days | WETH | USDC | $1,026.92 | $2.96 | 0.29% | $3,474.341447 | $3,484.344675 | 2 | $1.03 | ||
Long | 2021-12-14 | 1 days | WETH | USDC | $1,027.21 | $5.91 | 0.58% | $3,552.274278 | $3,572.704226 | 2 | $1.03 | ||
Long | 2021-12-18 | 1 days | WETH | USDC | $1,027.80 | $9.36 | 0.91% | $3,500.320336 | $3,532.188265 | 2 | $1.03 | ||
Long | 2021-12-20 | 1 days | WETH | USDC | $1,028.74 | $26.72 | 2.60% | $3,475.556395 | $3,565.822203 | 2 | $1.04 | ||
Long | 2021-12-28 | 2 days | WETH | USDC | $1,031.41 | $28.55 | 2.77% | $3,438.090325 | $3,533.250284 | 2 | $1.05 | ||
Long | 2021-12-31 | WETH | USDC | $1,034.26 | $3,559.576339 | 1 | $0.52 |
Finishing notes#
Print out a line to signal the notebook finished the execution successfully.
[15]:
print("All ok")
All ok