Tính toán giá đóng cửa của các cây nến Heiken Ashi trên các khung thời gian khác nhau, làm cơ sở cho phân tích động lực tiếp theo.
Tính toán sự thay đổi tỷ lệ phần trăm giữa giá mở và giá đóng lịch sử trong các khoảng thời gian khác nhau, cho cả khung thời gian hàng tháng và hàng ngày.
Dựa trên các biến động động lực trung bình, chúng ta có thể tính toán lực hỗ trợ thị trường được phản ánh thực sự bởi giá hiện tại, tức là ngưỡng động lực động ngoại trừ tiếng ồn thị trường.
Khi giá đóng vượt quá ngưỡng động lực, các vị trí dài được bắt đầu hàng tháng. Khi giá đóng dưới ngưỡng, các vị trí được đóng.
Ưu điểm lớn nhất nằm ở thực tế là thay vì chỉ đơn giản theo đuổi giá, chiến lược tính toán lực hỗ trợ thực sự đằng sau giá cho các bước vào và bước ra. Điều này có hiệu quả lọc tiếng ồn từ các thị trường khác nhau và cho phép chúng ta nắm bắt xu hướng tăng ổn định.
Ngoài ra, tất cả các dữ liệu cơ bản được bắt nguồn từ các nến Heiken Ashi, vốn giúp giảm vấn đề phụ thuộc quá nhiều vào các khung thời gian liên kết tồn tại trong các loại chiến lược nến khác.
Rủi ro lớn nhất là tính toán động lượng chỉ dựa trên giá lịch sử. Nếu các cơ sở cơ bản của công ty hoặc chế độ thị trường thay đổi đáng kể, tính đại diện của giá lịch sử giảm, dẫn đến lỗi trong việc xác định các mục nhập và thoát.
Ngoài ra, chiến lược tận dụng khung thời gian hàng tháng và hàng ngày. Điều này có nghĩa là hiệu suất thời gian thực không phải là tốt nhất, thiếu khả năng phản ứng nhanh chóng với những thay đổi giá mạnh mẽ. Do đó, có nguy cơ ra khỏi không kích hoạt kịp thời khi giá đột ngột thay đổi.
Các cách giảm thiểu có thể bao gồm kết hợp dữ liệu tần số cao hơn và phản hồi thời gian thực về các nguyên tắc cơ bản của công ty.
Có một số cách mà chiến lược có thể được cải thiện hơn nữa:
Tăng cường thêm các nến Heiken Ashi chính nó tức là tối ưu hóa cấu hình trọng lượng.
Đưa ra dữ liệu tần số cao hơn như các thanh phút để cải thiện thời gian thực.
Xem xét thêm cơ chế thu lợi nhuận và tái nhập dựa trên ngày & tuần trên đầu mục hàng tháng.
Tóm lại, chiến lược này rất ổn định nói chung, với việc theo dõi đà kiểm soát rủi ro một cách hiệu quả. Ưu điểm lớn nhất là sử dụng lực cơ bản đằng sau giá thay vì chính giá để xác định điều kiện thị trường thực sự cho các bước vào và ra. Bước tiếp theo là cải thiện thêm bằng cách kết hợp tần suất cao hơn và dữ liệu thông tin hơn để tận dụng tốt hơn các cơ hội thị trường.
/*backtest start: 2023-01-12 00:00:00 end: 2024-01-18 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ // This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © FrancoPassuello //@version=5 strategy("Heiken Ashi ADM", overlay=true) haClose = (open + high + low + close) / 4 // prevHaOpen = line.new(na, na, na, na, width = 1) haOpen = (open[1] + close[1]) / 2 // line.set_xy1(prevHaOpen, bar_index[1], nz(haOpen[1])) // line.set_xy2(prevHaOpen, bar_index, haClose[1]) [monopen, _1monopen, _2monopen, _3monopen, _4monopen, _5monopen, _6monopen] = request.security(syminfo.tickerid, "M", [haOpen, haOpen[1], haOpen[2], haOpen[3], haOpen[4], haOpen[5], haOpen[6]] , barmerge.gaps_off, barmerge.lookahead_on) [monclose, _1monclose, _3monclose, _6monclose] = request.security(syminfo.tickerid, "M", [haClose, haClose[1], haClose[3], haClose[6]] , barmerge.gaps_off, barmerge.lookahead_on) [dayclose1, _21dayclose, _63dayclose, _126dayclose, dayclose] = request.security(syminfo.tickerid, "1D", [haClose[1], haClose[21], haClose[63], haClose[126], haClose], barmerge.gaps_off, barmerge.lookahead_on) [dayopen1, _21dayopen, _63dayopen, _126dayopen] = request.security(syminfo.tickerid, "1D", [haOpen[1], haOpen[21], haOpen[63], haOpen[126]], barmerge.gaps_off, barmerge.lookahead_on) get_rate_of_return(price1, price2) => return_ = (price1/price2 -1)*100 return_ m0 = get_rate_of_return(monclose, monopen) m1 = get_rate_of_return(_1monclose, _1monopen) m2 = get_rate_of_return(monclose, _2monopen) m3 = get_rate_of_return(_1monclose, _3monopen) m4 = get_rate_of_return(monclose, _4monopen) m5 = get_rate_of_return(monclose, _5monopen) m6 = get_rate_of_return(_1monclose, _6monopen) MS = (m1 + m3 + m6)/100 CS = (m0 + m2 + m5)/100 d1 = get_rate_of_return(dayclose1, _21dayopen) d2 = get_rate_of_return(dayclose1, _63dayopen) d3 = get_rate_of_return(dayclose1, _126dayopen) DS = (d1 + d2 + d3)/100 //Last (DAILY) lastd_s_avg1 = DS/3 lastd_Approximate1 = dayclose1*(1-lastd_s_avg1) last_approx1_d21 = lastd_Approximate1 / _21dayopen-1 last_approx1_d63 = lastd_Approximate1 / _63dayopen-1 last_approx1_d126 = lastd_Approximate1 / _126dayopen-1 lastd_s_avg2 = (last_approx1_d21 + last_approx1_d63 + last_approx1_d126) / 3 lastd_approximate2 = (dayclose1)*(1-(lastd_s_avg1 + lastd_s_avg2)) lastd_price = lastd_approximate2 //plot(lastd_price,color = color.rgb(255, 255, 255, 14), title = "Last momentum threshold") //Last last_s_avg1 = MS/3 last_Approximate1 = _1monclose*(1-last_s_avg1) last_approx1_m1 = last_Approximate1 / _1monopen-1 last_approx1_m3 = last_Approximate1 / _3monopen-1 last_approx1_m6 = last_Approximate1 / _6monopen-1 last_s_avg2 = (last_approx1_m1 + last_approx1_m3 + last_approx1_m6) / 3 last_approximate2 = (_1monclose)*(1-(last_s_avg1 + last_s_avg2)) last_price = last_approximate2 Scoring_price = _1monclose*(1-CS) plot(last_price,color = color.rgb(255, 255, 255, 14), title = "Last momentum threshold") //plot(Scoring_price,color = color.rgb(234, 0, 255, 14), title = "Last momentum threshold") //Long based on month close and being the first trade of the month. var int lastClosedMonth = -1 limit_longCondition = _1monclose > last_approximate2 and (lastClosedMonth == -1 or month(time) != lastClosedMonth) // Long based on day close and being the first trade of the month. limit_Dlongcondition = dayclose1 > lastd_approximate2 and (lastClosedMonth == -1 or month(time) != lastClosedMonth) // Close trade based on day close DCloseLongCondition = dayclose1<lastd_approximate2 //Old standard Trading rules longCondition = _1monclose > Scoring_price MCloseLongCondition = _1monclose<Scoring_price shortCondition = CS < 0 if (longCondition) strategy.entry("Long", strategy.long) if (strategy.position_size > 0 and MCloseLongCondition) strategy.close("Long") lastClosedMonth := month(time)