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 Limitpips moins cher à l'achat et un prix limite qui est Limitpips 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