Python script voor DCA inleg USDC bij Bitvavo

Ja precies, wat is dat nu voor een titel Veel? Nou een techneut plus nogal van het hobbyen op z’n tijd is gelijk aan dat dit dus wel eens kan voorbij komen op dit blog. Heet ook investeren in jezelf, zo blijft de bovenkamer ook actief. En daarbij wordt een van m’n DCA strategien aan de kant van de Bitvavo exchange geautomatiseerd. Dus twee klappen in een vlieg, of zoiets. In een makkelijk voorbeeld een beetje kennismaken met Python en de Bitvavo API. Nice (al vind ik dat zelf).

Wat bedoel je nu eigenlijk?

De doelstelling is om:

  1. Mijn Python skills weer wat afstoffen.
  2. Babbelen met de Bitvavo API.
  3. En dan wekelijks een check en wanneer de conditie juist is, een koop order plaatsen.
  4. Dus wekelijks inplanbaar.
  5. Zodat de euro’s niet niets staan te doen en bij USDC (redelijk stable) per week een opbrengst te hebben. USDC heeft bij Bitvavo staking een jaarlijkse opbrengst van 6.10%.
  6. Tenzij de buffer van euro’s onder een bepaald bedrag is, aangezien er ook een cryptohopper loopt die af en toe ook euro’s nodig heeft om te reageren op de markt.
  7. Mijzelf in de thuis Matrix server informeren, bijvoorbeeld van de aankoop.

Dus dit is een redelijk makkelijk voorbeeld om kennis te maken. Ja hardcore coders zullen het wellicht efficienter kunnen doen, de doelstelling is niet om de meest efficiente code te maken 😉

Wat heb je daar nu voor nodig?

  1. Python basis kennis of Google-Fu skills om de gaten in te vullen.
  2. Python.
  3. Als editor en uitvoer gebruik ik JupyterLab notebook. Maar je kan ook VS Code gebruiken of welke je prettig vindt (veel kloppen in VI bijvoorbeeld).
  4. Een Bitvavo account. Als je deze nog niet heb kijk dan vooral bij de bonusverwijzing pagina. Daar staat een linkje voor als je een account aan maakt je 1000 euro transactie te goed krijgt.
  5. Een API key en secret in je Bitvavo account. Redelijk makkelijk in je account menu onder API. Maak hier een nieuwe. Maak gebruik van een whitelist IP adres als je dat kunt. Ik maak zelf gebruik van een KPN verbinding die redelijk statisch is, dus die heb ik opgevoerd zodat alleen van dit IP kan worden gebabbeld met deze API key en secret. Zet verder de trade mogelijkheid pas aan wanneer je er klaar voor bent! Doe je dat eerder en maak je een foutje, tsja dat kan leergeld kosten.
  6. Een saldo.
  7. Staking ingeschakeld.
  8. Een matrix server. Die draait hier op een raspbery PI draaien met Umbrel.

Uitvoering

Allereerst heb je de Bitvavo API documentatie nodig: https://docs.bitvavo.com/. Daarna moet je zorgen dat je de Bitvavo API module ook in Python krijgt. Dat kan met een pip install. Als je dit in het Jupyter notebook doet: !pip install python-bitvavo-api (zonder ! als je dit direct in Python probeert).

Verder wil je een matrixclient hebben, en pandas gebruiken voor het verwerken van de data: !pip install matrix_client en !pip install pandas

Feest, nu kan je gaan babbelen met Matrix en Bitvavo.

Starten met het aanroepen van al die componenten die we nodig hebben:

from python_bitvavo_api.bitvavo import Bitvavo
import pandas as pd
import time
import datetime
from datetime import date
import calendar
curr_date = date.today()
DayToday = calendar.day_name[curr_date.weekday()]
from matrix_client.client import MatrixClient

Dus in volgorde, Bitvavo, pandas als pd, tijd en datum, daar de dag van vandaag van maken en de Matrix client

Dan kunnen we gaan beginnen met de verbindingen te leggen. Allereerst met Matrix:

#Connecto to Local matrix server (umbrel)
client = MatrixClient("http://je interne ip:8008")
token = client.login(username="apiusr",password="apipwd")

#Connect to Bitvavo Bot Room (get Room id from Element)
rooms = client.get_rooms()
room = client.join_room("!roomid:adres")

Zoals je begrijpt hebben we wat dingetjes weggelaten. Anyhoe, je verbindt met de client, in mijn geval een intern ip adres. Dan log je in met een api user en password. En als laatste join je de juiste room. De rooms is gebruikt om de ID’s op te halen, dat kan je bijvoorbeeld ook doen in Element of welke Matrix client je normaal gebruikt.
Je zit nu in de juiste room en we kunnen verder.

# Connect to Bitvavo API
bitvavo = Bitvavo({
    'APIKEY': apikey,
    'APISECRET': apisecret,
    'RESTURL': 'https://api.bitvavo.com/v2',
    'WSURL': 'wss://ws.bitvavo.com/v2/',
    'ACCESSWINDOW': 10000,
    'DEBUGGING': False
})

apikey en apisecret heb ik als variabelen staan in een andere notebook, die ik even ervoor include. Je kan zelf hiervoor deze variabelen declareren en vullen, of je zet deze hier in de plaats voor (‘je apikey’ etc.)

We hebben nu een verbinding met Bitvavo en mn account. Het eerste wat ik wil weten is wat de status van mn te gebruiken euro’s is. Is dit bijvoorbeeld onder de 100, dan wil ik helemaal geen DCA doen. Hiervoor gebruik ik een function definitie die later aan te roepen is.

def getBitvavoAccountdata():
    frame = pd.DataFrame(bitvavo.balance({}))
    return frame 

Simpel. Er wordt een dataframe gevuld met de bitvavo.balance en die wordt teruggegeven. Niet veel meer over uit te leggen. Maar wel wat je terugkrijgt natuurlijk. Als je deze functie zou aanroepen met getBitvavoAccountdata() dan krijg je alle assets van je account met symbool, hoeveel beschikbaar (eigenlijk hoeveel je er hebt) en of er openstaande orders zijn. Een voorbeeld van de output hier onder.

	symbol	available	inOrder
0	EUR	314.69	0
1	USDC	80.075692	0
2	USDT	0	0
3	AAVE	0.00001567	0
4	ADA	68.635561	0

Die moet doorgelopen worden om de EUR stand te vinden. Ik ga er stiekem niet vanuit dat dit altijd de eerste regel is. En misschien wil ik op een later tijdstip ook iets met een andere symbol doen. Daarvoor definieren we een zoek functie. Die we gebruiken om de output van de getBitvavoAccountdata() door te zoeken op EUR

def search(dataFrame, item):
  mask = (dataFrame.applymap(lambda x: isinstance(x, str) and item in x)).any(1)
  return dataFrame[mask]

# deze drie regels zijn alleen een voorbeeld, we gebruiken deze functies later in een if blok als we ook daadwerkelijk weten dat we kunnen gaan kopen.
BitvavoData = getBitvavoAccountdata()
euroamount = search(BitvavoData, 'EUR')
gotsome = euroamount[euroamount['available'] >= '10' ]

We stoppen de output van getBitvavoAccountdata in een variabel, die stoppen we in de zoekfunctie met de assetnaam EUR. Die regel komt terug in een variabel euroamount. Als dat hoger of gelijk is aan 10, gaan we deze in de variabel gotsome stoppen. Daar kunnen we later dan wat mee.

 if not gotsome.empty:
        response = room.send_text("We got enough EUR " + str(datetime.datetime.now()))
        # create order
        order = bitvavo.placeOrder('USDC-EUR','buy','market',{ 'amount': '10'})
        response = room.send_text("Order placed: " + str(order))
       # print order
    else:
        response = room.send_text("Not enough balance, skipping buy " + str(datetime.datetime.now()))

Dus als gotsome niet leeg is dan hebben we besloten dat dit een goede conditie is om tot een order over te gaan. Dat wordt medegedeeld in het Matrix kanaal. Verder wordt met bitvavo.PlaceOrder een market order ingediend voor 10 USDC. De output hiervan wordt wederom in Matrix gepost.

Als gotsome leeg blijft, is er niet voldaan aan de conditie >= 10, en gaan we niets doen. Dat posten we ook in Matrix.

Het enige wat we moeten doen, is deze code nog in een conditie stoppen die voor de wekelijkse check wordt gebruikt. Zeg maar dat ik dit alleen op zondag wil hebben uitgevoerd. We hadden eerder al de DayToday definieerd met de dag dat het script wordt uitgevoerd. Dus een check

DaySchedule = "Sunday"
if DayToday == DaySchedule:
    print('Today is the day, lets buy USDC')
    BuyUSDC = True
else:
    BuyUSDC = False

Dan doen we het eerder scriptblok van uitlezen van Bitvavo account en afwegen of we overgaan tot kopen in een conditie of BuyUSDC nu wel of niet True is. Ik hoef niet te weten dat het niet zondag is, dus dat posten we niet in Matrix.

if BuyUSDC:
    BitvavoData = getBitvavoAccountdata()
    euroamount = search(BitvavoData, 'EUR')
    gotsome = euroamount[euroamount['available'] >= '10' ]
    if not gotsome.empty:
        response = room.send_text("We got enough EUR " + str(datetime.datetime.now()))
        # create order
        order = bitvavo.placeOrder('USDC-EUR','buy','market',{ 'amount': '10'})
        response = room.send_text("Order placed: " + str(order))
       # print order
    else:
        response = room.send_text("Not enough balance, skipping buy " + str(datetime.datetime.now()))       
else:
    print("It is not Sunday")

De post in matrix als uitkomst

Voila dat is het dan. Ik heb het script ingepland als taak om wekelijks uit te voeren. Dus daar hoef ik de komende tijd niet meer naar om te kijken.

En ga je nog iets anders doen met Python en een strategie?

Jazeker ik ben aan het verder bekijken wat er bijvoorbeeld ook met de Binance API kan. En verder probeer ik wat technische indicatoren te gebruiken waarbij er een afweging gemaakt wordt van kopen of verkopen. Bijvoorbeeld op basis van SMA of RSI of een combinatie of wat dan ook. Wordt vervolgd

2 gedachten over “Python script voor DCA inleg USDC bij Bitvavo”

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.