BTC Simulation

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

Hey, ich habe eine kleine BTC Simulation geschrieben, einfach nur zum lernen.

Das Programm soll folgendes machen:

Es wird alle 20 Sekunden der aktuelle BTC-Kurs geladen. Wenn der Kurs unter einer bestimmten Grenze ist (PRICE_TO_BUY ), soll er mit dem aktuellen Guthaben in Euro (euro_balance) so viele BTC wie möglich kaufen. Wenn der Kurs unter PRICE_TO_SELL ist, soll er alle aktuellen BTC die ich habe wieder verkaufen. Wenn der Kurs dann wieder unter die Grenze von PRICE_TO_BUY kommt wieder für das ganze Geld kaufen.

Da ich das Programm nicht richtig testen kann, wollte ich fragen ob mir einer sagen kann ob das Programm das macht was ich möchte oder ob ich ein Fehler in der Logik habe.


Code: Alles auswählen

import requests
from bs4 import BeautifulSoup
import time

HEADERS = {"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0"}
URL = "https://www.google.com/search?q=btc+kurs&ie=utf-8&oe=utf-8"
PRICE_TO_SELL = 10900
PRICE_TO_BUY = 10300

def get_current_btc_course(URL):          
    page = requests.get(URL, headers=HEADERS)
    soup = BeautifulSoup(page.content, "html.parser")
    price = soup.find(id="knowledge-currency__tgt-amount").get_text()
    converted_price = float(price.replace(".", "").replace(",","."))
    return converted_price
    
def btc_to_euro(btc):
    return btc * get_current_btc_course(URL)

def euro_to_btc(euro):
    return euro / get_current_btc_course(URL)

def buy_all_btc(euro_balance, btc_balance):
    if euro_balance > 0:
        btc_balance += euro_to_btc(euro_balance)
        euro_balance = 0
        print(f"Du hast jetzt {btc_balance} BTC")
    
def sell_all_btc(euro_balance, btc_balance):
    if btc_balance > 0:
        euro_balance += btc_to_euro(btc_balance)
        btc_balance = 0
        print(f"Du hast jetzt {euro_balance} Euro")
        
def main():
    euro_balance = 500
    btc_balance = 0
    while True:
        current_btc_course = get_current_btc_course(URL)
        print(f"Aktueller BTC-Kurs: {current_btc_course} Euro")
        if current_btc_course <= PRICE_TO_BUY:
            buy_all_btc(euro_balance, btc_balance)
        elif current_btc_course >= PRICE_TO_SELL:
            sell_all_btc(euro_balance, btc_balance)
        time.sleep(20)
        
        
if __name__ == '__main__':
    main() 
Benutzeravatar
__blackjack__
User
Beiträge: 13116
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Jankie: Dann schreibe es so um, dass Du es testen kannst. Am wenigsten invasiv wäre es die URL variabel zu machen. Dann könntest Du Dir einen kleinen Webserver, zum Beispiel mit `bottle` schreiben, der selbst generierte Kurse/Schwankungen zum testen ausliefert.

Etwas weniger aufwändig wäre es die `get_current_btc_course()`-Funktion als Argument zu übergeben. Da könnte man dann auch eine andere Funktion stattdessen übergeben, die Testkurse liefert.

Was man direkt als Fehler schon so sehen kann, ist das die `*_all_btc()`-Funktionen vielleicht auch etwas an den Aufrufer zurückgeben sollten, denn sonst machen die Zuweisungen an die lokalen `*_balance`-Variablen keinen Sinn, weil die letzlich keinen Effekt haben.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

Dann werde ich das mal Versuchen, hab auch überlegt ob ich statt get_current_btc_course() mir einfach ein random Wert immer ausgeben lasse zum testen.

Meinst du das so?

Code: Alles auswählen

def buy_all_btc(euro_balance, btc_balance):
    if euro_balance > 0:
        btc_balance += euro_to_btc(euro_balance)
        euro_balance = 0
    return euro_balance, btc_balance
    
def sell_all_btc(euro_balance, btc_balance):
    if btc_balance > 0:
        euro_balance += btc_to_euro(btc_balance)
        btc_balance = 0
    return euro_balance, btc_balance
        
def main():
    euro_balance = 500
    btc_balance = 0
    while True:
        current_btc_course = get_current_btc_course(URL)
        print(f"Aktueller BTC-Kurs: {current_btc_course} Euro")
        if current_btc_course <= PRICE_TO_BUY:
            euro_balance, btc_balance = buy_all_btc(euro_balance, btc_balance)
            print(f"Du hast jetzt {btc_balance} BTC")
        elif current_btc_course >= PRICE_TO_SELL:
            euro_balance, btc_balance = sell_all_btc(euro_balance, btc_balance)
            print(f"Du hast jetzt {euro_balance} Euro")
        time.sleep(20)
Benutzeravatar
__blackjack__
User
Beiträge: 13116
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Jankie: Bei zufälligen Werten muss da ja zufällig eine Reihenfolge heraus kommen zu dem was Du testen willst.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

Also ich hab es jetzt mal so getestet, ich wollte eigentlich nur ausprobieren ob die Logik so funktioniert wie ich es mir vorstelle. Wenn ich richtig gedacht habe, dürfte man ja damit nie unter die 500 kommen, die ich zum start bei

Code: Alles auswählen

euro_balance = 500
festgelegt habe. Er kauft ja nur unter einer Grenze und verkauft nur, wenn der Kurs über einer bestimmten Grenze ist, allerdings fällt er manchmal unter die 500. Habe da wohl irgendwo einen Denkfehler drin.


So hab ich getestet:

Code: Alles auswählen

import requests
from bs4 import BeautifulSoup
import time

import random

HEADERS = {"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0"}
URL = "https://www.google.com/search?q=btc+kurs&ie=utf-8&oe=utf-8"
PRICE_TO_SELL = 11300
PRICE_TO_BUY = 10500
course_to_test = [11500,11865,11360,10201,10120,10465,10530,10480,10580,10630,10690,10820,10960,10650,10780,10990,11090,11180,11260,11250,11280,11310,11350,11290]


#def get_current_btc_course(URL):          
#    page = requests.get(URL, headers=HEADERS)
#    soup = BeautifulSoup(page.content, "html.parser")
#    price = soup.find(id="knowledge-currency__tgt-amount").get_text()
#    converted_price = float(price.replace(".", "").replace(",","."))
#    return converted_price



def get_current_btc_course(URL):
    return random.choice(course_to_test)
        
    
def btc_to_euro(btc):
    return btc * get_current_btc_course(URL)

def euro_to_btc(euro):
    return euro / get_current_btc_course(URL)

def buy_all_btc(euro_balance, btc_balance):
    if euro_balance > 0:
        btc_balance += euro_to_btc(euro_balance)
        euro_balance = 0
    return euro_balance, btc_balance
    
def sell_all_btc(euro_balance, btc_balance):
    if btc_balance > 0:
        euro_balance += btc_to_euro(btc_balance)
        btc_balance = 0
    return euro_balance, btc_balance
        
def main():
    euro_balance = 500
    btc_balance = 0
    while True:
        current_btc_course = get_current_btc_course(URL)
        print(f"Aktueller BTC-Kurs: {current_btc_course} Euro")
        if current_btc_course <= PRICE_TO_BUY and euro_balance > 0:
            euro_balance, btc_balance = buy_all_btc(euro_balance, btc_balance)
            print(f"Du hast jetzt {btc_balance} BTC")
        elif current_btc_course >= PRICE_TO_SELL and btc_balance > 0:
            euro_balance, btc_balance = sell_all_btc(euro_balance, btc_balance)
            print(f"Du hast jetzt {euro_balance} Euro")
        time.sleep(0.5)
        
if __name__ == '__main__':
    main()     
Benutzeravatar
__blackjack__
User
Beiträge: 13116
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Jankie: Das Problem liegt daran, dass Du den aktuellen Kurs holst um zu entscheiden was Du tust. Und bei der Aktion holst Du wieder den aktuellen Kurs um den Tausch zu vollziehen. Das ist auch richtig so, und es passiert genau das was Dir auch real passieren kann: Zwischen dem Zeitpunkt wo Du entscheidest was Du tun möchtest und dem Zeitpunkt wo Du es tatsächlich tust, kann sich der Kurs geändert haben.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

Ahhhhhhh, jetzt hats klick gemacht. Also muss ich den current_btc_course auch mit in die Funktionen btc_to_euro und euro_to_btc übergeben. Das Programm soll ja auch niemals mit echtem Geld irgendwas machen, ist eher eine kleine Spielerrei gewesen um mich bisschen mit Web Scraping mal auseinander zu setzen. Danke für die Hilfe!
Benutzeravatar
__blackjack__
User
Beiträge: 13116
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Jankie: Nein, eigentlich machst Du da fast alles richtig, denn der Kurs kann sich zwischen diesen beiden Zeitpunkten ja real ändern und wenn man das ”in echt” anwenden will, dann sollte man diesen Fall und diese Ungenauigkeit auch irgendwie in die Entscheidung mit hinein nehmen, und selbst dann kann man nicht 100%ig garantieren dass man nicht auch Verlust machen kann. Das ist vielleicht die wichtigste Erkenntnis die man aus diesem Test/Spiel mitnehmen kann.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

Quasi habe ich ausversehen einen Fehler gemacht, der die Simulation realer erscheinen lässt. Auch nicht schlecht.
Aber ich meine mit Fehler dass es sich anders verhält als es meine Erwartung war bzw. wie ich es angedacht habe.
Antworten