Bu Pine Script kodu, Perry J. Kaufman’ın “Trading The Channel” makalesine dayalı üç farklı işlem yaklaşımını sunar: trend takibi, kanal kırılmaları ve kanal içi işlemler. Kod, lineer regresyonla eğilim belirler, üst/alt kanal sınırlarını hesaplar ve kullanıcının seçimine göre pozisyon açma/kapama kurallarını uygular. Ayrıca volatiliteye dayalı pozisyon boyutlandırma da içerir.
Detaylı açıklama ve orijinal kod için: Traders.com Mayıs 2025 Traders’ Tips
// TASC Issue: May 2025
// Article: A Test Of Three Approaches
// Trading The Channel
// Article By: Perry J. Kaufman
// Language: TradingView's Pine Script® v6
// Provided By: PineCoders, for tradingview.com
//@version=6
title ='TASC 2025.05 Trading The Channel'
stitle = 'Trading The Channel'
qtyt = strategy.fixed
strategy(title, stitle, false, default_qty_type=qtyt)
//@enum Trade Rules.
enum RULE
T1 = 'Trade the trend.'
T2 = 'Trade a channel breakout.'
T3 = 'Trade within the channel.'
string TT1 = 'Recommended use of `close`, `hlc3` or `hl2`.'
string TT2 = 'Percent of Bands to use as trading zones.'
string TT3 = 'When "Trade within the channel."\n -> Only long when trend is up\n -> Only short when trend is down'
RULE rule = input.enum(RULE.T1, 'Select Trade rule:')
int period = input.int(40, 'Period:')
float price = input.source(close, 'Source:', tooltip=TT1)
float zone = input.float(0.2, 'Zone %:', tooltip=TT2)
bool longonly = input.bool(false, 'Long Only?')
bool filter = input.bool(false, 'Extra filter "Trade within the channel."', tooltip=TT3)
// LRISS : Linear regression intercept, slope and signal
// @function Method of least squares to calculate
// linear regression intercept and slope.
// @param price Data Series Source.
// @param period Data window.
LRISS(float src, simple int length) =>
var float sx = length * (length + 1) / 2
var float sxx = length * (length + 1) * (2 * length + 1) / 6
var float sxy = 0.0
float sy = math.sum(src, length)
float syy = math.sum(src * src, length)
float linreg = ta.linreg(price, period, 0)
float oldSrc = src[length]
sxy += switch
bar_index <= length - 1 => (length - bar_index) * src
=> sy - length * oldSrc
float slope = -(length * sxy - sx * sy) / (length * sxx - sx * sx)
intercept = linreg - slope * period
signal = math.sign(slope)
[linreg, intercept, slope, signal]
// LRISS() function call
[linreg, intercept, slope, signal] = LRISS(price, period)
change = ta.change(signal)
float t = 0, float b = 0, int n = bar_index, int x1 = n - period
float y1 = linreg - period * slope, float band_range = na
float buy_zone = na, float sell_zone = na
// Channel straight lines
// @variable linreg line
var lI = line.new(na, na, na, na, force_overlay=true)
// @variable channel top line
var lT = line.new(na, na, na, na, force_overlay=true
, color=color.red)
// @variable channel top line last bar
var lT_= line.new(na, na, na, na, force_overlay=true
, color=#ce0e0e80)
// @variable channel bottom line
var lB = line.new(na, na, na, na, force_overlay=true
, color=color.lime)
// @variable channel bottom line last bar
var lB_= line.new(na, na, na, na, force_overlay=true
, color=#0ece4b80)
// @variable Initial Capital
float icap = strategy.initial_capital
//@variable Value of Contract in cash.
float vcon = 100000.0
//@variable Units per Contract.
float ucon = vcon / close
// @variable fraction of capital in contracts.
int ncon = math.floor((icap * 0.8 / close) / ucon)
// @variable max contracts
int mcon = math.floor((strategy.equity / close) / ucon)
// @variable Number of contracts to trade.
float size = math.min(ncon, mcon)
//@variable position size
float POSITION = strategy.position_size
//@variable named constant for display
DSP = display.all - display.status_line
for i = 0 to period
b := math.max(b, linreg - (i * slope) - low[i])
t := math.max(t, high[i] - (linreg - (i * slope)))
float upperband = linreg + t + slope
float lowerband = linreg - b + slope
if rule != RULE.T1 and last_bar_index - n < 300
lI.set_xy1(x1, y1), lI.set_xy2(n+1, linreg + slope)
lT.set_xy1(x1, y1 + t), lT.set_xy2(n+1, upperband)
lT_.set_xy1(n, upperband), lT_.set_xy2(n+1, upperband)
lB.set_xy1(x1, y1 - b), lB.set_xy2(n+1, lowerband)
lB_.set_xy1(n, lowerband), lB_.set_xy2(n+1, lowerband)
// for new positions
// Position sizes for equities will be a $10,000 investment
// divided by the closing price. For futures it will be a $25,000
// investment using volatility parity - the investment divided
// by the product of the 20-day average true range and the
// big point value.
// Rule 1: Trade the Channel.
if rule == RULE.T1 and signal != signal[1]
if POSITION <= 0 and signal == 1
// cover all shorts
strategy.close_all('R1X')
strategy.entry('R1L', strategy.long)
else if POSITION >= 0 and signal == -1
strategy.close_all('R1X')
if not longonly
// sell short contract this bar on close
strategy.entry('R1S', strategy.short)
// Rule 2: Trade a Channel Breakout.
// We do not use the direction of the slope as a filter.
if rule == RULE.T2
// Exit current position
if POSITION > 0 and close < lowerband
// sell all contracts
strategy.close_all('R2X')
if not longonly
strategy.entry('R2S', strategy.short)
else if POSITION < 0 and close > upperband
//buy to cover
strategy.entry('R2L', strategy.long)
else if POSITION <= 0 and close > upperband
strategy.entry('R2L', strategy.long)
else if POSITION >= 0 and close < lowerband
strategy.close_all('R2X')
if not longonly
strategy.entry('R2S', strategy.short)
// Rule 3: Trade within the channel.
// We can filter it with the direction of the trendline
if rule == RULE.T3
band_range := upperband - lowerband
buy_zone := lowerband + zone * band_range
sell_zone := upperband - zone * band_range
// Exit when in the zone or slope reverses direction
// Long Exit
if POSITION > 0
if close >= sell_zone or slope <= 0
strategy.close_all('L3 Exit')
// Short Exit
if POSITION < 0
if close <= buy_zone or slope >= 0
strategy.close_all('S3 Exit')
// Long Entry
if POSITION <= 0
and (filter ? slope > 0 : true)
and close <= buy_zone
strategy.entry('L3 Entry', strategy.long)
// Short Entry (optional)
if not longonly and POSITION >= 0
and (filter ? slope < 0 : true)
and close >= sell_zone
strategy.entry('S3 Entry', strategy.short)
sma = ta.sma(close, period)
dir = ta.change(sma)
plot(slope, color= slope > 0 ? #ed7722 : #0e46be
, display = DSP, linewidth = 2)
plot(rule == RULE.T1 ? sma : na, 'SMA compare'
, color = dir > 0 ? #ed7722 : #0e46be
, force_overlay=true, display = DSP)
plotshape(rule == RULE.T1 and change != 0 and signal > 0 ?
0 : na, '', shape.triangleup, location.absolute
, size = size.tiny, color = color.lime, display = DSP)
plotshape(rule == RULE.T1 and change != 0 and signal < 0 ?
0 : na, '', shape.triangledown, location.absolute
, size = size.tiny, color = color.red, display = DSP)
pT = plot(rule != RULE.T1 ? upperband : na, 'upper'
, color.rgb(206, 14, 14, rule == RULE.T2 ? 40 : 100)
, force_overlay=true , display = DSP)
pB = plot(rule != RULE.T1 ? lowerband : na, 'lower'
, color.rgb(14, 206, 75, rule == RULE.T2 ? 40 : 100)
, force_overlay=true , display = DSP)
pT_ = plot(rule == RULE.T3 ? sell_zone : na, 'upper'
, #ff990000, force_overlay=true, display = DSP)
pB_ = plot(rule == RULE.T3 ? buy_zone : na, 'lower'
, #ff990000, force_overlay=true, display = DSP)
fill(pT, pT_, upperband, sell_zone
, #ce0e0e4f, #ce0e0e10, "Upperband")
fill(pB, pB_, lowerband, buy_zone
, #0ece4b4f, #0ece4b10, "Upperband")
hline(0)
Yorum bırakın