[PYTHON] Ich habe am Wochenende versucht, mit Bitcoin Systre zu beginnen

Hintergrund

――Wenn ich im Internet surfte, fand ich eine Seite, die sehr hilfreich für Systre war.

Was du getan hast

1. Rufen Sie Bitcoin-Daten von der CryptWatch-API ab

import json
import requests
import pandas as pd
import datetime
from pprint import pprint
import time

class PriceGetterCryptwatch():
#Unterlassung
    def get_price(self, periods, after=None, before=None, exchange="bitflyer", currency="btcjpy"):
        """
        input
        periods:Zyklus 86400 für täglich
        after:Holen Sie sich mit unixTime ein Diagramm nach dem anderen
        before:Holen Sie sich vorher ein Diagramm mit unixTime
        exchange:Virtueller Geldwechsel
        currency:Währungspaar

        output
API-Ergebnisse:JSON-Format
        """
        url = "https://api.cryptowat.ch/markets/"+exchange+"/"+currency+"/ohlc?periods="+str(periods)

        if after:
            after=int(after)
            url += "&after=" + str(after)
        elif before:
            before=int(before)
            url += "&before=" + str(before)

        print(url)
        responce = requests.request("GET", url)
        return responce.json()

    def apidata_to_dataframe(self, data, periods):
        """
        [ CloseTime , OpenPrice , HighPrice , LowPrice , ClosePrice , Volume]
        [Datum (und Uhrzeit,Offener Preis,Hoher Preis,Niedriger Preis,Schlusskurs,Volumen]
        """
        #Da die letzte Spalte unbekannt ist, löschen Sie sie vorerst
        df = pd.DataFrame(data["result"][str(periods)],columns=[ "CloseTime" , "OpenPrice" , "HighPrice" , "LowPrice" , "ClosePrice" , "Volume", "None"])
        df = df.drop("None", axis=1)
        #Konvertieren Sie die Unix-Zeit in Echtzeit
        df["CloseTime"] = df["CloseTime"].map(self.unixtime_to_datetime)
        return df

Vergangene Daten speichern

--Cryptwatch scheint in der Lage zu sein, bis zu 6000 Daten von den neuesten zu sammeln.

Funktion

def save_data(periods):
    getter = PriceGetterCryptwatch()
    date = getter.datetime_to_obj(2017,1,1)
    date = getter.datetime_to_unixtime(date)

    # designate start date
    data = getter.get_price(periods, after=date)
    df = getter.apidata_to_dataframe(data, periods)

    start_time = (df["CloseTime"].iloc[0])
    last_time = (df["CloseTime"].iloc[-1]) # unixtime
    filename = str(start_time) + " - " + str(last_time)  + "period " + str(periods)
    filename += ".csv"
    filename = filename.replace(":", "-")

    df.to_csv(filename, index=False, float_format="%.6f")

def update_data(old_filename, periods):
    df_old = pd.read_csv(old_filename)
    old_size = df_old.shape[0]

    # get new data
    getter = PriceGetterCryptwatch()
    date = getter.datetime_to_obj(2018,1,1)
    date = getter.datetime_to_unixtime(date)

    # designate start date
    data = getter.get_price(periods,after=date)
    df = getter.apidata_to_dataframe(data, periods)
    
    df_temp = pd.concat([df_old, df], axis=0)
    df_temp["CloseTime"] = pd.to_datetime(df_temp["CloseTime"]) 
    df_save = df_temp.drop_duplicates(subset="CloseTime")
    df_save = df_save.sort_values("CloseTime")
    df_save = df_save.reset_index(drop=True)
    new_size = df_save.shape[0] - old_size

    if new_size > 0:
        print("NewData : {}".format(new_size))

        start_time = df_save["CloseTime"].iloc[0]
        last_time = df_save["CloseTime"].iloc[-1] # unixtime
        filename = str(start_time) + " - " + str(last_time)  + "period " + str(periods)
        filename += ".csv"
        filename = filename.replace(":", "-")

        dir_name = os.path.dirname(old_filename)
        filename = os.path.join(dir_name, filename)
        df_save.to_csv(filename, index=False, float_format="%.6f")
    else:
        print("NewData None")

--Ausführen

    PERIOD_1MIN = 60
    FILENAME_OLD_1MIN = "./Data/2019-11-06 12-45-00 - 2019-11-11 09-03-00period 60.csv"
    update_data(FILENAME_OLD_1MIN, PERIOD_1MIN)

--Ergebnis

https://api.cryptowat.ch/markets/bitflyer/btcjpy/ohlc?periods=60&after=1514732400
NewData : 258
CloseTime,OpenPrice,HighPrice,LowPrice,ClosePrice,Volume
2019-11-06 12:45:00,1013343,1013343,1013343,1013343,0.090000
2019-11-06 12:46:00,1013343,1013622,1012862,1013091,2.730759
2019-11-06 12:47:00,1013375,1013839,1013345,1013345,1.170000
...

2019-11-11 13:26:00,981670,982509,981670,982509,0.778839
2019-11-11 13:27:00,982489,982489,982003,982003,0.205953
2019-11-11 13:28:00,982052,982052,982052,982052,0.010000

2. Handelssimulation

BitCoin-Preisdiagramm (4 Stunden und gleitende Durchschnitte (12h, 20h))

スクリーンショット 2019-11-11 13.34.02.png

――Ich werde es erweitern

スクリーンショット 2019-11-11 13.39.36.png

Implementierung des Handelsalgorithmus

--Erstellte eine grundlegende Klasse für den Kauf und Verkauf von Teilen und erbte sie, um ein Handelsalgo zu schaffen ――Der Moment, in dem die kurzfristige Linie die langfristige Linie überschreitet und BUY überschreitet

class TradeBase():
#Unterlassung

    def __init__(self, jpy_asset, bitcoin_asset, period):
        self.jpy_asset = jpy_asset
        self.bitcoin_asset = bitcoin_asset
        self.period = period
        self.df = None

    def buy_coin(self, bitcoin_price, jpy_asset, bitcoin_asset, jpy_buy_amount=None):
        """
Zum Backtesting
        """
        if jpy_buy_amount == None:
            jpy_buy_amount = jpy_asset

        bitcoin_buy_amount = jpy_buy_amount / bitcoin_price
        
        new_jpy_asset =  jpy_asset-jpy_buy_amount
        new_bitcoin_asset =  bitcoin_asset+bitcoin_buy_amount
        
        return new_jpy_asset, new_bitcoin_asset
        
    def sell_coin(self, bitcoin_price, jpy_asset, bitcoin_asset, bitcoin_sell_amount=None):
        """
Zum Backtesting
        """
        if bitcoin_sell_amount== None:
            bitcoin_sell_amount = bitcoin_asset

        jpy_sell_amount = bitcoin_price * bitcoin_sell_amount
        
        new_jpy_asset =  jpy_asset + jpy_sell_amount
        new_bitcoin_asset =  bitcoin_asset-bitcoin_sell_amount
        
        return new_jpy_asset, new_bitcoin_asset


class TradeWithMovingAverage(TradeBase):
    """
Beim Kauf und Verkauf nur an der Schnittstelle zweier Arten von gleitendem Durchschnitt
    """
    def __init__(self, jpy_asset, bitcoin_asset, period, period_ma_type1, period_ma_type2):
        super().__init__(jpy_asset, bitcoin_asset, period)
        self.period_ma_type1 = period_ma_type1
        self.period_ma_type2 = period_ma_type2
        self.rolling_win_type1 = int(period_ma_type1 / period)
        self.rolling_win_type2 = int(period_ma_type2 / period)
        # for trade func
        self.prev_mean_type1 = None
        self.prev_mean_type2 = None
        self.jpy_asset_result = []
        self.data = None
    
    def judge_sell_or_buy(self, new_mean_fast, prev_mean_fast, new_mean_slow, prev_mean_slow):
        """
Beurteilung des Kaufs und Verkaufs anhand der gleitenden Durchschnittslinie
        """
        if prev_mean_fast > prev_mean_slow:
            if new_mean_fast < new_mean_slow:
                return "SELL"
            else:
                return "NOTHING"

        elif prev_mean_fast < prev_mean_slow:
            if new_mean_fast > new_mean_slow:
                return "BUY"
            else:
                return "NOTHING"
        else:
            return "NOTHING"
        
    def trade(self, init_var=True):

        if self.data is None:
            print(" Data is None")
            return
        
        if init_var:
            self.prev_mean_type1 = None
            self.prev_mean_type2 = None
            self.jpy_asset_result = []

        mean_type1 = None
        mean_type2 = None
        
        last_sell_jpyasset = None
        for i, value in enumerate(self.data):
            # Average
            if i > self.rolling_win_type1:
                mean_type1 = self.data.iloc[int(i-self.rolling_win_type1):i].mean()

            if i > self.rolling_win_type2:
                mean_type2 = self.data.iloc[int(i-self.rolling_win_type2):i].mean()
            
            if mean_type1 is None or mean_type2 is None:
                self.jpy_asset_result.append(self.jpy_asset)
                continue
            
            # Trade
            bitcoin_price = value
            if self.prev_mean_type1 and self.prev_mean_type2:
                judge = self.judge_sell_or_buy(mean_type1, self.prev_mean_type1,
                    mean_type2, self.prev_mean_type2)
                
                if judge == "SELL":
                    if self.bitcoin_asset > 0:
                        self.jpy_asset, self.bitcoin_asset = self.sell_coin(bitcoin_price, self.jpy_asset, self.bitcoin_asset)
                        last_sell_jpyasset = self.jpy_asset

                elif judge == "BUY":
                    if self.jpy_asset > 0:
                        self.jpy_asset, self.bitcoin_asset = self.buy_coin(bitcoin_price, self.jpy_asset, self.bitcoin_asset, jpy_buy_amount=self.jpy_asset)

                else:
                    pass

            self.prev_mean_type1 = mean_type1
            self.prev_mean_type2 = mean_type2
            self.jpy_asset_result.append(self.jpy_asset)
            
        self.last_sell_jpyasset = last_sell_jpyasset
        print("Result: Jpy{:.1f} bitcoin{:.4f} (LAST JPY: {})".format(self.jpy_asset, self.bitcoin_asset, self.last_sell_jpyasset))
        return self.jpy_asset, self.bitcoin_asset

Ausführungsergebnis

jpy = 10000
bitcoin = 0
period = 60*60*4    #4 Stunden

trader = TradeWithMovingAverage(jpy_asset=jpy, bitcoin_asset=bitcoin, period=period,
                                period_ma_type1=period*3, period_ma_type2=period*5)
#Datensatz(Handbuch)
trader.df = df
trader.data = df["ClosePrice"]
trader.trade()
trader.show_trade_result()

Vermögensübergang (japanischer Yen)

―― Ab dem Startpunkt von 10.000 Yen hat es sich mehr als verdreifacht, und es scheint unerwartet zu funktionieren.

スクリーンショット 2019-11-11 13.52.02.png スクリーンショット 2019-11-11 14.04.50.png

3. Eindrücke

»Mir war klar, dass der mechanische Handel ohne Vorurteile stabiler zu sein scheint als der Mensch. »Ich bin froh, dass ich ein Gefühl dafür habe, einen Handelsalgorithmus zu entwickeln. ――Ich denke, wir werden Verbesserungen vornehmen, die andere Indikatoren berücksichtigen. ――Es scheint, dass die Verwendung in der Praxis viel Zeit in Anspruch nehmen wird.

Recommended Posts

Ich habe am Wochenende versucht, mit Bitcoin Systre zu beginnen
Ich habe versucht, mit Hy anzufangen
Ich habe versucht, mit Blenders Python script_Part 01 zu beginnen
Ich habe versucht, mit Blenders Python script_Part 02 zu beginnen
Ich habe versucht, mit Hy ・ Define a class zu beginnen
[Python] Ein Memo, das ich versucht habe, mit Asyncio zu beginnen
Der einfachste Weg, um mit Django zu beginnen
Ich habe versucht, die Daten mit Zwietracht zu speichern
Ich habe versucht, CloudWatch-Daten mit Python abzurufen
Ich habe versucht, mit tkinter mit dem Taschenrechner zu spielen
Ich habe versucht, den Authentifizierungscode der Qiita-API mit Python abzurufen.
Ich habe es mit den Top 100 PyPI-Paketen versucht.> Ich habe versucht, die auf Python installierten Pakete grafisch darzustellen
Ich habe versucht, die Filminformationen der TMDb-API mit Python abzurufen
Ich habe versucht, Mine Sweeper auf dem Terminal mit Python zu implementieren
Ich habe versucht, eine CSV-Datei mit Python zu berühren
Ich habe versucht, Soma Cube mit Python zu lösen
Ich habe versucht, das Problem mit Python Vol.1 zu lösen
Ich möchte mit dem Linux-Kernel beginnen. Wie ist die Listenkopfstruktur?
Ich habe versucht, die Entropie des Bildes mit Python zu finden
Ich habe versucht zu simulieren, wie sich die Infektion mit Python ausbreitet
Ich habe versucht, die Emotionen des gesamten Romans "Wetterkind" zu analysieren
Ich habe versucht, die Standortinformationen des Odakyu-Busses zu erhalten
Memo, um den Wert auf der HTML-Javascript-Seite mit Jupiter zu erhalten
Ich habe versucht, mit TensorFlow den Durchschnitt mehrerer Spalten zu ermitteln
Ich habe versucht, die Zugverspätungsinformationen mit LINE Notify zu benachrichtigen
Mindestkenntnisse, um mit dem Python-Protokollierungsmodul zu beginnen
Ich habe versucht, das Python-Skript unter Windows 10 von 2.7.11 auf 3.6.0 zu ändern
Ich habe versucht, den Ipython-Cluster unter AWS auf das Minimum zu starten
Ich habe versucht, verschiedene Informationen von der Codeforces-API abzurufen
Link, um mit Python zu beginnen
Erste Schritte mit MicroPython (unter macOS)
Wie fange ich mit Scrapy an?
Erste Schritte mit Python
Wie fange ich mit Django an?
Ich habe versucht, den Ball zu bewegen
Ich habe versucht, den Abschnitt zu schätzen.
[Shell-Start] Ich habe versucht, die Shell mit einem billigen Linux-Board-G-Cluster auf dem Fernseher anzuzeigen
Ich habe versucht, den Datenverkehr mit WebSocket in Echtzeit zu beschreiben
Ich habe versucht, die Anfängerausgabe des Ameisenbuchs mit Python zu lösen
Erste Schritte mit dem Python-Framework Django unter Mac OS X.
Ich habe versucht, den Index der Liste mithilfe der Aufzählungsfunktion abzurufen
Ich habe versucht, die Bewässerung des Pflanzgefäßes mit Raspberry Pi zu automatisieren
Ein Memorandum beim automatischen Erwerb mit Selen
Ich habe eine Kreuzvalidierung basierend auf dem Rastersuchergebnis mit scikit-learn versucht
Ich habe ein Skript geschrieben, mit dem Sie mit hoher Geschwindigkeit mit AtCoder beginnen können!
Ich habe versucht, das Bild mit OpenCV im "Skizzenstil" zu verarbeiten
Ich habe versucht, den auf Papier gestempelten Stempel mit OpenCV zu digitalisieren
Ich habe versucht, einen Sender auf der IoT-Plattform "Rimotte" zu registrieren.
Ich habe versucht, die GUI auf einem Mac mit X Window System anzuzeigen
Ich habe versucht, das Bild mit OpenCV im "Bleistift-Zeichenstil" zu verarbeiten
Ich habe versucht, die Größe des logischen Volumes mit LVM zu erweitern
Ich habe versucht, alle Bemerkungen von Slack mit Wordcloud (Python) zusammenzufassen.
Ich habe versucht, die Effizienz der täglichen Arbeit mit Python zu verbessern
PhytoMine-I hat versucht, mit Python die genetischen Informationen der Pflanze zu erhalten
Schritt Notizen, um mit Django zu beginnen
Ich habe versucht, Autoencoder mit TensorFlow zu implementieren
Ich habe versucht, den Befehl umask zusammenzufassen