Trong số nhiều chiến lược giao dịch, chiến lược kênh Donchian là một trong những chiến lược đột phá cổ điển nhất. Nó nổi tiếng từ đầu năm 1970. Vào thời điểm đó, một công ty nước ngoài đã tiến hành thử nghiệm mô phỏng và nghiên cứu về các chiến lược giao dịch chương trình chính. Kết quả cho thấy chiến lược kênh Donchian là chiến lược thành công nhất trong tất cả các thử nghiệm chiến lược.
Sau đó, khóa đào tạo thương nhân
Chiến lược giao dịch đột phá phù hợp với các loại giao dịch có xu hướng tương đối mượt mà. Phương pháp giao dịch đột phá phổ biến nhất là sử dụng mối quan hệ vị trí tương đối giữa giá, hỗ trợ và kháng cự để đánh giá điểm giao dịch cụ thể. Chiến lược kênh Donchian trong bài viết này cũng dựa trên nguyên tắc này.
Kênh Donchian là một chỉ số xu hướng, và ngoại hình và tín hiệu của nó tương tự như của chỉ số Bollinger Band. Tuy nhiên, kênh giá của Donchian được xây dựng theo giá cao nhất và giá thấp nhất trong một khoảng thời gian nhất định. Ví dụ, giá trị tối đa của giá cao nhất của 50 đường K mới nhất được tính để tạo thành đường dẫn trên; Tính toán giá trị tối thiểu của giá thấp nhất của 50 đường K mới nhất để tạo thành đường dẫn dưới.
Như được hiển thị trong hình trên, chỉ số này bao gồm ba đường cong với màu sắc khác nhau. Theo mặc định, giá cao nhất và thấp nhất trong 20 giai đoạn được sử dụng để hiển thị sự biến động của giá thị trường. Khi kênh hẹp, điều đó có nghĩa là biến động thị trường nhỏ. Ngược lại, khi kênh rộng, điều đó có nghĩa là biến động thị trường lớn.
Nếu giá tăng trên đường dẫn trên, đó là tín hiệu mua; Ngược lại, nếu giá giảm dưới đường dẫn dưới, đó là tín hiệu bán. Vì đường dẫn trên và dưới được tính bằng giá cao nhất và thấp nhất, nói chung, giá hiếm khi tăng và giảm dưới đường dẫn trên và dưới cùng một lúc. Trong hầu hết các trường hợp, giá di chuyển dọc theo đường dẫn trên hoặc dưới một bên, hoặc giữa đường dẫn trên và dưới.
Có nhiều cách để sử dụng kênh Donchian, có thể sử dụng một mình hoặc kết hợp với các chỉ số khác. Trong bài học này, chúng tôi sẽ sử dụng phương pháp đơn giản nhất. Đó là, khi giá vượt qua đường dẫn trên từ dưới lên trên, tức là trên đường áp lực, chúng tôi tin rằng sức mạnh của nhiều bên đang tăng lên, một làn sóng thị trường tăng đã được hình thành và tín hiệu mua vị trí mở đã được tạo ra; Khi giá giảm xuống dưới đường dẫn dưới từ trên xuống dưới, tức là dưới đường hỗ trợ, chúng tôi tin rằng phía vị trí ngắn đang tăng cường, một làn sóng xu hướng giảm đã được hình thành và tín hiệu bán vị trí mở đã được tạo ra.
Nếu giá giảm trở lại đường ray giữa kênh Donchian sau khi mua để mở một vị trí, chúng tôi nghĩ rằng lực đa bên đang suy yếu, hoặc lực nhóm vị trí ngắn đang tăng cường, và tín hiệu bán và đóng vị trí được tạo ra; Nếu giá tăng trở lại đường ray giữa kênh Donchian sau khi mở vị trí bán, chúng tôi nghĩ rằng phía vị trí ngắn đang suy yếu, hoặc các lực đa bên đang tăng cường, và tín hiệu đóng vị trí mua được tạo ra.
Điều kiện mua và bán
Tiếp theo, chúng ta sẽ hiểu chiến lược này một lần một trong môi trường nghiên cứu của nền tảng FMZ Quant:
Nhập môi trường nghiên cứu của nền tảng FMZ Quant, như được hiển thị bên dưới:
Chiến lược kênh Donchian trong phiên bản Python.ipynb Trong [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.
Trong [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.
Bỏ [2]:0
Trong [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.
Ra khỏi [1]:
{
Sau đó, chúng ta có được mảng K-line, bởi vì theo logic chiến lược, chúng ta cần thị trường chạy trong một khoảng thời gian và sau đó đưa ra các phán đoán logic, để logic chiến lược của chúng ta có thể thích nghi tốt hơn với thị trường. Ở đây chúng ta sẽ tạm thời lấy 50 K-line làm yêu cầu khởi đầu. Thông tin K-line của FMZ Quant được lưu trữ dưới dạng mảng, chứa giá cao nhất, giá thấp nhất, giá mở cửa, giá đóng cửa, số lượng giao dịch và các thông tin khác. Đối với nội dung của phần này, vui lòng tham khảo tài liệu API chính thức của nền tảng FMZ Quant:https://www.fmz.com/api
Trong [4]:
# Next we define a variable to store the K-line array.
records = exchange.GetRecords() # Get the K-line array
Trong [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
Ra khỏi [5]: 3846.0
Sau đó, chúng ta cần tính giá trị tối đa của giá cao nhất và giá trị tối thiểu của giá thấp nhất trong 50 K-line bằng cách sử dụng giá đóng như tiêu chuẩn.
Trong [6]:
upper = TA.Highest(records, 50, 'High') # Get the maximum value of the 50-period maximum price
upper
Ra ngoài[6]: 3903.0
Trong [7]:
lower = TA.Lowest(records, 50, 'Low') # Get the minimum value of the 50-period minimum price
lower
Ra ngoài[7]: 3856.0
Tiếp theo, chúng ta cần tính toán giá trị trung bình của các đường ray trên và dưới của kênh này.
Trong [8]:
middle = (upper + lower) / 2 # Calculate the average value of the upper and lower tracks.
middle
Ra ngoài[8]: 3879,5
Ở trên, chúng ta đã hoàn thành tất cả các tính toán cần thiết cho chiến lược này. Tiếp theo, chúng ta sẽ bắt đầu đánh giá các điều kiện mở ra một cách hợp lý và thực hiện hoạt động vị trí mở thực tế theo kết quả của phán đoán hợp lý. Cần lưu ý ở đây rằng chúng ta cần sử dụng mẫu tương lai hàng hóa trong nước của nền tảng FMZ Quant. Vì môi trường nghiên cứu hiện tại không thể hỗ trợ mẫu này, chúng ta sẽ viết nó tạm thời, nhưng hoạt động sẽ báo cáo lỗi, trong trang viết chiến lược nền tảng FMZ Quant cho mã hóa thực tế, nhập mẫu này mà không có vấn đề gì, địa chỉ mẫu là:https://www.fmz.com/strategy/24288. Khi bạn mã trên trang chỉnh sửa chiến lược nền tảng FMZ Quant, bạn cần sao chép mẫu này vào thư viện chiến lược của riêng bạn trước tiên, và sau đó kiểm tra nó khi backtesting.
Trong [ ]:
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.
Bước tiếp theo là xác định logic của chiến lược và mở và đóng các vị trí theo logic.
Trong [ ]:
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
Trong [ ]:
# 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