Mein Name ist Masukawa (https://www.facebook.com/ryozodesert) und ich bin Praktikant bei Smart Trade Co., Ltd.. .. Ich studiere maschinelles Lernen.
Smart Trade Co., Ltd.
Finanzdemokratie
Basierend auf dieser Philosophie haben wir "QuantX Factory" entwickelt, eine Plattform, auf der jeder problemlos Handelsalgorithmen entwickeln kann.
In meinem ersten Monat als Praktikant werde ich erklären, wie man die Pandas- und Talib-Methoden verwendet, die häufig bei der Erstellung von Algorithmen verwendet werden, um grundlegende technische Indikatoren wie MACD, gleitende Durchschnitte und RSI zu implementieren.
(Hinweis: Sie müssen den Inhalt dieses Codes derzeit nicht vollständig verstehen.) </ font>
#Bibliotheksimport
#Erforderliche Bibliothek
#Backtest Engine "maron" importieren
import maron
import maron.signalfunc as sf
import maron.execfunc as ef
#Zusätzliche Bibliothek
#Wenn Sie zusätzliche Bibliotheken benötigen, fügen Sie diese gemäß dem folgenden Beispiel hinzu.
#Importieren Sie das Datenanalysetool "pandas" und verwenden Sie es unter dem Namen "pd".
import pandas as pd
#Importieren Sie den Finanzfunktionssatz "talib" und verwenden Sie ihn mit dem Namen "ta"
import talib as ta
import numpy as np
#Importieren Sie "" und verwenden Sie es als ""
# import as
#Bestellmethode(Bitte kommentieren Sie nur eine der folgenden drei entsprechend der gewünschten Bestellmethode aus)
# ot = maron.OrderType.MARKET_CLOSE #Bestellung zum Zeitpunkt des Schlusskurses am Tag nach Signalausgabe
ot = maron.OrderType.MARKET_OPEN #Bestellung zum Zeitpunkt des Eröffnungskurses am Tag nach Signalausgabe
# ot = maron.OrderType.LIMIT #Bestellung begrenzen
def initialize(ctx): #Initialisierungsteil
ctx.logger.debug("initialize() called") #Protokollausgabe
ctx.target = 0.1
ctx.loss_cut = -0.02
ctx.plofit = 0.05
ctx.configure(
channels={
"jp.stock": {
"symbols": [
"jp.stock.2914", #JT(Japanische Tabakindustrie)
"jp.stock.8766", #Tokio Marine Holdings
"jp.stock.8031", #Mitsui Bussan
"jp.stock.8316", #Sumitomo Mitsui Financial Group
"jp.stock.8411", #Mizuho Financial Group
"jp.stock.9437", #NTT Docomo
"jp.stock.4502", #Takeda Pharmazeutische Industrie
"jp.stock.8058", #Mitsubishi Corporation
"jp.stock.9433", #KDDI
"jp.stock.9432", #Nippon Telecom Telefon
"jp.stock.7267", #Honda (Honda Giken Kogyo)
"jp.stock.8306", #Mitsubishi UFJ Financial Group
"jp.stock.4503", #Astellas Pharmaceutical
"jp.stock.4063", #Shinetsu Chemische Industrie
"jp.stock.7974", #Nintendo
"jp.stock.6981", #Murata Seisakusho
"jp.stock.3382", #Seven & i Holdings
"jp.stock.9020", #East Japan Passagierbahn
"jp.stock.8802", #Mitsubishi Estate
"jp.stock.9022", #Tokai Passagierbahn
"jp.stock.9984", #Softbank Group
"jp.stock.6861", #Keyence
"jp.stock.6501", #Hitachi, Ltd.
"jp.stock.6752", #Panasonic
"jp.stock.6758", #Sony
"jp.stock.6954", #Fanac
"jp.stock.7203", #Toyota Motor
"jp.stock.7751", #Kanon
"jp.stock.4452", #Kao
"jp.stock.6098", #Rekrutieren Sie Beteiligungen
],
#⑥
"columns": ["close_price_adj", #Schlusskurs(Nach Bereinigung um Aktiensplit)
]}})
def _my_signal(data): #Kauf und Verkauf von Signalerzeugungsteilen
#Wenn Sie den Inhalt der Daten überprüfen möchten, kommentieren Sie dies bitte unten aus
# ctx.logger.debug(data)
syms = data.minor_axis #Bestandsliste erstellen
dates = data.major_axis #Datumsliste erstellen
'''↓ Schreiben Sie den Code, um die für die Logikberechnung erforderlichen Daten aus den Daten der 3D-Struktur zu erhalten. ↓'''
cp = data["close_price_adj"].fillna("ffill")
'''↑ Schreiben Sie den Code, um die für die Logikberechnung erforderlichen Daten aus den Daten der 3D-Struktur zu erhalten. ↑'''
'''↓ Schreiben Sie den Code, um die Logik zu berechnen, die zur Definition der Handelsbedingungen erforderlich ist. ↓'''
movave5 = cp.rolling(window = 5, center = False).mean()
movave25 = cp.rolling(window = 25, center = False).mean()
'''↑ Schreiben Sie den Code, um die Logik zu berechnen, die zum Definieren der Handelsbedingungen erforderlich ist. ↑'''
#Definieren Sie Kauf- und Verkaufssignale(Rückgabe als Bool-Wert)
buy_sig = (movave5 > movave25) & (movave5.shift(1) < movave25.shift(1))
sell_sig = (movave5 < movave25) & (movave5.shift(1) > movave25.shift(1))
# market_Alle 0 genannt sig.Erstellen Sie einen Datenrahmen mit dem Namen "horizontal: Markenname, vertikal: Datum", in dem 0 gespeichert ist
market_sig = pd.DataFrame(data=0.0, columns=syms, index=dates)
# buy_1, wenn sig True ist.0、sell_Wenn sig wahr ist-1.0, 0, wenn beide wahr sind.Auf 0 setzen
market_sig[buy_sig == True] = 1.0
market_sig[sell_sig == True] = -1.0
market_sig[(buy_sig == True) & (sell_sig == True)] = 0.0
# market_Wenn Sie den Inhalt von sig überprüfen möchten, kommentieren Sie dies bitte unten aus
# ctx.logger.debug(market_sig)
return {
"buy:sig":buy_sig,
"sell:sig": sell_sig,
"market:sig": market_sig,
#Bitte fügen Sie die Daten, die Sie anzeigen möchten, in die unten stehende Backtest-Ergebnistabelle ein
}
ctx.regist_signal("my_signal", _my_signal) #Signalregistrierung
def handle_signals(ctx, date, current): #Täglicher Verarbeitungsteil
'''
current: pd.DataFrame
'''
#initialisieren_my_Vermarkten Sie das durch das Signal erzeugte Signal_In Sig
market_sig = current["market:sig"]
done_syms = set([]) #Legen Sie den Typ fest, in dem Aktien gespeichert werden, für die eine Gewinnabrechnung und eine Verlustkürzung durchgeführt wurden
none_syms = set([]) # portfolio.Legen Sie den Typ fest, in dem Marken gespeichert werden, die an Positionen nicht vorhanden sind
# portfolio.positions(Marken, die Sie besitzen)Zielaktien(sym)Überprüfen Sie, ob es gibt
for (sym, val) in market_sig.items():
if sym not in ctx.portfolio.positions:
none_syms.add(sym)
# portfolio.positions(Marken, die Sie besitzen)Jede Marke von(sym)Überprüfen Sie, ob die Anzahl der von gehaltenen Aktien
for (sym, val) in ctx.portfolio.positions.items():
if val["amount"] == 0:
none_syms.add(sym)
#Verlustkürzung, Gewinnabrechnung(Rentabilität)Einstellungen von
#Iterativer Prozess, um die Aktien, die Sie besitzen, einzeln zu überprüfen
for (sym, val) in ctx.portfolio.positions.items():
#Erwerb des Gewinn-Verlust-Verhältnisses
returns = val["returns"]
if returns < -0.03: #Gewinn-Verlust-Verhältnis-3%Weniger als(Absolutwert 3%Größerer Verlust)Im Falle von
#Verkaufsauftrag zur Verlustreduzierung
sec = ctx.getSecurity(sym)
sec.order(-val["amount"], comment="Verlustschnitt(%f)" % returns)
#Das Problem, das sym zugewiesen wurde, wurde dem festgelegten Typ hinzugefügt, in dem das Problem gespeichert ist, für das eine Gewinnabrechnung und eine Verlustkürzung durchgeführt wurden.
done_syms.add(sym)
elif returns > 0.05: #Gewinn-Verlust-Verhältnis+5%Wenn größer als
#Gewinnmitnahme(Rentabilität)Bestellung verkaufen für
sec = ctx.getSecurity(sym)
sec.order(-val["amount"], comment="Gewinnmitnahmeverkauf(%f)" % returns)
#Das Problem, das sym zugewiesen wurde, wurde dem festgelegten Typ hinzugefügt, in dem das Problem gespeichert ist, für das eine Gewinnabrechnung und eine Verlustkürzung durchgeführt wurden.
done_syms.add(sym)
buy = market_sig[market_sig > 0.0] #Signal kaufen
for (sym, val) in buy.items(): #Verarbeiten Sie Aktien mit Kaufsignalen nacheinander
# done_syms oder keine_Wenn syms sym hat
if sym in done_syms:
continue #Verarbeitung überspringen
#Bestellung kaufen
sec = ctx.getSecurity(sym)
sec.order(sec.unit() * 1, orderType=ot, comment="SIGNAL BUY")
#Wenn Sie das unten stehende Kaufauftragsprotokoll ausgeben möchten, kommentieren Sie dies bitte unten aus(Langfristige Vorsicht)
#ctx.logger.debug("BUY: %s, %f" % (sec.code(), val))
sell = market_sig[market_sig < 0.0] #Signal verkaufen
for (sym, val) in sell.items(): #Verarbeiten Sie Aktien mit Verkaufssignalen nacheinander
# done_syms oder keine_Wenn syms sym hat
if (sym in done_syms) | (sym in none_syms):
continue #Verarbeitung überspringen
#Bestellung verkaufen
sec = ctx.getSecurity(sym)
sec.order(sec.unit() * -1,orderType=ot, comment="SIGNAL SELL")
Abbildung 1: Algorithmus unter Verwendung des goldenen Kreuzes und des toten Kreuzes der gleitenden Durchschnittslinie (siehe: https://factory.quantx.io/developer/149d79a8cf744f059af0e96918913a9f/coding / Kodierung))
pd.DataFrame.rolling(window)
Beispiel: Implementieren Sie einen gleitenden 25-Tage-Durchschnitt
In Zeile 82 von FIG.
movave25 = cp.rolling(window = 25).mean()
Es heißt, aber das ist es, was den gleitenden 25-Tage-Durchschnitt definiert.
Sie haben jetzt move25, einen DataFrame, in dem gleitende Durchschnittswerte für 25 Tage gespeichert werden.
pandas.DataFrame.shift(periods)
Beispiel: Beurteilung des goldenen Kreuzes und des toten Kreuzes
In Zeile 87 von FIG.
buy_sig = (movave5 > movave25) & (movave5.shift(1) < movave25.shift(1))
Dieser Code gibt jedoch an, dass "der gleitende 5-Tage-Durchschnitt des Tages größer als der gleitende 25-Tage-Durchschnitt und der gleitende 5-Tage-Durchschnitt des vorherigen Tages kleiner als der gleitende 25-Tage-Durchschnitt ist", dh ein goldenes Kreuz. Ich bin. Linie 88 ist das Gegenteil.
Auf diese Weise wird die Verschiebungsmethode verwendet.
Eine Bibliothek, mit der Sie technische Indikatoren einfach implementieren können. Unter der folgenden URL finden Sie die Indikatoren, die implementiert werden können. https://mrjbq7.github.io/ta-lib/funcs.html
# Sample Algorithm
#Bibliotheksimport
#Erforderliche Bibliothek
import maron
import maron.signalfunc as sf
import maron.execfunc as ef
#Zusätzliche Bibliothek
#In den Hinweisen auf dem rechten Bildschirm finden Sie die Bibliotheken, die verwendet werden können ①
import pandas as pd
import talib as ta
import numpy as np
#Bestellmethode(Bitte kommentieren Sie nur eine der beiden folgenden entsprechend der gewünschten Bestellmethode aus)
#Die Bestellmethode finden Sie im Hinweis auf dem rechten Bildschirm ②
#ot = maron.OrderType.MARKET_CLOSE #Bestellung zum Zeitpunkt des Schlusskurses am Tag nach Signalausgabe
ot = maron.OrderType.MARKET_OPEN #Bestellung zum Zeitpunkt des Eröffnungskurses am Tag nach Signalausgabe
#ot = maron.OrderType.LIMIT #Bestellung begrenzen
#Erwerb von Aktien und Spalten
#Die Bezeichnung der Marke ③ entnehmen Sie bitte dem Hinweis auf dem rechten Bildschirm
#Bitte beachten Sie den Hinweis auf dem rechten Bildschirm, um Spalten zu erhalten ④
def initialize(ctx):
#Aufbau
ctx.logger.debug("initialize() called")
ctx.configure(
channels={ #Kanal verwendet
"jp.stock": {
"symbols": [
"jp.stock.2914", #JT(Japanische Tabakindustrie)
"jp.stock.8766", #Tokio Marine Holdings
"jp.stock.8031", #Mitsui Bussan
"jp.stock.8316", #Sumitomo Mitsui Financial Group
"jp.stock.8411", #Mizuho Financial Group
"jp.stock.9437", #NTT Docomo
"jp.stock.4502", #Takeda Pharmazeutische Industrie
"jp.stock.8058", #Mitsubishi Corporation
"jp.stock.9433", #KDDI
"jp.stock.9432", #Nippon Telecom Telefon
"jp.stock.7267", #Honda (Honda Giken Kogyo)
"jp.stock.8306", #Mitsubishi UFJ Financial Group
"jp.stock.4503", #Astellas Pharmaceutical
"jp.stock.4063", #Shinetsu Chemische Industrie
"jp.stock.7974", #Nintendo
"jp.stock.6981", #Murata Seisakusho
"jp.stock.3382", #Seven & i Holdings
"jp.stock.9020", #East Japan Passagierbahn
"jp.stock.8802", #Mitsubishi Estate
"jp.stock.9022", #Tokai Passagierbahn
"jp.stock.9984", #Softbank Group
"jp.stock.6861", #Keyence
"jp.stock.6501", #Hitachi, Ltd.
"jp.stock.6752", #Panasonic
"jp.stock.6758", #Sony
"jp.stock.6954", #Fanac
"jp.stock.7203", #Toyota Motor
"jp.stock.7751", #Kanon
"jp.stock.4452", #Kao
"jp.stock.6098", #Rekrutieren Sie Beteiligungen
],
"columns": [
"close_price", #Schlusskurs
"close_price_adj", #Schlusskurs(Nach Bereinigung um Aktiensplit)
#"volume_adj", #Volumen
#"txn_volume", #Handelspreis
]
}
}
)
#Signaldefinition
def _my_signal(data):
#Erhalten Sie Schlusskursdaten
cp=data["close_price_adj"].fillna(method="ffill")
syms = data.minor_axis #Bestandsliste erstellen
dates = data.major_axis #Datumsliste erstellen
#Wo werden Daten gespeichert?
macd = pd.DataFrame(data=0.0, columns=syms, index=dates)
macdsignal = pd.DataFrame(data=0.0, columns=syms, index=dates)
macdhist = pd.DataFrame(data=0.0, columns=syms, index=dates)
rsi = pd.DataFrame(data = 0.0, columns = syms, index = dates)
#TA-Berechnung des MACD durch Lib
for (sym,val) in cp.items():
macd[sym],macdsignal[sym],macdhist[sym] = ta.MACD(cp[sym])
rsi[sym] = ta.RSI(cp[sym].values.astype(np.double), timeperiod = 10)
macd_golden = (macd > macdsignal) & (macd.shift(1) < macdsignal.shift(1))
macd_dead = (macd < macdsignal) & (macd.shift(1) > macdsignal.shift(1))
#Kauf und Verkauf von Signalerzeugungsteilen
buy_sig = macd_golden | (rsi < 30)
sell_sig = macd_dead | (rsi > 70)
#market_Erstellen Sie einen Datenrahmen namens sig, der alle Nullen enthält
market_sig = pd.DataFrame(data=0.0, columns=syms, index=dates)
#buy_1, wenn sig True ist.0、sell_Wenn sig wahr ist-1.Auf 0 setzen
market_sig[buy_sig == True] = 1.0
market_sig[sell_sig == True] = -1.0
market_sig[(buy_sig == True) & (sell_sig == True)] = 0.0
# ctx.logger.debug(market_sig)
return {
"MACD:g2": macd,
"MACDSignal:g2": macdsignal,
"MACDHist": macdhist,
"market:sig": market_sig,
}
#Signalregistrierung
ctx.regist_signal("my_signal", _my_signal)
def handle_signals(ctx, date, current): #Täglicher Verarbeitungsteil
'''
current: pd.DataFrame
'''
#initialisieren_my_Vermarkten Sie das durch das Signal erzeugte Signal_In Sig
market_sig = current["market:sig"]
done_syms = set([]) #Legen Sie den Typ fest, in dem Aktien gespeichert werden, für die eine Gewinnabrechnung und eine Verlustkürzung durchgeführt wurden
none_syms = set([]) # portfolio.Legen Sie den Typ fest, in dem Marken gespeichert werden, die an Positionen nicht vorhanden sind
# portfolio.positions(Marken, die Sie besitzen)Zielaktien(sym)Überprüfen Sie, ob es gibt
for (sym, val) in market_sig.items():
if sym not in ctx.portfolio.positions:
none_syms.add(sym)
# portfolio.positions(Marken, die Sie besitzen)Jede Marke von(sym)Überprüfen Sie, ob die Anzahl der von gehaltenen Aktien
for (sym, val) in ctx.portfolio.positions.items():
if val["amount"] == 0:
none_syms.add(sym)
#Verlustkürzung, Gewinnabrechnung(Rentabilität)Einstellungen von
#Iterativer Prozess, um die Aktien, die Sie besitzen, einzeln zu überprüfen
for (sym, val) in ctx.portfolio.positions.items():
#Erwerb des Gewinn-Verlust-Verhältnisses
returns = val["returns"]
if returns < -0.03: #Gewinn-Verlust-Verhältnis-3%Weniger als(Absolutwert 3%Größerer Verlust)Im Falle von
#Verkaufsauftrag zur Verlustreduzierung
sec = ctx.getSecurity(sym)
sec.order(-val["amount"], comment="Verlustschnitt(%f)" % returns)
#Das Problem, das sym zugewiesen wurde, wurde dem festgelegten Typ hinzugefügt, in dem das Problem gespeichert ist, für das eine Gewinnabrechnung und eine Verlustkürzung durchgeführt wurden.
done_syms.add(sym)
elif returns > 0.05: #Gewinn-Verlust-Verhältnis+5%Wenn größer als
#Gewinnmitnahme(Rentabilität)Bestellung verkaufen für
sec = ctx.getSecurity(sym)
sec.order(-val["amount"], comment="Gewinnmitnahmeverkauf(%f)" % returns)
#Das Problem, das sym zugewiesen wurde, wurde dem festgelegten Typ hinzugefügt, in dem das Problem gespeichert ist, für das eine Gewinnabrechnung und eine Verlustkürzung durchgeführt wurden.
done_syms.add(sym)
buy = market_sig[market_sig > 0.0] #Signal kaufen
for (sym, val) in buy.items(): #Verarbeiten Sie Aktien mit Kaufsignalen nacheinander
# done_syms oder keine_Wenn syms sym hat
if sym in done_syms:
continue #Verarbeitung überspringen
#Bestellung kaufen
sec = ctx.getSecurity(sym)
sec.order(sec.unit() * 1, orderType=ot, comment="SIGNAL BUY")
#Wenn Sie das unten stehende Kaufauftragsprotokoll ausgeben möchten, kommentieren Sie dies bitte unten aus(Langfristige Vorsicht)
#ctx.logger.debug("BUY: %s, %f" % (sec.code(), val))
sell = market_sig[market_sig < 0.0] #Signal verkaufen
for (sym, val) in sell.items(): #Verarbeiten Sie Aktien mit Verkaufssignalen nacheinander
# done_syms oder keine_Wenn syms sym hat
if (sym in done_syms) | (sym in none_syms):
continue #Verarbeitung überspringen
#Bestellung verkaufen
sec = ctx.getSecurity(sym)
sec.order(sec.unit() * -1,orderType=ot, comment="SIGNAL SELL")
Abbildung 2: Algorithmus mit goldenem RSI- und MACD-Kreuz und totem Kreuz (siehe: https://factory.quantx.io/developer/6ba1eb1b748d46a18ce128fea3156282/coding / Kodierung))
RSI
talib.RSI(close, timeperiod = 14)
――RSI ist ein technischer Index, der zwischen „überkauft“ und „überverkauft“ unterscheidet.
Beispiel: In Zeile 82 des Codes in Abbildung 2.
rsi = pd.DataFrame(data = 0.0, columns = syms, index = dates)
Definieren Sie einen DataFrame, um den RSI jedes Problems zu speichern
Zur Aussage in Zeile 85
for (sym,val) in cp.items():
rsi[sym] = ta.RSI(cp[sym].values.astype(np.double), timeperiod = 10)
Der RSI jeder Marke wird in gespeichert.
cp [sym]
ein Objekt vom Typ DataFrame ist, konvertieren Sie es in ein Objekt vom Typ Array mit cp [sym] .values
.
--Und cp [sym] .values.astype (np.double)
konvertiert den Inhalt des Arrays in den Typ np.double.MACD
ta.MACD(close)
――Es handelt sich um einen technischen Index, der die Linie des gleitenden Durchschnitts anwendet und den Zeitpunkt des Kaufs und Verkaufs misst, indem die MACD-Linie und die japanische Linie der MACD-Signallinie kombiniert werden.
Beispiel: In den Zeilen 79-81 des Codes in Abbildung 2.
macd = pd.DataFrame(data=0.0, columns=syms, index=dates)
macdsignal = pd.DataFrame(data=0.0, columns=syms, index=dates)
macdhist = pd.DataFrame(data=0.0, columns=syms, index=dates)
Definiert einen DataFrame, in dem der Rückgabewert gespeichert wird. Zur Aussage in Zeile 85
for (sym,val) in cp.items():
macd[sym],macdsignal[sym],macdhist[sym] = ta.MACD(cp[sym])
Nehmen Sie den Macd, Macdsignal, Macdhist jeder Marke auf.
Die Linien 90 und 91 bestimmen das goldene Kreuz und das tote Kreuz der MACD-Linie und der MACD-Signallinie.
macd_golden = (macd > macdsignal) & (macd.shift(1) < macdsignal.shift(1))
macd_dead = (macd < macdsignal) & (macd.shift(1) > macdsignal.shift(1))
buy_sig = macd_golden | (rsi < 30) #Goldenes Kreuz und überverkauft
sell_sig = macd_dead | (rsi > 70) #Totes Kreuz und überkauft
Auf diese Weise erleichtert talib die Implementierung bekannter technischer Indikatoren wie MACD und RSI.
Dieses Mal habe ich die Methoden aufgegriffen, die häufig bei der Herstellung von Algen für Talib und Pandas verwendet werden. Ich hoffe, Sie lesen dies und erhalten ein besseres Verständnis der Algorithmen von QuantX Factory. Vielen Dank, dass Sie den schlechten Text bis zum Ende gelesen haben.
Bitte beachten Sie, dass wir nicht für Gewinne oder Verluste verantwortlich sind, die durch tatsächliche Transaktionen mit diesem Code / Wissen verursacht werden.