RE: [ENG/ITA] Earning HIVE Thanks to My Scripts: Bridges Arbitrage and Grid Trading

You are viewing a single comment's thread:

Interessante, grazie!
Lo script immagino tu lo faccia girare su un computer locale... Mac o Windows?
hai per caso il codice di get_balances(account, nodes, session)?
E.... come conservi le chiavi di accesso?
Grazie



0
0
0.000
22 comments
avatar

get_balances è una funzione delle api di hive, se non erro...

0
0
0.000
avatar

Uso Windows, principalmente perchè ho sempre e solo usato quello, per cui se uno mi mette davanti un computer con Mac o Linux vado in tilt 🤣

Quando, e se, arriverò alla fase in cui lo script dovrà operare autonomamente, allora utilizzerò Github Actions per hostarlo, in modo non dover tenere una (mia) macchina sempre accesa.

come conservi le chiavi di accesso?

Per ora sono hardocoded nel codice (in barba a qualsiasi best practice in materia di sicurezza), ma appena lo renderò operativo ed autonomo utilizzerò la funzione "Secrets" di Github, che funziona in maniera simile (per il poco che ci capisco) all'utilizzo di un file .env.

hai per caso il codice di get_balances(account, nodes, session)?

Eccolo qua, con sotto anche get_response, che è la funzione che si interfaccia con le API di Hive:

def get_balances(account, nodes, session: requests.Session):
    data = (
        f'{{"jsonrpc":"2.0", "method":"condenser_api.get_accounts", '
        f'"params":[["{account}"]], "id":1}}'
    )
    result = get_response(data, nodes, session)
    return result[0]["balance"].split()[0], result[0]["hbd_balance"].split()[0]
def get_response(data, nodes, session: requests.Session):
    for node in nodes:
        response = session.post(node, data=data)

        if response.status_code == 502:
            continue

        result = response.json().get("result", [])

        if result or result == []:
            return result

        print(f"Error: Status Code: {response.status_code}")

get_balances è una funzione delle api di hive, se non erro...

Se c'era mi è sfuggita: nel mio codice io ho utilizzato get_accounts dell'API Condenser, che contiene varie informazioni sull'account selezionato, incluso l'ammontare di HIVE e HBD che possiede.

get_balances nel mio script è quindi solo una funzione personalizzata creata da me per costruire la prima parte della richiesta.

0
0
0.000
avatar

grazie mille!

Ancora una domanda, scusa...
Il codice seguente, se ho capito bene, crea un ordine di vendita di Hive al prezzo sell_price.

sell_price = round(highest + diff * highest / 100, 4)
place_sell_order(account, sell_price, amount, market)

Se il prezzo dell'hive è più basso round(highest + diff * highest / 100, 4), viene chiamata lo stesso la funzione 'place_sell_order', ma l'ordine non viene eseguito, mentre se l'hive è maggiore di round(highest + diff * highest / 100, 4), l'ordine viene eseguito e gli hive vengono venduti (cioè convertiti in Hbd).

Ho capito bene la logica?

Grazie!

0
0
0.000
avatar

Figurati! Non sai quanto mi fa piacere ricevere domande e confrontarmi con qualcuno su questi argomenti :) mi aiuta ad imparare!

Il codice seguente, se ho capito bene, crea un ordine di vendita di Hive al prezzo sell_price.

Sì, anche se, per essere più precisi, la parte a cui ti riferisci si occupa di vendere HBD al prezzo sell_price

        if float(hbd) > amount:
            sell_price = round(highest + diff * highest / 100, 4)
            print("Looking to sell HBD...")

            sell = place_sell_order(
                account, sell_price, amount, market
            )  # Buy HIVE, sell HBD
            time.sleep(3)

Mentre la parte che vende Hive (al prezzo buy_price) è quella dopo:

        if float(hive) > amount * lowest:
            buy_price = round(lowest - diff * lowest / 100, 4)
            print("Looking to sell HIVE...")

            buy = place_buy_order(
                account, buy_price, amount, market
            )  # Sell HIVE, buy HBD
            time.sleep(3)

Se il prezzo dell'hive è più basso round(highest + diff * highest / 100, 4), viene chiamata lo stesso la funzione 'place_sell_order', ma l'ordine non viene eseguito, mentre se l'hive è maggiore di round(highest + diff * highest / 100, 4), l'ordine viene eseguito e gli hive vengono venduti (cioè convertiti in Hbd).

Qui è un po' diverso perchè la condizione che innesca la creazione o meno di un ordine è questa (nel caso di vendita di HIVE, ad esempio):

        if float(hive) > amount * lowest:

Quindi, se il mio balance (float(hive) è maggiore dell'ammontare che intendo vendere (amount * lowest), allora lo script procede con la parte successiva e crea l'ordine.

Se invece il mio balance è uguale o minore, allora l'ordine non viene creato e si passa alla successiva iterazione del for loop.

Questa parte qui invece si occupa di determinare il prezzo di vendita (sempre di HIVE in questo caso):

buy_price = round(lowest - diff * lowest / 100, 4)

Per cui la logica è: verifico se ho balance sufficiente per creare un ordine con l'importo che ho scelto; se ce l'ho, calcolo il prezzo a cui voglio vendere e creo l'ordine chiamando la funzione place_buy_order(account, buy_price, amount, market) o place_sell_order(account, buy_price, amount, market) (che sono due funzioni della libreria beem).

Spero di essere stato chiaro, perchè il mio codice di sicuro non lo è 🤣

0
0
0.000
avatar

Grazie mille, ma devo rifletterci perchè non mi è chiaro.
Intanto partiamo dalle base, ti chiedo: lowest e highest cosa sono? Variabili dinamiche o cablate? Il prezzo più basso e più alto dell'hive?

0
0
0.000
avatar

Sono variabili dinamiche, rispettivamente l'offerta di vendita più bassa e di acquisto più alta presenti sul mercato.

0
0
0.000
avatar

in che periodo?

0
0
0.000
avatar

Ogni volta che lo script viene lanciato interrogo le API di Hive per ottenere il prezzo attuale; poi durante l'esecuzione dello script il prezzo non viene riaggiornato (anche se nel caso di esecuzione di più ordini potrei voler riaggiornare costantemente il prezzo, così da assicurarmi di star piazzando le offerte di vendita/acquisto con prezzi coerenti con quelli di mercato). Per ora lo aggiorno solo all'inizio perchè nella fase di test piazzo al massimo 3 ordini di vendita e 3 di acquisto, quindi il tutto si conclude in meno di 20 secondi.

0
0
0.000
avatar

A proposito di: if float(hive) > amount * lowest:
(vend hive per comprare hbd)

amount è la quantità di hbd (supponiamo 10) che voglio comprare. Supponiamo che 1 hbd valga 3.8 hive. quindi 10 * 3.8 = 38 hive. Devo avere almeno 38 hive per comprare 10 hbd. Ovviamente vendo gli hive quando il prezzo degli hbd è minore (lowest). Lowest per cui è conveniente comprare hbd. lowest è cablato o dinamico?

0
0
0.000
avatar

amount è la quantità di hbd (supponiamo 10) che voglio comprare. Supponiamo che 1 hbd valga 3.8 hive. quindi 10 * 3.8 = 38 hive. Devo avere almeno 38 hive per comprare 10 hbd

Tutto esatto; da qui poi vendo HIVE quando il prezzo di HIVE sale, e precisamente quando supera di una certa percentuale (che decido io al momento della creazione dell'ordine) l'offerta di vendita più bassa (lowest).

Quindi, continuando il tuo esempio, ho 38 HIVE che valgono 10 HBD e piazzo l'ordine di vendita con place_buy_order(account, buy_price, amount, market) impostando come prezzo 3.8 HIVE - (1 * 3.8 / 100), se vogliamo sfruttare un aumento del prezzo di HIVE rispetto ad HBD dell'1%.

Questa parte mentre lavoravo mi ha confuso un sacco perchè beem e le api di Hive in alcuni casi valutano i prezzi in HBD ed in altri in HIVE, per cui anche nello script ho dovuto tenerne conto.

0
0
0.000
avatar

Ok, grazie! Inizia ad essere più chiaro, nonostante io sia ancora ignorante su molti dettagli. Ad esempio, tu imposti il prezzo di vendita, ma se il prezzo di vendita reale non coincide, cosa succede? Succede che l'ordine rimane in stand-by? Parte non appena il prezzo di vendita coincide?... Grazie

0
0
0.000
avatar

Esattamente! In realtà è proprio quella l'idea dietro il grid trading: piazzo ordini di vendita incrementalmente più alti del prezzo di vendita attuale, così se il prezzo di HIVE sale, lo converto via via in HBD, sfruttando questa "oscillazione" verso l'alto. Idem, per gli ordini di acquisto, in cui vendo HBD per HIVE: piazzo ordini in attesa che il prezzo di HIVE cali dell'1%, 2%, 3%, etc, così posso trarre vantaggio di un'oscillazione verso il basso.

Quindi questo grid trading funziona bene se HIVE tende a restare stabilmente su un certo prezzo, aumentando ed diminuendo di valore poco ma spesso. Se poi il prezzo aumenta o diminuisce troppo, il mio script cancella gli ordini che ormai sono fuori range e ne piazza di nuovi leggermente sopra e sotto il nuovo valore.

Teoricamente, perciò, dovrebbe essere possibile ottenere un guadagno se si riescono a cogliere abbastanza oscillazioni di prezzo all'interno di un certo range, prima che il prezzo si sposti in un nuovo range.

In pratica, probabilmente alla fine sarà solo un esercizio dove avrò imparato qualcosa (si spera!) 🤣

0
0
0.000
avatar

Ciao! Ho provato a lanciare questo script con python, in effetti mi ha creato l'ordine (ho cercato di vendere un hive a 0.22 hbd, se ho capito bene), ma non è successo niente... Ho provato anche con prezzi maggiori, ma niente. Secondo te lo script è giusto? Se l'ordine non è accettato entro quanto tempo scade? Grazie!

from beem import Hive
from beem.account import Account
from beembase.operations import Custom_json
import json

Dati utente

username = "barnabo73"
active_key = "myactivekey" # tua chiave privata

Inizializza blockchain

hive = Hive(keys=[active_key])
account = Account(username, blockchain_instance=hive)

Parametri ordine

quantity = "1.00000"
price = "0.22"
symbol = "SWAP.HIVE" # Hive su Hive-Engine
order_type = "sell"

json_data = {
"contractName": "market",
"contractAction": "sell",
"contractPayload": {
"symbol": symbol,
"quantity": quantity,
"price": price
}
}

Prepara e firma la transazione JSON

tx = Custom_json(
**{
"required_auths": [username],
"required_posting_auths": [],
"id": "ssc-mainnet-hive",
"json": json.dumps(json_data)
}
)

Invia la transazione

broadcast_result = hive.finalizeOp(tx, username, "active")

print("Ordine piazzato:")
print(broadcast_result)

0
0
0.000
avatar

Appena posso controllo meglio, però intanto vedo che stai interagendo con Hive-Engine, per cui sicuramente il funzionamento sarà un po' diverso da Hive (magari non c'è tutto quel casino sul valore dell'operazione che una volta è in HIVE e l'altra in HBD 🤣).

0
0
0.000
avatar

Ecco, ora dovrebbe andare.

Mancava "type": "custom_json_operation", quando veniva creato il custom_json.

from beem import Hive
from beem.account import Account
from beembase.operations import Custom_json
import json
# Dati utente

username = "xxxx"
active_key = "xxxxx" # tua chiave privata

# Inizializza blockchain
hive = Hive(keys=[active_key])
account = Account(username, blockchain_instance=hive)

# Parametri ordine
quantity = "1.00000"
price = "1"
symbol = "SWAP.HIVE" # Hive su Hive-Engine
order_type = "sell"

json_data = {
    "contractName": "market",
    "contractAction": order_type,
    "contractPayload": {
        "symbol": symbol,
        "quantity": quantity,
        "price": price
    }
}

# Prepara e firma la transazione JSON
tx = Custom_json(
    **{
    "type": "custom_json_operation", # <--- mancava questo
    "required_auths": [username],
    "required_posting_auths": [],
    "id": "ssc-mainnet-hive",
    "json": json.dumps(json_data)
    }
)

# Invia la transazione
broadcast_result = hive.finalizeOp(tx, username, "active")

print("Ordine piazzato:")
print(broadcast_result)

Ho fatto due test con un altro token (perchè non avevo SWAP.HIVE a disposizione) e mi ha creato gli ordini :)

orders.JPG

0
0
0.000
avatar

grazie mille! Ho riprovato con la correzione, ma non capisco come capire se l'ordine è andato a buon fine...

0
0
0.000
avatar

Puoi controllare su questo block explorer:

https://he.dtools.dev/@barnabo73

Vedo però che non hai SWAP.HIVE disponibili, per cui se stai provando a creare ordini per questo token la transazione non andrà a buon fine!

0
0
0.000
avatar

scusa ancora la mia somme ignoranza, ma cosa sono gli swap.hive? Se intendi hive disponibili, ne ho molti....

0
0
0.000
avatar

SWAP.HIVE è l'equivalente di HIVE ma su Hive-Engine, per cui è proprio un token diverso, per quanto di valore identico ad HIVE.

Nel tuo wallet su Hive-Engine vedo che non ci sono SWAP.HIVE:

Per vedere se il tuo script funziona potresti cambiare il token symbol con WAIV, lanciare il tuo script e poi controllare su un block explorer o tramite lo script che hai inserito nell'altro commento se l'ordine così è stato recepito dalla blockchain (di base stavolta dovrebbe perchè hai disponibili parecchi WAIV).

Entrambi gli script che hai condiviso nei commenti sono infatti relativi ad Hive-Engine, non Hive, per cui è al primo che devi fare riferimento per vedere se hai abbastanza token per creare un ordine.

Per creare qualcosa che funzioni su Hive (invece che Hive-Engine) dovresti fare riferimento alla documentazione di beem ed a quella sulle API di Hive.

Se ti serve qualche esempio concreto dimmi pure :) nelle mie repositories su Github trovi alcuni esempi, anche se quelli più interessanti sono in repo private (perchè dentro ci copio spesso le mie chiavi private, evviva la sicurezza 🤣), ma posso inviarti in qualche modo anche quelli se ti possono fare comodo.

0
0
0.000
avatar

ah, ok! Beem invece usa i token direttamente su hive, se ho capito bene. Grazie mille, quando ho tempo ci studio un po'! I tuoi commenti sono molto preziosi, come vedi sono molto ignorante su molti aspetti base della blockchain, c'è molto da studiare...

0
0
0.000
avatar

Dipende, beem può essere utilizzata sia per Hive che per Hive-Engine, in alcune sue parti; ciò che fa la differenza sono:

  • i nodi a cui ti connetti (https://api.hive-engine.com/rpc/contracts ad esempio è un nodo di Hive-Engine)
  • come costruisci l'informazione che vuoi inviare (l'utilizzo del "payload" e di un "custom_json" ad esempio è tipico di Hive-Engine)

Esempi di nodi di Hive sono invece questi:

urls = [
        "https://api.deathwing.me",
        "https://api.hive.blog",
        "https://hive-api.arcange.eu",
        "https://hive.roelandp.nl",
        "https://api.openhive.network",
        "https://api.c0ff33a.uk",
        "https://anyx.io",
        "https://techcoderx.com",
        "https://rpc.mahdiyari.info",
    ]

Mentre un esempio di costruzione di un trasferimento, sempre per Hive, è questo:

def transfer_hive(sender, receiver="arc7icwolf", amount="0.001", memo=""):
    data = Transfer(
        **{"from": sender, "to": receiver, "amount": f"{amount} HIVE", "memo": memo}
    )
    
    hive = connect_to_hive()
    tx = TransactionBuilder(hive_instance=hive)
    tx.appendOps(data)
    tx.appendWif(PRIVATE_KEY)
    tx.sign()
    tx_id = tx.broadcast()
    print(tx_id)

La parte finale la potresti anche sostituire con hive.finalizeOps() che ti ho visto usare nel primo script che hai condiviso, dato che quello si occupa di inviare e firmare la transazione.

sono molto ignorante su molti aspetti base della blockchain, c'è molto da studiare...

Tranquillo, siamo sulla stessa barca 🤣

0
0
0.000
avatar

ho usato questo codice per vedere gli ordini attivi, ma brancolo un po' nel buio... Mi dice 'Nessun ordine attivo trovato....' eppure quando ho lanciato il tuo script corretto mi ha dato 'ordine piazzato'. Grazie ancora!

import requests

username = "myusername"

url = "https://api.hive-engine.com/rpc/contracts"
payload = {
"jsonrpc": "2.0",
"id": 1,
"method": "find",
"params": {
"contract": "market",
"table": "openOrders",
"query": {
"account": username
},
"limit": 1000
}
}

response = requests.post(url, json=payload)
orders = response.json().get("result", [])

print(f"Ordini attivi per {username}:")
if orders is None:
print("Nessun ordine attivo trovato o risposta non valida.")
else:
for order in orders:
print(order)

0
0
0.000