İSTANBUL

“Biz istiyoruz ki, bu memlekette yapılan her iş, üç beş kişinin çıkarına değil, bu toprakları dolduran milyonların yararına olsun!”


Perry J. Kaufman’ın “Trading The Channel

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