BG MVC Model View Controller eğitim serisi yayında...

Ana sayfa > Borsa > Pine Script Programlama > Pine Script strateji örnekleri > pine_script_strateji_ma_008

Pine Script stratejileri

Kapanış değeri ve long ve short işlemlerde sayısı seçime bağlı olarak belirlenebilen on hareketli ortalama ile backtest zaman aralığı seçilebilen, iz süren stop tercihli, trend güç ve hacim gösterge destekli strateji

Bu strateji, aşağıda gösterilen ön tanımlı değerler ile kapanış değeri ve on hareketli ortalama değeri kullanılarak oluşturulmuştur. Hareketli ortalama değerleri (5, 10, 22, 34, 55, 89, 100, 144, 200, 233) long ve short işlemlerinde seçime bağlı olarak belirlenebilen sayıda kullanılabilir.

  • calc_on_every_tick=true: Bar içinde gerçek zamanlı hesaplama
  • commission_value=0.04: Komisyon yüzdesi: 0.0004 (Onbinde dört)
  • initial_capital=10000: İlk sermaye: 10000
  • default_qty_type=strategy.cash: Sermaye türü: Peşin
  • default_qty_value=10000: İşlem yapılacak sermaye: 10000

Bu ayarlar, stratejinin "Ayarlar/Özellikler" sekmesinde değiştirilebilir.

Strateji aşağıda belirtilen esaslar dahilinde çalışır:

  • Hareketli ortalama türü seçilebilir (EMA veya SMA)
  • Hareketli ortalama uzunlukları (ön tanımlı değerler: 5, 10, 22, 34, 55, 89, 100, 144, 200, 233) seçilebilir.
  • Long işlem için seçilen sayıda (1-10) hareketli ortalama değeri, en küçük uzunluktan en büyük uzunlukta olan değere kadar yukarıdan aşağı doğru sıralanıyorsa ve kapanış değeri açılış değerinden büyükse (bar rengi yeşil ise) long koşulu gerçekleşir.
  • Short işlem için seçilen sayıda (1-5) hareketli ortalama değeri, en büyük uzunluktan en küçük uzunlukta olan değere kadar yukarından aşağı doğru sıralanıyorsa ve kapanış değeri açılış değerinden küçükse (bar rengi kırmızı ise) short koşulu gerçekleşir.
  • Short koşul veya iz süren stop değeri long işlemden çıkış için kullanılır.
  • Arayüz üzerinden backtest işlemleri tarih aralığı seçilebilir.
  • Trend gücü ve işlem hacmi ölçülerek, isteğe bağlı olarak long ve short koşulların gerçekleşmesinde değerlendirilir.
  • Trend gücü ve işlem hacmi değerlendirilmesi, alım ve satış işlemlerinin doğruluğunu onaylamaya yarar.

Long ve short işlemlerde kullanılabilecek hareketli ortalama sayısı değiştirildiğinde, karlı yüzde ve net kar yüzde değerleri değişecektir.


// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Niteya
//@version=5
// Bu strateji şablonu sadece eğitim amaçlı olarak verilmiştir. Yatırım kararlarınızda kullanmayınız.
strategy("Niteya Strategy Moving Average", shorttitle='Niteya MA', overlay=true, calc_on_every_tick=true, commission_value=0.04, initial_capital=10000, default_qty_type=strategy.cash, default_qty_value=10000)

ma_type = input.string(title='MA type', defval='EMA', options=['EMA', 'SMA']) // Hareketli ortalama türü seçimi

ml = input.int(2, title="Multi MA sayısı Long", options=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], inline='maopt')
ms = input.int(4, title="Short", options=[1, 2, 3, 4, 5], inline='maopt')

// Hareketli ortalama uzunlukları seçimi
length1 = input(5, 'MA Length1')
length2 = input(10, 'MA Length2')
length3 = input(22, 'MA Length3')
length4 = input(34, 'MA Length4')
length5 = input(55, 'MA Length5')
length6 = input(89, 'MA Length6')
length7 = input(100, 'MA Length7')
length8 = input(144, 'MA Length8')
length9 = input(200, 'MA Length9')
length10 = input(233, 'MA Length10')

src = close

MA1 = ma_type=='EMA' ? ta.ema(src, length1) : ta.sma(src, length1)
MA2 = ma_type=='EMA' ? ta.ema(src, length2) : ta.sma(src, length2)
MA3 = ma_type=='EMA' ? ta.ema(src, length3) : ta.sma(src, length3)
MA4 = ma_type=='EMA' ? ta.ema(src, length4) : ta.sma(src, length4)
MA5 = ma_type=='EMA' ? ta.ema(src, length5) : ta.sma(src, length5)
MA6 = ma_type=='EMA' ? ta.ema(src, length6) : ta.sma(src, length6)
MA7 = ma_type=='EMA' ? ta.ema(src, length7) : ta.sma(src, length7)
MA8 = ma_type=='EMA' ? ta.ema(src, length8) : ta.sma(src, length8)
MA9 = ma_type=='EMA' ? ta.ema(src, length9) : ta.sma(src, length9)
MA10 = ma_type=='EMA' ? ta.ema(src, length10) : ta.sma(src, length10)

ma_long = (ml>1 ? ta.crossover(MA1, MA2) or (MA1>MA2) : true) and (ml>2 ? ta.crossover(MA2, MA3) or (MA2>MA3) : true) and 
 (ml>3 ? ta.crossover(MA3, MA4) or (MA3>MA4) : true) and (ml>4 ? ta.crossover(MA4, MA5) or (MA4>MA5) : true) and (ml>5 ? ta.crossover(MA5, MA6) or (MA5>MA6) : true) and 
 (ml>6 ? ta.crossover(MA6, MA7) or (MA6>MA7) : true) and (ml>7 ? ta.crossover(MA7, MA8) or (MA7>MA8) : true) and (ml>8 ? ta.crossover(MA8, MA9) or (MA8>MA9) : true) and 
 (ml>9 ? ta.crossover(MA9, MA10) or (MA9>MA10): true) and close>open
ma_short = (ms>1 ? ta.crossunder(MA1, MA2) or (MA1<MA2) : true) and (ms>2 ? ta.crossunder(MA2, MA3) or (MA2<MA3) : true) and
 (ms>3 ? ta.crossunder(MA3, MA4) or (MA3<MA4) : true) and (ms>4 ? ta.crossunder(MA4, MA5) or (MA4<MA5) : true) and close<open

long_cond = ma_long ? true : false // Long işleme giriş değerinin kontrolü
short_cond = ma_short ? true : false // Short işleme giriş değerinin kontrolü

supporting_ind = "Destekleyen indikatörler"
is_volume = input.bool(false, title="Volume", inline='volume', group=supporting_ind)
volume_short = input.bool(false, title="Using in short", inline='volume', group=supporting_ind)
is_adx = input.bool(false, title="Trend strength", inline='adx', group=supporting_ind)
adx_short = input.bool(false, title="Using in short", inline='adx', group=supporting_ind)

// DMI inputs
dmi_lensig = input.int(14, title="ADX Smoothing", minval=1, maxval=50, group=supporting_ind)
dmi_len = input.int(14, minval=1, title="ADX DI Length", group=supporting_ind)
dmi_level = input.int(25, minval=20, title="ADX level", group=supporting_ind)

// Long işlemden çıkış yöntemi
sl_method = input.string('Short', title="Long exit method", options=['Stop loss', 'Short', 'Both'])

// Stop loss için ATR değerleri
atr_period = input.int(14, 'Stop loss ATR period', minval=1, step=1)
atr_multiplier = input.float(3, 'Stop loss ATR multiplier', minval=1, step=0.1)

// Backtest periyodu
var backtest = "Backtest period"
StartDay = input(1, 'Başlangıç günü', group=backtest)
StartMonth = input(1, 'Başlangıç ayı', group=backtest)
StartYear = input(2021, 'Başlangıç yılı', group=backtest)
PeriodStart = timestamp(StartYear, StartMonth, StartDay, 0, 0)

StopDay = input(31, 'Bitiş günü', group=backtest)
StopMonth = input(12, 'Bitiş ayı', group=backtest)
StopYear = input(9999, 'Bitiş yılı', group=backtest)
PeriodStop = timestamp(StopYear, StopMonth, StopDay, 0, 0)

// DMI hesaplamaları
up = ta.change(high)
down = -ta.change(low)
plusDM = na(up) ? na : (up > down and up > 0 ? up : 0)
minusDM = na(down) ? na : (down > up and down > 0 ? down : 0)
trur = ta.rma(ta.tr, dmi_len)
plus = fixnan(100 * ta.rma(plusDM, dmi_len) / trur)
minus = fixnan(100 * ta.rma(minusDM, dmi_len) / trur)
sum = plus + minus
adx = 100 * ta.rma(math.abs(plus - minus) / (sum == 0 ? 1 : sum), dmi_lensig)
adx_value = adx>adx[1] and adx>=dmi_level ? ((close>open) and (plus>minus) ? 1 : -1) : 0

// Volume hesaplamaları
volume_value = (volume >= 1.1 * ta.sma(volume, 10)) ? ((close>open) ? 1 : -1) : 0

var int long_no = 0
var int close_no = 0

// ATR hesaplamaları
atr_long = ta.atr(atr_period)

// İz süren stop hesaplamaları
stop_loss_atr = atr_multiplier * atr_long
Trail = 0.0
iff_1 = close > nz(Trail[1], 0) ? close - stop_loss_atr : close + stop_loss_atr
iff_2 = close < nz(Trail[1], 0) and close[1] < nz(Trail[1], 0) ? math.min(nz(Trail[1], 0), close + stop_loss_atr) : iff_1
Trail := close > nz(Trail[1], 0) and close[1] > nz(Trail[1], 0) ? math.max(nz(Trail[1], 0), close - stop_loss_atr) : iff_2

ind_sup = not is_adx and not is_volume

entry_long_main = long_cond

entry_long_sup = ((is_adx and adx_value==1 ? true : not is_adx ? true : false) and 
                 (is_volume and volume_value==1 ? true : not is_volume ? true : false)) or
                 ind_sup
                   
entry_short_main = short_cond

entry_short_sup = ((is_adx and ((adx_short and adx_value==-1) or not adx_short) ? true : not is_adx ? true : false) and 
                  (is_volume and ((volume_short and volume_value==-1) or not volume_short) ? true : not is_volume ? true : false)) or
                  ind_sup

entry_long = (entry_long_main and entry_long_sup)
entry_short = (entry_short_main and entry_short_sup)
			 
stop_loss_long = Trail

exit_long = close<stop_loss_long		 
			
var int PeriodS1 = 0 // Strateji backtest başlangıç tarihini gösteren değişken
var int PeriodS2 = 0 // Strateji backtest bitiş tarihini gösteren değişken
var float close_s = na // Strateji backtest başlangıç tarihindeki hisse fiyatını gösteren değişken 
var float close_e = na // Strateji backtest bitiş tarihindeki hisse fiyatını gösteren değişken
var bool cs=false, ce=false

// İlk barda değerleri atama
if barstate.isfirst
    close_s := close
    PeriodS1 := timestamp(year(time), month(time), dayofmonth(time), 0, 0)

// Başlangıç ve bitiş kapanış değerlerini strateji backtest işlem tarihi başlangıç ve bitiş tarihlerine göre ayarlama
if time >= PeriodStart and not cs
    close_s := close
    PeriodS1 := timestamp(year(time), month(time), dayofmonth(time), 0, 0)
    cs := true

if time <= PeriodStop and not ce
    PeriodS2 := timestamp(year(time), month(time), dayofmonth(time), 0, 0)
    close_e := close
    ce := true

// Aktif bar tarihinin strateji backtest işlemi başlangıç ve bitiş tarihinin içinde olup olmadığını gösteren fonksiyon
In_Period() =>
    time >= PeriodStart and time <= PeriodStop ? true : false

if In_Period()

	if entry_long and strategy.opentrades==0 // Long koşul gerçekleşmisse ve açılmış bir işlem yoksa long işlem aç
		strategy.entry('long', strategy.long, comment='BUY')
		long_no += 1

    // Seçeneğe bağlı olarak, short koşul gerçekleşmisse veya iz süren stop seviyesinin altına geçilmişse ve 
	// açılmış bir işlem varsa long işlemi kapat
	if strategy.opentrades>0 and (sl_method=='Both' ? exit_long or entry_short : (sl_method=='Stop loss' ? exit_long : entry_short))
        strategy.close_all(comment='SELL')        
        close_no += 1		

// İz süren stop çizimi
plot_con = In_Period() and strategy.position_size > 0
plot(plot_con and not exit_long ? stop_loss_long : na, style=plot.style_linebr, color=color.new(color.red, 0), linewidth=1, title='Stop loss seviyesi')		
		
// Stratejinin kârlı yüzde oranını hesaplayan fonksiyon 
GetWinRate(includeEvens = false) =>
	winTradeCount = strategy.wintrades + 
         (includeEvens ? strategy.eventrades : 0)
	(winTradeCount / strategy.closedtrades) * 100

if(barstate.islast)
    if time <= PeriodStop
        PeriodS2 := timestamp(year(time), month(time), dayofmonth(time), 0, 0)
        close_e := close
		
    string time_str = ''
    period = timeframe.period
    gwr = GetWinRate()       
    text_color_wr = gwr > 0 ? color.green : gwr < 0 ? color.red : color.gray 
    text_color_np = strategy.netprofit > 0 ? color.green : strategy.netprofit < 0 ? color.red : color.gray 
    text_color_single = close_e-close_s > 0 ? color.green : close_e-close_s < 0 ? color.red : color.gray 

    tr = syminfo.currency=='TRY'
    
    // Zaman aralığını metein olarak alma
	switch 
        period=="1" => time_str := '1 ' + (tr ? 'dakika' : 'minute')
        period=="3" => time_str := '3 ' + (tr ? 'dakika' : 'minute')
        period=="5" => time_str := '5 ' + (tr ? 'dakika' : 'minute')
        period=="15" => time_str := '15 ' + (tr ? 'dakika' : 'minute')
        period=="30" => time_str := '30 ' + (tr ? 'dakika' : 'minute')
        period=="45" => time_str := '45 ' + (tr ? 'dakika' : 'minute')
        period=="60" => time_str := '1 ' + (tr ? 'saat' : 'hour')
        period=="120" => time_str := '2 ' + (tr ? 'saat' : 'hour')
        period=="180" => time_str := '3 ' + (tr ? 'saat' : 'hour')
        period=="240" => time_str := '4 ' + (tr ? 'saat' : 'hour')
        str.pos(period, "D")>=0 => time_str := '1 ' + (tr ? 'gün' : 'day')
        str.pos(period, "W")>=0 => time_str := '1 ' + (tr ? 'hafta' : 'week')
        str.pos(period, "M")>=0 => time_str := '1 ' + (tr ? 'ay' : 'month')

    var table m_table = table.new(position.middle_left, columns=2, rows=14, bgcolor=color.rgb(212, 212, 212), border_width=1, border_color=color.white)
    
    table.merge_cells(m_table, 0, 0, 1, 0)
    
    table.cell(m_table, 0, 0, "Niteya MA (" + str.tostring(dayofmonth(PeriodS1), "00") + '.' + str.tostring(month(PeriodS1), "00") + '.' + str.tostring(year(PeriodS1)) + "-" +
     str.tostring(dayofmonth(time), "00") + '.' + str.tostring(month(time), "00") + '.' + str.tostring(year(time)) + ")", text_color=color.white, text_halign=text.align_center, text_size=size.normal, bgcolor=color.new(#31153a, 0))
    
    table.cell(m_table, 0, 1, tr ? 'Periyot' : 'Period', text_color=color.rgb(244, 244, 244), text_halign=text.align_left, text_size=size.large, bgcolor=color.orange)
    table.cell(m_table, 0, 2, tr ? 'İlk sermaye' : 'Capital' , text_color=color.rgb(244, 244, 244), text_halign=text.align_left, text_size=size.large, bgcolor=color.orange)
    table.cell(m_table, 0, 3, (tr ? 'Karlı yüzde' : 'Profitable percent') + ' (%)', text_color=color.rgb(244, 244, 244), text_halign=text.align_left, text_size=size.large, bgcolor=color.orange)
    table.cell(m_table, 0, 4, (tr ? 'Net kar' : 'Net profit') + ' (%)', text_color=color.rgb(244, 244, 244), text_halign=text.align_left, text_size=size.large, bgcolor=color.orange)
    table.cell(m_table, 0, 5, tr ? 'Net kar' : 'Net profit', text_color=color.rgb(244, 244, 244), text_halign=text.align_left, text_size=size.large, bgcolor=color.orange)
    table.cell(m_table, 0, 6, tr ? 'Açılan işlemler' : 'Opened trades', text_color=color.rgb(244, 244, 244), text_halign=text.align_left, text_size=size.large, bgcolor=color.orange)
    table.cell(m_table, 0, 7, tr ? 'Kapanan işlemler' : 'Closed trades', text_color=color.rgb(244, 244, 244), text_halign=text.align_left, text_size=size.large, bgcolor=color.orange)
    table.cell(m_table, 0, 8, tr ? 'Başlangıç tarihi' : 'Start date', text_color=color.rgb(244, 244, 244), text_halign=text.align_left, text_size=size.large, bgcolor=color.orange)
    table.cell(m_table, 0, 9, tr ? 'Bitiş tarihi' : 'Stop date', text_color=color.rgb(244, 244, 244), text_halign=text.align_left, text_size=size.large, bgcolor=color.orange)

    table.cell(m_table, 0, 10, tr ? 'İlk fiyat' : 'First price', text_color=color.rgb(244, 244, 244), text_halign=text.align_left, text_size=size.large, bgcolor=color.rgb(103, 74, 31))
    table.cell(m_table, 0, 11, tr ? 'Son fiyat' : 'Last price', text_color=color.rgb(244, 244, 244), text_halign=text.align_left, text_size=size.large, bgcolor=color.rgb(103, 74, 31))
    table.cell(m_table, 0, 12, (tr ? 'Net kar' : 'Net profit') + ' (%)', text_color=color.rgb(244, 244, 244), text_halign=text.align_left, text_size=size.large, bgcolor=color.rgb(103, 74, 31))
    table.cell(m_table, 0, 13, tr ? 'Net kar' : 'Net profit', text_color=color.rgb(244, 244, 244), text_halign=text.align_left, text_size=size.large, bgcolor=color.rgb(103, 74, 31))

    table.cell(m_table, 1, 1, str.tostring(time_str), text_color=#505050, text_halign=text.align_right, text_size=size.large, bgcolor=color.rgb(212, 212, 212))
    table.cell(m_table, 1, 2, str.tostring(strategy.initial_capital), text_color=#505050, text_halign=text.align_right, text_size=size.large, bgcolor=color.rgb(212, 212, 212))
    
    if not na(gwr)
        table.cell(m_table, 1, 3, str.tostring(gwr, '0.00'), text_color=text_color_wr, text_halign=text.align_right, text_size=size.large, bgcolor=color.rgb(212, 212, 212))
        table.cell(m_table, 1, 4, str.tostring((100*strategy.netprofit)/strategy.initial_capital, '0.00'), text_color=text_color_np, text_halign=text.align_right, text_size=size.large, bgcolor=color.rgb(212, 212, 212))
        table.cell(m_table, 1, 5, str.tostring(strategy.netprofit, '0.00'), text_color=text_color_np, text_halign=text.align_right, text_size=size.large, bgcolor=color.rgb(212, 212, 212))
        table.cell(m_table, 1, 6, str.tostring(long_no), text_color=#505050, text_halign=text.align_right, text_size=size.large, bgcolor=color.rgb(212, 212, 212))
        table.cell(m_table, 1, 7, str.tostring(strategy.closedtrades), text_color=#505050, text_halign=text.align_right, text_size=size.large, bgcolor=color.rgb(212, 212, 212))
    
    table.cell(m_table, 1, 8, str.tostring(dayofmonth(PeriodS1), "00") + '.' + str.tostring(month(PeriodS1), "00") + '.' + str.tostring(year(PeriodS1)), text_color=#505050, text_halign=text.align_right, text_size=size.large, bgcolor=color.rgb(212, 212, 212))
    table.cell(m_table, 1, 9, str.tostring(dayofmonth(PeriodS2), "00") + '.' + str.tostring(month(PeriodS2), "00") + '.' + str.tostring(year(PeriodS2)), text_color=#505050, text_halign=text.align_right, text_size=size.large, bgcolor=color.rgb(212, 212, 212))

    np = (close_e-close_s)*(strategy.initial_capital/close_s)
    
    table.cell(m_table, 1, 10, str.tostring(close_s, '0.000'), text_color=#505050, text_halign=text.align_right, text_size=size.large, bgcolor=color.rgb(212, 212, 212))
    table.cell(m_table, 1, 11, str.tostring(close_e, '0.000'), text_color=#505050, text_halign=text.align_right, text_size=size.large, bgcolor=color.rgb(212, 212, 212))
    table.cell(m_table, 1, 12, str.tostring((100*np)/strategy.initial_capital, '0.00'), text_color=text_color_single, text_halign=text.align_right, text_size=size.large, bgcolor=color.rgb(212, 212, 212))
    table.cell(m_table, 1, 13, str.tostring(np, '0.00'), text_color=text_color_single, text_halign=text.align_right, text_size=size.large, bgcolor=color.rgb(212, 212, 212))


Yukarıdaki strateji ile ilgili bir uygulama aşağıdaki grafikte gösterilmektedir: