← К каталогу
Исходный код · ID 4207

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 и перейдите к оплате.

Стоимость полного кода
1 296,50₽ ≈ $15.85