9. Erstellen benutzerdefinierter Handelsstrategien mit qteasy
qteasy ist ein vollständig lokalisiertes und betriebenes Quantitative Trading-Analyse-Toolkit mit folgenden Funktionen:
Erfassung, Reinigung, Speicherung und Verarbeitung von Finanzdaten, Visualisierung und Verwendung
Erstellung quantitativer Handelsstrategien und Bereitstellung einer Vielzahl von integrierten grundlegenden Handelsstrategien
Vektorisierte Hochgeschwindigkeits-Backtests von Handelsstrategien und Bewertung der Handelsergebnisse
Optimierung und Bewertung von Handelsstrategieparametern
Bereitstellung und Echtzeitbetrieb von Handelsstrategien
Durch diese Tutorials werden Sie die Hauptfunktionen und Verwendungsmethoden von qteasy anhand einer Reihe praktischer Beispiele vollständig verstehen.
9.1. Vorbereitungen vor dem Start
Bevor Sie mit diesem Tutorial beginnen, stellen Sie bitte sicher, dass Sie Folgendes beherrschen:
Installieren und Konfigurieren von
qteasy- QTEASY-Tutorial 1eine lokale Datenquelle einrichten und genügend historische Daten lokal heruntergeladen haben - QTEASY Tutorial 2
Lernen Sie, Händlerobjekte zu erstellen und integrierte Handelsstrategien zu verwenden, - QTEASY Tutorial 3
Lernen Sie, einen Mixer zu verwenden, um mehrere einfache Strategien zu komplexeren Handelsstrategien zu verbinden - QTEASY Tutorial 4
Weitere Informationen über die Verwendung der eingebauten Handelsstrategien, die Erstellung benutzerdefinierter Strategien und mehr finden Sie in der [QTEASY-Dokumentation] (https://qteasy.readthedocs.io). Für diejenigen unter Ihnen, die mit den Grundlagen der Verwendung von qteasy nicht vertraut sind, finden Sie dort eine ausführliche Anleitung.
9.2. Ziele dieses Abschnitts
Der qteasy-Kernel ist als Rahmenwerk konzipiert, das hohe Ausführungsgeschwindigkeiten mit ausreichender Flexibilität kombiniert, so dass Sie theoretisch jede Art von Handelsstrategie umsetzen können, die Sie sich vorstellen.
Gleichzeitig wurde das Backtesting-Framework qteasy auf eine ganz besondere Art und Weise entwickelt, um zu verhindern, dass Sie versehentlich Future-Funktionen in Ihre Handelsstrategie importieren, um sicherzustellen, dass Ihre Handelsstrategie ausschließlich auf der Grundlage von Daten aus der Vergangenheit backgetestet wird, und um eine Vielzahl von Vorverarbeitungstechniken und JIT-Techniken zur Kompilierung der Schlüsselfunktionen des Kernels zu verwenden, um die Geschwindigkeit der Sprache C zu erreichen.
Um jedoch eine theoretisch unendliche Anzahl von Handelsstrategien zu erreichen, reicht es nicht immer aus, nur die eingebauten Handelsstrategien zu verwenden und Strategien zu mischen. Einige spezifische Handelsstrategien oder besonders komplexe Handelsstrategien können nicht durch das Mischen der eingebauten Strategien erstellt werden, so dass wir die von qteasy bereitgestellte Basisklasse Strategy verwenden müssen, um eine benutzerdefinierte Handelsstrategie auf der Grundlage bestimmter Regeln zu erstellen. Strategie auf der Grundlage bestimmter Regeln.
In diesem Abschnitt stellen wir Ihnen die Handelsstrategie-Basisklassen von qteasy vor und erklären Ihnen anhand einiger konkreter Beispiele, wie Sie auf der Grundlage dieser Basisklassen eine eigene Handelsstrategie erstellen können. Um Schritt für Schritt vorgehen zu können, beginnen wir mit einem einfacheren Beispiel.
9.3. Maßgeschneiderte Methoden zur Umsetzung der Politik
Im Arbeitsablauf des quantitativen Handels ist eine Handelsstrategie eigentlich eine Funktion, die bekannte Informationen als Input nimmt und durch eine Reihe von logischen Schlussfolgerungen Handelsentscheidungen ausgibt. Unabhängig von der technischen Schule, unabhängig vom Handelsstil, unabhängig von der Analysemethode, ist die grundlegendste Definition einer Handelsstrategie die folgende.
! [Bildbeschreibung hier einfügen] (… /img/Essenz_der_Strategie.png)
Zum Beispiel:
Technische Analysten verwenden vergangene Aktienkurse (Eingangsdaten), um technische Indikatoren zu berechnen (logische Extrapolation) und Kauf-/Verkaufsoperationen durchzuführen (Handelsentscheidungen).
Der Value-Investor verwendet Indikatoren börsennotierter Unternehmen (Eingabedaten), analysiert das Wachstumspotenzial des Unternehmens (logische Schlussfolgerung) und entscheidet, welche Aktien er kaufen/verkaufen möchte (Handelsentscheidung)
Makroanalysten, auch wenn sie sich nicht um den Preis einzelner Aktien kümmern, müssen sich auf aktuelle Nachrichten und die Marktstimmung beziehen (immer noch Eingabedaten), den Gesamttrend des Marktes analysieren (logische Schlussfolgerung) und entscheiden, ob sie in den Markt einsteigen oder nicht (Handelsentscheidung)
Der Hochfrequenz- oder Ultrahochfrequenz-Arbitragehandel erfordert auch eine Analyse der Größe des Arbitrageraums (logische Ableitung) auf der Grundlage kurzfristiger Echtzeit-Preisänderungen (Eingangsdaten), um schnell in das Geschäft eingreifen zu können (Handelsentscheidung)
Die obige Handelsstrategie wird als Timing Trading Strategy“ bezeichnet, wenn sie eine kleine Anzahl von Anlagen mit hoher Frequenz verfolgt, oder als Stock Picking Strategy“, wenn sie eine große Anzahl von Anlagen mit niedriger Frequenz verfolgt.
Kurz gesagt, alle quantitativen Handel, ist eine Reihe von ** regelmäßig eine logische Ableitung, in jedem Lauf, um die neuesten Daten zu der Zeit als Eingabe, die Ausgabe von einer Reihe von Handelsentscheidungen ** zu extrahieren. So wiederholt laufen, die Bildung eines stabilen Strom von Handelsoperationen, verallgemeinert, ist dies das abstrakte Konzept der Handelsstrategie.
9.4. Verwendung der Strategieklasse Strategy aus `qteasy
„qteasy“-Handelsstrategien werden basierend auf den oben genannten Konzepten definiert. Die durch „qteasy“ definierten Strategieklassen sind Träger von Daten und Handelslogik. Indem Sie die Klasse „Strategy“ erben und Ihre eigene Strategieklasse definieren – indem Sie die von der Strategie benötigten Daten und die Implementierungslogik der Strategie innerhalb dieser Klasse angeben – können Sie eine benutzerdefinierte Handelsstrategie erstellen.
Daher umfasst eine Handelsstrategie im Design von „qteasy“ die folgenden vier Kernelemente:
Festlegung des Zeitplans für die Durchführung von Maßnahmen
Strategielaufzeit-Timing – Wann und mit welcher Häufigkeit eine Strategie ausgeführt wird, wird von der Strategiegruppe bestimmt. Beim Hinzufügen einer Strategie zu einem „Operator“ können Sie die Parameter „run_freq“ und „run_timing“ angeben; Zusammen bestimmen diese beiden Parameter das Laufzeit-Timing der Strategie.
Die einstellbaren Parameter und historischen Daten einer Strategie
Auch Handelsstrategien in „qteasy“ haben ein besonderes Design: einstellbare Parameter. Einstellbare Parameter sind Parameter, die während der Strategieausführung kontinuierlich angepasst werden, wie z. B. der Zeitraum des gleitenden Durchschnitts, die Anzahl der Aktien in einem Stockpicking-Ranking usw. Diese Parameter wirken sich direkt auf die Leistung der Strategie aus. Daher möchten wir sie anpassen, um die optimale Parameterkombination zu finden und so die beste Leistung zu erzielen. „qteasy“ bietet eine sehr praktische Schnittstelle zum Definieren einstellbarer Parameter. Benutzer können in den Attributen der Strategie eine beliebige Anzahl einstellbarer Parameter definieren und für jeden einstellbaren Parameter einen Namen, einen Wertebereich, einen Datentyp usw. angeben. Diese definierten einstellbaren Parameter werden automatisch an die Strategieimplementierungsfunktion übergeben, und Benutzer können diese Parameter direkt zur Implementierung der Handelslogik verwenden.
Anpassbare Parameter einer Strategie – Parameter, die in einer Strategie angepasst werden müssen, wie z. B. der Zeitraum des gleitenden Durchschnitts, die Anzahl der Aktien in einem Stockpicking-Ranking und so weiter. Diese Parameter wirken sich direkt auf die Leistung der Strategie aus. Daher möchten wir sie anpassen, um die optimale Parameterkombination zu finden und so die beste Leistung zu erzielen. „qteasy“ bietet eine sehr praktische Schnittstelle, „Parameters“, zum Definieren einstellbarer Parameter. Benutzer können in den Attributen der Strategie eine beliebige Anzahl einstellbarer Parameter definieren und für jeden einstellbaren Parameter einen Namen, einen Wertebereich, einen Datentyp usw. angeben. Diese definierten einstellbaren Parameter werden automatisch an die Strategieimplementierungsfunktion übergeben, und Benutzer können diese Parameter direkt zur Implementierung der Handelslogik verwenden.
Definition der für die Strategie benötigten Daten
Strategy_data_needed - die von der Strategie benötigten Daten; z.B. benötigen Sie tägliche K-Linien-Daten für die letzten 10 Tage oder Kurs-Gewinn-Verhältnisse für das letzte Jahr? In
qteasykann die von der Strategie benötigte Datenmenge völlig frei mit Eigenschaften wieStrategy.data_typesdefiniert werden, die den Datentyp, die Häufigkeit und die Länge des Fensters angebenStrategielogik - Durch Überschreiben der Methode
Strategy.realize()kann der Benutzer selbst festlegen, wie die Eingabedaten zur Generierung von Handelsentscheidungen verwendet werden.
Die Ausgangssignale einer Strategie
Mit „qteasy“ können Benutzer verschiedene Arten von Handelssignalen definieren: „PT“, „PS“, „VS“ usw. Benutzer können je nach Bedarf verschiedene Arten von Handelssignalen auswählen, um verschiedene Arten von Handelsstrategien umzusetzen. Die Bedeutung von Handelssignalen wird im Folgenden kurz beschrieben. Eine detaillierte Einführung in verschiedene Arten von Handelssignalen finden Sie unter Handelssignale.
PT-Signal —— Stellt den Prozentsatz der Position dar. Die Ausgabe ist ein Wert zwischen 0 und 1, der angibt, welcher Anteil der Position gehalten werden soll. Beispielsweise bedeutet ein Output von 0,5, dass er 50 % der Position hält; 0 bedeutet, keine zu halten; 1 bedeutet vollständig investiert;
PS-Signal – stellt den Handelsprozentsatz dar. Die Ausgabe ist ein Wert zwischen -1 und 1, der angibt, welcher Anteil der Position gekauft/verkauft werden soll. Beispielsweise bedeutet ein Output von 0,5 den Kauf von 50 % der Position, -0,5 bedeutet den Verkauf von 50 % der Position und 0 bedeutet keine Aktion;
VS-Typ-Signal —— Stellt die Handelsmenge dar. Die Ausgabezahl gibt die Anzahl der zu kaufenden/verkaufenden Aktien an; Beispielsweise bedeutet 500 den Kauf von 500 Aktien und -300 den Verkauf von 300 Aktien.
Abgesehen von den oben genannten strategiebezogenen Informationen ist der ganze Rest der Arbeit qteasy erledigt, alle Handelsdaten werden automatisch in ein ndarray-Array entsprechend den Strategieattributen verpackt, das leicht extrahiert und verwendet werden kann; dieselbe Handelsstrategie wird automatisch die Handelsdaten extrahieren, wenn sie auf dem Live-Markt läuft, und die Handelssignale entsprechend der definierten Strategie generieren, und wird auch automatisch die historischen Daten extrahieren und automatisch die historischen Datenscheiben in der Backtesting-Zeit generieren, ohne zukünftige Funktionen zu bilden. Dieselbe Handelsstrategie extrahiert automatisch die Handelsdaten und generiert Handelssignale entsprechend der definierten Strategie, wenn sie auf dem Live-Markt läuft, und extrahiert auch automatisch die historischen Daten beim Backtesting und generiert automatisch Slices von historischen Daten, ohne zukünftige Funktionen zu bilden. Zugleich werden alle Handelsdaten
Folglich ist die Anpassung von Richtlinien in qteasy sehr einfach:
__init__()Definieren Sie alle Parameter der Strategie in dieser Methode, einschließlich des Namens, der Beschreibung und vor allem der einstellbaren Parameter, Datentypen usw. der Strategie. Diese Parameter werden von „qteasy“ automatisch erkannt und können direkt verwendet werden, wenn die Strategie ausgeführt wird.realize()Definieren Sie in dieser Methode die Logik der Strategie: Extrahieren Sie automatisch generierte Handelsdaten und generieren Sie Handelssignale auf der Grundlage dieser Daten.
! [Bildbeschreibung hier einfügen] (…/img/Strategie_Klasse_Illustration.png)
Zusätzlich zu den oben beschriebenen Strategieattributen haben benutzerdefinierte Strategien auch die gleichen grundlegenden Attribute wie die integrierten Handelsstrategien, wie z. B. die Anzahl der einstellbaren Parameter, den Typ usw., da sie die gleichen sind wie die integrierten Handelsstrategien, werden sie hier nicht wiederholt.
9.5. Drei verschiedene benutzerdefinierte Strategie-Basisklassen
qteasy bietet drei verschiedene Richtlinienklassen, um es den Benutzern zu erleichtern, individuelle Richtlinien für verschiedene Situationen zu erstellen.
GeneralStg: Allgemeine Handelsstrategieklasse, bei der der Benutzer für alle gehandelten Vermögenswerte in der Methoderealize()Handelsentscheidungssignale angeben muss.FactorSorter: Factor Picking Klasse, der Benutzer muss nur den Stock Picking Faktor in derrealize()Methode definieren, dann können Sie verschiedene Stock Picking Aktionen durch Objekteigenschaften implementieren.RuleIterator: Eine zyklische Regelklasse, bei der der Benutzer eine Stock-Picking- oder Timing-Regel für eine Aktie definiert, und dieselbe Regel zyklisch auf alle Aktien angewendet wird, wobei für verschiedene Aktien unterschiedliche Parameter definiert werden können.
Die Eigenschaften und Methoden der drei Handelsstrategie-Basisklassen sind identisch, der einzige Unterschied liegt in der Definition der Methode realize().
Im Folgenden wird anhand einiger Beispiele Schritt für Schritt erläutert, wie Sie eine benutzerdefinierte Richtlinie erstellen können.
9.6. Definition einer Double-SMA-Timing-Handelsstrategie
Unser erstes Beispiel ist die einfachste Doppel-SMA-Timing-Handelsstrategie, die zu den klassischsten Timing-Handelsstrategien gehört. Diese SMA-Timing-Strategie hat zwei einstellbare Parameter:
FMA Fast Mean Period
SMA Slow SMA Cycle Die Strategie berechnet einen einfachen gleitenden Durchschnitt, der durch die beiden oben genannten Zyklen auf der Grundlage der Schlusskurse der vergangenen Periode generiert wird, und erzeugt ein Handelssignal, wenn sich die beiden Durchschnitte kreuzen:
Ein vollständiges Kaufsignal wird ausgelöst, wenn der schnelle SMA die obere Begrenzung von unten nach oben kreuzt
Alle Verkaufssignale werden ausgelöst, wenn die schnellen Durchschnitte die obere Begrenzung von oben nach unten durchbrechen
! Bildbeschreibung hier einfügen
Die Logik dieser Strategie ist sehr einfach. Wie definieren wir also diese Strategie? Zunächst müssen wir entscheiden, welche Handelsstrategie-Basisklasse wir verwenden wollen. In vielen Fällen können alle drei Handelsstrategie-Basisklassen verwendet werden, um dieselbe Handelsstrategie zu erstellen, außer dass einige der Basisklassen im Voraus für bestimmte Arten von Strategien definiert wurden, wodurch der Strategiecode weiter vereinfacht wird. Bei dieser Strategie handelt es sich um eine typische Timing-Strategie, d. h. um eine Strategie, bei der dieselben Regeln auf verschiedene Anlagen angewandt werden, so dass wir mit dem Aufbau der Strategie unter Verwendung der Strategieklasse „RuleIterator“ beginnen können. Auf die beiden anderen Strategieklassen werden wir in späteren Beispielen zurückkommen.
Lassen Sie uns nun die drei Hauptelemente dieser Strategie verdeutlichen:
Das Timing der Strategie - der Einfachheit halber definieren wir diese Strategie so, dass sie jeden Tag zum Börsenschluss ausgeführt wird
Benötigte Daten für die Strategie - um die beiden SMAs zu berechnen, benötigen wir den historischen Schlusskurs (
"close") für jedes Mal, wenn die Strategie ausgeführt wird, und wir benötigen historische Daten für mindestens SMA-Tage in einer Reihe in der Vergangenheit, um für die Berechnung des SMA Slow ausreichend zu sein SMALogik der Strategie - Nach der Extraktion des Schlusskurses werden zunächst die beiden SMAs berechnet und dann festgestellt, ob der SMA des letzten Tages nach oben/unten durchgedrungen ist. Konkret wird das relative Verhältnis zwischen den beiden gleitenden Durchschnitten von gestern und heute verglichen. Wenn gestern der SMA größer als der FMA war und heute der SMA kleiner als der FMA ist, bedeutet dies, dass der FMA den SMA von unten durchdrungen hat, und es sollte ein Kaufsignal für die gesamte Position generiert werden, also ein Signal von 1. Wenn die Situation genau umgekehrt ist, wird ein Verkaufssignal für die gesamte Position ausgegeben - 1, und in allen anderen Fällen wird eine 0 ausgegeben, also kein Handelssignal.
Mit den obigen Ausführungen wollen wir uns nun ansehen, wie der Strategiecode definiert wird. Der erste Schritt für einen grundlegenden Strategiecode besteht darin, von der Strategie-Basisklasse (in diesem Fall „RuleIterator“) zu erben und eine eigene Klasse zu erstellen:
from qteasy import RuleIterator
from qteasy import Parameter, StgData
class Cross_SMA(RuleIterator):
# 策略的属性定义在__init__()方法中
def __init__(self):
super().__init__(
)
# 策略的具体实现代码写在策略的realize()函数中
def realize(self):
"""策略的具体实现代码:
"""
pass
Nun, die oben genannten Zeilen von Code, ist unsere erste benutzerdefinierte Handelsstrategie des gesamten Rahmens, in diesem Rahmen, um die Attribute zu füllen, fügen Sie Logik, kann eine komplette Handelsstrategie zu werden. Wie dies zu tun, definieren wir zunächst die grundlegenden Attribute der Strategie - Name, Beschreibung und einstellbare Parameter:
Der Name und die Beschreibung sind die Informationen der Strategie, es ist praktisch, die Verwendung der Strategie zu kennen, wenn sie später aufgerufen wird, wir können sie nach unseren Wünschen definieren, das kritischere Attribut ist der einstellbare Parameter.
In unserer Strategie möchten wir, dass die Berechnungsparameter der schnellen und langsamen Durchschnitte anpassbar sind, da diese beiden Parameter direkt die genaue Position der schnellen und langsamen Durchschnitte beeinflussen, was sich direkt auf den Schnittpunkt der beiden Durchschnitte auswirkt, was zu unterschiedlichen Kauf- und Verkaufspunkten führt, siehe die folgenden beiden Diagramme, die jeweils den Schnittpunkt der Durchschnitte der gleichen Aktie mit unterschiedlichen Geschwindigkeiten im gleichen Zeitraum zeigen, und wenn die Durchschnitte mit unterschiedlichen Zeiträumen berechnet werden, ergeben sich die folgenden Wenn die SMAs für unterschiedliche Zeiträume berechnet werden, sind die resultierenden Kauf- und Verkaufspunkte völlig unterschiedlich:
Die SMA-Perioden im obigen Chart sind 15 Tage/40 Tage und erzeugen drei Kauf- und zwei Verkaufssignale
Die SMA-Perioden im obigen Chart sind 5 Tage/50 Tage und generieren zwei Kauf- und ein Verkaufssignal!
Da sich die SMA-Periode direkt auf die Leistung einer Strategie auswirkt, liegt es nahe, die optimale Kombination von SMA-Perioden (Parameterkombinationen) zu finden, um die Leistung der Strategie zu optimieren. Um dies zu erreichen, erlaubt qteasy dem Benutzer, diese Parameter als „einstellbare Parameter“ zu definieren und bietet einen Optimierungsalgorithmus, um die optimalen Parameter zu finden. Bei allen eingebauten Handelsstrategien sind die Anzahl und die Bedeutung der anpassbaren Parameter festgelegt und können vom Benutzer nicht geändert werden, aber bei kundenspezifischen Strategien hat der Benutzer einen großen Spielraum, und theoretisch kann jede Variable, die für den Betrieb der Strategie verwendet wird, als anpassbarer Parameter definiert werden.
Hier definieren wir die Periode der schnellen und langsamen Durchschnitte als einstellbare Parameter mit den folgenden Definitionen in den Strategieeigenschaften
Die einstellbaren Parameter einer Strategie werden mithilfe von „Parameter“-Objekten definiert. Mit diesen Objekten können wir für jeden einstellbaren Parameter einen Namen, einen Wertebereich, einen Datentyp usw. angeben. Diese definierten einstellbaren Parameter werden automatisch an die Strategieimplementierungsfunktion übergeben, und Benutzer können sie direkt zur Implementierung der Handelslogik verwenden.
pars=[Parameter((10, 100), data_type='int', name='fast', value=30),
Parameter((10, 100), data_type='int', name='slow', value=60)], # 策略默认参数是快均线周期30, 慢均线周期60
Definition der für die Strategie benötigten Daten
Die von der Strategie benötigten Daten werden durch das Objekt „StgData“ bestimmt. In „qteasy“ kann jedes Datentypobjekt durch eine eindeutige ID, Datenhäufigkeit und Asset-Typ identifiziert werden. Sie können auch die Länge des Datenfensters festlegen.
Nach der Definition der Strategiedaten packt qteasy die Daten automatisch in das Fenster und sendet sie an die Strategie-Funktion realize(), wenn im Prozess des Backtestings alle historischen Daten in eine Reihe von Datenfenstern nach den gleichen Regeln verpackt werden, so dass es keine Rolle spielt, ob es sich um einen Backtesting- oder einen Live-Lauf handelt, die Funktion realize() empfängt die historischen Daten in genau dem gleichen Format und behandelt sie auf genau die gleiche Weise. Die Funktion realize() empfängt die historischen Daten in genau demselben Format und behandelt sie auf genau dieselbe Weise, wodurch die Konsistenz zwischen Live- und Backtest-Läufen sichergestellt und mögliche zukünftige Funktionen im Backtest vermieden werden:

Die Definition des Datentyps ist wie folgt, wir benötigen den täglichen Schlusskurs für die letzten 201 Tage, der Grund, warum wir den Schlusskurs für 201 Tage benötigen, ist, dass wir den maximalen Bereich des einstellbaren Parameters auf 200 festgelegt haben, um den gleitenden Durchschnitt mit einer Periode von 200 zu berechnen, benötigen wir den Schlusskurs für 201 Tage
data_types=[StgType('close', asset_type='ANY', freq='d', window_length=201)] # 策略基于收盘价计算均线,因此数据类型为'close',历史数据的频率为日,历史数据窗口长度为201,每一次交易信号都是由它之前前201天的历史数据决定的
Basierend auf den oben definierten Datentypen weist qteasy dieser Strategie eine eindeutige ID zu: „close_ANY_d“. Mit dieser ID können Sie in der Strategieumsetzungsfunktion historische Daten abrufen; Wir werden später vorstellen, wie historische Daten abgerufen werden.
Zu diesem Zeitpunkt sind alle wichtigen Attribute der benutzerdefinierten Handelsstrategie vollständig definiert. Als Nächstes definieren wir die Umsetzung der Strategie.
Implementierung einer benutzerdefinierten Handelsstrategie: realize()
In der Methode realize() müssen wir drei Dinge tun, die wir der Reihe nach angehen werden:
Abrufen historischer Daten
Einstellbare Parameter abrufen
Logik schreiben, um eine Ausgabe zu erzeugen
Erhalten Sie historische Daten und einstellbare Parameterwerte:
Wie bereits erwähnt, ist der einstellbare Parameter dieser Strategie die Periode der Mittelwertberechnung. Um die Periode mit Hilfe des einstellbaren Parameters zu berechnen, müssen wir die Werte des einstellbaren Parameters erhalten, die in der par_values-Eigenschaft der Strategie gespeichert sind und über self.par_values abgerufen werden können.
Mit der Methode „realize()“ ist es sehr einfach, einstellbare Parameter und historische Daten zu erhalten: Verwenden Sie jeweils „self.get_data()“ und „self.get_pars()“. Beide Methoden können mehrere Datenreihen oder Parameter gleichzeitig abrufen; Die abgerufenen Werte werden in ein „Tupel“ entpackt, das Benutzer direkt verwenden können.
def realize(self):
"""策略的具体实现代码
"""
close = self.get_data('close_ANY_d') # 通过数据ID获取数据:最近201天的收盘价
f, s = self.get_pars('fast', 'slow') # 读取快均线(fast)和慢均线(slow)的计算周期
Zu diesem Zeitpunkt sind alle Elemente, die für die Implementierung der Richtlinienlogik benötigt werden, vorhanden, und wir können als Nächstes mit der Implementierung der Richtlinienlogik beginnen.
Wenn der Benutzer die ta-lib Bibliothek installiert hat, dann kann die SMA Funktion von ta-lib direkt aufgerufen werden, um die gleitenden Durchschnittspreise zu berechnen, wenn nicht, dann ist das jetzt nicht so wichtig, weil qteasy dem Benutzer eine ta-lib freie Version der SMA Funktion zur Verfügung stellt (nicht alle technischen Indikatoren (nicht alle technischen Indikatoren haben ta-lib freie Versionen, siehe die Dokumentation für Details) können direkt für die Berechnung referenziert werden.
def realize(self, h, **kwargs):
"""策略的具体实现代码
"""
...
from qteasy.tafuncs import sma
# 使用qt.sma计算简单移动平均价
s_ma = sma(close, s)
f_ma = sma(close, f)
# 为了考察两条均线的交叉, 计算两根均线昨日和今日的值,以便判断
s_today, s_last = s_ma[-1], s_ma[-2]
f_today, f_last = f_ma[-1], f_ma[-2]
Nach der Berechnung der gleitenden Durchschnitte können wir die Ausgabe der Strategie, d.h. die Handelsentscheidung, direkt in der Methode realize festlegen.
Bei Strategien vom Typ RuleIterator müssen wir, egal wie viele Aktien unsere Strategie gleichzeitig bearbeitet, nur einen Satz von Regeln definieren, der als RuleIteration bezeichnet wird, so dass wir nur eine Zahl ausgeben müssen, die die Handelsentscheidung darstellt. Diese Zahl wird von qteasy automatisch in verschiedene Handelsaufträge umgewandelt. Die Regeln für die Umwandlung werden durch den Betriebsmodus des Operator-Objekts definiert, der in den vorherigen Tutorials beschrieben wurde, so dass ich ihn hier nicht wiederholen werde.
Kurz gesagt, wenn wir vorhaben, Operator im `“PS“-Modus arbeiten zu lassen, dann genügt es, das Handelssignal „1“ an dem Tag zu erzeugen, an dem wir kaufen sollten, und das Handelssignal „-1“ an dem Tag, an dem wir verkaufen sollten, und „0“ auszugeben, wenn wir nicht handeln wollen. „-1“ an dem Tag, an dem Sie kaufen sollten, und „0“ an dem Tag, an dem Sie verkaufen sollten, wenn Sie nicht handeln wollen:
def realize(self, h, **kwargs):
"""策略的具体实现代码
"""
...
if (f_last < s_last) and (f_today > s_today):
# 当快均线自下而上穿过上边界(即昨日快均线低于慢均线,而今天高于于慢均线),发出全仓买入信号
return 1
elif (f_last > s_last) and (f_today < s_today):
# 当快均线自上而下穿过上边界(即昨日快均线高于慢均线,而今天低于于慢均线),发出全部卖出信号
return -1
else: # 其余情况不产生任何信号
return 0
An diesem Punkt ist die Handelsstrategie definiert! Der Benutzer muss sich nur noch auf die Definition der Daten und der Logik der Strategie konzentrieren. Der vollständige Code sieht wie folgt aus (alle Kommentare wurden entfernt, um Platz zu sparen):
from qteasy import RuleIterator, Parameter, StgData
from qteasy.tafuncs import sma
# 创建双均线交易策略类
class Cross_SMA_PS(RuleIterator):
def __init__(self):
super().__init__(
name='CROSSLINE', # 策略的名称
description='快慢双均线择时策略', # 策略的描述
pars=[Parameter((10, 100), par_type='int', name='fast', value=30),
Parameter((10, 100), par_type='int', name='slow', value=60)],
data_types=[StgData('close', freq='d', asset_type='ANY', window_length=201)],
)
def realize(self):
close = self.get_data('close_ANY_d') # 通过数据ID获取数据:最近201天的收盘价
f, s = self.get_pars('fast', 'slow') # 读取快均线(fast)和慢均线(slow)的计算周期
# 使用qt.sma计算简单移动平均价
s_ma = sma(close, s)
f_ma = sma(close, f)
# 为了考察两条均线的交叉, 计算两根均线昨日和今日的值,以便判断
s_today, s_last = s_ma[-1], s_ma[-2]
f_today, f_last = f_ma[-1], f_ma[-2]
if (f_last < s_last) and (f_today > s_today):
# 当快均线自下而上穿过上边界(即昨日快均线低于慢均线,而今天高于于慢均线),发出全仓买入信号
return 1
elif (f_last > s_last) and (f_today < s_today):
# 当快均线自上而下穿过上边界(即昨日快均线高于慢均线,而今天低于于慢均线),发出全部卖出信号
return -1
else: # 其余情况不产生任何信号
return 0
Als Nächstes können wir diese benutzerdefinierte Strategie genau wie jede andere integrierte Handelsstrategie verwenden.
Wir müssen ein neues „Operator“-Objekt erstellen und beim Erstellen die „Cross_SMA“-Strategie, die wir gerade erstellt haben, in „Operator“ hinzufügen und dabei den Signaltyp dieser Strategie als „PS“ angeben. Dies weist „Operator“ an, die „PS“-Regeln zu verwenden, um die von der Handelsstrategie generierten Signale zu interpretieren:
op = qt.Operator(strategies=[Cross_SMA_PS()], signal_type='PS')
Schauen wir uns die Backtesting-Ergebnisse für diese Strategie an.
Backtest-Ergebnisse für die erste Strategie
Die Parameter für das Strategie-Backtesting sind genau die gleichen wie für die integrierte Handelsstrategie
op = qt.Operator([Cross_SMA_PS()], signal_type='PS')
# 设置op的策略参数
op.set_parameter(0,
par_values= (20, 60) # 设置快慢均线周期分别为20天、60天
)
# 设置基本回测参数,开始运行模拟交易回测
res = qt.run(op,
mode=1, # 运行模式为回测模式
asset_pool='000300.SH', # 投资标的为000300.SH即沪深300指数
invest_start='20110101', # 回测开始日期
invest_end='20191231', # 回测结束日期
visual=True # 生成交易回测结果分析图
)
Die Ergebnisse des Backtests lauten wie folgt:

Nachfolgend können wir versuchen, die einstellbaren Parameter der Strategie zu ändern und den Backtest erneut mit demselben Backtest-Intervall wie zuvor durchzuführen:
op.set_parameter(0,
par_values= (25, 166) # 设置快慢均线周期分别为25天、166天
)
# 设置基本回测参数,开始运行模拟交易回测,回测参数完全一样
res = qt.run(op,
mode=1, # 运行模式为回测模式
asset_pool='000300.SH', # 投资标的为000300.SH即沪深300指数
invest_start='20110101', # 回测开始日期
visual=True # 生成交易回测结果分析图
)
Wie Sie sehen können, haben sich die Backtesting-Ergebnisse der Strategie nach der Änderung der Parameter deutlich verbessert: Wie Sie die Strategieparameter optimieren können, erfahren Sie in den folgenden Abschnitten dieses Tutorials!
====================================
| |
| BACKTEST REPORT |
| |
====================================
qteasy running mode: 1 - History back testing
time consumption for operate signal creation: 111.0 ms
time consumption for operation back testing: 2.1 ms
investment starts on 2011-01-04 15:00:00
ends on 2019-12-30 15:00:00
Total looped periods: 9.0 years.
-------------operation summary:------------
Only non-empty shares are displayed, call
"loop_result["oper_count"]" for complete operation summary
Sell Cnt Buy Cnt Total Long pct Short pct Empty pct
000300.SH 6 7 13 46.8% -0.0% 53.2%
Total operation fee: ¥ 283.00
total investment amount: ¥ 100,000.00
final value: ¥ 180,675.40
Total return: 80.68%
Avg Yearly return: 6.80%
Skewness: -1.01
Kurtosis: 17.32
Benchmark return: 27.96%
Benchmark Yearly return: 2.78%
------strategy loop_results indicators------
alpha: -1.011
Beta: -4.128
Sharp ratio: 0.368
Info ratio: 0.009
250 day volatility: 0.134
Max drawdown: 31.58%
peak / valley: 2015-06-08 / 2015-07-08
recovered on: 2018-01-22
==================END OF REPORT===================

Bisher haben wir eine einfache benutzerdefinierte Time-Trading-Strategie implementiert. Wie implementieren wir nun die beiden anderen Strategieklassen? Lassen Sie uns das anhand von zwei weiteren Beispielen erläutern.
9.7. Rückblick auf diesen Abschnitt
In diesem Abschnitt haben wir die abstrakte Definition einer Handelsstrategie in qteasy kennengelernt, die grundlegenden Elemente, die in einer Handelsstrategie enthalten sind und wie sie definiert werden, verstanden und tatsächlich eine maßgeschneiderte Double Averaging Handelsstrategie mit einem der einfachsten Beispiele erstellt.
Als Nächstes werden wir auch mit den benutzerdefinierten Handelsstrategien fortfahren, da es eine Menge Inhalt zu ihnen gibt, so dass die Tutorials zu den benutzerdefinierten Handelsstrategien drei Kapitel einnehmen werden. Im nächsten Kapitel werden wir lernen, wie man Handelsstrategien mit Hilfe von zwei anderen benutzerdefinierten Strategie-Basisklassen erstellt (FactorSorter Factor Stock Picking Base Class und GeneralStg General Strategy Base Class). Ein weiteres Kapitel widmen wir dann einer komplexeren benutzerdefinierten Handelsstrategie, die die Flexibilität von qteasy demonstriert - wir sehen uns also im nächsten Abschnitt!