移動平均乖離率エンベロープV0.91本体
//@version=5
//Moving Average Envelope - MA-E- V0.9 終値の移動平均線と上値、下値の乖離率 @issei_tamrua0008 2024-03-28
strategy('Moving Average Envelope - MA-E- V0.91', shorttitle='Moving Average Envelope V0.91',overlay =true) //, format=format.price, precision=2, timeframe="", timeframe_gaps=true
IptPeriod = input.timeframe(defval="",title="マルチタイムフレーム(MT)",
tooltip = '乖離率 マルチタイム')// マルチタイムフレームのデータを取得
// ▼ ▼ ▼ Smoothed Rate of Change
//input
str_upper = input.string("最高値", options=["最高値","上髭中心","終値"], inline="101")
upper_view = input.bool(true, inline="101")
str_lower = input.string("最安値", options=["最安値","下髭中心","終値"], inline="102")
lower_view = input.bool(true, inline="102")
maPeriod = input(25, title='偏差取得平均線',group=" - 移動平均線乖離率 - -Moving Average Deviation Ratio-")
// 集計用
aggreg = input(100, title='集計回数',group="集計用")
maentropy = input(25, title='緑範囲集計')
rms = input.int(defval=200,minval=0, step=10,title="閾値",tooltip = "2乗累積平方根 又は 絶対値平均足数、最大値を求めるときの閾値とする、雑音除去の精度")
ave_rms = input.string(defval="2乗累積平方根",options=["2乗累積平方根","絶対値平均"],title="閾値の方法",tooltip = "レンジ確認用閾値" + "\n" + "本来2乗累積平方根だけど、最大値を求めすぎて、INができないかも。の緊急措置用")
center_view = input.bool(true, "",inline="104")
sma_center = input.int(25 , inline="104")
center_color = input.color(defval=color.new(color.blue, 0), title = "" , inline="104",tooltip = "中心位置確認用、利確などに。 計算には使用していない")
long_view = input.bool(true, "",inline="105")
sma_long = input.int(100, inline="105")
long_color = input.color(defval=color.new(color.purple, 0), title = "" , inline="105",tooltip = "トレンド確認用、計算には使用していない")
short_view = input.bool(true, "",inline="106")
sma_short = input.int(3, inline="106")
short_color = input.color(defval=color.new(color.gray, 0), title = "" , inline="106",tooltip = "利確予定ライン" + "\n" + "センターラインとのクロスオーバーでロング、アンダーオーバーでショート利確かも")
Dev0 = input.float(defval=2.0,minval=0.0,maxval=5.0, step=0.1,title="IN用 標準偏差", inline="200",tooltip = "閾値内の偏差") //標準偏差
color_div0 = input.color(defval=color.new(color.green, 0), inline="200")
Dev1 = input.float(defval=2.0,minval=0.0,maxval=5.0, step=0.1,title="偏差内最大 標準偏差", inline="201",tooltip = "閾値外の偏差" + "\n" +
"0で2乗累積平方根 又は 絶対値平均") //標準偏差
color_div1 = input.color(defval=color.new(color.orange, 0), inline="201")
Dev2 = input.float(defval=4.0,minval=0.0,maxval=5.0, step=0.5,title="損切用 標準偏差", inline="202",tooltip = "0で非表示") //標準偏差
color_div2 = input.color(defval=color.new(color.yellow, 0), inline="202")
rms_bai = input.float(defval=1.0,minval=0.0,maxval=100, step=0.01,title="閾値倍率",tooltip = "閾値の倍率 閾値を使わない場合は100くらいにすればいいかも" + "\n" + "この閾値は描画時の閾値、集計時の閾値とは違う" )
value_view = input.bool(true, "価格表示 取引:白 レンジ外:灰")
value_stay = input.int(10, "価格位置",minval=0,maxval=20, step=1)
threshold_00 = input.bool(true, "閾値を使う",inline="303",group="レンジの確認方法")
threshold_03 = input.bool(true, "閾値 長期線",inline="304",group="レンジの確認方法")
threshold_01 = input.bool(true, "閾値 乖離率平均",inline="304",group="レンジの確認方法")
threshold_02 = input.bool(true, "閾値 偏差",inline="304",group="レンジの確認方法" , tooltip = "レンジの定義で使用する要素" + "\n" +
"長期の移動平均が第1ライン内にある場合" + "\n" +
"乖離率の移動平均が2乗累積平方根内にある場合" + "\n" +
"乖離率のボリンジャーバンドが2乗累積平方根内にある場合" )
alart = input.bool(true, "アラート",inline="302")
strategy = input.bool(false, "ストラテジー",inline="302")
strategy_son = input.bool(true, "第2ラインで損切",inline="302")
date_s = input.time(timestamp("05 Mar 2024"), "ストラテジー 開始", confirm=true)
date_e = input.time(timestamp("29 Mar 2024"), "ストラテジー 終了", confirm=true)
high_time = request.security(syminfo.tickerid, IptPeriod, high,barmerge.gaps_on,barmerge.lookahead_on)
low_time = request.security(syminfo.tickerid, IptPeriod, low,barmerge.gaps_on,barmerge.lookahead_on)
close_time = request.security(syminfo.tickerid, IptPeriod, close,barmerge.gaps_on,barmerge.lookahead_on)
open_time = request.security(syminfo.tickerid, IptPeriod, open,barmerge.gaps_on,barmerge.lookahead_on)
time_close_time = request.security(syminfo.tickerid, IptPeriod, time_close,barmerge.gaps_on,barmerge.lookahead_on)
bar_index_time = request.security(syminfo.tickerid, IptPeriod, bar_index,barmerge.gaps_on,barmerge.lookahead_on)
float upper = str_upper == "最高値" ? high_time : str_upper == "上髭中心" ? (high_time + math.max(close_time,open_time)) * 0.5 : close_time
float lower = str_lower == "下髭中心" ? (low_time + math.min(close_time,open_time)) * 0.5 : close_time
var float[] array_inside_up = array.new_float(maentropy,0.0)
var float[] array_inside_down = array.new_float(maentropy,0.0)
var float[] array_inside_up_count = array.new_float()
var float[] array_inside_down_count = array.new_float()
var float[] array_over_up = array.new_float(aggreg,0.0)
var float[] array_over_down = array.new_float(aggreg,0.0)
var float[] array_over_up_count = array.new_float()
var float[] array_over_down_count = array.new_float()
//deviation rate
sma_up = ta.sma(upper, maPeriod)
sma_low = ta.sma(lower, maPeriod)
rate_upper = upper / sma_up * 100 - 100
rate_lower = lower / sma_low * 100 - 100
ave_upper = ta.sma(math.abs(rate_upper),rms)
ave_lower = ta.sma(-math.abs(rate_lower),rms)
rms_upper = math.sqrt(ta.sma(math.pow(rate_upper, 2),rms))
rms_lower = -math.sqrt(ta.sma(math.pow(rate_lower, 2),rms))
rms_upper := ave_rms == "2乗累積平方根" ? rms_upper : ave_upper
rms_lower := ave_rms == "2乗累積平方根" ? rms_lower : ave_lower
// レンジ内用 偏差ラインの内側範囲の最大値
if ta.sma(rate_upper,maentropy) > 0 and rate_upper > 0
array.insert(array_inside_up_count,0,rate_upper)
if ta.sma(rate_upper,maentropy)[1] > 0 and ta.sma(rate_upper,maentropy) <= 0
if array.max(array_inside_up_count) < rms_upper and array.max(array_inside_up_count) > 0
array.insert(array_inside_up,0,array.max(array_inside_up_count))
array.remove(array_inside_up,array.size(array_inside_up)-1)
array.clear(array_inside_up_count)
else
array.clear(array_inside_up_count)
//レンジ内用 偏差ラインの内側範囲の最小値
if ta.sma(rate_lower,maentropy) < 0 and rate_lower < 0
array.insert(array_inside_down_count,0,rate_lower)
if ta.sma(rate_lower,maentropy)[1] < 0 and ta.sma(rate_lower,maentropy) >= 0
if array.min(array_inside_down_count) > rms_lower and array.min(array_inside_down_count) < 0
array.insert(array_inside_down,0,array.min(array_inside_down_count))
array.remove(array_inside_down,array.size(array_inside_down)-1)
array.clear(array_inside_down_count)
else
array.clear(array_inside_down_count)
float std_inside_up_ave = 0.0
float std_inside_up_std = 0.0
float std_inside_up_plus0 = 0.0
float std_inside_down_ave = 0.0
float std_inside_down_std = 0.0
float std_inside_down_minu0 = 0.0
// 最大値偏差
if array.get(array_inside_up,maPeriod - 1 ) > 0
std_inside_up_ave := array.avg(array_inside_up)
std_inside_up_std := array.stdev(array_inside_up)
std_inside_up_plus0 := std_inside_up_ave + std_inside_up_std * Dev0
// 最小値偏差
if array.get(array_inside_down,maPeriod - 1 ) < 0
std_inside_down_ave := array.avg(array_inside_down)
std_inside_down_std := array.stdev(array_inside_down)
std_inside_down_minu0 := std_inside_down_ave - std_inside_down_std * Dev0
rms_inside_up_plus0 = math.sqrt(ta.sma(math.pow(std_inside_up_plus0, 2),maPeriod))
rms_inside_down_minu0 = -math.sqrt(ta.sma(math.pow(std_inside_down_minu0, 2),maPeriod))
// 集計用 偏差ラインのオーバーラップ範囲の最大値
if rate_upper > rms_upper
array.insert(array_over_up_count,0,rate_upper)
if rate_upper[1] > rms_upper[1] and rate_upper <= rms_upper
array.insert(array_over_up,0,array.max(array_over_up_count))
array.remove(array_over_up,array.size(array_over_up)-1)
array.clear(array_over_up_count)
//集計用 偏差ラインのオーバーラップ範囲の最小値 マイナスの値なので絶対値に
if rate_lower < rms_lower
array.insert(array_over_down_count,0,-rate_lower)
if rate_lower[1] < rms_lower[1] and rate_lower >= rms_lower
array.insert(array_over_down,0,array.max(array_over_down_count))
array.remove(array_over_down,array.size(array_over_down)-1)
array.clear(array_over_down_count)
float std_over_up_ave = 0.0
float std_over_up_std = 0.0
float std_over_up_plus0 = 0.0
float std_over_up_plus1 = 0.0
float std_over_down_ave = 0.0
float std_over_down_std = 0.0
float std_over_down_minu0 = 0.0
float std_over_down_minu1 = 0.0
// 最大値偏差
if array.get(array_over_up,aggreg - 1 ) > 0
std_over_up_ave := array.avg(array_over_up)
std_over_up_std := array.stdev(array_over_up)
std_over_up_plus0 := std_over_up_ave + std_over_up_std * Dev1
std_over_up_plus1 := std_over_up_ave + std_over_up_std * Dev2
// 最小値偏差
if array.get(array_over_down,aggreg - 1 ) > 0
std_over_down_ave := -array.avg(array_over_down)
std_over_down_std := -array.stdev(array_over_down)
std_over_down_minu0 := std_over_down_ave + std_over_down_std * Dev1
std_over_down_minu1 := std_over_down_ave + std_over_down_std * Dev2
plot( center_view ? ta.sma((high_time+low_time)*0.5,sma_center) : na,title="Center", color=center_color)
plot( long_view ? ta.sma((high_time+low_time)*0.5,sma_long) : na,title="L_sma", color=long_color)
plot( short_view ? ta.sma((high_time+low_time)*0.5,sma_short) : na,title="S_sma", color=short_color)
bool threshold_1 = true
bool threshold_2 = true
bool threshold_3 = true
// 以下、アラート用閾値
ave_upper := ta.sma(rate_upper,aggreg)
ave_lower := ta.sma(rate_lower,aggreg)
up_plusDev = ave_upper + ta.stdev(rate_upper,aggreg) * 2 // 乖離率の標準偏差 2σ
low_plusDev = ave_lower - ta.stdev(rate_lower,aggreg) * 2 // 乖離率の標準偏差 2σ
rms_up_plusDev = math.sqrt(ta.sma(math.pow(up_plusDev, 2),rms))
rms_low_plusDev = -math.sqrt(ta.sma(math.pow(low_plusDev, 2),rms))
// 閾値 長期線がトレンド内に収まっている時をレンジと仮定
if threshold_00 and threshold_03
if sma_up * (1+std_over_up_plus0/100) < ta.sma((high_time+low_time)*0.5,sma_long) // 上の第一ライン > 長期線
threshold_3 := false
if sma_low * (1+std_over_down_minu0/100) > ta.sma((high_time+low_time)*0.5,sma_long) // 下の第一ライン > 長期線
threshold_3 := false
// 閾値 乖離率平均線 乖離率が平均以上になった時にトレンドと仮定
if threshold_00 and threshold_01
if ave_upper > rms_upper
threshold_1 := false
if ave_lower < rms_lower
threshold_1 := false
// 閾値 乖離率のボリンジャーバンド 株価が大きく動くときに、存在確率も大きく開くので、開く大きさが許容値内かでレンジを判断
if threshold_00 and threshold_02
if up_plusDev > rms_up_plusDev
threshold_2 := false
if low_plusDev < rms_low_plusDev
threshold_2 := false
// アラート
alertcondition((threshold_3 and threshold_1 and threshold_2) and (high_time > sma_up * (1+std_over_up_plus0/100)) , title="Upper Line Over", message="Upper Line Over" + "\n" + "{{ticker}} {{interval}}分足/ {{time}} " + "\n" + "終値:{{close}} , 出来高:{{volume}} ")
alertcondition((threshold_3 and threshold_1 and threshold_2) and (low_time < sma_low * (1+std_over_down_minu0/100)), title="Lower Line Over", message="{{ticker}} {{interval}}分足/ {{time}} " + "\n" + "終値:{{close}} , 出来高:{{volume}} ")
if (alart and threshold_3 and threshold_1 and threshold_2) and (high_time > sma_up * (1+std_over_up_plus0/100))
alert("Upper Line Over" + "\n" + "{{ticker}} {{interval}}分足/ {{time}} " + "\n" + "終値:{{close}} , 出来高:{{volume}} ")
if (alart and threshold_3 and threshold_1 and threshold_2) and (low_time < sma_low * (1+std_over_down_minu0/100))
alert("Lower Line Over" + "\n" + "{{ticker}} {{interval}}分足/ {{time}} " + "\n" + "終値:{{close}} , 出来高:{{volume}} ")
// ▲▲▲▲ アラート
// ▽▽▽▽ トレンド転換 EXIT ストラテジー
if strategy.position_size > 0 and time_close_time > date_s and time_close_time <= date_e and ta.crossunder(ta.sma((high_time+low_time)*0.5,sma_short),ta.sma((high_time+low_time)*0.5,sma_center))
strategy.cancel_all()
strategy.close( id = "str_L" , comment = "close_Long",alert_message="ロング 決済")
if strategy.position_size < 0 and time_close_time > date_s and time_close_time <= date_e and ta.crossover(ta.sma((high_time+low_time)*0.5,sma_short),ta.sma((high_time+low_time)*0.5,sma_center))
strategy.cancel_all()
strategy.close( id = "str_S" , comment = "close_short",alert_message="ショート 決済")
// ▽▽▽▽ トレンド転換 エントリー ストラテジー
strategy.entry("str_L", strategy.long, when=strategy and time_close_time > date_s and time_close_time <= date_e and (threshold_3 and threshold_1 and threshold_2) and (low_time < sma_low * (1+std_over_down_minu0/100)) and (low_time > sma_low * (1+std_over_down_minu1/100)) ,
alert_message="Lower Line Over" + "\n" + "{{ticker}} {{interval}}分足/ {{time}} " + "\n" + "終値:{{close}} , 出来高:{{volume}} ")
strategy.entry("str_S", strategy.short, when=strategy and time_close_time > date_s and time_close_time <= date_e and (threshold_3 and threshold_1 and threshold_2) and (high_time > sma_up * (1+std_over_up_plus0/100)) and (high_time < sma_up * (1+std_over_up_plus1/100)),
alert_message="トレンド転換 売りENT")
strategy.exit("str_L", when=strategy_son and time_close_time > date_s and time_close_time <= date_e and (close_time < sma_low * (1 + std_over_down_minu1/100)) ,stop = sma_low * (1 + std_over_down_minu1/100) )
strategy.exit("str_S", when=strategy_son and time_close_time > date_s and time_close_time <= date_e and (close_time > sma_up * (1 + std_over_up_plus1/100)) ,stop = sma_up * (1 + std_over_up_plus1/100) )
// labelを宣言
label label_h2 = na
label label_h1 = na
label label_h0 = na
label label_l0 = na
label label_l1 = na
label label_l2 = na
// 古いものは削除
label.delete( label_h2[1] )
label.delete( label_h1[1] )
label.delete( label_h0[1] )
label.delete( label_l0[1] )
label.delete( label_l1[1] )
label.delete( label_l2[1] )
// labelを描画
label_h2 := label.new( bar_index_time + value_stay ,sma_up * (1 + std_over_up_plus1/100) , style=label.style_none , textcolor= threshold_3 and threshold_1 and threshold_2 ? color_div2 :color.new(color.white, 40),
text = value_view ? str.tostring(sma_up * (1 + std_over_up_plus1/100) , "#,###.##") : na )
label_h1 := label.new( bar_index_time + value_stay ,sma_up * (1+std_over_up_plus0/100) , style=label.style_none , textcolor= threshold_3 and threshold_1 and threshold_2 ? color_div1 :color.new(color.white, 50),
text = value_view ? str.tostring(sma_up * (1 + std_over_up_plus0/100) , "#,###.##") : na )
label_h0 := label.new( bar_index_time + value_stay ,sma_up * (1+rms_inside_up_plus0/100) , style=label.style_none , textcolor= threshold_3 and threshold_1 and threshold_2 ? color_div0 :color.new(color.white, 60),
text = value_view ? str.tostring(sma_up * (1+rms_inside_up_plus0/100) , "#,###.##") : na )
label_l0 := label.new( bar_index_time + value_stay ,sma_low * (1+rms_inside_down_minu0/100) , style=label.style_none , textcolor= threshold_3 and threshold_1 and threshold_2 ? color_div0 :color.new(color.white, 60),
text = value_view ? str.tostring(sma_low * (1+rms_inside_down_minu0/100) , "#,###.##") : na )
label_l1 := label.new( bar_index_time + value_stay ,sma_low * (1+std_over_down_minu0/100) , style=label.style_none , textcolor= threshold_3 and threshold_1 and threshold_2 ? color_div1 :color.new(color.white, 50),
text = value_view ? str.tostring(sma_low * (1+std_over_down_minu0/100) , "#,###.##") : na )
label_l2 := label.new( bar_index_time + value_stay ,sma_low * (1 + std_over_down_minu1/100) , style=label.style_none , textcolor= threshold_3 and threshold_1 and threshold_2 ? color_div2 :color.new(color.white, 40),
text = value_view ? str.tostring(sma_low * (1 + std_over_down_minu1/100) , "#,###.##") : na )
plus0 = plot( Dev0 > 0 ? sma_up * (1+rms_inside_up_plus0/100) : na ,color = threshold_3 and threshold_1 and threshold_2 ? color_div0 : color.new(color.white, 40))
minu0 = plot( Dev0 > 0 ? sma_low * (1+rms_inside_down_minu0/100) : na ,color =threshold_3 and threshold_1 and threshold_2 ? color_div0 : color.new(color.white, 40))
plus1 = plot( Dev1 > 0 ? sma_up * (1+std_over_up_plus0/100) : Dev1 == 0 ? sma_up * (1 + rms_upper/100 * rms_bai) : na,title="Upper", color= threshold_3 and threshold_1 and threshold_2 ? color_div1 : color.new(color.white, 40))
plus2 = plot( Dev2 > 0 ? sma_up * (1+std_over_up_plus1/100) : na,title="Up_over", color= threshold_3 and threshold_1 and threshold_2 ? color_div2 : color.new(color.white, 40))
minu1 = plot( Dev1 > 0 ? sma_low * (1+std_over_down_minu0/100) : Dev1 == 0 ? sma_up * (1 + rms_lower/100 * rms_bai) : na,title="Lower", color= threshold_3 and threshold_1 and threshold_2 ? color_div1 : color.new(color.white, 40))
minu2 = plot( Dev2 > 0 ? sma_low * (1+std_over_down_minu1/100) : na,title="Low_over", color= threshold_3 and threshold_1 and threshold_2 ? color_div2 : color.new(color.white, 40))
// plot( upper_view and ( Dev1 > 0 or Dev2 > 0 ) ? sma_up : na,title="high", color=color.blue)
// plot( lower_view and ( Dev1 > 0 or Dev2 > 0 ) ? sma_low : na,title="low", color=color.blue)
fill(plus1, plus2, color = threshold_3 and threshold_1 and threshold_2 ? close_time > sma_up * (1+std_over_up_plus1/100) ? color.new(color.red,0) :
high_time > sma_up * (1+std_over_up_plus0/100) ? color.new(color.yellow,20) : na : na, title="upColor")
fill(minu1, minu2, color = threshold_3 and threshold_1 and threshold_2 ? close_time < sma_low * (1+std_over_down_minu1/100) ? color.new(color.red,0) :
low_time < sma_low * (1+std_over_down_minu0/100) ? color.new(color.yellow,20) : na:na, title="upColor")
この記事が気に入ったらサポートをしてみませんか?