Apakah bottom IHSG sudah selesai? (code)

Secara teknikal, kuncinya adalah resistance 6452


Sebelumnya area AR 6377 ini sudah tertembus -> sehingga confirm valid support.

Tentu potensi 5300 sebagai bottom confirm.

Ada peluang koreksi kembali, tapi cenderung kecil ( ada yang bilang 20% )

Yang perlu diperhatikan adalah area gap yang masih terbuka.


Lalu saham-nya apa aja?




// © Zeiierman
// Modified into Strategy for Swing Trading Stocks by AI Assistant

//@version=6
strategy('Volume SuperTrend AI - Swing Strategy', overlay = true, initial_capital = 100000000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, commission_value = 0.15, slippage = 2)

// ============================================================================
// ~~ BACKTEST DATE RANGE SETTINGS
// ============================================================================
groupDate = '⏰ Backtest Date Range'
startYear   = input.int(2020, 'Start Year',   minval = 1900, maxval = 2100, group = groupDate)
startMonth  = input.int(1,    'Start Month',  minval = 1,    maxval = 12,   group = groupDate)
startDay    = input.int(1,    'Start Day',    minval = 1,    maxval = 31,   group = groupDate)
endYear     = input.int(2100, 'End Year',     minval = 1900, maxval = 2100, group = groupDate)
endMonth    = input.int(12,   'End Month',    minval = 1,    maxval = 12,   group = groupDate)
endDay      = input.int(31,   'End Day',      minval = 1,    maxval = 31,   group = groupDate)

startTime = timestamp(startYear, startMonth, startDay, 0, 0)
endTime   = timestamp(endYear, endMonth, endDay, 23, 59)
inDateRange = time >= startTime and time <= endTime

// ============================================================================
// ~~ STRATEGY SETTINGS
// ============================================================================
groupStrat = '📊 Strategy Settings'
useLong     = input.bool(true,  'Enable Long Positions',  group = groupStrat)
useShort    = input.bool(false, 'Enable Short Positions', group = groupStrat)
useStopLoss = input.bool(true,  'Use Stop Loss',          group = groupStrat)
stopLossPct = input.float(7.0,  'Stop Loss %',            minval = 0.1, maxval = 50.0, step = 0.5, group = groupStrat)
useTakeProfit = input.bool(false, 'Use Take Profit',      group = groupStrat)
takeProfitPct = input.float(15.0, 'Take Profit %',        minval = 0.1, maxval = 100.0, step = 0.5, group = groupStrat)
trailingStop = input.bool(false, 'Use Trailing Stop',     group = groupStrat)
trailPct = input.float(10.0,    'Trailing Stop %',       minval = 0.1, maxval = 50.0, step = 0.5, group = groupStrat)

// ============================================================================
// ~~ TOOLTIPS
// ============================================================================
t1 = 'Neighbors (k): Jumlah tetangga terdekat dalam algoritma KNN. Naikkan untuk sinyal lebih stabil, turunkan untuk lebih responsif.\n\nData (n): Jumlah data historis untuk training KNN. Naikkan untuk konteks lebih luas.'
t2 = 'Price Trend: Panjang WMA harga untuk label KNN. Naikkan untuk smoothing lebih kuat.\n\nPrediction Trend: Panjang WMA SuperTrend untuk smoothing. Naikkan untuk fokus tren jangka panjang.'
t3 = 'Length: Periode ATR dan MA. Naikkan untuk tren jangka panjang (swing).\n\nFactor: Multiplier ATR. Naikkan untuk bands lebih lebar, cocok untuk saham volatil.'
t4 = 'Pilih MA berbasis volume: VWMA paling responsif terhadap volume, WMA memberi bobot pada data terbaru, SMA paling sederhana.'
t5 = 'Warna visual untuk tren Bullish, Bearish, dan Neutral.'

// ============================================================================
// ~~ AI SETTINGS (Optimized for Swing Trading)
// ============================================================================
groupAI = '🤖 AI Settings'
k = input.int(5, title = 'Neighbors (k)', minval = 1, maxval = 100, inline = 'AI', group = groupAI)
n_ = input.int(20, title = 'Data (n)', minval = 1, maxval = 100, inline = 'AI', group = groupAI, tooltip = t1)
n = math.max(k, n_)

KNN_PriceLen = input.int(50, title = 'Price Trend Length', minval = 2, maxval = 500, step = 10, inline = 'AITrend', group = groupAI)
KNN_STLen = input.int(200, title = 'Prediction Trend Length', minval = 2, maxval = 500, step = 10, inline = 'AITrend', group = groupAI, tooltip = t2)

// ============================================================================
// ~~ SUPER TREND SETTINGS (Optimized for Swing Trading)
// ============================================================================
groupST = '📈 SuperTrend Settings'
len = input.int(14, 'ATR Length', minval = 1, inline = 'SuperTrend', group = groupST)
factor = input.float(2.5, 'ATR Factor', step = 0.1, inline = 'SuperTrend', group = groupST, tooltip = t3)
maSrc = input.string('VWMA', 'MA Source', ['SMA', 'EMA', 'WMA', 'RMA', 'VWMA'], inline = '', group = groupST, tooltip = t4)

upCol = input.color(color.new(color.green, 0), 'Bullish Color', inline = 'col', group = groupST)
dnCol = input.color(color.new(color.red, 0), 'Bearish Color', inline = 'col', group = groupST)
neCol = input.color(color.new(color.blue, 0), 'Neutral Color', inline = 'col', group = groupST, tooltip = t5)

// ============================================================================
// ~~ SIGNAL SETTINGS
// ============================================================================
groupSig = '🔔 Signal Settings'
signalMode = input.string('Trend Start', 'Entry Signal Mode', ['Trend Start', 'Trend Confirmation', 'Both'], group = groupSig)
useCloudFilter = input.bool(true, 'Use Cloud Filter (Entry only when Cloud is valid)', group = groupSig)

// ============================================================================
// ~~ CLOUD FILL SETTINGS
// ============================================================================
groupCloud = '☁️ Cloud Fill'
showCloud = input.bool(true, 'Show Cloud Fill', group = groupCloud)
cloudBull = input.color(color.new(color.green, 70), 'Bull Cloud', inline = 'cloudcol', group = groupCloud)
cloudBear = input.color(color.new(color.red, 70), 'Bear Cloud', inline = 'cloudcol', group = groupCloud)
cloudTransp = input.int(78, 'Cloud Transparency', minval = 0, maxval = 95, group = groupCloud)
cloudRefLen = input.int(10, 'Cloud Reference Length', minval = 1, group = groupCloud)
cloudLineSmooth = input.int(2, 'Cloud Line Smoothing', minval = 1, group = groupCloud)
cloudLayers = input.int(3, 'Cloud Richness', minval = 1, maxval = 3, group = groupCloud)

// ============================================================================
// ~~ CALCULATE VOLUME WEIGHTED MA
// ============================================================================
vwma = switch maSrc
    'SMA'  => ta.sma(close * volume, len) / ta.sma(volume, len)
    'EMA'  => ta.ema(close * volume, len) / ta.ema(volume, len)
    'WMA'  => ta.wma(close * volume, len) / ta.wma(volume, len)
    'RMA'  => ta.rma(close * volume, len) / ta.rma(volume, len)
    'VWMA' => ta.vwma(close * volume, len) / ta.vwma(volume, len)

// ============================================================================
// ~~ SUPERTREND CALCULATION
// ============================================================================
atr = ta.atr(len)
upperBand = vwma + factor * atr
lowerBand = vwma - factor * atr
prevLowerBand = nz(lowerBand[1])
prevUpperBand = nz(upperBand[1])

lowerBand := lowerBand > prevLowerBand or close[1] < prevLowerBand ? lowerBand : prevLowerBand
upperBand := upperBand < prevUpperBand or close[1] > prevUpperBand ? upperBand : prevUpperBand

int direction = na
float superTrend = na
prevSuperTrend = superTrend[1]

if na(atr[1])
    direction := 1
else if prevSuperTrend == prevUpperBand
    direction := close > upperBand ? -1 : 1
else
    direction := close < lowerBand ? 1 : -1

superTrend := direction == -1 ? lowerBand : upperBand

// ============================================================================
// ~~ KNN DATA PREPARATION
// ============================================================================
price = ta.wma(close, KNN_PriceLen)
sT = ta.wma(superTrend, KNN_STLen)

data = array.new_float(n)
labels = array.new_int(n)

for i = 0 to n - 1 by 1
    data.set(i, superTrend[i])
    label_i = price[i] > sT[i] ? 1 : 0
    labels.set(i, label_i)

// ============================================================================
// ~~ KNN DISTANCE FUNCTION
// ============================================================================
distance(x1, x2) =>
    math.abs(x1 - x2)

// ============================================================================
// ~~ WEIGHTED KNN FUNCTION
// ============================================================================
knn_weighted(data, labels, k, x) =>
    n1 = data.size()
    distances = array.new_float(n1)
    indices = array.new_int(n1)

    for i = 0 to n1 - 1 by 1
        x_i = data.get(i)
        dist = distance(x, x_i)
        distances.set(i, dist)
        indices.set(i, i)

    // Bubble sort by distance
    for i = 0 to n1 - 2 by 1
        for j = 0 to n1 - i - 2 by 1
            if distances.get(j) > distances.get(j + 1)
                tempDist = distances.get(j)
                distances.set(j, distances.get(j + 1))
                distances.set(j + 1, tempDist)

                tempIndex = indices.get(j)
                indices.set(j, indices.get(j + 1))
                indices.set(j + 1, tempIndex)

    weighted_sum = 0.0
    total_weight = 0.0

    for i = 0 to k - 1 by 1
        index = indices.get(i)
        label_i = labels.get(index)
        weight_i = 1 / (distances.get(i) + 1e-6)
        weighted_sum := weighted_sum + weight_i * label_i
        total_weight := total_weight + weight_i

    weighted_sum / total_weight

// ============================================================================
// ~~ CLASSIFY CURRENT DATA POINT
// ============================================================================
current_superTrend = superTrend
label_ = knn_weighted(data, labels, k, current_superTrend)

// ============================================================================
// ~~ TREND COLOR
// ============================================================================
col = label_ == 1 ? upCol : label_ == 0 ? dnCol : neCol

// ============================================================================
// ~~ CLOUD CALCULATION
// ============================================================================
cloudLine = ta.sma(current_superTrend, cloudLineSmooth)
cloudRef = ta.ema((open + close) / 2, cloudRefLen)

cloudA = not na(cloudLine) and not na(cloudRef) ? cloudLine + (cloudRef - cloudLine) * 0.25 : na
cloudB = not na(cloudLine) and not na(cloudRef) ? cloudLine + (cloudRef - cloudLine) * 0.50 : na
cloudC = not na(cloudLine) and not na(cloudRef) ? cloudLine + (cloudRef - cloudLine) * 0.75 : na

cloudBaseColor = label_ == 1 ? cloudBull : label_ == 0 ? cloudBear : neCol
cloudValid = not na(cloudLine) and not na(cloudRef)

// ============================================================================
// ~~ SIGNAL GENERATION
// ============================================================================
Start_TrendUp = col == upCol and (col[1] != upCol or col[1] == neCol)
Start_TrendDn = col == dnCol and (col[1] != dnCol or col[1] == neCol)
TrendUp = direction == -1 and direction[1] == 1 and label_ == 1
TrendDn = direction == 1 and direction[1] == -1 and label_ == 0

// Filter by cloud validity if enabled
longCondition = useCloudFilter ? (Start_TrendUp or TrendUp) and cloudValid : (Start_TrendUp or TrendUp)
shortCondition = useCloudFilter ? (Start_TrendDn or TrendDn) and cloudValid : (Start_TrendDn or TrendDn)

// Signal mode selection
if signalMode == 'Trend Start'
    longCondition := Start_TrendUp and (not useCloudFilter or cloudValid)
    shortCondition := Start_TrendDn and (not useCloudFilter or cloudValid)
else if signalMode == 'Trend Confirmation'
    longCondition := TrendUp and (not useCloudFilter or cloudValid)
    shortCondition := TrendDn and (not useCloudFilter or cloudValid)

// ============================================================================
// ~~ STRATEGY EXECUTION
// ============================================================================
// LONG ENTRY
if useLong and longCondition and inDateRange and strategy.position_size <= 0
    strategy.entry('Long Entry', strategy.long, comment = 'BUY')

// SHORT ENTRY
if useShort and shortCondition and inDateRange and strategy.position_size >= 0
    strategy.entry('Short Entry', strategy.short, comment = 'SELL')

// EXIT CONDITIONS (opposite signal)
if useLong and strategy.position_size > 0
    if shortCondition
        strategy.close('Long Entry', comment = 'Trend Reversal')

if useShort and strategy.position_size < 0
    if longCondition
        strategy.close('Short Entry', comment = 'Trend Reversal')

// ============================================================================
// ~~ STOP LOSS & TAKE PROFIT
// ============================================================================
if useLong and strategy.position_size > 0
    if useStopLoss
        strategy.exit('Long SL', 'Long Entry', stop = strategy.position_avg_price * (1 - stopLossPct / 100))
    if useTakeProfit
        strategy.exit('Long TP', 'Long Entry', limit = strategy.position_avg_price * (1 + takeProfitPct / 100))
    if trailingStop
        strategy.exit('Long Trail', 'Long Entry', trail_points = na, trail_offset = na, loss = trailPct)

if useShort and strategy.position_size < 0
    if useStopLoss
        strategy.exit('Short SL', 'Short Entry', stop = strategy.position_avg_price * (1 + stopLossPct / 100))
    if useTakeProfit
        strategy.exit('Short TP', 'Short Entry', limit = strategy.position_avg_price * (1 - takeProfitPct / 100))
    if trailingStop
        strategy.exit('Short Trail', 'Short Entry', trail_points = na, trail_offset = na, loss = trailPct)

// ============================================================================
// ~~ PLOTTING
// ============================================================================
plot(current_superTrend, color = col, title = 'Volume SuperTrend AI', linewidth = 2)

// Cloud plots
pCloudLine = plot(showCloud ? cloudLine : na, title = 'Cloud Active Line', color = color.new(chart.fg_color, 100), display = display.none)
pCloudA = plot(showCloud and cloudLayers >= 1 ? cloudA : na, title = 'Cloud Layer A', color = color.new(chart.fg_color, 100), display = display.none)
pCloudB = plot(showCloud and cloudLayers >= 2 ? cloudB : na, title = 'Cloud Layer B', color = color.new(chart.fg_color, 100), display = display.none)
pCloudC = plot(showCloud and cloudLayers >= 3 ? cloudC : na, title = 'Cloud Layer C', color = color.new(chart.fg_color, 100), display = display.none)
pCloudRef = plot(showCloud ? cloudRef : na, title = 'Cloud Reference', color = color.new(chart.fg_color, 100), display = display.none)

fill(pCloudLine, pCloudA, color = showCloud and cloudLayers >= 1 ? color.new(cloudBaseColor, math.max(0, cloudTransp - 18)) : na, title = 'Cloud Fill 1')
fill(pCloudA, pCloudB, color = showCloud and cloudLayers >= 2 ? color.new(cloudBaseColor, math.max(0, cloudTransp - 6)) : na, title = 'Cloud Fill 2')
fill(pCloudB, pCloudC, color = showCloud and cloudLayers >= 3 ? color.new(cloudBaseColor, math.min(95, cloudTransp + 6)) : na, title = 'Cloud Fill 3')
fill(pCloudC, pCloudRef, color = showCloud and cloudLayers >= 3 ? color.new(cloudBaseColor, math.min(95, cloudTransp + 18)) : na, title = 'Cloud Fill 4')
fill(pCloudB, pCloudRef, color = showCloud and cloudLayers == 2 ? color.new(cloudBaseColor, math.min(95, cloudTransp + 10)) : na, title = 'Cloud Fill 2-Layer')
fill(pCloudA, pCloudRef, color = showCloud and cloudLayers == 1 ? color.new(cloudBaseColor, math.min(95, cloudTransp + 14)) : na, title = 'Cloud Fill 1-Layer')

// ============================================================================
// ~~ SIGNAL PLOTS
// ============================================================================
plotshape(Start_TrendUp and useLong, location = location.belowbar, style = shape.triangleup, size = size.small, color = color.new(color.green, 0), title = 'Bullish Trend Start')
plotshape(Start_TrendDn and useShort, location = location.abovebar, style = shape.triangledown, size = size.small, color = color.new(color.red, 0), title = 'Bearish Trend Start')
plotshape(TrendUp and useLong, location = location.belowbar, style = shape.labelup, size = size.tiny, color = color.new(color.green, 0), text = 'BUY', textcolor = color.white, title = 'Bullish Confirmation')
plotshape(TrendDn and useShort, location = location.abovebar, style = shape.labeldown, size = size.tiny, color = color.new(color.red, 0), text = 'SELL', textcolor = color.white, title = 'Bearish Confirmation')

// ============================================================================
// ~~ BACKTEST PERIOD VISUALIZATION
// ============================================================================
bgcolor(inDateRange ? color.new(color.gray, 95) : color.new(color.black, 50), title = 'Backtest Period')


Komentar

Postingan populer dari blog ini

BTC akankah koreksi? update astronacci (scheduled post)

Update proyeksi Juli 2025 emas dan IHSG (scheduled post)