本页源码来自 TradingView 公开发布的开源脚本,版权归原作者所有, 请遵循其原始许可(Pine 脚本常见 CC BY-NC-SA / MPL-2.0 / MIT)。 本项目仅用于研究检索与许可范围内的移植。
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// This work is licensed under a Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) https://creativecommons.org/licenses/by-nc-sa/4.0/171819202111121314151612345678910
// derived from Smart Money Concepts by LuxAlgo - https://www.tradingview.com/script/CnB3fSph-Smart-Money-Concepts-LUX/
// © robbatt
import TradingView/ta/8
import robbatt/lib_plot_objects/49 as D
import robbatt/lib_profile/34 as PF
import robbatt/lib_no_delay/18 as ND
import robbatt/lib_math/2 as M
import robbatt/lib_smc/11 as SMC
//@version=6
indicator("Smart Money Concepts (Advanced)", "SMC+", overlay = true, max_bars_back = 500)
////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------}
//Functions
//-----------------------------------------------------------------------------{
//-----------------------------------------------------------------------------{
//Constants
//-----------------------------------------------------------------------------{
//Tooltips
string SHOW_SWING = 'Display market Structure'
string SHOW_SWING_POINTS = 'Display swing point as labels on the chart'
string SHOW_SWHL_POINTS = 'Highlight most recent strong and weak high/low points on the chart'
string SWING_OB = 'Display swing order blocks on the chart\n\nNumber of internal swing blocks to display on the chart'
string FILTER_OB = "Order Block size filter, based on multiples of ATR. Each detected block must be in a specific range to be relevant. We don't want too small, but also not too big in case of spiking candles"
string SHOW_EQHL = 'Display equal highs and equal lows on the chart'
string EQHL_BARS = 'Number of bars used to confirm equal highs and equal lows'
string EQHL_THRESHOLD = 'Sensitivity threshold in a range (0, 1) used for the detection of equal highs & lows\n\nLower values will return fewer but more pertinent results'
string SHOW_FVG = 'Display fair values gaps on the chart'
string FILTER_FVG = 'Filter out non significant fair value gaps'
string FVG_TF = 'Fair value gaps timeframe'
string EXTEND_FVG = 'Determine how many bars to extend the Fair Value Gap boxes on chart'
//----------------------------------------}
//Swing Structure
//----------------------------------------{
var g_struct = 'Market Structure'
var bool show_Structure = input.bool (false , 'Show Market Structure' , group = g_struct, tooltip = SHOW_SWING)
var string show_bull = input.string ('All' , 'Bullish Structure ', options = ['All', 'BOS', 'CHoCH'], group = g_struct, inline = 'bull')
var color bull_css = input.color (#089981, '' , group = g_struct, inline = 'bull')
var string show_bear = input.string('All' , 'Bearish Structure', options = ['All', 'BOS', 'CHoCH'], group = g_struct, inline = 'bear')
var color bear_css = input.color (#f23645 , '' , group = g_struct, inline = 'bear')
var bool show_swing_points = input.bool (false , 'Show Swings Points' , group = g_struct, inline = 'swings', tooltip = SHOW_SWING_POINTS)
var int swing_length = input.int (50 , '' , minval = 10 , group = g_struct, inline = 'swings')
var bool show_latest_swings_levels = input.bool (true , 'Show Strong/Weak High/Low' , group = g_struct, tooltip = SHOW_SWHL_POINTS)
var bool show_bull_bos = show_Structure and (show_bull == 'All' or show_bull == 'BOS')
var bool show_bull_choch = show_Structure and (show_bull == 'All' or show_bull == 'CHoCH')
var bool show_bear_bos = show_Structure and (show_bear == 'All' or show_bear == 'BOS')
var bool show_bear_choch = show_Structure and (show_bear == 'All' or show_bear == 'CHoCH')
//----------------------------------------}
//Order Blocks
//----------------------------------------{
var g_ob = 'Order Blocks'
var show_ob = input.bool (true , 'Show Order Blocks' , group = g_ob, inline = 'OB', tooltip = SWING_OB)
var bull_ob_css = input.color(color.new(#1848cc, 80), '' , group = g_ob, inline = 'OB')
var bear_ob_css = input.color(color.new(#b22833, 80), '' , group = g_ob, inline = 'OB')
var ob_showlast = input.int (5 , 'Show last' , minval = 1 , group = g_ob, inline = 'OB')
var ob_filter_min_mult = input.float(0.2 , 'Size Filter (ATR50 x) Min' , minval = 0, step = 0.1 , group = g_ob, inline = 'OB Filter')
var ob_filter_max_mult = input.float(2.5 , 'Max' , minval = 1, step = 0.1 , group = g_ob, inline = 'OB Filter', tooltip = FILTER_OB)
var show_ob_id = false //input.bool (false , 'show Order Block ID' , group = g_ob)
var extend_blocks = input.bool (true, 'extend blocks' , group = g_ob)
var clear_broken_buffer = input.bool (true, 'hide broken blocks' , group = g_ob)
var use_ob_profile = input.bool (true, 'use profiles' , group = g_ob, display = display.none)
var use_ob_soft_confirm = input.bool (true, 'use soft confirm' , inline = 'soft confirm', group = g_ob, display = display.none, tooltip = 'After extension stop, price touched poc but then exited the block in trend direction. This would be a soft confirmation, often this allows to use the ob before the confirmation period of 50 bars or a structural break in trend direction')
var soft_confirm_offset_atr_len = 50 // input.int (50 , 'ATR len' , minval = 1 , inline = 'soft confirm', group = g_ob)
var soft_confirm_offset_atr_mult = 1 // input.float(1 , 'x' , minval = 1, step = 0.1, inline = 'soft confirm', group = g_ob)
var use_retracements_with_FVG_out = input.bool (true, 'use retracements with FVG out as trend supporting OB' , group = g_ob, display = display.none, tooltip = 'After extension stop, price continued in trend direction, rendering the extesion invalid. If this continuation happened with an FVG crossing the previous pivotal origin of the forming block, it can be seen as a retracement, which is a block of take profits followed by even more agressive entries supporting the trend. So instead of skipping the extension, we are using this information to create a flipped Order Block')
float soft_confirm_offset = ND.atr(soft_confirm_offset_atr_len) * soft_confirm_offset_atr_mult
var PF.ProfileArgs profile_args_bull = PF.ProfileArgs.new(xloc = xloc.bar_time, extend = true, show_labels = true, args_poc_line = D.LineArgs.new(color.green, line.style_dashed, xloc = xloc.bar_time), args_poc_label = D.LabelArgs.new(color.green, xloc = xloc.bar_time, style = label.style_label_left, size = size.small))
var PF.ProfileArgs profile_args_bear = PF.ProfileArgs.new(xloc = xloc.bar_time , extend = true, show_labels = true, args_poc_line = D.LineArgs.new(color.red , line.style_dashed, xloc = xloc.bar_time) , args_poc_label = D.LabelArgs.new(color.red, xloc = xloc.bar_time, style = label.style_label_left, size = size.small))
var SMC.OrderBlockConfig ob_config_bull = SMC.OrderBlockConfig.new(show_ob, ob_showlast, show_ob_id, show_profile = true,
args = D.BoxArgs.new(bg_color = bull_ob_css, border_color = #00000000, xloc = xloc.bar_time),
txt_args = D.BoxTextArgs.new(color.green, size.normal, text_halign = text.align_right),
txt = 'OB ⬈',
profile_args = profile_args_bull
)
var SMC.OrderBlockConfig ob_config_bear = SMC.OrderBlockConfig.new(show_ob, ob_showlast, show_ob_id, show_profile = true,
args = D.BoxArgs.new(bg_color = bear_ob_css, border_color = #00000000, xloc = xloc.bar_time),
txt_args = D.BoxTextArgs.new(color.red, size.normal, text_halign = text.align_right),
txt = 'OB ⬊',
profile_args = profile_args_bear
)
var enable_structure = show_bull_bos or show_bear_bos or show_bull_choch or show_bear_choch or show_swing_points or show_latest_swings_levels
[trend, bull_bos_alert, bull_choch_alert, top_x, top, trail_up_x, trail_up, hh, bear_bos_alert, bear_choch_alert, btm_x, btm, trail_dn_x, trail_dn, ll, hhll_x] =
SMC.structure(swing_length, bull_css, bear_css, na, na, false, show_swing_points, show_latest_swings_levels, show_bull_bos or show_bear_bos, show_bull_choch or show_bear_choch, line.style_solid, size.small, keep_history = true, enabled = enable_structure)
ob_threshold_atr = ND.atr(50)
ob_threshold_min = ob_threshold_atr * ob_filter_min_mult
ob_threshold_max = ob_threshold_atr * ob_filter_max_mult
[ob_blocks_bull, ob_blocks_bear, new_ob_bull, new_ob_bear, ob_broken_bull, ob_broken_bear] = SMC.track_obs(swing_length, hh, ll, trail_up, trail_dn, bull_bos_alert, bull_choch_alert, bear_bos_alert, bear_choch_alert, ob_threshold_min, ob_threshold_max, ob_config_bull, ob_config_bear, enabled = show_ob, extend_blocks = extend_blocks, clear_broken_buffer_before = clear_broken_buffer, align_edge_to_value_area = use_ob_profile, align_break_price_to_poc = use_ob_profile, profile_args_bull = profile_args_bull, profile_args_bear = profile_args_bear, use_soft_confirm = use_ob_soft_confirm, soft_confirm_offset = soft_confirm_offset, use_retracements_with_FVG_out = use_retracements_with_FVG_out)
ob_blocks_bull.draw(ob_config_bull)
ob_blocks_bear.draw(ob_config_bear)
//-----------------------------------------------------------------------------}
//Fair Value Gaps
//-----------------------------------------------------------------------------{
var g_fvg = 'Fair Value Gaps'
var show_fvg = input.bool (true , 'Fair Value Gaps' , group = g_fvg, inline = 'show', tooltip = SHOW_FVG + '\n' + FVG_TF)
var bull_fvg_css = input.color (color.new(#00ff68, 70), '' , group = g_fvg, inline = 'show')
var bear_fvg_css = input.color (color.new(#ff0008, 70), '' , group = g_fvg, inline = 'show')
var fvg_show_last = input.int (5 , "Show last" , minval = 0 , group = g_fvg, inline = 'show')
var fvg_linewidth = input.int (0 , ' Border width' , minval = 0 , group = g_fvg, inline = 'details')
var fvg_tf = input.timeframe('' , "Timeframe" , group = g_fvg, inline = 'details')
var filter_insignificant_fvgs = input.bool (true , "Filter: min size" , group = g_fvg, inline = 'fvg_min', tooltip = FILTER_FVG)
var min_fvg_size_atr_len = input.int (50 , 'ATR Length' , minval = 1 , group = g_fvg, inline = 'fvg_min')
var min_fvg_size_atr_mult = input.float (0.5 , 'x' , minval = 0, step = 0.1 , group = g_fvg, inline = 'fvg_min')
float fvg_size_threshold = filter_insignificant_fvgs ? ND.atr(min_fvg_size_atr_len) * min_fvg_size_atr_mult : 0
var fvg_min_bars = input.int (1 , "extend min (bars) " , minval = 0 , group = g_fvg, inline = 'ext', tooltip = EXTEND_FVG)
var fvg_extend_until_filled = input.bool (true , 'until filled' , group = g_fvg, inline = 'ext')
var fvg_fill_target_ratio = input.float (60 , "Filled at % " , minval = -100, maxval = 200, step = 5, group = g_fvg, inline = 'filled') / 100
var fvg_delete_filled = input.bool (true , 'remove filled ' , group = g_fvg, inline = 'filled')
[fvg_h, fvg_l, fvg_v, fvg_th] = request.security(syminfo.tickerid, fvg_tf, [high, low, volume[2] + volume[1] + volume, fvg_size_threshold])
change_fvg_tf = ta.change(fvg_v) != 0
// pure value approach (no objects)
// [bullish_fvg_alert, bull_top, bull_btm, bearish_fvg_alert, bear_top, bear_btm] = fvgs(fvg_h, fvg_l, fvg_size_threshold, change_fvg_tf, bull_fvg_css, bear_fvg_css, fvg_min_bars, show_fvg, show_fvg)
[bullish_fvg_alert, bearish_fvg_alert, fvgs_bull, fvgs_bear, new_fvg_bull, new_fvg_bear, filled_fvgs_bull, filled_fvgs_bear] = SMC.fvgs_objects(fvg_h, fvg_l, fvg_v, SMC.FVGFillMode.CLOSE, fvg_fill_target_ratio, fvg_size_threshold, change_fvg_tf, show_fvg)
var fvg_config_bull = SMC.FVGConfig.new(show = show_fvg, show_last = fvg_show_last, txt = 'FVG ⬈', show_probability = true, delete_when_filled = fvg_delete_filled, extend_bars = fvg_min_bars, extend_until_filled = fvg_extend_until_filled , box_args = D.BoxArgs.new(bull_fvg_css, fvg_linewidth, line.style_solid, color.new(bull_fvg_css, 90)), box_text_args = D.BoxTextArgs.new(color.green, size.normal, text.align_right, text.align_center), line_args = D.LineArgs.new(bull_fvg_css, line.style_solid, 1))
var fvg_config_bear = SMC.FVGConfig.new(show = show_fvg, show_last = fvg_show_last, txt = 'FVG ⬊', show_probability = true, delete_when_filled = fvg_delete_filled, extend_bars = fvg_min_bars, extend_until_filled = fvg_extend_until_filled , box_args = D.BoxArgs.new(bear_fvg_css, fvg_linewidth, line.style_solid, color.new(bear_fvg_css, 90)), box_text_args = D.BoxTextArgs.new(color.red , size.normal, text.align_right, text.align_center), line_args = D.LineArgs.new(bear_fvg_css, line.style_solid, 1))
fvgs_bull.draw(fvg_config_bull)
fvgs_bear.draw(fvg_config_bear)
filled_fvgs_bull.draw(fvg_config_bull)
filled_fvgs_bear.draw(fvg_config_bear)
//----------------------------------------}
//EQH/EQL
//----------------------------------------{
var show_eq = input.bool (false, 'Equal High/Low' , group = 'EQH/EQL', tooltip = SHOW_EQHL)
var eq_len = input.int (3 , 'Bars Confirmation', minval = 1 , group = 'EQH/EQL', tooltip = EQHL_BARS)
var eq_threshold_in = input.float(0.1 , 'Threshold' , minval = 0, maxval = 0.5, step = 0.1, group = 'EQH/EQL', tooltip = EQHL_THRESHOLD)
eq_atr = ND.atr(50)
eq_threshold = eq_threshold_in * eq_atr
[eqh_alert, eqh_x1, eqh_y1, eqh_x2, eqh_y2, eql_alert, eql_x1, eql_y1, eql_x2, eql_y2] = SMC.equal_levels(eq_len, eq_threshold, bear_css, bull_css, show_eq, show_eq, keep_history = true)
//-----------------------------------------------------------------------------}
//Alerts
//-----------------------------------------------------------------------------{
//Swing Structure
alertcondition(bull_bos_alert , 'Bullish BOS', 'Internal Bullish BOS formed')
alertcondition(bull_choch_alert, 'Bullish CHoCH', 'Internal Bullish CHoCH formed')
alertcondition(ob_broken_bear.size() > 0, 'Bearish OB Breakout', 'Price broke bullish OB')
alertcondition(ob_broken_bull.size() > 0, 'Bullish OB Breakout', 'Price broke bearish OB')
//EQH/EQL
alertcondition(eqh_alert, 'Equal Highs', 'Equal highs detected')
alertcondition(eql_alert, 'Equal Lows', 'Equal lows detected')
//FVG
alertcondition(bullish_fvg_alert, 'Bullish FVG', 'Bullish FVG formed')
alertcondition(bearish_fvg_alert, 'Bearish FVG', 'Bearish FVG formed')
//-----------------------------------------------------------------------------}