Crypto Arbitrage Indicator

This script demonstrates how to use v6 Pine Script syntax to utilize the new dynamic security function requests to create an arbitrage signal indicator which alerts you when a crypto asset gets a price dislocation between two exchanges.

Check out my other free lessons!

Source Code


// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © ZenAndTheArtOfTrading / PineScriptMastery.com
// @version=6
indicator("Crypto Arbitrage", overlay=true)

// Get user inputs
string INPUT_CRYPTO_EXCHANGE = input.string("Bitstamp,Coinbase,Binance,Bitfinex,Kraken,Gemini,Bybit,OKX,Cryptocom,Kucoin,Gateio", "Crypto Exchanges")
float INPUT_MIN_DISTANCE = input.float(3, "Minimum % Distance")

// Convert lists to arrays
var array<string> cryptoExchanges = str.split(INPUT_CRYPTO_EXCHANGE, ",")

// Prepare price values
float highestPrice = high
string highestPriceExchange = ""
float lowestPrice = low 
string lowestPriceExchange = ""

if (syminfo.type == "crypto")
    for i = 0 to cryptoExchanges.size() - 1
        priceHigh   = request.security(cryptoExchanges.get(i) + ":" + syminfo.ticker, timeframe.period, high, ignore_invalid_symbol=true)
        priceLow    = request.security(cryptoExchanges.get(i) + ":" + syminfo.ticker, timeframe.period, low, ignore_invalid_symbol=true)
        if (priceHigh > highestPrice)
            highestPrice := priceHigh
            highestPriceExchange := cryptoExchanges.get(i)
        if (priceLow < lowestPrice)
            lowestPrice := priceLow
            lowestPriceExchange := cryptoExchanges.get(i)

// Get price differentials 
float priceHighDiff = ((highestPrice - high) / high)
float priceLowDiff = ((low - lowestPrice) / low)

// Check minimum price differential threshold
bool priceHighArbitrage = priceHighDiff >= (INPUT_MIN_DISTANCE / 100)
bool priceLowArbitrage = priceLowDiff >= (INPUT_MIN_DISTANCE / 100)

// Draw volume
plot(priceHighArbitrage ? highestPrice : na, "Highest Price", color.red, style=plot.style_linebr)
plot(priceLowArbitrage ? lowestPrice : na, "Lowest Price", color.blue, style=plot.style_linebr)

if (priceHighArbitrage)
    string priceHighDiffStr = str.tostring(priceHighDiff * 100, "#.##") + "%"
    label.new(bar_index, highestPrice, "< " + highestPriceExchange + " " + priceHighDiffStr, color=color.new(color.black, 100), style=label.style_label_left)
    alert("High price on " + highestPriceExchange + " for " + syminfo.ticker + " exceeded " + priceHighDiffStr)

if (priceLowArbitrage)
    string priceLowDiffStr = str.tostring(priceLowDiff * 100, "#.##") + "%"
    label.new(bar_index, lowestPrice, "< " + lowestPriceExchange + " " + priceLowDiffStr, color=color.new(color.black, 100), style=label.style_label_left)
    alert("Low price on " + lowestPriceExchange + " for " + syminfo.ticker + " exceeded " + priceLowDiffStr)