――Wenn ich im Internet surfte, fand ich eine Seite, die sehr hilfreich für Systre war.
Verstehe auch in der Literatur! Erste Schritte mit dem automatisierten BOT-Handel von Bitcoin ――Es wurde auf sehr leicht verständliche Weise erklärt ――Ich habe das Gefühl, dass ich es schaffen kann, auch wenn ich keine Erfahrung mit Systre habe. ――Ich war interessiert, also habe ich beschlossen, am Wochenende einen Code zu schreiben, um das Gefühl zu überprüfen.
Github Dies ist der Code, den ich dieses Mal geschrieben habe. (Notizbuchformat)
Übrigens Herausforderung, virtuelle Währung durch LSTM vorherzusagen hat es nicht sehr gut funktioniert. ――Dieses Mal habe ich einen einfachen Algorithmus mit gleitenden Durchschnittslinien geschrieben, ohne plötzlich zum maschinellen Lernen zu springen.
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
--Cryptwatch scheint in der Lage zu sein, bis zu 6000 Daten von den neuesten zu sammeln.
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
――Ich werde es erweitern
--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
In dem Moment, in dem die kurzfristige Linie die langfristige Linie kreuzt und unter SELL fällt
Stellen Sie zunächst Ihren eigenen JPY und BitCoin ein und wiederholen Sie den Kauf und Verkauf basierend auf Argo. ――Es handelt sich um eine Spielerspezifikation, die alle Ihre JPY- und BitCoin-Assets in jede Transaktion einbezieht.
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
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()
―― Ab dem Startpunkt von 10.000 Yen hat es sich mehr als verdreifacht, und es scheint unerwartet zu funktionieren.
»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