Je m'appelle Masukawa (https://www.facebook.com/ryozodesert) et je suis stagiaire chez SmartTrade Co., Ltd.. .. J'étudie l'apprentissage automatique.
Smart Trade Co., Ltd.
Démocratie financière
Sur la base de cette philosophie, nous avons développé "QuantX Factory", une plate-forme sur laquelle tout le monde peut facilement développer des algorithmes de trading.
Au cours de mon premier mois en tant que stagiaire, j'expliquerai comment utiliser les méthodes pandas et talib qui sont fréquemment utilisées dans la création d'algorithmes pour implémenter des indicateurs techniques de base tels que MACD, moyennes mobiles et RSI.
(Remarque: vous n'êtes pas obligé de bien comprendre le contenu de ce code pour le moment) </ font>
#Importation de bibliothèque
#Bibliothèque requise
#Importer le moteur de backtest "maron"
import maron
import maron.signalfunc as sf
import maron.execfunc as ef
#Bibliothèque supplémentaire
#Si vous avez besoin de bibliothèques supplémentaires, ajoutez-les selon l'exemple ci-dessous.
#Importez l'outil d'analyse de données "pandas" et utilisez-le sous le nom "pd"
import pandas as pd
#Importez le jeu de fonctions financières "talib" et utilisez-le avec le nom "ta"
import talib as ta
import numpy as np
#Importez "" et utilisez-le comme ""
# import as
#Méthode de commande(Veuillez décommenter un seul des trois suivants selon la méthode de commande souhaitée)
# ot = maron.OrderType.MARKET_CLOSE #Ordre au moment du cours de clôture le lendemain de l'émission du signal
ot = maron.OrderType.MARKET_OPEN #Commande au moment du cours d'ouverture le lendemain de l'émission du signal
# ot = maron.OrderType.LIMIT #Limiter l'ordre
def initialize(ctx): #Partie d'initialisation
ctx.logger.debug("initialize() called") #Sortie de journal
ctx.target = 0.1
ctx.loss_cut = -0.02
ctx.plofit = 0.05
ctx.configure(
channels={
"jp.stock": {
"symbols": [
"jp.stock.2914", #JT(L'industrie japonaise du tabac)
"jp.stock.8766", #Tokio Marine Holdings
"jp.stock.8031", #Mitsui Bussan
"jp.stock.8316", #Groupe financier Sumitomo Mitsui
"jp.stock.8411", #Groupe financier Mizuho
"jp.stock.9437", #NTT Docomo
"jp.stock.4502", #Industrie pharmaceutique Takeda
"jp.stock.8058", #Mitsubishi Corporation
"jp.stock.9433", #KDDI
"jp.stock.9432", #Téléphone Nippon Telecom
"jp.stock.7267", #Honda (Honda Giken Kogyo)
"jp.stock.8306", #Groupe financier Mitsubishi UFJ
"jp.stock.4503", #Astellas Pharmaceutical
"jp.stock.4063", #Industrie chimique Shinetsu
"jp.stock.7974", #Nintendo
"jp.stock.6981", #Murata Seisakusho
"jp.stock.3382", #Seven & i Holdings
"jp.stock.9020", #Chemin de fer de passagers de l'est du Japon
"jp.stock.8802", #Domaine Mitsubishi
"jp.stock.9022", #Chemin de fer de passagers de Tokai
"jp.stock.9984", #Groupe Softbank
"jp.stock.6861", #Keyence
"jp.stock.6501", #Hitachi, Ltd.
"jp.stock.6752", #Panasonic
"jp.stock.6758", #Sony
"jp.stock.6954", #Fanac
"jp.stock.7203", #Moteur Toyota
"jp.stock.7751", #Canon
"jp.stock.4452", #Kao
"jp.stock.6098", #Recruter Holdings
],
#⑥
"columns": ["close_price_adj", #le dernier prix(Après ajustement pour le fractionnement d'actions)
]}})
def _my_signal(data): #Acheter et vendre une partie de génération de signal
#Si vous souhaitez vérifier le contenu des données, veuillez décommenter ci-dessous
# ctx.logger.debug(data)
syms = data.minor_axis #Créer une liste de stock
dates = data.major_axis #Créer une liste de dates
'''↓ Ecrire le code pour obtenir les données nécessaires au calcul logique à partir des données de la structure 3D ↓'''
cp = data["close_price_adj"].fillna("ffill")
'''↑ Ecrire le code pour obtenir les données nécessaires au calcul logique à partir des données de la structure 3D ↑'''
'''↓ Ecrire le code pour calculer la logique nécessaire pour définir les conditions de trading ↓'''
movave5 = cp.rolling(window = 5, center = False).mean()
movave25 = cp.rolling(window = 25, center = False).mean()
'''↑ Ecrire le code pour calculer la logique nécessaire pour définir les conditions de trading ↑'''
#Définir les signaux d'achat et de vente(Retour en tant que valeur booléenne)
buy_sig = (movave5 > movave25) & (movave5.shift(1) < movave25.shift(1))
sell_sig = (movave5 < movave25) & (movave5.shift(1) > movave25.shift(1))
# market_Tous les 0 appelés sig.Créez un bloc de données "horizontal: nom de la marque, vertical: date" qui stocke 0
market_sig = pd.DataFrame(data=0.0, columns=syms, index=dates)
# buy_1 quand sig est vrai.0、sell_Quand sig est vrai-1.0, 0 lorsque les deux sont Vrai.Mettre à 0
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_Si vous souhaitez vérifier le contenu de sig, veuillez décommenter ci-dessous
# ctx.logger.debug(market_sig)
return {
"buy:sig":buy_sig,
"sell:sig": sell_sig,
"market:sig": market_sig,
#Veuillez ajouter les données que vous souhaitez afficher dans le tableau des résultats du backtest ci-dessous
}
ctx.regist_signal("my_signal", _my_signal) #Enregistrement du signal
def handle_signals(ctx, date, current): #Partie de traitement quotidien
'''
current: pd.DataFrame
'''
#initialiser_my_Commercialiser le signal généré par le signal_Magasin dans sig
market_sig = current["market:sig"]
done_syms = set([]) #Type de set qui stocke les stocks pour lesquels le règlement des bénéfices et la réduction des pertes ont été effectués
none_syms = set([]) # portfolio.Définissez le type qui stocke les marques qui n'existent pas dans des positions
# portfolio.positions(Marques que vous possédez)Actions cibles(sym)Vérifiez s'il y a
for (sym, val) in market_sig.items():
if sym not in ctx.portfolio.positions:
none_syms.add(sym)
# portfolio.positions(Marques que vous possédez)Chaque marque de(sym)Vérifiez si le nombre d'actions détenues par
for (sym, val) in ctx.portfolio.positions.items():
if val["amount"] == 0:
none_syms.add(sym)
#Réduction des pertes, règlement des bénéfices(Rentabilité)paramètres de
#Processus itératif pour vérifier les stocks que vous possédez un par un
for (sym, val) in ctx.portfolio.positions.items():
#Acquisition du ratio profit / perte
returns = val["returns"]
if returns < -0.03: #Ratio profit / perte-3%Moins que(Valeur absolue 3%Plus grande perte)dans le cas de
#Ordre de vente pour réduction des pertes
sec = ctx.getSecurity(sym)
sec.order(-val["amount"], comment="Coupe de perte(%f)" % returns)
#Ajout du problème affecté à sym au type d'ensemble qui stocke le problème pour lequel le règlement des bénéfices et la réduction des pertes ont été effectués.
done_syms.add(sym)
elif returns > 0.05: #Ratio profit / perte+5%Si supérieur à
#Prise de bénéfices(Rentabilité)Ordre de vente pour
sec = ctx.getSecurity(sym)
sec.order(-val["amount"], comment="Vente à but lucratif(%f)" % returns)
#Ajout du problème affecté à sym au type d'ensemble qui stocke le problème pour lequel le règlement des bénéfices et la réduction des pertes ont été effectués.
done_syms.add(sym)
buy = market_sig[market_sig > 0.0] #Acheter signal
for (sym, val) in buy.items(): #Traitez les actions avec les signaux d'achat un par un
# done_syms ou aucun_Si syms a sym
if sym in done_syms:
continue #Ignorer le traitement
#Acheter la commande
sec = ctx.getSecurity(sym)
sec.order(sec.unit() * 1, orderType=ot, comment="SIGNAL BUY")
#Si vous souhaitez afficher le journal des commandes d'achat ci-dessous, veuillez supprimer les commentaires ci-dessous(Attention à long terme)
#ctx.logger.debug("BUY: %s, %f" % (sec.code(), val))
sell = market_sig[market_sig < 0.0] #Signal de vente
for (sym, val) in sell.items(): #Traitez les actions avec les signaux de vente un par un
# done_syms ou aucun_Si syms a sym
if (sym in done_syms) | (sym in none_syms):
continue #Ignorer le traitement
#Ordre de vente
sec = ctx.getSecurity(sym)
sec.order(sec.unit() * -1,orderType=ot, comment="SIGNAL SELL")
Figure 1: Algorithme utilisant la croix dorée et la croix morte de la ligne moyenne mobile (voir: https://factory.quantx.io/developer/149d79a8cf744f059af0e96918913a9f/coding / codage))
pd.DataFrame.rolling(window)
Exemple: implémenter une moyenne mobile sur 25 jours
Dans la ligne 82 de la Fig.
movave25 = cp.rolling(window = 25).mean()
Cela dit, mais c'est ce qui définit la moyenne mobile sur 25 jours.
cp.rolling (window = 25)
to cp
, qui est un DataFrame qui stocke le prix de clôture de chaque date de chaque marque, et un objet roulant est retourné.Vous disposez maintenant de move25, un DataFrame qui stocke 25 jours de moyennes mobiles.
pandas.DataFrame.shift(periods)
--Retourne un objet DataFrame, une méthode qui déplace (décale) les données stockées dans un bloc de données par périodes </ font> --Utilisation: détecte les changements dans la relation d'amplitude entre les deux lignes de moyenne mobile, la ligne à court terme et la ligne à long terme, à partir de la veille.
Exemple: Jugement de la croix d'or et de la croix morte
Dans la ligne 87 de la Fig.
buy_sig = (movave5 > movave25) & (movave5.shift(1) < movave25.shift(1))
Cependant, ce code indique que "la moyenne mobile sur 5 jours du jour est supérieure à la moyenne mobile sur 25 jours et la moyenne mobile sur 5 jours du jour précédent est plus petite que la moyenne mobile sur 25 jours", c'est-à-dire une croix en or. Je suis. La ligne 88 est le contraire.
La méthode de décalage est utilisée de cette manière.
Une bibliothèque qui vous permet d'implémenter facilement des indicateurs techniques. Veuillez vous référer à l'URL suivante pour les indicateurs qui peuvent être mis en œuvre. https://mrjbq7.github.io/ta-lib/funcs.html
# Sample Algorithm
#Importation de bibliothèque
#Bibliothèque requise
import maron
import maron.signalfunc as sf
import maron.execfunc as ef
#Bibliothèque supplémentaire
#Veuillez consulter les notes sur l'écran de droite pour les bibliothèques qui peuvent être utilisées ①
import pandas as pd
import talib as ta
import numpy as np
#Méthode de commande(Veuillez décommenter un seul des deux suivants selon la méthode de commande souhaitée)
#Veuillez consulter la note sur l'écran de droite pour la méthode de commande ②
#ot = maron.OrderType.MARKET_CLOSE #Ordre au moment du cours de clôture le lendemain de l'émission du signal
ot = maron.OrderType.MARKET_OPEN #Commande au moment du cours d'ouverture le lendemain de l'émission du signal
#ot = maron.OrderType.LIMIT #Limiter l'ordre
#Acquisition de stocks et de colonnes
#Veuillez consulter la note sur l'écran de droite pour la désignation de la marque ③
#Veuillez consulter la note sur l'écran de droite pour obtenir les colonnes ④
def initialize(ctx):
#Réglage
ctx.logger.debug("initialize() called")
ctx.configure(
channels={ #Canal utilisé
"jp.stock": {
"symbols": [
"jp.stock.2914", #JT(L'industrie japonaise du tabac)
"jp.stock.8766", #Tokio Marine Holdings
"jp.stock.8031", #Mitsui Bussan
"jp.stock.8316", #Groupe financier Sumitomo Mitsui
"jp.stock.8411", #Groupe financier Mizuho
"jp.stock.9437", #NTT Docomo
"jp.stock.4502", #Industrie pharmaceutique Takeda
"jp.stock.8058", #Mitsubishi Corporation
"jp.stock.9433", #KDDI
"jp.stock.9432", #Téléphone Nippon Telecom
"jp.stock.7267", #Honda (Honda Giken Kogyo)
"jp.stock.8306", #Groupe financier Mitsubishi UFJ
"jp.stock.4503", #Astellas Pharmaceutical
"jp.stock.4063", #Industrie chimique Shinetsu
"jp.stock.7974", #Nintendo
"jp.stock.6981", #Murata Seisakusho
"jp.stock.3382", #Seven & i Holdings
"jp.stock.9020", #Chemin de fer de passagers de l'est du Japon
"jp.stock.8802", #Domaine Mitsubishi
"jp.stock.9022", #Chemin de fer de passagers de Tokai
"jp.stock.9984", #Groupe Softbank
"jp.stock.6861", #Keyence
"jp.stock.6501", #Hitachi, Ltd.
"jp.stock.6752", #Panasonic
"jp.stock.6758", #Sony
"jp.stock.6954", #Fanac
"jp.stock.7203", #Moteur Toyota
"jp.stock.7751", #Canon
"jp.stock.4452", #Kao
"jp.stock.6098", #Recruter Holdings
],
"columns": [
"close_price", #le dernier prix
"close_price_adj", #le dernier prix(Après ajustement pour le fractionnement d'actions)
#"volume_adj", #Le volume
#"txn_volume", #Prix de négociation
]
}
}
)
#Définition du signal
def _my_signal(data):
#Obtenez des données sur les prix de clôture
cp=data["close_price_adj"].fillna(method="ffill")
syms = data.minor_axis #Créer une liste de stock
dates = data.major_axis #Créer une liste de dates
#Où stocker les données
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-Calcul de MACD par 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))
#Acheter et vendre une partie de génération de signal
buy_sig = macd_golden | (rsi < 30)
sell_sig = macd_dead | (rsi > 70)
#market_Créez un bloc de données appelé sig qui contient tous les 0
market_sig = pd.DataFrame(data=0.0, columns=syms, index=dates)
#buy_1 quand sig est vrai.0、sell_Quand sig est vrai-1.Mettre à 0
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,
}
#Enregistrement du signal
ctx.regist_signal("my_signal", _my_signal)
def handle_signals(ctx, date, current): #Partie de traitement quotidien
'''
current: pd.DataFrame
'''
#initialiser_my_Commercialiser le signal généré par le signal_Magasin dans sig
market_sig = current["market:sig"]
done_syms = set([]) #Type de set qui stocke les stocks pour lesquels le règlement des bénéfices et la réduction des pertes ont été effectués
none_syms = set([]) # portfolio.Définissez le type qui stocke les marques qui n'existent pas dans des positions
# portfolio.positions(Marques que vous possédez)Actions cibles(sym)Vérifiez s'il y a
for (sym, val) in market_sig.items():
if sym not in ctx.portfolio.positions:
none_syms.add(sym)
# portfolio.positions(Marques que vous possédez)Chaque marque de(sym)Vérifiez si le nombre d'actions détenues par
for (sym, val) in ctx.portfolio.positions.items():
if val["amount"] == 0:
none_syms.add(sym)
#Réduction des pertes, règlement des bénéfices(Rentabilité)paramètres de
#Processus itératif pour vérifier les stocks que vous possédez un par un
for (sym, val) in ctx.portfolio.positions.items():
#Acquisition du ratio profit / perte
returns = val["returns"]
if returns < -0.03: #Ratio profit / perte-3%Moins que(Valeur absolue 3%Plus grande perte)dans le cas de
#Ordre de vente pour réduction des pertes
sec = ctx.getSecurity(sym)
sec.order(-val["amount"], comment="Coupe de perte(%f)" % returns)
#Ajout du problème affecté à sym au type d'ensemble qui stocke le problème pour lequel le règlement des bénéfices et la réduction des pertes ont été effectués.
done_syms.add(sym)
elif returns > 0.05: #Ratio profit / perte+5%Si supérieur à
#Prise de bénéfices(Rentabilité)Ordre de vente pour
sec = ctx.getSecurity(sym)
sec.order(-val["amount"], comment="Vente à but lucratif(%f)" % returns)
#Ajout du problème affecté à sym au type d'ensemble qui stocke le problème pour lequel le règlement des bénéfices et la réduction des pertes ont été effectués.
done_syms.add(sym)
buy = market_sig[market_sig > 0.0] #Acheter signal
for (sym, val) in buy.items(): #Traitez les actions avec les signaux d'achat un par un
# done_syms ou aucun_Si syms a sym
if sym in done_syms:
continue #Ignorer le traitement
#Acheter la commande
sec = ctx.getSecurity(sym)
sec.order(sec.unit() * 1, orderType=ot, comment="SIGNAL BUY")
#Si vous souhaitez afficher le journal des commandes d'achat ci-dessous, veuillez supprimer les commentaires ci-dessous(Attention à long terme)
#ctx.logger.debug("BUY: %s, %f" % (sec.code(), val))
sell = market_sig[market_sig < 0.0] #Signal de vente
for (sym, val) in sell.items(): #Traitez les actions avec les signaux de vente un par un
# done_syms ou aucun_Si syms a sym
if (sym in done_syms) | (sym in none_syms):
continue #Ignorer le traitement
#Ordre de vente
sec = ctx.getSecurity(sym)
sec.order(sec.unit() * -1,orderType=ot, comment="SIGNAL SELL")
Figure 2: Algorithme utilisant la croix dorée RSI et MACD et la croix morte (voir: https://factory.quantx.io/developer/6ba1eb1b748d46a18ce128fea3156282/coding / codage))
RSI
talib.RSI(close, timeperiod = 14)
――RSI est un indice technique qui fait la distinction entre «surachat» et «survente».
Exemple: à la ligne 82 du code de la figure 2.
rsi = pd.DataFrame(data = 0.0, columns = syms, index = dates)
Définir un DataFrame pour stocker le RSI de chaque problème
Pour le relevé à la ligne 85
for (sym,val) in cp.items():
rsi[sym] = ta.RSI(cp[sym].values.astype(np.double), timeperiod = 10)
Le RSI de chaque marque est stocké dans.
cp [sym]
est un objet de type DataFrame, convertissez-le en objet de type tableau avec cp [sym] .values
.
--Et cp [sym] .values.astype (np.double)
convertit le contenu du tableau en type np.double.
--Cette fois, nous prendrons RSI pendant 10 jours, définissez donc timeperiod = 10.MACD
ta.MACD(close)
――Il s'agit d'un indice technique qui applique la ligne de moyenne mobile et mesure le moment de l'achat et de la vente en combinant la ligne MACD et la ligne japonaise de la ligne de signal MACD.
Exemple: aux lignes 79-81 du code de la figure 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)
Définit un DataFrame qui stocke la valeur de retour. Pour le relevé à la ligne 85
for (sym,val) in cp.items():
macd[sym],macdsignal[sym],macdhist[sym] = ta.MACD(cp[sym])
Prenez le macd, macdsignal, macdhist de chaque marque.
Les lignes 90 et 91 déterminent la croix dorée et la croix morte de la ligne MACD et de la ligne de signal MACD.
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) #Croix d'or et survendu
sell_sig = macd_dead | (rsi > 70) #Croix morte et surachat
De cette manière, talib facilite la mise en œuvre d'indicateurs techniques bien connus tels que MACD et RSI.
Cette fois, j'ai choisi les méthodes fréquemment utilisées pour créer des algos pour talib et pandas. J'espère que vous lirez ceci et que vous aurez une meilleure compréhension des algorithmes de QuantX Factory. Merci d'avoir lu le pauvre texte jusqu'à la fin.
Veuillez noter que nous ne sommes pas responsables des profits ou des pertes causés par des transactions réelles utilisant ce code / cette connaissance.
Recommended Posts