Chiến lược này tạo ra các tín hiệu giao dịch dựa trên sự chéo chéo giữa giá mở và giá cao. Nó đi dài khi giá mở vượt quá giá cao và đi ngắn khi giá mở vượt dưới giá cao. Trung bình chuyển động có thể được sử dụng để làm mịn dữ liệu giá và giảm giao dịch ồn ào.
Xác định xem có nên sử dụng độ phân giải thay thế dựa trên thông số đầu vào useRes. Nếu được bật, hãy đặt độ phân giải bằng stratRes.
Quyết định sử dụng trung bình động (useMA) dựa trên tham số đầu vào. Nếu được bật, chọn loại MA với baseType và đặt thời gian dài với basisLen.
Nhận dữ liệu chuỗi giá mở (mở) và giá đóng (khép).
So sánh giá mở hiện tại x với openSeries openSeries. Nếu x lớn hơn openSeries, đặt trendState thành long, nếu không thì thành short.
Tạo tín hiệu dài longCond khi giá mở vượt trên chuỗi MA mở. Tạo tín hiệu ngắn shortCond khi giá mở vượt dưới chuỗi MA mở.
Nhập các vị trí dài hoặc ngắn dựa trên tín hiệu dài và ngắn.
Sử dụng hai chuỗi giá khác nhau, mở và cao, tránh những hạn chế của chuỗi duy nhất.
Các kỹ thuật MA lọc ra tiếng ồn ngắn hạn và tập trung vào xu hướng chính.
Cấu hình linh hoạt của các loại và tham số MA để có hiệu quả tối ưu.
Tùy chọn dừng lỗ để kiểm soát rủi ro và khóa lợi nhuận.
Không gian tối ưu hóa cao để điều chỉnh các thông số cho các sản phẩm và môi trường thị trường khác nhau.
Nguồn tín hiệu duy nhất dẫn đến tín hiệu khan hiếm và có khả năng bỏ lỡ giao dịch.
Sự chậm trễ của MA có thể dẫn đến việc bỏ lỡ các cơ hội ngắn hạn.
Cấu hình stop loss không đúng có thể dẫn đến thoát sớm hoặc mất quá nhiều.
Điều chỉnh tham số kém có thể gây ra giao dịch hư cấu quá mức ảnh hưởng đến màn trình diễn trực tiếp.
Tối ưu hóa tham số là một thách thức cho các sản phẩm và môi trường khác nhau.
Thêm thêm các chỉ số hoặc mô hình ML để làm giàu nguồn tín hiệu. Điều chỉnh tốt các loại MA và tham số. Thiết lập stop loss cẩn thận với một số bộ đệm để nắm bắt nhiều lợi nhuận hơn. Kiểm tra kỹ lưỡng và tối ưu hóa các tham số.
Kết hợp các chỉ số bổ sung như Bollinger Bands, KD vv để mở rộng nguồn tín hiệu.
Áp dụng các mô hình học máy để tạo tín hiệu.
Tối ưu hóa các tham số MA để tìm các cấu hình tốt nhất.
Cân bằng mức dừng lỗ giữa rủi ro và thu lợi nhuận.
Thêm các phương pháp tối ưu hóa tham số để tự động tìm các thiết lập tối ưu.
Phát triển các mẫu tham số chuyên biệt cho các sản phẩm khác nhau.
Xây dựng khung kiểm tra hậu quả định lượng cho các lần lặp chiến lược nhanh chóng.
Chiến lược này tạo ra các tín hiệu dựa trên các đường chéo cao mở và sử dụng MAs để lọc tiếng ồn. Nó cung cấp tính linh hoạt thông qua các tham số có thể cấu hình. Chiến lược này có những lợi thế nhưng cũng có một số vấn đề như tín hiệu thưa thớt và trễ. Các cải tiến hơn nữa có thể được thực hiện thông qua nhiều chỉ số, mô hình học máy, vv. Cần điều chỉnh và tối ưu hóa tham số rộng rãi để có hiệu suất tốt nhất trên các sản phẩm và môi trường thị trường khác nhau.
/*backtest start: 2022-10-17 00:00:00 end: 2023-10-17 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=2 //strategy(title = "Open Close Cross Strategy", shorttitle = "OCC Strategy", overlay = true, pyramiding = 0, default_qty_type = strategy.percent_of_equity, default_qty_value = 10) // Revision: 1 // Author: @JayRogers // // Description: // - Strategy based around Open-Close Crossovers. // Setup: // - I have generally found that setting the strategy resolution to 3-4x that of the chart you are viewing // tends to yield the best results, regardless of which MA option you may choose (if any) // - Don't aim for perfection. Just aim to get a reasonably snug fit with the O-C band, with good runs of // green and red. // - Option to either use basic open and close series data, or pick your poison with a wide array of MA types. // - Optional trailing stop for damage mitigation if desired (can be toggled on/off) // - Positions get taken automagically following a crossover - which is why it's better to set the resolution // of the script greater than that of your chart, so that the trades get taken sooner rather than later. // - If you make use of the trailing stops, be sure to take your time tweaking the values. Cutting it too fine // will cost you profits but keep you safer, while letting them loose could lead to more drawdown than you // can handle. // === INPUTS === useRes = input(defval = true, title = "Use Alternate Resolution? ( recommended )") stratRes = input(defval = "120", title = "Set Resolution ( should not be lower than chart )") useMA = input(defval = true, title = "Use MA? ( otherwise use simple Open/Close data )") basisType = input(defval = "DEMA", title = "MA Type: SMA, EMA, DEMA, TEMA, WMA, VWMA, SMMA, HullMA, LSMA, ALMA ( case sensitive )") basisLen = input(defval = 14, title = "MA Period", minval = 1) offsetSigma = input(defval = 6, title = "Offset for LSMA / Sigma for ALMA", minval = 0) offsetALMA = input(defval = 0.85, title = "Offset for ALMA", minval = 0, step = 0.01) useStop = input(defval = true, title = "Use Trailing Stop?") slPoints = input(defval = 200, title = "Stop Loss Trail Points", minval = 1) slOffset = input(defval = 400, title = "Stop Loss Trail Offset", minval = 1) // === /INPUTS === // === BASE FUNCTIONS === // Returns MA input selection variant, default to SMA if blank or typo. variant(type, src, len, offSig, offALMA) => v1 = sma(src, len) // Simple v2 = ema(src, len) // Exponential v3 = 2 * v2 - ema(v2, len) // Double Exponential v4 = 3 * (v2 - ema(v2, len)) + ema(ema(v2, len), len) // Triple Exponential v5 = wma(src, len) // Weighted v6 = vwma(src, len) // Volume Weighted v7 = na(v5[1]) ? sma(src, len) : (v5[1] * (len - 1) + src) / len // Smoothed v8 = wma(2 * wma(src, len / 2) - wma(src, len), round(sqrt(len))) // Hull v9 = linreg(src, len, offSig) // Least Squares v10 = alma(src, len, offALMA, offSig) // Arnaud Legoux type=="EMA"?v2 : type=="DEMA"?v3 : type=="TEMA"?v4 : type=="WMA"?v5 : type=="VWMA"?v6 : type=="SMMA"?v7 : type=="HullMA"?v8 : type=="LSMA"?v9 : type=="ALMA"?v10 : v1 // security wrapper for repeat calls reso(exp, use, res) => use ? request.security(syminfo.tickerid, res, exp) : exp // === /BASE FUNCTIONS === // === SERIES SETUP === // open/close //closeSeries = useMA ? reso(variant(basisType, close, basisLen, offsetSigma, offsetALMA), useRes, stratRes) : reso(close, useRes, stratRes) openSeries = useMA ? reso(variant(basisType, open, basisLen, offsetSigma, offsetALMA), useRes, stratRes) : reso(open, useRes, stratRes) x = openSeries[1] trendState = x > openSeries ? true : x < openSeries ? false : trendState[1] // === /SERIES === // === PLOTTING === barcolor(color = x > openSeries ? #006600 : #990000, title = "Bar Colours") // channel outline closePlot = plot(x, title = "Close Line", color = #009900, linewidth = 2, style = line, transp = 90) openPlot = plot(openSeries, title = "Open Line", color = #CC0000, linewidth = 2, style = line, transp = 90) // channel fill closePlotU = plot(trendState ? x : na, transp = 100, editable = false) openPlotU = plot(trendState ? openSeries : na, transp = 100, editable = false) closePlotD = plot(trendState ? na : x, transp = 100, editable = false) openPlotD = plot(trendState ? na : openSeries, transp = 100, editable = false) fill(openPlotU, closePlotU, title = "Up Trend Fill", color = #009900, transp = 40) fill(openPlotD, closePlotD, title = "Down Trend Fill", color = #CC0000, transp = 40) // === /PLOTTING === // === STRATEGY === // conditions longCond = crossover(openSeries, x) shortCond = crossunder(openSeries, x) // entries and base exit strategy.entry("long", true, when = longCond) strategy.entry("short", false, when = shortCond) // if we're using the trailing stop //if (useStop) // strategy.exit("XL", from_entry = "long", trail_points = slPoints, trail_offset = slOffset) // strategy.exit("XS", from_entry = "short", trail_points = slPoints, trail_offset = slOffset) // not sure needed, but just incase.. //strategy.exit("XL", from_entry = "long", when = shortCond) //strategy.exit("XS", from_entry = "short", when = longCond) // === /STRATEGY ===