Chiến lược giao dịch định lượng dựa trên bộ lọc Voss và chỉ số xu hướng

Tác giả:ChaoZhang, Ngày: 2023-09-19 16:59:10
Tags:

Tổng quan

Chiến lược này kết hợp Voss Predictive Filter và Ehlers Instantaneous Trendline chỉ số để xác định các bước ngoặt chu kỳ trong thị trường cho giao dịch định lượng. Voss filter cung cấp tín hiệu mua / bán sớm, trong khi chỉ số xu hướng xác định hướng xu hướng tổng thể để tránh gây nhầm lẫn từ bộ lọc Voss trong thị trường xu hướng. Chiến lược này hoạt động tốt trên các công cụ như Bitcoin thể hiện các mô hình chu kỳ, như được chứng minh bởi kết quả backtest tốt.

Chiến lược logic

Bộ lọc dự đoán Voss

Bộ lọc Voss xuất phát từ bài viết của John F. Ehlers A Peek Into The Future.

_filt = 0.5 * _s3 * _x1 + _f1 * _s2 * _filt[1] - _s1 * _filt[2] 
_voss = _x2 * _filt - _sumC

Trong đó _x1 là chênh lệch giá thứ nhất; _x2 là yếu tố làm mịn; _s1, _s2, _s3 là tham số bộ lọc; _f1 là tham số chu kỳ; _filt là đầu ra bộ lọc; _voss là đầu ra cuối cùng.

Bộ lọc có thể được xem như một bộ lọc mịn mà nhấn mạnh thông tin chu kỳ hiện tại và quá khứ để tạo ra các tín hiệu sớm.

Chỉ số đường xu hướng tức thời

Chỉ số đường xu hướng được tính như sau:

_it = (_a-((_a*_a)/4.0))*_src+0.5*_a*_a*_src[1]-(_a-0.75*_a*_a)*_src[2]+2*(1-_a)*nz(_it[1])+-(1-_a)*(1-_a)*nz(_it[2]) 

Nó vẽ một đường xu hướng trong thời gian thực phù hợp với hành động giá, xác định chính xác hướng và sức mạnh xu hướng.

Chiến lược logic

Một tín hiệu mua được tạo ra khi Voss vượt qua kết quả lọc.

Một tín hiệu bán được tạo ra khi Voss đi qua kết quả lọc.

Các tín hiệu giao dịch chỉ được chấp nhận nếu được xác nhận bởi chỉ số đường xu hướng.

Ưu điểm

  • Bộ lọc Voss cung cấp các tín hiệu dự đoán sớm để bắt được các vòng xoay chu kỳ
  • Chỉ số đường xu hướng xác định chính xác hướng xu hướng, tránh các tín hiệu sai
  • Các thông số có thể được tối ưu hóa cho các chu kỳ và môi trường thị trường khác nhau
  • Dừng có thể được thêm vào để kiểm soát rủi ro

Rủi ro và giảm thiểu

  • Chiến lược dựa trên các tín hiệu sớm, có khả năng bỏ lỡ một số xu hướng
  • Các tín hiệu chống xu hướng có thể xảy ra trong xu hướng mạnh, gây ra tổn thất

Các rủi ro có thể được giảm bằng cách:

  • Các tham số thời gian tối ưu hóa cho chu kỳ thiết bị
  • Giảm băng thông bộ lọc để giảm tín hiệu sai
  • Thêm bộ lọc xu hướng để tránh các tín hiệu chống lại xu hướng mạnh
  • Sử dụng dừng để kiểm soát lỗ cho mỗi giao dịch

Cơ hội gia tăng

Chiến lược có thể được cải thiện bằng cách:

  • Cố gắng các nguồn giá khác nhau như gần, trung bình di chuyển vv
  • Thời gian điều chỉnh bộ lọc cho các chu kỳ cụ thể của thiết bị
  • Tối ưu hóa các thông số chỉ số xu hướng để phát hiện xu hướng tốt hơn
  • Thử các chỉ số xu hướng khác nhau để kết hợp tốt hơn
  • Thêm dừng lại, dừng lại để kiểm soát rủi ro tốt hơn
  • Tối ưu hóa tham số cho tập hợp tham số tốt nhất

Kết luận

Chiến lược này kết hợp bộ lọc Voss và chỉ số xu hướng để xác định hiệu quả các bước ngoặt chu kỳ trên thị trường. Với các thông số tối ưu và kiểm soát rủi ro, nó có thể tạo ra một hệ thống giao dịch định lượng mạnh mẽ. Nó có thể áp dụng rộng rãi cho các công cụ hiển thị các mô hình chu kỳ, như được chứng minh bởi kết quả backtest tốt. Nhìn chung, chiến lược có khả năng dự đoán độc đáo và tiềm năng nâng cao rộng rãi thông qua tối ưu hóa đa chiều.


/*backtest
start: 2023-08-19 00:00:00
end: 2023-09-18 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// A Peek Into the Future
// John F. Ehlers
// TASC Aug 2019

// Created by e2e4mfck for tradingview.com
// Modified by © Bitduke

//@version=4
//strategy("Voss Strategy (Filter + IT)", overlay=false, calc_on_every_tick=false,pyramiding=0, default_qty_type=strategy.cash,default_qty_value=1000, currency=currency.USD, initial_capital=1000,commission_type=strategy.commission.percent, commission_value=0.075)

// voss filter

source = input(close, type = input.source)
period = input(20, type = input.integer)
predict = input(4, type = input.integer)
bandwidth = input(0.25, type = input.float)

// it trendline

src = input(hl2, title="Source IT")
a = input(0.07, title="Alpha", step=0.01) 
fr = input(false, title="Fill Trend Region")
ebc = input(false, title="Enable barcolors")
hr = input(false, title="Hide Ribbon")


voss_filter (_period, _predict, _bandwidth, _source) =>
	float _filt = 0, float _sumC = 0, float _voss = 0
	_PI		= 2 * asin(1)
	_order	= 3 * _predict
	_f1		= cos(2 * _PI / _period)
	_g1		= cos(_bandwidth * 2 * _PI / _period)
	_s1		= 1 / _g1 - sqrt(1 / (_g1 * _g1) - 1)
	_s2		= 1 + _s1
	_s3		= 1 - _s1
	_x1		= _source - _source[2]
	_x2		= (3 + _order) / 2

	for _i = 0 to (_order - 1)
		_sumC := _sumC + ((_i + 1) / _order) * _voss[_order - _i]

	if bar_index <= _order
		_filt := 0		
		_voss := 0		
	else			
		_filt := 0.5 * _s3 * _x1 + _f1 * _s2 * _filt[1] - _s1 * _filt[2]
		_voss := _x2 * _filt - _sumC

	[_voss, _filt]


[Voss, Filt] = voss_filter(period, predict, bandwidth, source)


instantaneous_trendline (_src, _a, _freq, _ebc, _hr) =>
    _it = 0.0
    _it := (_a-((_a*_a)/4.0))*_src+0.5*_a*_a*_src[1]-(_a-0.75*_a*_a)*_src[2]+2*(1-_a )*nz(_it[1], ((_src+2*_src[1]+_src[2])/4.0))-(1-_a)*(1-_a)*nz(_it[2], ((_src+2*_src[1]+_src[2])/4.0))
    _lag = 2.0*_it-nz(_it[2])
    
    [_it, _lag]

[it, lag] = instantaneous_trendline(src, a, fr, ebc, hr)

// - - - - -  - - - - - //

plot(Filt, title = "Filter", style = plot.style_line, color = color.red, linewidth = 2)
plot(Voss, title = "Voss", style = plot.style_line, color = color.blue,	linewidth = 2)
hline(0.0, title = "Zero", linestyle = hline.style_dashed, color = color.black,	linewidth = 1)
plot(hr? na:it, title="IT Trend", color= fr? color.gray : color.red, linewidth=1)
plot(hr? na:lag, title="IT Trigger", color=fr? color.gray : color.blue, linewidth=1)


// Strategy Logic
longCondition =  lag < it  and crossover(Voss,Filt) 
shortCondition = it > lag and crossover(Filt,Voss) 

strategy.entry("Voss_Short", strategy.short, when=shortCondition)
strategy.entry("Voss_Long", strategy.long, when=longCondition)


// === Backtesting Dates === thanks to Trost

testPeriodSwitch = input(true, "Custom Backtesting Dates")
testStartYear = input(2019, "Backtest Start Year")
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testStartHour = input(0, "Backtest Start Hour")
testPeriodStart = timestamp(testStartYear, testStartMonth, testStartDay, testStartHour, 0)
testStopYear = input(2020, "Backtest Stop Year")
testStopMonth = input(2, "Backtest Stop Month")
testStopDay = input(29, "Backtest Stop Day")
testStopHour = input(0, "Backtest Stop Hour")
testPeriodStop = timestamp(testStopYear, testStopMonth, testStopDay, testStopHour, 0)
testPeriod() =>
    time >= testPeriodStart and time <= testPeriodStop ? true : false
testPeriod_1 = testPeriod()
isPeriod = true
// === /END

if not isPeriod
    strategy.cancel_all()
    strategy.close_all()


Thêm nữa