Backtesting FX System avec Python (1) C'est une continuation de.
Les seuls systèmes qui peuvent être testés en amont dans (1) sont ceux qui achètent et vendent sur le marché au prix d'ouverture de la barre suivante pour le signal généré à partir du cours de clôture fixe. Cette fois, j'ai essayé de passer du trading limité et du profit / perte de position ouverte au système de prise de profit et de réduction des pertes.
Le débit global est le même que (1). Les parties communes sont brièvement écrites, veuillez donc vous référer à l'article (1) pour plus de détails.
Créez des données EUR / USD, 1 heure à 4 valeurs pour 2015 sous la forme «ohlc».
import numpy as np
import pandas as pd
import indicators as ind #indicators.Importation de py
dataM1 = pd.read_csv('DAT_ASCII_EURUSD_M1_2015.csv', sep=';',
names=('Time','Open','High','Low','Close', ''),
index_col='Time', parse_dates=True)
dataM1.index += pd.offsets.Hour(7) #Décalage de 7 heures
ohlc = ind.TF_ohlc(dataM1, 'H') #Création de données horaires
Créez un signal d'achat / vente pour que le système soit backtesté. Cette fois, l'entrée est l'intersection de la moyenne mobile et la sortie est l'intersection de la moyenne mobile et du cours de clôture.
Les indicateurs techniques utilisés sont deux moyennes mobiles pour l'entrée et une moyenne mobile pour la sortie.
FastMA = ind.iMA(ohlc, 10) #Moyenne mobile à court terme pour l'entrée
SlowMA = ind.iMA(ohlc, 30) #Moyenne mobile à long terme pour l'entrée
ExitMA = ind.iMA(ohlc, 5) #Moyenne mobile de sortie
Créez un signal d'achat / vente en utilisant ces valeurs d'indice.
#Acheter le signal d'entrée
BuyEntry = ((FastMA > SlowMA) & (FastMA.shift() <= SlowMA.shift())).values
#Vendre un signal d'entrée
SellEntry = ((FastMA < SlowMA) & (FastMA.shift() >= SlowMA.shift())).values
#Acheter un signal de sortie
BuyExit = ((ohlc.Close < ExitMA) & (ohlc.Close.shift() >= ExitMA.shift())).values
#Vendre un signal de sortie
SellExit = ((ohlc.Close > ExitMA) & (ohlc.Close.shift() <= ExitMA.shift())).values
Ces signaux sont générés à toutes les positions qui remplissent les conditions d'intersection, mais certains ne sont pas réellement adoptés selon la présence ou l'absence de positions. Le contrôle autour de cela est effectué par la fonction de backtest suivante.
Cette fois, les deux points suivants ont été ajoutés en tant qu'extensions des règles de trading du système.
Par conséquent, l'argument de la fonction est augmenté comme suit.
def Backtest(ohlc, BuyEntry, SellEntry, BuyExit, SellExit, lots=0.1, spread=2, TP=0, SL=0, Limit=0, Expiration=10):
Substituer une valeur positive pour Limit
dans cela indiquera un prix limite qui est Limit
pips moins cher à l'achat et un prix limite qui est Limit
pips plus élevé pour la vente, sans acheter ou vendre immédiatement au signal d'entrée. .. ʻExpiration` est la période de validité du prix limite et est spécifiée par le nombre de barres.
«TP» et «SL» représentent respectivement le bénéfice (pips) pour la prise de bénéfices et la perte (pips) pour la réduction des pertes. Cela fonctionne en attribuant une valeur positive.
La fonction entière ressemble à ceci:
def Backtest(ohlc, BuyEntry, SellEntry, BuyExit, SellExit, lots=0.1, spread=2, TP=0, SL=0, Limit=0, Expiration=10):
Open = ohlc.Open.values #Prix ouvert
Low = ohlc.Low.values #Bas prix
High = ohlc.High.values #Prix élevé
Point = 0.0001 #Valeur de 1pip
if(Open[0] > 50): Point = 0.01 #1 valeur pip du cercle croisé
Spread = spread*Point #Propagé
Lots = lots*100000 #Volume d'échange réel
N = len(ohlc) #Taille des données FX
LongTrade = np.zeros(N) #Acheter des informations commerciales
ShortTrade = np.zeros(N) #Vendre des informations commerciales
#Acheter le prix d'entrée
BuyEntryS = np.hstack((False, BuyEntry[:-1])) #Acheter le décalage du signal d'entrée
if Limit == 0: LongTrade[BuyEntryS] = Open[BuyEntryS]+Spread #Achat sur le marché
else: #Achat limité
for i in range(N-Expiration):
if BuyEntryS[i]:
BuyLimit = Open[i]-Limit*Point #Prix limite
for j in range(Expiration):
if Low[i+j] <= BuyLimit: #Conditions contractuelles
LongTrade[i+j] = BuyLimit+Spread
break
#Acheter le prix de sortie
BuyExitS = np.hstack((False, BuyExit[:-2], True)) #Acheter le décalage du signal de sortie
LongTrade[BuyExitS] = -Open[BuyExitS]
#Vendre le prix d'entrée
SellEntryS = np.hstack((False, SellEntry[:-1])) #Vendre le décalage du signal d'entrée
if Limit == 0: ShortTrade[SellEntryS] = Open[SellEntryS] #Vente au marché
else: #Limiter la vente
for i in range(N-Expiration):
if SellEntryS[i]:
SellLimit = Open[i]+Limit*Point #Prix limite
for j in range(Expiration):
if High[i+j] >= SellLimit: #Conditions contractuelles
ShortTrade[i+j] = SellLimit
break
#Vendre le prix de sortie
SellExitS = np.hstack((False, SellExit[:-2], True)) #Vendre le décalage du signal de sortie
ShortTrade[SellExitS] = -(Open[SellExitS]+Spread)
LongPL = np.zeros(N) #Gain / perte de position d'achat
ShortPL = np.zeros(N) #Gain / perte de position de vente
BuyPrice = SellPrice = 0.0 #Prix de vente
for i in range(1,N):
if LongTrade[i] > 0: #Acheter le signal d'entrée
if BuyPrice == 0:
BuyPrice = LongTrade[i]
ShortTrade[i] = -BuyPrice #Vendre la sortie
else: LongTrade[i] = 0
if ShortTrade[i] > 0: #Vendre un signal d'entrée
if SellPrice == 0:
SellPrice = ShortTrade[i]
LongTrade[i] = -SellPrice #Acheter la sortie
else: ShortTrade[i] = 0
if LongTrade[i] < 0: #Acheter un signal de sortie
if BuyPrice != 0:
LongPL[i] = -(BuyPrice+LongTrade[i])*Lots #Règlement des profits et pertes
BuyPrice = 0
else: LongTrade[i] = 0
if ShortTrade[i] < 0: #Vendre un signal de sortie
if SellPrice != 0:
ShortPL[i] = (SellPrice+ShortTrade[i])*Lots #Règlement des profits et pertes
SellPrice = 0
else: ShortTrade[i] = 0
if BuyPrice != 0 and SL > 0: #Règlement de la position d'achat par SL
StopPrice = BuyPrice-SL*Point
if Low[i] <= StopPrice:
LongTrade[i] = -StopPrice
LongPL[i] = -(BuyPrice+LongTrade[i])*Lots #Règlement des profits et pertes
BuyPrice = 0
if BuyPrice != 0 and TP > 0: #Règlement de la position d'achat par TP
LimitPrice = BuyPrice+TP*Point
if High[i] >= LimitPrice:
LongTrade[i] = -LimitPrice
LongPL[i] = -(BuyPrice+LongTrade[i])*Lots #Règlement des profits et pertes
BuyPrice = 0
if SellPrice != 0 and SL > 0: #Règlement de la position de vente par SL
StopPrice = SellPrice+SL*Point
if High[i]+Spread >= StopPrice:
ShortTrade[i] = -StopPrice
ShortPL[i] = (SellPrice+ShortTrade[i])*Lots #Règlement des profits et pertes
SellPrice = 0
if SellPrice != 0 and TP > 0: #Règlement de la position de vente par TP
LimitPrice = SellPrice-TP*Point
if Low[i]+Spread <= LimitPrice:
ShortTrade[i] = -LimitPrice
ShortPL[i] = (SellPrice+ShortTrade[i])*Lots #Règlement des profits et pertes
SellPrice = 0
return pd.DataFrame({'Long':LongTrade, 'Short':ShortTrade}, index=ohlc.index),\
pd.DataFrame({'Long':LongPL, 'Short':ShortPL}, index=ohlc.index)
Cela fait assez longtemps, mais pour l'expliquer brièvement, commencez par prétraiter le signal comme suit.
BuyEntry
, SellEntry
, BuyExit
, SellExit
d'un échantillon pour faire BuyEntryS
, SellEntryS
, BuyExitS
, SellExitS
. C'est pour que le signal apparaisse dans la barre où les achats et les ventes ont lieu.Après cela, tournez la barre du début à la fin, et traitez l'achat, la vente et le règlement tout en vérifiant l'existence de la position et les profits et pertes de la position. Renvoie le prix réel négocié à «LongTrade», «ShortTrade» et le bénéfice et la perte fixes à «LongPL», «ShortPL».
L'exemple suivant est un backtest d'un système qui achète et vend à un prix limite à 20 pips du prix au moment du signal d'entrée et se stabilise avec un profit de 100 pips ou une perte de 50 pips séparément du signal de sortie.
Trade, PL = Backtest(ohlc, BuyEntry, SellEntry, BuyExit, SellExit, TP=100, SL=50, Limit=20)
Cette fois, je n'afficherai que la courbe des actifs.
from pandas_highcharts.display import display_charts
Initial = 10000 #Actifs initiaux
Equity = (PL.Long+PL.Short).cumsum() #Bénéfice et perte cumulés
display_charts(pd.DataFrame({'Equity':Equity+Initial}), chart_type="stock", title="Courbe des actifs", figsize=(640,480), grid=True)
Le code publié dans cet article a été téléchargé ci-dessous. MT5IndicatorsPy/EA_sample2.ipynb
Recommended Posts