[ENG/ITA] Python and Arbitraging: Almost There... But Not Quite Yet


La versione italiana si trova sotto quella inglese

The italian version is under the english one


Python and Arbitraging: Almost There... But Not Quite Yet

In these past months, as I’ve started dedicating myself more actively to arbitrage, I’ve often found good opportunities: sometimes just a few dollars, other times dozens of dollars, but in all cases these gains are helping me build a parallel portfolio alongside the one I have on Hive.

A key tool that’s helping me generate these profits is Python, thanks to which I’ve created 3 scripts that assist me—more or less actively—and allow me to seize some of these opportunities when they arise.

Currently, my 3 scripts are:

  1. one dedicated to arbitraging HIVE and SWAP.HIVE through the bridges available on Beeswap and uSwap: this is the most complete script, which handles monitoring and automatically performing all operations;
  2. another that monitors the price of LEO on Arbitrum and Hive-Engine: this script doesn’t carry out transactions on its own, but it alerts me very precisely when the conditions for a possible arbitrage occur;
  3. and finally, one that monitors the values of the tokens SPS and DEC on Hive-Engine, Ethereum, Binance Smart Chain, and Base; as with LEO, this script doesn’t perform operations on its own, but simply notifies me when it detects potential opportunities. The difference from the LEO script is that, whereas that one simulates swaps through official APIs, this one simulates a human user performing a swap on the DEXs where SPS and DEC are tradeable.

This particular approach in the third script comes from the difficulty I encountered when attempting to interface directly with APIs from DEXs like Uniswap or Pancakeswap: after spending some time on it, I realized I wasn’t getting anywhere… so I looked for an alternative solution.

However, this solution has an obvious disadvantage: it’s much less fast and efficient, since it requires connecting to the various DEXs, loading their interfaces, entering the swap data, and then reading the result… much more complicated than making an API call that directly returns a result.

But there’s also one big advantage—at least for me: the same script is easily adaptable to many different DEXs and doesn’t require me to learn how each DEX’s API works.

For someone like me who has little time and very limited familiarity with Python or other programming languages, being able to simulate and monitor 3 different DEXs (and potentially more) with a single script that only requires adding a few lines to support a new DEX… well, that’s pretty great!


def uniswap(browser, url):
    DEX = "uniswap"
    WAIT_SELECTOR = "input[data-testid='amount-input-in']"
    INPUT_SELECTOR = "input[data-testid^='amount-input']"

    def simulate_uni(inputs):
        # Add personalized logic here, if needed
        return simulate_swap(inputs)
    print("Launching uniswap")
    return run_dex_query(browser, url, simulate_uni, DEX, WAIT_SELECTOR, INPUT_SELECTOR)

These few lines are indeed all I need to add a new DEX: basically I just have to identify the values to assign to WAIT_SELECTOR and INPUT_SELECTOR… and I’m done!


… even though I’m not 100% done yet!

Right, because the script still consists of several parts: simulating swaps on the DEXs is a fundamental part, but then I also need to check the results obtained and see whether any of them are significant.

And this is the part I still need to finish working on, because I’m not yet completely satisfied with the outcome.


def find_divergence(values_dict):
    print("\n" + ", ".join(f"{k}: {v}" for k, v in values_dict.items()))

    max_key = max(values_dict, key=values_dict.get)
    max_value = values_dict[max_key]

    outliers = []

    for key, value in values_dict.items():
        threshold = get_threshold(key, max_key)
        diff_percent = ((max_value - value) / max_value) * 100

        if diff_percent > threshold:
            outliers.append({
                "name": key,
                "value": value,
                "diff_percent": diff_percent,
                "threshold": threshold,
            })

    calculate_divergence({
        "max_name": max_key,
        "max_value": max_value,
        "outliers": outliers,
    })

Currently this part identifies differences between the provided values, but it only does so relative to the highest value, not the lowest.

Since I’m interested in arbitrage in both directions, I’d need to expand this check, or perhaps structure it in a completely different way so it can detect all differences among the values that exceed the thresholds I’m interested in.

In short, the script works, and it’s very close to the result I was looking for… but there’s still something missing before I can truly say “I’m done”!


cover made with Grok AI and edited with GIMP

to support the #OliodiBalena community, @balaenoptera is 3% beneficiary of this post


If you've read this far, thank you! If you want to leave an upvote, a reblog, a follow, a comment... well, any sign of life is really much appreciated!


Versione italiana

Italian version


Python e Arbitraggio: Ci Sono Quasi... Ma Non Ancora

In questi mesi in cui ho iniziato a dedicarmi più attivamente all'arbitraggio ho trovato spesso buone opportunità: alle volte si tratta di qualche dollaro, altre invece di decine di dollari, ma in tutti i casi sono guadagni che mi stanno aiutando a costruire un portafoglio parallelo a quello che ho su Hive.

Uno strumento fondamentale che mi sta aiutando a realizzare questi profitti è Python, grazie al quale ho creato 3 script che mi assistono, più o meno attivamente, e mi consentono di cogliere alcune di queste opportunità quando si presentano.

Attualmente i miei 3 script sono:

  1. uno dedicato all'arbitraggio di HIVE e SWAP.HIVE attraverso i bridge disponibili su Beeswap e uSwap: questo è lo script più completo, che si occupa di monitorare ed effettuare automaticamente tutte le operazioni;
  2. un altro per monitorare invece il prezzo di LEO su Arbitrum e su Hive-Engine: questo script non effettua autonomamente transazioni, ma mi segnala in maniera molto precisa quando si verificano le condizioni per un possibile arbitraggio;
  3. un ultimo, infine, che si occupa di monitorare i valori dei token SPS e DEC su Hive-Engine, Ethereum, Binance Smart Chain e Base; come per LEO, anche questo script non effettua operazioni autonomamente, ma si limita ad avvisarmi quando rileva potenziali opportunità: la differenza rispetto a quello di LEO è che, mentre quest'ultimo simula gli swap attraverso delle API ufficiali, quest'altro simula un utente umano che effettua uno swap tramite i DEX su cui SPS e DEC sono scambiabili.

Questa particolarità di questo terzo script è dovuta alla difficoltà che ho riscontrato nell'interfacciarmi direttamente con le API di DEX come Uniswap o Pancakeswap: dopo averci perso un po' di tempo ho realizzato che non stavo andando da nessuna parte... ed ho così cercato una soluzione alternativa.

Questa soluzione ha però un evidente vantaggio: è molto meno veloce ed efficiente, dato che richiede di collegarsi ai vari DEX, caricare le relative interfacce, inserire i dati dello swap e poi leggere il risultato... molto più complicato di una chiamata ad un API che restituisce direttamente un risultato.

Tuttavia c'è anche un grosso - almeno per me - vantaggio: lo stesso script è facilmente adattabile per molti DEX diversi e non mi richiede di imparare il funzionamento delle API di ognuno.

Per me che ho poco tempo e troppa poca dimestichezza con Python o altri linguaggi di programmazione, poter simulare e monitorare 3 DEX diversi (e potenzialmente anche di più) con un solo script che mi richiede di aggiungere giusto qualche riga per aggiungere un nuovo DEX... be', si tratta di tanta roba!


def uniswap(browser, url):
    DEX = "uniswap"
    WAIT_SELECTOR = "input[data-testid='amount-input-in']"
    INPUT_SELECTOR = "input[data-testid^='amount-input']"

    def simulate_uni(inputs):
        # Add personalized logic here, if needed
        return simulate_swap(inputs)
    print("Launching uniswap")
    return run_dex_query(browser, url, simulate_uni, DEX, WAIT_SELECTOR, INPUT_SELECTOR)

Queste poche righe sono infatti tutto ciò che mi serve per inserire un nuovo DEX: di base devo solo identificare i valori da assegnare a WAIT_SELECTOR e INPUT_SELECTOR... ed ho già finito!


... anche se non ho ancora finito al 100%!

Già, perchè lo script consta comunque di diverse parti: simulare gli swap sui DEX è una parte fondamentale, ma poi serve anche controllare i risultati ottenuti e vedere se ce ne sono di rilevanti.

Ecco, questa è la parte su cui ancora devo finire di lavorare, perchè non sono ancora completamente soddisfatto del risultato.


def find_divergence(values_dict):
    print("\n" + ", ".join(f"{k}: {v}" for k, v in values_dict.items()))

    max_key = max(values_dict, key=values_dict.get)
    max_value = values_dict[max_key]

    outliers = []

    for key, value in values_dict.items():
        threshold = get_threshold(key, max_key)
        diff_percent = ((max_value - value) / max_value) * 100

        if diff_percent > threshold:
            outliers.append({
                "name": key,
                "value": value,
                "diff_percent": diff_percent,
                "threshold": threshold,
            })

    calculate_divergence({
        "max_name": max_key,
        "max_value": max_value,
        "outliers": outliers,
    })

Attualmente questa parte identifica delle differenze tra i valori forniti, ma lo fa solo rispetto al valore più alto, non invece al più basso.

Dato che a me interessa arbitraggi in entrambe le direzioni, mi servirebbe di ampliare questo controllo, o magari strutturarlo in maniera totalmente diversa in modo da rilevare tutte le differenze fra i valori forniti che superino le varie soglie che mi interessano.

Insomma, lo script funziona, si avvicina moltissimo al risultato che cercavo... ma manca ancora un qualcosa per poter davvero dire "ho finito"!


cover realizzata con Grok AI ed editata con GIMP

a supporto della community #OliodiBalena, il 3% delle ricompense di questo post va a @balaenoptera

Se sei arrivato a leggere fin qui, grazie! Se hai voglia di lasciare un upvote, un reblog, un follow, un commento... be', un qualsiasi segnale di vita, in realtà, è molto apprezzato!

Posted Using INLEO