Machine Learning Support & Resistance [FEELS]
Сообщите нам, если считаете, что материал размещён без разрешения.
Сообщить о материале
Обращение по товару «indicator_machine_learning_support_&_resistance_for_tradingview.pine» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
О программе
Индикатор «Machine Learning Support & Resistance [FEELS]» предназначен для автоматического определения зон поддержки и сопротивления на графике цен. Он использует метод k-средних для кластеризации точек swing high и swing low, собранных с помощью встроенных функций Pine Script для определения пивотов.
Модель обрабатывает swing точки в логарифмическом пространстве, перебирает количество кластеров и оценивает качество разделения с помощью коэффициента силуэта. Группы с недостаточным количеством точек или низкой плотностью классифицируются как шум и не отображаются на графике.
Подтверждённые уровни отрисовываются в виде зон (коробок) с настраиваемой шириной и цветом. Индикатор также отображает статистику удержания уровней, таблицу данных, профиль распределения swing точек и отправляет оповещения при входе цены в зону или её пробитии.
Настройки программы
| Настройка | Описание |
|---|---|
| pivLen | Ширина пивота с каждой стороны. Большее значение даёт меньше, но более значимых swing точек. |
| histBars | Количество недавних баров, из которых берутся swing точки для обработки моделью. |
| maxPiv | Максимальное количество последних swing high и swing low, обрабатываемых моделью. |
| autoK | Модель перебирает количество уровней в заданном диапазоне, оценивает качество разделения кластеров и выбирает оптимальное. При выключении количество уровней фиксируется параметром kFix. |
| kMin | Нижняя граница диапазона количества уровней, перебираемых моделью. |
| kMax | Верхняя граница диапазона количества уровней, перебираемых моделью. |
| kFix | Фиксированное количество уровней, используемое при отключённом автоматическом выборе. |
| minPts | Минимальное количество swing точек в группе для признания её уровнем. Группы с меньшим количеством считаются шумом. |
| selPct | Порог концентрации группы для признания её уровнем. Более высокие значения оставляют только уровни с высокой плотностью swing точек. |
| maxZones | Максимальное количество уровней, отображаемых на графике — выбираются ближайшие к цене. |
| maxDist | Максимальное расстояние от текущей цены, за которое отображаются уровни. Установка 0 показывает все уровни. |
| passes | Количество итераций пересоздания центров кластеров перед окончательным определением уровней. |
| minWIn | Минимальная ширина зоны, гарантирующая видимость даже очень компактных групп. |
| maxWIn | Верхний предел ширины зоны как доля от цены уровня. |
| maxWRng | Второй предел ширины зоны, измеряемый как доля от общего ценового диапазона, обработанного моделью. |
| softEdge | Отрисовка уровня как плотного ядра с плавными краями — плотные уровни выглядят чётко, разрежённые — размыто. |
| showProf | Отображение гистограммы распределения swing точек по цене — исходных данных для модели. |
| profBins | Количество интервалов (бин) для отображения гистограммы распределения swing точек по цене. |
| profW | Ширина столбцов гистограммы распределения в барах. |
| showStats | Отображение статистики удержания: как часто цена входила в уровень и выходила с той же стороны, не пробив его. |
| showTable | Отображение таблицы с информацией о найденных уровнях, количестве swing точек и статистике удержания. |
| statBack | Количество баров истории, используемых для расчёта частоты удержания уровней. |
| statWin | Количество баров, в течение которых цена должна закрыться за уровнем, чтобы визит считаться пробитием. |
| supCol | Цвет зон поддержки. |
| resCol | Цвет зон сопротивления. |
| noiseCol | Цвет swing точек, отвергнутых моделью как слишком разреженные для формирования уровня. |
| showDots | Отображение всех swing точек, рассмотренных моделью, цветом по принадлежности к уровню или шуму. |
| showNoise | Отображение swing точек, отвергнутых моделью как шум. |
| dotSizeS | Размер точек swing точек на графике. |
| showMid | Отображение центральной линии каждого уровня. |
| extBars | Количество баров, на которые зоны продлеваются вправо от текущего бара. |
| txtSizeS | Размер текста меток уровней и таблицы. |
Поиск по коду файла
indicator("Machine Learning Support & Resistance [FEELS]", "ML S&R", overlay = true, max_boxes_count = 500, max_lines_count = 100, max_labels_count = 500, max_bars_back = 5000)
pivLen = input.int(10, "Swing size", minval = 2, maxval = 50, tooltip = "Pivot width on each side. Bigger = fewer, more significant swing points feed the model")
histBars = input.int(1000, "History, bars", minval = 200, maxval = 5000, step = 100, tooltip = "Only swing points from this many recent bars feed the model, so levels come from structure that still matters")
maxPiv = input.int(250, "Swing points used", minval = 20, maxval = 400, tooltip = "How many of the most recent swing highs and lows the model runs on")
autoK = input.bool(true, "Model picks the level count", tooltip = "The model tries every level count in the range below, scores how cleanly each one separates the swings, and keeps the best. Turn off to fix the count yourself")
kMin = input.int(3, "Fewest levels", minval = 2, maxval = 12, tooltip = "Lower end of the range the model searches")
kMax = input.int(9, "Most levels", minval = 3, maxval = 14, tooltip = "Upper end of the range the model searches")
kFix = input.int(6, "Level count", minval = 2, maxval = 14, tooltip = "Used when the model is not picking the count itself")
minPts = input.int(3, "Min swings per level", minval = 2, maxval = 20, tooltip = "A group with fewer swings than this is not treated as a level, and its swings are labelled noise")
selPct = input.int(60, "Selectivity", minval = 0, maxval = 200, step = 10, tooltip = "How concentrated a group must be to count as a level, measured against the average group on the chart. Higher values keep only the levels where swings really pile up and label the rest noise")
maxZones = input.int(8, "Max levels shown", minval = 1, maxval = 20, tooltip = "Only the levels nearest to price are drawn")
maxDist = input.float(60, "Max distance from price, %", minval = 0, maxval = 500, step = 10, tooltip = "Levels further than this from the current price are hidden, measured proportionally so up and down are treated alike. Set 0 to show every level")
passes = input.int(15, "Refinement passes", minval = 3, maxval = 40, tooltip = "How many times the model re-centres the groups before settling")
grpW = "Zone width"
minWIn = input.float(0.15, "Minimum width, %", minval = 0.05, maxval = 5, step = 0.05, group = grpW, tooltip = "A very tight group still draws at least this wide so it stays visible")
maxWIn = input.float(1.0, "Maximum width, %", minval = 0.1, maxval = 25, step = 0.1, group = grpW, tooltip = "Safety cap. A group is never drawn wider than this share of its level")
maxWRng = input.float(6.0, "Maximum width, % of range", minval = 1, maxval = 50, step = 1, group = grpW, tooltip = "Second cap, measured against the whole price range the model looked at. This keeps zones thin on intraday charts, where the range is small and a percentage of price would cover the screen")
softEdge = input.bool(true, "Density edges", group = grpW, tooltip = "Draws each level as a dense core fading into softer edges, so a tightly agreed level looks sharp and a loosely agreed one looks blurred")
grpP = "Density profile"
showProf = input.bool(false, "Show profile", group = grpP, tooltip = "Draws how the swing points are distributed across price, which is the raw data the model works on")
profBins = input.int(48, "Resolution", minval = 12, maxval = 100, group = grpP)
profW = input.int(70, "Width, bars", minval = 10, maxval = 200, group = grpP)
grpT = "Hold rate"
showStats = input.bool(true, "Show hold rate", group = grpT, tooltip = "Counts how often price entered a level and left from the same side instead of closing through it")
showTable = input.bool(true, "Show table", group = grpT)
statBack = input.int(500, "Lookback, bars", minval = 100, maxval = 1500, group = grpT)
statWin = input.int(10, "Reaction window, bars", minval = 3, maxval = 100, group = grpT, tooltip = "How long price has to close through a level before that visit counts as broken")
grpS = "Style"
supCol = input.color(#089981, "Support", group = grpS)
resCol = input.color(#f23645, "Resistance", group = grpS)
noiseCol = input.color(#787b86, "Noise", group = grpS, tooltip = "Swings the model rejected as too sparse to form a level")
showDots = input.bool(true, "Show swing points", group = grpS, tooltip = "Draws every swing point the model looked at, coloured by the level it belongs to")
showNoise = input.bool(true, "Show rejected swings", group = grpS)
dotSizeS = input.string("Large", "Swing point size", options = ["Tiny", "Small", "Normal", "Large"], group = grpS)
showMid = input.bool(true, "Show level centre", group = grpS)
extBars = input.int(8, "Extend right, bars", minval = 0, maxval = 100, group = grpS)
txtSizeS = input.string("Small", "Text size", options = ["Tiny", "Small", "Normal", "Large"], group = grpS)
txtSize = txtSizeS == "Tiny" ? size.tiny : txtSizeS == "Normal" ? size.normal : txtSizeS == "Large" ? size.large : size.small
dotSize = dotSizeS == "Large" ? size.large : dotSizeS == "Normal" ? size.normal : dotSizeS == "Small" ? size.small : size.tiny
var pvP = array.new<float>()
var pvB = array.new<int>()
var boxes = array.new<box>()
var tags = array.new<label>()
var dots = array.new<label>()
var mids = array.new<line>()
ph = ta.pivothigh(pivLen, pivLen)
pl = ta.pivotlow(pivLen, pivLen)
f_kmeans(array<float> data, int k, int iters) =>
n = array.size(data)
cent = array.new<float>(k, 0.0)
if n > 0
srt = array.copy(data)
array.sort(srt)
for i = 0 to k - 1
idx = math.max(0, math.min(n - 1, int((i + 0.5) * n / k)))
array.set(cent, i, array.get(srt, idx))
for it = 1 to iters
sums = array.new<float>(k, 0.0)
cnts = array.new<int>(k, 0)
for j = 0 to n - 1
v = array.get(data, j)
best = 0
bd = math.abs(v - array.get(cent, 0))
for c = 1 to k - 1
d = math.abs(v - array.get(cent, c))
if d < bd
bd := d
best := c
array.set(sums, best, array.get(sums, best) + v)
array.set(cnts, best, array.get(cnts, best) + 1)
for c = 0 to k - 1
if array.get(cnts, c) > 0
array.set(cent, c, array.get(sums, c) / array.get(cnts, c))
cent
f_nearest(array<float> cent, float v) =>
best = 0
bd = math.abs(v - array.get(cent, 0))
for c = 1 to array.size(cent) - 1
d = math.abs(v - array.get(cent, c))
if d < bd
bd := d
best := c
best
f_silhouette(array<float> data, array<float> cent) =>
n = array.size(data)
k = array.size(cent)
tot = 0.0
cnt = 0
for j = 0 to n - 1
v = array.get(data, j)
d1 = 1e9
d2 = 1e9
for c = 0 to k - 1
d = math.abs(v - array.get(cent, c))
if d < d1
d2 := d1
d1 := d
else if d < d2
d2 := d
if d2 > 0
tot += (d2 - d1) / d2
cnt += 1
cnt > 0 ? tot / cnt : 0.0
f_holdRate(float bot, float top) =>
visits = 0
held = 0
lim = math.min(statBack, bar_index - 1)
if lim > statWin + 2
for o = lim to statWin + 1
if o <= 4980
inNow = low[o] <= top and high[o] >= bot
inPrev = low[o + 1] <= top and high[o + 1] >= bot
if inNow and not inPrev
fromBelow = close[o + 1] < bot
fromAbove = close[o + 1] > top
if fromBelow or fromAbove
visits += 1
broke = false
for f = 1 to statWin
c = close[o - f]
if not broke and (fromBelow ? c > top : c < bot)
broke := true
if not broke
held += 1
[visits, held]
f_clear() =>
if array.size(boxes) > 0
for i = 0 to array.size(boxes) - 1
box.delete(array.get(boxes, i))
array.clear(boxes)
if array.size(tags) > 0
for i = 0 to array.size(tags) - 1
label.delete(array.get(tags, i))
array.clear(tags)
if array.size(dots) > 0
for i = 0 to array.size(dots) - 1
label.delete(array.get(dots, i))
array.clear(dots)
if array.size(mids) > 0
for i = 0 to array.size(mids) - 1
line.delete(array.get(mids, i))
array.clear(mids)
if barstate.isconfirmed
if not na(ph) and ph > 0
array.push(pvP, ph)
array.push(pvB, bar_index - pivLen)
if not na(pl) and pl > 0
array.push(pvP, pl)
array.push(pvB, bar_index - pivLen)
while array.size(pvP) > maxPiv
array.shift(pvP)
array.shift(pvB)
while array.size(pvB) > 0 and bar_index - array.get(pvB, 0) > histBars
array.shift(pvP)
array.shift(pvB)
var table stat = table.new(position.top_right, 3, 24, border_width = 1)
touched = false
brokeZ =Показано первые 50% кода (символов: 12965)
Открыть по тарифу
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
Разовая покупка файла
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.