Backtesting FX Systre avec Python (2)

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éation de données à 4 valeurs

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éer des signaux d'achat et de vente

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.

Créer une fonction de backtest

Cette fois, les deux points suivants ont été ajoutés en tant qu'extensions des règles de trading du système.

  1. Spécifiez un prix limite à un certain pips du prix au moment du signal d'entrée, et exécutez-le lorsque le prix est atteint.
  2. Réglez lorsque la position ouverte atteint un certain profit ou une perte de pips.

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.

  1. Décalez chaque signal 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.
  2. Remplacez «LongTrade», «ShortTrade» par le prix à acheter ou à vendre au moment du signal. L'entrée est un nombre positif, la sortie est un nombre négatif, et dans le cas du trading limite, le prix de vente est entré à la position de la barre qui a atteint le prix limite pour la première fois pendant la période de validité.

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».

Exemple d'exécution de backtest

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)

chart.png

Le code publié dans cet article a été téléchargé ci-dessous. MT5IndicatorsPy/EA_sample2.ipynb

Recommended Posts

Backtesting FX Systre avec Python (2)
Backtesting FX Systre avec Python (1)
Optimisation des paramètres de systole FX en Python
FizzBuzz en Python3
Grattage avec Python
Statistiques avec python
Grattage avec Python
Python avec Go
Twilio avec Python
Intégrer avec Python
Jouez avec 2016-Python
AES256 avec python
Testé avec Python
Convertissez des données FX 1 minute en données 5 minutes avec Python
python commence par ()
avec syntaxe (Python)
Bingo avec python
Zundokokiyoshi avec python
Excel avec Python
Micro-ordinateur avec Python
Cast avec python
Communication série avec Python
Zip, décompressez avec python
Django 1.11 a démarré avec Python3.6
Jugement des nombres premiers avec Python
Python avec eclipse + PyDev.
Communication de socket avec Python
Analyse de données avec python 2
Grattage en Python (préparation)
Apprendre Python avec ChemTHEATER 03
Recherche séquentielle avec Python
Exécutez Python avec VBA
Manipuler yaml avec python
Résolvez AtCoder 167 avec python
Communication série avec python
[Python] Utiliser JSON avec Python
Apprendre Python avec ChemTHEATER 05-1
Apprenez Python avec ChemTHEATER
Exécutez prepDE.py avec python3
1.1 Premiers pas avec Python
Collecter des tweets avec Python
Binarisation avec OpenCV / Python
3. 3. Programmation IA avec Python
Méthode Kernel avec Python
Non bloquant avec Python + uWSGI
Grattage avec Python + PhantomJS
Publier des tweets avec python
Utiliser mecab avec Python 3
[Python] Redirection avec CGIHTTPServer
Utiliser Kinesis avec Python
Premiers pas avec Python
Utiliser DynamoDB avec Python
Getter Zundko avec python
Gérez Excel avec python
Loi d'Ohm avec Python
Jugement des nombres premiers avec python
Exécutez Blender avec python
Résoudre des maths avec Python
Python à partir de Windows 7
Multi-processus de manière asynchrone avec python
Programmation Python avec Atom