# Technical analysis without external libraries

Calculating indicators and oscillators

In my last blog, I discussed the use of Bollinger Bands in financial analysis, as well as showed an implementation in Deephaven that took only two table operations.

Deephaven makes implementing technical indicators easy without any third-party integrations.

Effective trading strategies typically require more than one technical indicator. Bollinger Bands are a great place to start, but how are others implemented in a tool like Deephaven? Many of the most popular and useful indicators are also easy to implement with Deephaven alone.

## Data​

All examples in this blog will use a cryptocurrency history dataset of trade data from September 22, 2021. The calculations will be done on a per-instrument-exchange pair basis.

Quick analysis shows that this data has 17 unique instrument/exchange pairs. There are 4 unique instruments and 7 different exchanges.

``from deephaven import read_csvcrypto_table = read_csv("https://media.githubusercontent.com/media/deephaven/examples/main/CryptoCurrencyHistory/CSV/CryptoTrades_20210922.csv")instrument_exchange_pairs = crypto_table.select_distinct(["Instrument", "Exchange"])``

## Indicators​

Each of the following sections will briefly discuss an indicator and show how to implement it in Deephaven. Because each indicator's implementations share many similarities, things are kept simple.

### Moving average convergence divergence (MACD)​

MACD is calculated by subtracting a longer-term EMA from a shorter-term EMA. It's compared with a signal line, which is the MACD's moving average. This indicator is used to evaluate current market conditions.

A one-minute bar is used for this calculation. The shorter-period EMA uses 12 bars, the longer-period EMA uses 26 bars, and the signal line is calculated using 9 bars. The MACD calculation is enclosed in comments in the code. It only takes three table operations: two `update_by` statements and an `update`.

``from deephaven.updateby import ema_time, rolling_avg_timefrom deephaven.replay import TableReplayerfrom deephaven.plot.figure import Figurefrom deephaven.time import to_j_instantfrom deephaven import read_csvcrypto_table = read_csv("https://media.githubusercontent.com/media/deephaven/examples/main/CryptoCurrencyHistory/CSV/CryptoTrades_20210922.csv")ema_12min = ema_time(ts_col="Timestamp", decay_time="PT12m", cols=["EMA_12Min = Price"])ema_26min = ema_time(ts_col="Timestamp", decay_time="PT26m", cols=["EMA_26Min = Price"])sma_9min = rolling_avg_time(ts_col="Timestamp", cols=["Signal = MACD"], rev_time="PT9m")# Calculating MACDcrypto_macd = crypto_table.update_by(        ops=[ema_12min, ema_26min],        by=["Instrument", "Exchange"]    ).update(        formulas=["MACD = EMA_12Min - EMA_26Min"]    ).update_by(        ops=[sma_9min],        by=["Instrument", "Exchange"]    )# Done calculating MACDbtc_binance_macd = crypto_macd.where(["Instrument == `BTC/USD`", "Exchange == `binance`"])btc_binance_macd_plot = Figure().\    plot_xy(series_name="MACD", t=btc_binance_macd, x="Timestamp", y="MACD").\    plot_xy(series_name="Signal", t=btc_binance_macd, x="Timestamp", y="Signal").\    chart_title(title="BTC on Binance MACD vs signal").\    show()``

### Stochastic oscillator​

The Stochastic oscillator is a momentum indicator that's useful for identifying if an asset is overbought or oversold. The stochastic oscillator requires keeping track of the highest and lowest trade prices of an asset over 14 periods.

In the code below, a one-minute bar is used.

``from deephaven.updateby import rolling_min_time, rolling_max_timefrom deephaven.replay import TableReplayerfrom deephaven.plot.figure import Figurefrom deephaven.time import to_j_instantfrom deephaven import read_csvcrypto_table = read_csv("https://media.githubusercontent.com/media/deephaven/examples/main/CryptoCurrencyHistory/CSV/CryptoTrades_20210922.csv")min_14m = rolling_min_time(ts_col="Timestamp", cols=["Min_14m = Price"], rev_time="PT14m")max_14m = rolling_max_time(ts_col="Timestamp", cols=["Max_14m = Price"], rev_time="PT14m")# Calculating stochastic oscillatorcrypto_so = crypto_table.update_by(        ops=[min_14m, max_14m],        by=["Instrument", "Exchange"]    ).update(        formulas=["StochOsc = ((Price - Min_14m)/(Max_14m - Min_14m)) * 100"]    )# Done calculating stochastic oscillatorbtc_binance_so = crypto_so.where(["Instrument == `BTC/USD`", "Exchange == `binance`"])eth_binance_so = crypto_so.where(["Instrument == `ETH/USD`", "Exchange == `binance`"])binance_so_plot = Figure().\    plot_xy(series_name="BTC/Binance", t=btc_binance_so, x="Timestamp", y="StochOsc").\    plot_xy(series_name="ETH/Binance", t=eth_binance_so, x="Timestamp", y="StochOsc").\    chart_title(title="Stochastic Oscillator for BTC and ETH trades on Binance").\    show()``

### Absolute price oscillator (APO)​

APO is yet another indicator that gives insight into bullish or bearish behavior of an asset. It requires keeping track of two EMAs: one for a shorter period, and one for a longer period. The longer is subtracted from the shorter. The example below uses a 5-minute and 15-minute EMA, respectively.

``from deephaven.updateby import ema_timefrom deephaven.replay import TableReplayerfrom deephaven.plot.figure import Figurefrom deephaven.time import to_j_instantfrom deephaven import read_csvcrypto_table = read_csv("https://media.githubusercontent.com/media/deephaven/examples/main/CryptoCurrencyHistory/CSV/CryptoTrades_20210922.csv")ema_5min = ema_time(ts_col="Timestamp", decay_time="PT5m", cols=["EMA_5Min = Price"])ema_15min = ema_time(ts_col="Timestamp", decay_time="PT15m", cols=["EMA_15Min = Price"])# Calculating absolute price oscillatorcrypto_apo = crypto_table.update_by(        ops=[ema_5min, ema_15min],        by=["Instrument", "Exchange"]    ).update(        formulas=["APO = EMA_5Min - EMA_15Min"]    )# Done calculating APObtc_binance_apo = crypto_apo.where(["Instrument == `BTC/USD`", "Exchange == `binance`"])btc_binance_apo_plot = Figure().\    plot_xy(series_name="BTC/Binance Price", t=btc_binance_apo, x="Timestamp", y="Price").\    x_twin().\    plot_xy(series_name="BTC/Binance APO", t=btc_binance_apo, x="Timestamp", y="APO").\    chart_title(title="Price and APO for BTC trades on Binance").\    show()``

## Reach out​

Our Community documentation has all of the resources you need to become a Deephaven power user. Our Slack community continues to grow, and we'd love to have you join us! If you have any questions, comments, or suggestions, please reach out to us there.