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
Posting Komentar