С целью получения предупреждений, возможно только в исследованиях, я создал исследование из стратегии, в которой я намеренно не использую пирамиду. Оповещения настроены на выполнение «Один раз на закрытие бара».
Поскольку у исследований нет опций пирамидирования, я запрограммировал в исследовании аналогичную функцию, чтобы избежать пирамидирования следующим образом:
- Инициализируйте логические переменные
Last_is_long
и Last_is_short
для хранения того, был ли последний ход длинным или коротким - Проверьте логические значения как часть полного
longCondition
и как часть полного shortCondition
- Я делаю
alertcondition()
на основе таких полных условий, которые включают логические значения, таким образом
Что-то вроде:
//@version=4
study(title="MyStudy", shorttitle="MyStudy", overlay=true)
...
//VARIABLE INITIALIZATION:
var bool Last_is_long = false
var bool Last_is_short = false
...
longCondition = myLongCondition() and not(Last_is_long)
shortCondition = myShortCondition() and not(Last_is_short)
...
alertcondition(longCondition, title='Long', message='Long now!')
if longCondition
label.new(time, close, text = "Long", color=color.lime, xloc = xloc.bar_time)
Last_is_long := true
Last_is_short := false
...
alertcondition(shortCondition, title='Short', message='Short now!')
if shortCondition
label.new(time, close, text = "Short", color=color.red, xloc = xloc.bar_time)
Last_is_long := false
Last_is_short := true
При просмотре диаграмм, это работает отлично. Однако с включенным предупреждением выглядит, что переменные Last_is_long
и Last_is_short
всегда реинициализируются (таким образом, false
), так как предупреждения поступают в каждом баре.
В одну сторону чтобы исправить это, нужно перерабатывать все фундаментальные функции myLongCondition()
и myShortCondition()
, чтобы избежать пирамидальной реализации, но я не вижу способа не падать снова в логических значениях, которые не следует повторно инициализировать.
Есть идеи, как это преодолеть?
Из любопытства: это известное и желаемое поведение, что Исследования с предупреждениями просто повторно инициируют переменные на каждом следующем шаге выполнения?
============================================== *
РЕДАКТИРОВАТЬ (полный скрипт ниже):
// Licensing information: free as bird. A referral to me would be much appreciated, though.
// Description: meant to be used with BTCUSD (or XBTUSD) on 3 mins to 1h candles charts.
// Idea is to provide a tool to detect break-out's from a dead band around an EMA, and to detect back-in's to the dead band.
// Detection is fundamentally based on how much %, at least, a certain candle body has ruptured the dead band (adjustable).
// Long and short flags are placed on the chart, as well as the deadband. Can be used to generate alers.
// With minimal modifications, can be convert to a Strategy script.
// Following are ideas to play around if you want. Room for improvements:
// - convert constants into inputs, and diversify thresholds assimetrically
// - play around with wether or not using pyramiding (here pyramiding is blocked)
// - look at several bars in a sequence, not only current
// © esturilio:
// TV : https://www.tradingview.com/u/esturilio/
// SO : https://stackoverflow.com/users/12678720/glauco-esturilio?tab=profile
// GH : esturilio
// TW : @esturilio
//@version=4
study(title="Deadband cross", shorttitle="DB-X", overlay=true)
// === INIT VARIABLES === (needed on Study because Studies don't know about pyramiding)
var bool Last_is_long = false
var bool Last_is_short = false
// Defining the EMA curve for visualization
emaLen = input(12, minval=1, title="EMA Length")
emaSrc = input(open, title="Source for EMA")
emaVal = ema(emaSrc, emaLen)
plot(emaVal, title="EMA", color=color.blue)
// Defining the deadbands:
var float SigmaVar = input(0.30, minval=0, title="% deadband") // band around EMA
SigmaUp = emaVal * (1 + SigmaVar/100)
SigmaDw = emaVal * (1 - SigmaVar/100)
plot(SigmaUp, title="Band+", color=color.orange)
plot(SigmaDw, title="Band-", color=color.orange)
// Definition of the threshold for cross detection:
bar_bodypercent_threshold = input(50,title="%bar threshold for cross detection")
// =============================================================================
// detect cross or already crossed situations:
n_bar_span = abs(close - open)
// following conditions will be used to detect a bullish situation
bull_cross() => (close > SigmaUp and open < SigmaUp) or (close > SigmaUp and open > SigmaUp)
bear_back_cross() => (close > SigmaDw and open < SigmaDw)
// following conditions will be used to detect a bearish situation
bear_cross() => (close < SigmaDw and open > SigmaDw) or (close < SigmaDw and open < SigmaDw)
bull_back_cross() => (close < SigmaUp and open > SigmaUp)
// =============================================================================
// Calculate bar% above SigmaUp when crossing upwards
percent_bar_above_SigmaUp = if bull_cross()
(100*(( max(close,open) - SigmaUp)/n_bar_span))
else
0
// Calculate bar% below SigmaUp when crossing back down
percent_bar_below_SigmaUp = if bull_back_cross()
(100*(( SigmaUp - min(close,open))/n_bar_span))
else
0
// Calculate bar% below SigmaDw when crossing downwards
percent_bar_below_SigmaDw = if bear_cross()
(100*(( SigmaDw - min(close,open))/n_bar_span))
else
0
// Calculate bar% above SigmaDw when crossing back up
percent_bar_above_SigmaDw = if bear_back_cross()
(100*((max(close,open) - SigmaDw)/n_bar_span))
else
0
// =============================================================================
// FINAL TRIGGERNIG:
//longCondition: either bull or back from bear
longCondition = ((close > SigmaUp) and (percent_bar_above_SigmaUp >= bar_bodypercent_threshold)) or ((close < SigmaUp) and (percent_bar_above_SigmaDw >= bar_bodypercent_threshold))
//shortCondition: either bear or back from bull
shortCondition = ((close < SigmaDw) and (percent_bar_below_SigmaDw >= bar_bodypercent_threshold)) or ((close > SigmaDw) and (percent_bar_below_SigmaUp >= bar_bodypercent_threshold))
longConditionFull = longCondition and Last_is_long == false
alertcondition(longConditionFull, title='LongTrigger', message='LongTrigger')
if longConditionFull
//if converting to strategy, you can uncomment below line for activating orders:
//strategy.entry("Long",strategy.long)
//plot green arrow
label.new(time, close, text = "L", style=label.style_labelup, yloc=yloc.belowbar, color=color.lime, xloc = xloc.bar_time)
//make sure pyramiding is not allowed
Last_is_long := true
Last_is_short := false
shortConditionFull = shortCondition and Last_is_short == false
alertcondition(shortConditionFull, title='ShortTrigger', message='ShortTrigger')
if shortConditionFull
//if converting to strategy, you can uncomment below line for activating orders:
//strategy.entry("Short",strategy.short)
//plot red arrow
label.new(time, close, text = "S", style=label.style_labeldown, yloc=yloc.abovebar, color=color.red, xloc = xloc.bar_time)
//make sure pyramiding is not allowed
Last_is_long := false
Last_is_short := true
//DEBUG & PLOTTING:
// Bull and back from bull
//plot(percent_bar_above_SigmaUp, title="%above EMA+s",color=color.green)
//plot(percent_bar_below_SigmaUp, title="%above EMA+s",color=color.olive)
// Bear and back from bear
//plot(percent_bar_below_SigmaDw, title="%below EMA-s",color=color.red)
//plot(percent_bar_above_SigmaDw, title="%below EMA-s",color=color.fuchsia)