Technical analysis#

Note: This notebook is somewhat outdated, as Trading Strategy has replaced cufflinks with plotly as its main charting library.

In this notebook, we will do basic technical analysis on decentralised exchange price data.

Technical analysis is a trading discipline employed to evaluate investments and identify trading opportunities by analyzing statistical trends gathered from trading activity, such as price movement and volume. More information.

We will

  • Create interactive charts (zoom, pan, etc.)

  • Download daily candle data for all pairs (several dozens of megabytes)

  • Extract data for ETH-USDC pair on Uniswap v2

  • Draw some standard technical analysis charts to identify if ETH-USDC pair is overbought or ovesold

  • Plot technical charts using Cufflinks library

Cufflinks is a library build on the top of Plotly. It gives good out of the box tools for quantative finance and technical analysis. Cufflinks builds on the top the top of Plotly, as introduced in the previous chapter.

To install cufflinks in your Python enviroment:

pip install cufflinks

Getting started#

First, let’s create Trading Strategy dataset client.

[25]:
from tradingstrategy.client import Client

client = Client.create_jupyter_client()
Started Trading Strategy in Jupyter notebook environment, configuration is stored in /Users/moo/.tradingstrategy

Fetch data#

Let’s download 1 day (24h) candles to all trading pairs. This dataset is several dozens of megabytes. You should see a progress bar during the download.

Note: We could also query live candle datasets for trading pairs we are interested in. However, the bundled dataset is faster for the future analysis, as after the download it will have all candles cached in your local notebook environment.

[26]:
from tradingstrategy.pair import PandasPairUniverse
from tradingstrategy.timebucket import TimeBucket


# Load trading pair metadata
all_pairs = client.fetch_pair_universe()
exchange_universe = client.fetch_exchange_universe()
pair_universe = PandasPairUniverse(all_pairs.to_pandas())

# Download all 24h candles as Parquet columnar data
all_candles = client.fetch_all_candles(TimeBucket.d1)

Let’s pick one pair, ETH-USDC on Uniswap v2, from the dataset to analyse.

[27]:
from tradingstrategy.chain import ChainId
import pandas as pd

# Convert PyArrow table to Pandas format to continue working on it
all_candles_dataframe = all_candles.to_pandas()

# To shorten this notebook, we know by hearth that USDC-ETH Uniswap v2 is the pair id numero uno,
# because that what Hayden used to test the production code when he deployed Uniswap v2
uniswap_v2 = exchange_universe.get_by_chain_and_slug(ChainId.ethereum, "uniswap-v2")

eth_usdc_pair = pair_universe.get_one_pair_from_pandas_universe(
    uniswap_v2.exchange_id,
    "WETH",
    "USDC"
)

eth_usdc_candles: pd.DataFrame = all_candles_dataframe.loc[all_candles_dataframe['pair_id'] == pair.pair_id]

print(f"Uniswap v2 ETH-USDC has {len(eth_usdc_candles)} daily candles")

# Because of swap exchange nature, we have separate volumes for buy and sell. We will
# combine this to generic `volume` column
eth_usdc_candles["volume"] = eth_usdc_candles["buy_volume"] + eth_usdc_candles["sell_volume"]
Uniswap v2 ETH-USDC has 923 daily candles

Volume chart#

The main benefit is having the trade volume (V in OHLCV) automatically rendered in the diagrams, as you would have on any trading view.

[28]:
import cufflinks as cf

# Needed for Sphinx/Jupyter/Pycharm compatibility
# See https://github.com/santosjorge/cufflinks/issues/267
cf.go_offline()

# Tell Cufflinks which data column to use as X axis for the daigram
eth_usdc_candles = eth_usdc_candles.set_axis(eth_usdc_candles["timestamp"], axis="index")

quant_chart = cf.QuantFig(
    eth_usdc_candles,
    title='ETH-USDC Uniswap v2',
    legend='top',
    name='ETH-USDC')
quant_chart.add_volume()
quant_chart.iplot()

MACD#

MACD, short for moving average convergence/divergence, is a trading indicator used in technical analysis of stock price. It is designed to reveal changes in the strength, direction, momentum, and duration of a trend in an assets’s price. Read more.

Below we plot MACD for our ETH-USDC pair.

[29]:
quant_chart = cf.QuantFig(
    eth_usdc_candles,
    title='ETH-USDC Uniswap v2',
    legend='top',
    name='ETH-USDC')
quant_chart.add_macd()
quant_chart.iplot()

RSI#

The relative strength index (RSI) is a technical indicator used in the analysis of financial markets. It is intended to chart the current and historical strength or weakness of a stock or market based on the closing prices of a recent trading period. The indicator should not be confused with relative strength. Read more.

Below we plot ESI for our ETH-USDC pair.

[30]:
quant_chart = cf.QuantFig(
    eth_usdc_candles,
    title='ETH-USDC Uniswap v2',
    legend='top',
    name='ETH-USDC')
quant_chart.add_rsi()
quant_chart.iplot()

Bollinger Bands#

Bollinger Bands are a type of statistical chart characterizing the prices and volatility over time of a financial instrument. Bollinger Bands display a graphical band (the envelope maximum and minimum of moving averages, and volatility (expressed by the width of the envelope) in one two-dimensional chart. Read more.

[31]:
quant_chart = cf.QuantFig(
    eth_usdc_candles,
    title='ETH-USDC Uniswap v2',
    legend='top',
    name='ETH-USDC')
quant_chart.add_bollinger_bands()
quant_chart.iplot()

Onwards! Next we will simulate trading based on our technical analysis and signals.