
この戦略は,複数の技術指標の組み合わせのシグナルを使用し,株式,デジタル通貨などの資産のダイナミックな取引を実現します. この戦略は,市場動向を自動的に認識し,トレンドを追跡することができます. 同時に,戦略は,リスクを制御するための止損機構を追加しています.
この戦略は,移動平均,相対的に強い指標 ((RSI),平均実際の波幅 ((ATR),方向運動指標 ((ADX) などを中心に,複数の指標を使用して,指標の組み合わせによって取引シグナルを生成します.
具体的には,この戦略は,まず,2つの移動平均を使用して金叉死叉信号を形成する.快線は10日,慢線は50日である.快線が下方からゆっくりとした線を突破すると,買い信号が生成され,快線が上方からゆっくりとした線を突破すると,売り信号が生成される.この2つの移動平均システムは,市場の中央の長線トレンドの転換を効果的に識別できる.
二重移動平均線に基づいて,戦略はまた,偽の突破を避けるためにトレンドシグナルを確認するためにRSI指標を導入する.RSIは,快線と慢線の差値によって市場の強さを判断する.Lengthは14である.RSIが30を超えると買入シグナルを生じ,70を超えると売出シグナルを生成する.
さらに,戦略はATR指標を使用して自動で止損値を調整する.ATR指標は市場の変動の程度を効果的に反映する.市場の変動が大きくなると,戦略は止損値をより幅広く設定し,止損される可能性を減らす.
最後に,戦略は,ADX指標でトレンドの強さを判断する.ADXは,正向指標DI+と負向指標DI-の差値によってトレンドの強さを判断する.ADX値が20を突破すると,トレンドが確立したと考えられ,実際の取引信号は発生する.
複数の指標を組み合わせることで,戦略は取引シグナルを発信する際により慎重になり,市場内の偽のシグナルに騙されないようにして,より高い勝率を得ることができます.
この戦略には以下の利点があります.
平均線,RSI,ATR,ADXなどの複数の指標を組み合わせることで,取引決定の正確性を高め,単一の指標による誤判を回避できます.
市場の変動に応じて自動でストップ・ローズを調整することで,ストップ・ローズが誘発される確率を小さくし,取引リスクを効果的にコントロールできます.
ADX指数でトレンドの強さを判断し,実際に取引すると,逆操作による損失を減らすことができます.
この戦略の平均線長,RSI長,ATR周期,ADX周期などのパラメータは,異なる市場に応じて調整して最適化され,適応性が強い.
長期トレンドを判断する快速平均線システムで,RSIなどの指標と連携して,短線ノイズの影響を軽減し,トレンドの中で長期線を保持して,より高い利益を得ることができます.
この戦略にはいくつかのリスクがあり,主なリスクは以下の通りです.
複数のパラメータの組み合わせは,最適化の難易度を高め,不適切なパラメータの組み合わせは,戦略の効果の歪みを引き起こす可能性があります.このリスクは,より充分な反射とパラメータの調整によって軽減することができます.
技術指標にはそれぞれ適用される市場状態がある.市場が特殊な状態に入ると,戦略に含まれる指標は同時に失効する可能性がある.このBLACK SWANイベントがもたらすリスクには注意が必要です.
策略では空頭取引が許される.空頭取引自体は無制限の損失のリスクがある.このリスクは,ストップ・ロスを設定することで軽減することができる.
トレンドが逆転する時には,指標信号が迅速に反応できず,逆転損失が形成されやすい.指標のパラメータの一部を適切に縮小して,感度が向上することができる.
この戦略はさらに改善できる余地があり,主な改善策は以下の通りです.
各指標と市場の状況の関連性を分析することで,各指標の重みを動的に調整する仕組みを設計し,異なる市場環境で意思決定の効果を向上させることができます.
ディープラーニングなどのモデルを使用して,価格変化の方向を予測し,人工的に設計された意思決定規則を補助し,戦略的意思決定の正確性を向上させる.
スライドウィンドウの履歴データに対して自動パラメータ最適化モジュールを設計し,指標パラメータの動的調整を実現し,市場変化に戦略をより良く適応させる.
波動理論などの変形周期分析方法が加えられ,トレンドの中での長線走勢を補助的に判断し,ポジションの利得確率を向上させる.
この戦略は,移動平均線,RSI,ATR,ADXなどの複数の指標を総合的に利用し,より完全な意思決定規則を設計し,均等線システムによって長線の傾向を判断することができ,RSIなどの短周期指標によって騒音干渉を減らすことができます.同時に,この戦略は,最適化の余地があり,より良いパフォーマンスを期待できます.全体的に,この戦略は,指標の組み合わせを使用して,意思決定の効果を向上させ,リスクを制御し,さらなる研究と応用に値します.
/*backtest
start: 2023-01-28 00:00:00
end: 2024-02-03 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
// This source code to my testing
// © sgb
//@version=5
strategy(title='Soren test 2', overlay=true, initial_capital=100, pyramiding=1, calc_on_order_fills=true, calc_on_every_tick=true, default_qty_type=strategy.percent_of_equity, default_qty_value=50, commission_value=0.04)
//SOURCE =============================================================================================================================================================================================================================================================================================================
src = input(open)
// INPUTS ============================================================================================================================================================================================================================================================================================================
//ADX --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ADX_options = input.string('MASANAKAMURA', title='Adx Type', options=['CLASSIC', 'MASANAKAMURA'], group='ADX')
ADX_len = input.int(38, title='Adx lenght', minval=1, group='ADX')
th = input.float(23, title='Adx Treshold', minval=0, step=0.5, group='ADX')
// Volume ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
volume_f = input.float(1.2, title='Volume mult.', minval=0, step=0.1, group='Volume')
sma_length = input.int(35, title='Volume lenght', minval=1, group='Volume')
//RSI----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
len_3 = input.int(25, title='RSI lenght', group='Relative Strenght Indeks')
src_3 = input.source(low, title='RSI Source', group='Relative Strenght Indeks')
RSI_VWAP_length = input(25, title='Rsi vwap lenght')
// Range Filter ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
per_ = input.int(26, title='SAMPLING PERIOD', minval=1, group='Range Filter')
mult = input.float(2.3, title='RANGE MULTIPLIER', minval=0.1, step=0.1, group='Range Filter')
// Cloud --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
len = input.int(1, title='Cloud Length', group='Cloud')
//RMI ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
RMI_len = input.int(26, title='Rmi Lenght', minval=1, group='Relative Momentum Index')
mom = input.int(17, title='Rmi Momentum', minval=1, group='Relative Momentum Index')
RMI_os = input.int(33, title='Rmi oversold', minval=0, group='Relative Momentum Index')
RMI_ob = input.int(68, title='Rmi overbought', minval=0, group='Relative Momentum Index')
// Indicators Calculations ========================================================================================================================================================================================================================================================================================================
// Range Filter ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
var bool L_RF = na
var bool S_RF = na
Range_filter(_src, _per_, _mult) =>
var float _upward = 0.0
var float _downward = 0.0
wper = _per_ * 2 - 1
avrng = ta.ema(math.abs(_src - _src[1]), _per_)
_smoothrng = ta.ema(avrng, wper) * _mult
_filt = _src
_filt := _src > nz(_filt[1]) ? _src - _smoothrng < nz(_filt[1]) ? nz(_filt[1]) : _src - _smoothrng : _src + _smoothrng > nz(_filt[1]) ? nz(_filt[1]) : _src + _smoothrng
_upward := _filt > _filt[1] ? nz(_upward[1]) + 1 : _filt < _filt[1] ? 0 : nz(_upward[1])
_downward := _filt < _filt[1] ? nz(_downward[1]) + 1 : _filt > _filt[1] ? 0 : nz(_downward[1])
[_smoothrng, _filt, _upward, _downward]
[smoothrng, filt, upward, downward] = Range_filter(src, per_, mult)
hband = filt + smoothrng
lband = filt - smoothrng
L_RF := high > hband and upward > 0
S_RF := low < lband and downward > 0
//ADX-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
calcADX(_len) =>
up = ta.change(high)
down = -ta.change(low)
plusDM = na(up) ? na : up > down and up > 0 ? up : 0
minusDM = na(down) ? na : down > up and down > 0 ? down : 0
truerange = ta.rma(ta.tr, _len)
_plus = fixnan(100 * ta.rma(plusDM, _len) / truerange)
_minus = fixnan(100 * ta.rma(minusDM, _len) / truerange)
sum = _plus + _minus
_adx = 100 * ta.rma(math.abs(_plus - _minus) / (sum == 0 ? 1 : sum), _len)
[_plus, _minus, _adx]
calcADX_Masanakamura(_len) =>
SmoothedTrueRange = 0.0
SmoothedDirectionalMovementPlus = 0.0
SmoothedDirectionalMovementMinus = 0.0
TrueRange = math.max(math.max(high - low, math.abs(high - nz(close[1]))), math.abs(low - nz(close[1])))
DirectionalMovementPlus = high - nz(high[1]) > nz(low[1]) - low ? math.max(high - nz(high[1]), 0) : 0
DirectionalMovementMinus = nz(low[1]) - low > high - nz(high[1]) ? math.max(nz(low[1]) - low, 0) : 0
SmoothedTrueRange := nz(SmoothedTrueRange[1]) - nz(SmoothedTrueRange[1]) / _len + TrueRange
SmoothedDirectionalMovementPlus := nz(SmoothedDirectionalMovementPlus[1]) - nz(SmoothedDirectionalMovementPlus[1]) / _len + DirectionalMovementPlus
SmoothedDirectionalMovementMinus := nz(SmoothedDirectionalMovementMinus[1]) - nz(SmoothedDirectionalMovementMinus[1]) / _len + DirectionalMovementMinus
DIP = SmoothedDirectionalMovementPlus / SmoothedTrueRange * 100
DIM = SmoothedDirectionalMovementMinus / SmoothedTrueRange * 100
DX = math.abs(DIP - DIM) / (DIP + DIM) * 100
adx = ta.sma(DX, _len)
[DIP, DIM, adx]
[DIPlusC, DIMinusC, ADXC] = calcADX(ADX_len)
[DIPlusM, DIMinusM, ADXM] = calcADX_Masanakamura(ADX_len)
DIPlus = ADX_options == 'CLASSIC' ? DIPlusC : DIPlusM
DIMinus = ADX_options == 'CLASSIC' ? DIMinusC : DIMinusM
ADX = ADX_options == 'CLASSIC' ? ADXC : ADXM
L_adx = DIPlus > DIMinus and ADX > th
S_adx = DIPlus < DIMinus and ADX > th
// Volume -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Volume_condt = volume > ta.sma(volume, sma_length) * volume_f
//RSI------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
up_3 = ta.rma(math.max(ta.change(src_3), 0), len_3)
down_3 = ta.rma(-math.min(ta.change(src_3), 0), len_3)
rsi_3 = down_3 == 0 ? 100 : up_3 == 0 ? 0 : 100 - 100 / (1 + up_3 / down_3)
L_rsi = rsi_3 < 70
S_rsi = rsi_3 > 30
RSI_VWAP = ta.rsi(ta.vwap(close), RSI_VWAP_length)
RSI_VWAP_overSold = 13
RSI_VWAP_overBought = 68
L_VAP = ta.crossover(RSI_VWAP, RSI_VWAP_overSold)
S_VAP = ta.crossunder(RSI_VWAP, RSI_VWAP_overBought)
//Cloud --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
PI = 2 * math.asin(1)
hilbertTransform(src) =>
0.0962 * src + 0.5769 * nz(src[2]) - 0.5769 * nz(src[4]) - 0.0962 * nz(src[6])
computeComponent(src, mesaPeriodMult) =>
hilbertTransform(src) * mesaPeriodMult
computeAlpha(src, fastLimit, slowLimit) =>
mesaPeriod = 0.0
mesaPeriodMult = 0.075 * nz(mesaPeriod[1]) + 0.54
smooth = 0.0
smooth := (4 * src + 3 * nz(src[1]) + 2 * nz(src[2]) + nz(src[3])) / 10
detrender = 0.0
detrender := computeComponent(smooth, mesaPeriodMult)
I1 = nz(detrender[3])
Q1 = computeComponent(detrender, mesaPeriodMult)
jI = computeComponent(I1, mesaPeriodMult)
jQ = computeComponent(Q1, mesaPeriodMult)
I2 = 0.0
Q2 = 0.0
I2 := I1 - jQ
Q2 := Q1 + jI
I2 := 0.2 * I2 + 0.8 * nz(I2[1])
Q2 := 0.2 * Q2 + 0.8 * nz(Q2[1])
Re = I2 * nz(I2[1]) + Q2 * nz(Q2[1])
Im = I2 * nz(Q2[1]) - Q2 * nz(I2[1])
Re := 0.2 * Re + 0.8 * nz(Re[1])
Im := 0.2 * Im + 0.8 * nz(Im[1])
if Re != 0 and Im != 0
mesaPeriod := 2 * PI / math.atan(Im / Re)
mesaPeriod
if mesaPeriod > 1.5 * nz(mesaPeriod[1])
mesaPeriod := 1.5 * nz(mesaPeriod[1])
mesaPeriod
if mesaPeriod < 0.67 * nz(mesaPeriod[1])
mesaPeriod := 0.67 * nz(mesaPeriod[1])
mesaPeriod
if mesaPeriod < 6
mesaPeriod := 6
mesaPeriod
if mesaPeriod > 50
mesaPeriod := 50
mesaPeriod
mesaPeriod := 0.2 * mesaPeriod + 0.8 * nz(mesaPeriod[1])
phase = 0.0
if I1 != 0
phase := 180 / PI * math.atan(Q1 / I1)
phase
deltaPhase = nz(phase[1]) - phase
if deltaPhase < 1
deltaPhase := 1
deltaPhase
alpha = fastLimit / deltaPhase
if alpha < slowLimit
alpha := slowLimit
alpha
[alpha, alpha / 2.0]
er = math.abs(ta.change(src, len)) / math.sum(math.abs(ta.change(src)), len)
[a, b] = computeAlpha(src, er, er * 0.1)
mama = 0.0
mama := a * src + (1 - a) * nz(mama[1])
fama = 0.0
fama := b * mama + (1 - b) * nz(fama[1])
alpha = math.pow(er * (b - a) + a, 2)
kama = 0.0
kama := alpha * src + (1 - alpha) * nz(kama[1])
L_cloud = kama > kama[1]
S_cloud = kama < kama[1]
// RMI -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
RMI(len, m) =>
up = ta.ema(math.max(close - close[m], 0), len)
dn = ta.ema(math.max(close[m] - close, 0), len)
RMI = dn == 0 ? 0 : 100 - 100 / (1 + up / dn)
RMI
L_rmi = ta.crossover(RMI(RMI_len, mom), RMI_os)
S_rmi = ta.crossunder(RMI(RMI_len, mom), RMI_ob)
//STRATEGY ==========================================================================================================================================================================================================================================================================================================
L_1 = L_VAP and L_RF and not S_adx
S_1 = S_VAP and S_RF and not L_adx
L_2 = L_adx and Volume_condt and L_rsi and L_cloud
S_2 = S_adx and Volume_condt and S_rsi and S_cloud
L_3 = L_rmi and L_RF and not S_adx
S_3 = S_rmi and S_RF and not L_adx
L_basic_condt = L_1 or L_2 or L_3
S_basic_condt = S_1 or S_2 or S_3
var bool longCondition = na
var bool shortCondition = na
var float last_open_longCondition = na
var float last_open_shortCondition = na
var int last_longCondition = 0
var int last_shortCondition = 0
longCondition := L_basic_condt
shortCondition := S_basic_condt
last_open_longCondition := longCondition ? close : nz(last_open_longCondition[1])
last_open_shortCondition := shortCondition ? close : nz(last_open_shortCondition[1])
last_longCondition := longCondition ? time : nz(last_longCondition[1])
last_shortCondition := shortCondition ? time : nz(last_shortCondition[1])
in_longCondition = last_longCondition > last_shortCondition
in_shortCondition = last_shortCondition > last_longCondition
// SWAP-SL ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
var int last_long_sl = na
var int last_short_sl = na
sl = input.float(2, 'Swap % period', minval=0, step=0.1, group='strategy settings')
long_sl = ta.crossunder(low, (1 - sl / 100) * last_open_longCondition) and in_longCondition and not longCondition
short_sl = ta.crossover(high, (1 + sl / 100) * last_open_shortCondition) and in_shortCondition and not shortCondition
last_long_sl := long_sl ? time : nz(last_long_sl[1])
last_short_sl := short_sl ? time : nz(last_short_sl[1])
var bool CondIni_long_sl = 0
CondIni_long_sl := long_sl ? 1 : longCondition ? -1 : nz(CondIni_long_sl[1])
var bool CondIni_short_sl = 0
CondIni_short_sl := short_sl ? 1 : shortCondition ? -1 : nz(CondIni_short_sl[1])
Final_Long_sl = long_sl and nz(CondIni_long_sl[1]) == -1 and in_longCondition and not longCondition
Final_Short_sl = short_sl and nz(CondIni_short_sl[1]) == -1 and in_shortCondition and not shortCondition
var int sectionLongs = 0
sectionLongs := nz(sectionLongs[1])
var int sectionShorts = 0
sectionShorts := nz(sectionShorts[1])
// RE-ENTRY ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
if longCondition or Final_Long_sl
sectionLongs += 1
sectionShorts := 0
sectionShorts
if shortCondition or Final_Short_sl
sectionLongs := 0
sectionShorts += 1
sectionShorts
var float sum_long = 0.0
var float sum_short = 0.0
if longCondition
sum_long := nz(last_open_longCondition) + nz(sum_long[1])
sum_short := 0.0
sum_short
if Final_Long_sl
sum_long := (1 - sl / 100) * last_open_longCondition + nz(sum_long[1])
sum_short := 0.0
sum_short
if shortCondition
sum_short := nz(last_open_shortCondition) + nz(sum_short[1])
sum_long := 0.0
sum_long
if Final_Short_sl
sum_long := 0.0
sum_short := (1 + sl / 100) * last_open_shortCondition + nz(sum_short[1])
sum_short
var float Position_Price = 0.0
Position_Price := nz(Position_Price[1])
Position_Price := longCondition or Final_Long_sl ? sum_long / sectionLongs : shortCondition or Final_Short_sl ? sum_short / sectionShorts : na
//TP_1 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
tp = input.float(1.2, 'Tp-1 ', minval=0, step=0.1, group='strategy settings')
long_tp = ta.crossover(high, (1 + tp / 100) * fixnan(Position_Price)) and in_longCondition and not longCondition
short_tp = ta.crossunder(low, (1 - tp / 100) * fixnan(Position_Price)) and in_shortCondition and not shortCondition
var int last_long_tp = na
var int last_short_tp = na
last_long_tp := long_tp ? time : nz(last_long_tp[1])
last_short_tp := short_tp ? time : nz(last_short_tp[1])
Final_Long_tp = long_tp and last_longCondition > nz(last_long_tp[1])
Final_Short_tp = short_tp and last_shortCondition > nz(last_short_tp[1])
fixnan_1 = fixnan(Position_Price)
ltp = Final_Long_tp ? fixnan_1 * (1 + tp / 100) : na
fixnan_2 = fixnan(Position_Price)
stp = Final_Short_tp ? fixnan_2 * (1 - tp / 100) : na
if Final_Short_tp or Final_Long_tp
sum_long := 0.0
sum_short := 0.0
sectionLongs := 0
sectionShorts := 0
sectionShorts
if Final_Long_tp
CondIni_long_sl == 1
if Final_Short_tp
CondIni_short_sl == 1
// COLORS & PLOTS --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ADX_COLOR = L_adx ? color.lime : S_adx ? color.red : color.orange
barcolor(color=ADX_COLOR)
hbandplot = plot(hband, title='RF HT', color=ADX_COLOR, transp=50)
lbandplot = plot(lband, title='RF LT', color=ADX_COLOR, transp=50)
fill(hbandplot, lbandplot, title='RF TR', color=ADX_COLOR, transp=90)
plotshape(longCondition, title='Long', style=shape.triangleup, location=location.belowbar, color=color.new(color.blue, 0), size=size.tiny)
plotshape(shortCondition, title='Short', style=shape.triangledown, location=location.abovebar, color=color.new(color.red, 0), size=size.tiny)
plot(ltp, style=plot.style_circles, linewidth=5, color=color.new(color.fuchsia, 0), editable=false)
plot(stp, style=plot.style_circles, linewidth=5, color=color.new(color.fuchsia, 0), editable=false)
//BACKTESTING--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Q = 50
SL = input.float(0.4, 'StopLoss ', minval=0, step=0.1)
strategy.entry('long', strategy.long, when=longCondition)
strategy.entry('short', strategy.short, when=shortCondition)
strategy.exit('TP', 'long', qty_percent=Q, limit=fixnan(Position_Price) * (1 + tp / 100))
strategy.exit('TP', 'short', qty_percent=Q, limit=fixnan(Position_Price) * (1 - tp / 100))
strategy.exit('SL', 'long', stop=fixnan(Position_Price) * (1 - SL / 100))
strategy.exit('SL', 'short', stop=fixnan(Position_Price) * (1 + SL / 100))
//
//
//
//
//
//
// By SGB