Unter vielen Handelsstrategien sollte die Donchian Channel-Strategie eine der klassischsten Durchbruchstrategie sein. Sie war bereits 1970 berühmt. Zu dieser Zeit führte eine ausländische Firma Simulationstests und Untersuchungen zu den Mainstream-Programm-Handelsstrategien durch. Die Ergebnisse zeigten, dass die Donchian Channel-Strategie die erfolgreichste aller Strategietests war.
Später fand in den Vereinigten Staaten das berühmteste
Durchbruchshandelsstrategie ist geeignet für den Handel mit Varianten mit relativ glatten Trend. Die häufigste Durchbruchshandelsmethode ist die Verwendung der relativen Position Beziehung zwischen Preis, Unterstützung und Widerstand, um den spezifischen Handelspunkt zu beurteilen. Die Donchian Channel Strategie in diesem Artikel basiert auch auf diesem Prinzip.
Der Donchian Channel ist ein Trendindikator, dessen Aussehen und Signal denjenigen des Bollinger Bands-Indikators etwas ähnlich sind. Der Preiskanal des Donchian ist jedoch nach dem höchsten Preis und dem niedrigsten Preis innerhalb eines bestimmten Zeitraums konstruiert. Zum Beispiel wird der maximale Wert des höchsten Preises der letzten 50 K-Linien berechnet, um die obere Spur zu bilden; Berechnen Sie den Mindestwert des niedrigsten Preises der letzten 50 K-Linien, um die untere Spur zu bilden.
Wie in der obigen Abbildung gezeigt, besteht dieser Indikator aus drei Kurven mit verschiedenen Farben. Standardmäßig werden die höchsten und niedrigsten Preise innerhalb von 20 Perioden verwendet, um die Volatilität der Marktpreise zu zeigen. Wenn der Kanal schmal ist, bedeutet dies, dass die Marktvolatilität gering ist. Umgekehrt bedeutet der Kanal breit, dass die Marktvolatilität groß ist.
Wenn der Preis über die obere Spur steigt, ist es ein Kaufsignal; Im Gegenteil, wenn der Preis unter die untere Spur fällt, ist es ein Verkaufssignal. Da die oberen und unteren Spuren durch die höchsten und niedrigsten Preise berechnet werden, steigen und fallen die Preise in der Regel selten unter die oberen und unteren Kanallinien gleichzeitig. In den meisten Fällen bewegt sich der Preis entlang der oberen oder unteren Spuren einseitig oder zwischen den oberen und unteren Spuren.
Es gibt viele Möglichkeiten, den Donchian Channel zu verwenden, die allein oder in Kombination mit anderen Indikatoren verwendet werden können. In dieser Lektion werden wir die einfachste Methode verwenden. Das heißt, wenn der Preis durch die obere Spur von unten nach oben bricht, d.h. über die Drucklinie, glauben wir, dass die Stärke vieler Parteien wächst, eine Welle des steigenden Marktes gebildet wurde und das Signal für eine geöffnete Position erzeugt wurde; Wenn der Preis unter die untere Spur von oben nach unten fällt, d.h. unter die Unterstützungslinie, glauben wir, dass die Seite der Short-Position stärker wird, eine Welle eines Abwärtstrends gebildet wurde und das Signal für eine Verkaufsposition erzeugt wurde.
Wenn der Preis nach dem Kauf zur Eröffnung einer Position auf die mittlere Spur des Donchian-Kanals zurückfällt, denken wir, dass die Multi-Partei-Kraft schwächt, oder die Short-Position-Partei-Kraft stärkt und das Signal zum Verkauf und Schließen der Position generiert wird; Wenn der Preis nach der Eröffnung der Verkaufsposition wieder auf die mittlere Spur des Donchian-Kanals steigt, denken wir, dass die Short-Positionsseite schwächt oder die Multi-Partei-Kräfte stärken und das Kaufschließungssignal generiert wird.
Kauf- und Verkaufsbedingungen
Als nächstes werden wir diese Strategie in der Forschungsumgebung der FMZ Quant-Plattform einzeln verstehen:
Die Forschungsumgebung der FMZ Quant-Plattform wird wie unten dargestellt eingegeben:
Donchian Channel Strategie in Python Version.ipynb In [1]:
from fmz import *
task = VCtx('''backtest
start: 2019-08-01 09:00:00
end: 2019-10-10 15:00:00
period: 5m
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
''')
# Create a Backtesting Environment
# The example format of the backtest information in red above can be obtained by clicking "Save settings" on the strategy edting page of the FMZ Quant platform.
In [2]:
# First, we need to get the position information, and we define a mp() function to do this.
def mp():
positions = exchange.GetPosition() # Get position array
if len(positions) == 0: # If the length of the position array is 0
return 0 # Prove a short position, return 0
for i in range(len(positions)): # Iterate through the positions array
if (positions[i]['Type'] == PD_LONG) or (positions[i]['Type'] == PD_LONG_YD):
return 1 # If there are long position orders, return 1
elif (positions[i]['Type'] == PD_SHORT) or (positions[i]['Type'] == PD_SHORT_YD):
return -1 # If there are short position orders, return -1
print(positions)
mp() # Next, we execute this function to get the position information, and we can see that the result is 0, which means that the current position is short.
Ausgeschaltet[2]:0
In [3]:
# Let's start testing this strategy using the current main rebar contract as an example.
exchange.SetContractType("rb888") # Set the variety code, the main contract is the contract code followed by the number 888.
Ausgeschaltet[3]:
{
Als nächstes erhalten wir das K-Line-Array, da wir nach der strategischen Logik den Markt für einen bestimmten Zeitraum laufen lassen müssen und dann logische Urteile fällen müssen, damit sich unsere strategische Logik besser an den Markt anpassen kann. Hier nehmen wir vorübergehend 50 K-Linien als Ausgangsvoraussetzung. Die K-Line-Informationen von FMZ Quant werden in Form eines Arrays gespeichert, das den höchsten Preis, den niedrigsten Preis, den Eröffnungspreis, den Schließpreis, die Handelsmenge und andere Informationen enthält. Für den Inhalt dieses Teils lesen Sie bitte das offizielle API-Dokument der FMZ Quant-Plattform:https://www.fmz.com/api
In [4]:
# Next we define a variable to store the K-line array.
records = exchange.GetRecords() # Get the K-line array
In [5]:
# According to the strategy logic description, we use the closing price as the price to open a position, so we need to calculate the closing price of the latest K-line.
close = records[len(records) - 1].Close # Get the latest K-line closing price
close
Ausgeschaltet[5]: 3846,0
Dann müssen wir den maximalen Wert des höchsten Preises und den minimalen Wert des niedrigsten Preises in den 50 K-Linien berechnen, indem wir den Schlusskurs als Standard verwenden.
In [6]:
upper = TA.Highest(records, 50, 'High') # Get the maximum value of the 50-period maximum price
upper
Ausgeschaltet[6]: 3903.0
In [7]:
lower = TA.Lowest(records, 50, 'Low') # Get the minimum value of the 50-period minimum price
lower
Aus[7]: 3856,0
Als nächstes müssen wir den Durchschnittswert der oberen und unteren Gleise dieses Kanals berechnen.
In [8]:
middle = (upper + lower) / 2 # Calculate the average value of the upper and lower tracks.
middle
Außen[8]: 3879,5
Wir haben oben alle für diese Strategie erforderlichen Berechnungen abgeschlossen. Als nächstes werden wir beginnen, die Eröffnungsbedingungen logisch zu beurteilen und die tatsächliche Eröffnungsposition nach den Ergebnissen des logischen Urteils auszuführen. Hier sollte beachtet werden, dass wir die inländische Rohstoff-Futures-Vorlage der FMZ Quant-Plattform verwenden müssen. Da die aktuelle Forschungsumgebung diese Vorlage nicht unterstützen kann, werden wir sie vorübergehend schreiben, aber die Operation wird einen Fehler melden, in der FMZ Quant-Plattform-Strategie-Schreibseite für die tatsächliche Codierung, importieren Sie diese Vorlage ohne Probleme, die Vorlageadresse ist:https://www.fmz.com/strategy/24288. Wenn Sie Code auf der FMZ Quant Plattform Strategie Bearbeitungseite, müssen Sie diese Vorlage zuerst in Ihre eigene Strategie-Bibliothek zu kopieren, und dann markieren Sie es bei Backtesting.
In [ ]:
obj = ext.NewPositionManager() # When using the FMZ Quant trading class library, errors will be reported at runtime, which can be ignored. Now it is the research environment,
# This problem does not occur during the actual coding process, and the following is the same without further comment.
Der nächste Schritt besteht darin, die Logik der Strategie zu bestimmen und entsprechend Positionen zu eröffnen und zu schließen.
In [ ]:
if positions > 0 and close < middle: # If you hold a long position order and the closing price falls below the middle track
obj.CoverAll() # Close all positions
if positions < 0 and close > middle: # If you hold a short position order and the closing price rises above the middle track
obj.CoverAll() # Close all positions
if positions == 0: # If it's a short position
if close > upper: # If the closing price rises above the upper track
obj.OpenLong("rb888", 1) # Buy opening positions
elif close < lower: # If the closing price falls below the lower track
obj.OpenShort("rb888", 1) # Sell opening positions
In [ ]:
# Complete strategy code:
def mp():
positions = exchange.GetPosition() # Get the position array
if len(positions) == 0: # If the length of the position array is 0
return 0 # It proved a short position, return 0
for i in range(len(positions)): # Iterate through the positions array
if (positions[i]['Type'] == PD_LONG) or (positions[i]['Type'] == PD_LONG_YD):
return 1 # If there are long position orders, return 1
elif (positions[i]['Type'] == PD_SHORT) or (positions[i]['Type'] == PD_SHORT_YD):
return -1 # If there are short position orders, return -1
def main(): # Main function
exchange.SetContractType("rb888") # Set the variety code, the main contract is the contract code followed by the number 888
while True: # Enter the loop
records = exchange.GetRecords() # Get the K-line array
if len(records) < 50: continue # If there are less than 50 K-lines, skip the loop
close = records[len(records) - 1].Close # Get the latest K-line closing price
positions = mp() # Get position information function
upper = TA.Highest(records, 50, 'High') # Get the maximum value of the 50-period maximum price
lower = TA.Lowest(records, 50, 'Low') # Get the minimum value of the 50-period minimum price
middle = (upper + lower) / 2 # Calculate the average value of the upper and lower tracks
obj = ext.NewPositionManager() # Use the Trading Library
if positions > 0 and close < middle: # If you hold a long position order and the closing price falls below the middle track
obj.CoverAll() # Close all positions
if positions < 0 and close > middle: # If you hold a short position order and the closing price rises above the middle track
obj.CoverAll() # Close all positions
if positions == 0: # If it's a short position
if close > upper: # If the closing price rises above the upper track
obj.OpenLong("rb888", 1) # Buy opening positions
elif close < lower: # If the closing price falls below the lower track
obj.OpenShort("rb888", 1) # Sell opening positions