Bu strateji ile, long ve short işlemlerin her biri için 4 farklı seçenekle işlem yapabilir, backtest zaman aralığı seçebilir, long işlemden çıkış yöntemi için gösterge short koşulu ile iz süren stop arasından birini tercih edebilirsiniz.
Stratejide, alım işlemi koşulu için, RSI göstergesi, isteğe bağlı olarak, EMA 200 ile birlikte kullanılır.
Stratejinin en avantajlı tarafı, long ve short işlemler için, RSI çizgisinin üst bant, alt bant, orta çizgi ve RSI hareketli ortalama değerlerinden birini kesmesinin kullanılabilmesidir. Böylece, kullanıcı hangi değerin karlı yüzde ve net kar yüzdelerini artıracağını görebilmektedir.
Bu ayarlar, stratejinin "Ayarlar/Özellikler" sekmesinde değiştirilebilir.
Strateji dahilinde, RSI göstergesi ile stratejiye ait ön tanımlı değerler değiştirilebilir:
// 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 RSI", shorttitle='Niteya RSI', overlay=true, calc_on_every_tick=true, commission_value=0.04, initial_capital=10000, default_qty_type=strategy.cash, default_qty_value=10000)
// RSI inputs
rsi_length = input.int(14, minval=1, title="RSI Length")
rsi_maLength = input.int(50, title="RSI MA Length")
rsi_band_lower_level = input.int(30, title="RSI Lower Band")
rsi_band_upper_level = input.int(70, title="RSI Upper Band")
rsi_value_base_long = input.string(title="RSI Long yöntemi", defval="RSI ↘ alt bant", options=['RSI ↘ alt bant', 'RSI ↗ alt bant', 'RSI ↗ MA', 'RSI ↗ 50'])
rsi_value_base_short = input.string(title="RSI Short yöntemi", defval="RSI ↗ üst bant", options=['RSI ↗ üst bant', 'RSI ↘ üst bant', 'RSI ↘ MA', 'RSI ↘ 50'])
// RSI calculations
rsi_calc(close_g) =>
rsi_up = ta.rma(math.max(ta.change(close_g), 0), rsi_length)
rsi_down = ta.rma(-math.min(ta.change(close_g), 0), rsi_length)
rsi = rsi_down == 0 ? 100 : rsi_up == 0 ? 0 : 100 - (100 / (1 + rsi_up / rsi_down))
rsi_MA = ta.sma(rsi, rsi_maLength)
rsi_cross_band_upper_index = ta.barssince(ta.cross(rsi, rsi_band_upper_level))
rsi_cross_MA_index = ta.barssince(ta.cross(rsi, rsi_MA))
rsi_cross_center_index = ta.barssince(ta.cross(rsi, 50))
rsi_cross_band_lower_index = ta.barssince(ta.cross(rsi, rsi_band_lower_level))
last_cross = math.min(rsi_cross_band_upper_index, rsi_cross_MA_index, rsi_cross_center_index, rsi_cross_band_lower_index)
rsi_band_upper=0, rsi_MA_val=0, rsi_center=0, rsi_band_lower=0
switch last_cross
rsi_cross_band_upper_index => // RSI çizgisi en son üst bant çizgisini kesmişse
// rsi üst bant çizgisini yukarı doğru kesmişşe -1, aşağı doğru kesmişşe -2, değilse 0
rsi_band_upper := not(rsi_band_upper_level[last_cross]-rsi[last_cross]>0) ? -2 : (rsi_band_upper_level[last_cross]-rsi[last_cross]>0) ? -1 : 0
rsi_cross_MA_index => // RSI çizgisi en son MA50 çizgisini kesmişse
// rsi MA çizgisini yukarı doğru kesmişşe 1, aşağı doğru kesmişşe -1, değilse 0
rsi_MA_val := not(rsi_MA[last_cross]-rsi[last_cross]>0) ? 1 : (rsi_MA[last_cross]-rsi[last_cross]>0) ? -1 : 0
rsi_cross_center_index => // RSI çizgisi merkez çizgisini (50) kesmişse
// rsi merkez çizgisini yukarı doğru kesmişşe, aşağı doğru kesmişse -1, değilse 0
rsi_center := not(50-rsi[last_cross]>0) ? 1 : (50-rsi[last_cross]>0) ? -1 : 0
rsi_cross_band_lower_index => // RSI çizgisi en son alt bant çizgisini kesmişse
// rsi alt bant çizgisini yukarı doğru kesmişşe 1, aşağı doğru kesmişşe 2, değilse 0
rsi_band_lower := not(rsi_band_lower_level[last_cross]-rsi[last_cross]>0) ? 1 : (rsi_band_lower_level[last_cross]-rsi[last_cross]>0) ? 2 : 0
rsi_long = switch rsi_value_base_long
'RSI ↘ alt bant' => rsi_band_lower==2 ? 1 : 0 // RSI alt bant çizgisini (30) aşağı doğru kestiğinde alım yap.
'RSI ↗ alt bant' => rsi_band_lower==1 ? 1 : 0 // RSI alt bant çizgisini (30) yukarı doğru kestiğinde alım yap.
'RSI ↗ MA' => rsi_MA_val==1 ? 1 : 0 // RSI MA çizgisini yukarı doğru kestiğinde alım yap.
'RSI ↗ 50' => rsi_center==1 ? 1 : 0 // RSI merkez çizgisini (50) yukarı doğru kestiğinde alım yap.
=> 0
rsi_short = switch rsi_value_base_short
'RSI ↗ üst bant' => rsi_band_upper==-2 ? -1 : 0 // RSI üst bant çizgisini yukarı doğru kestiğinde satış yap.
'RSI ↘ üst bant' => rsi_band_upper==-1 ? -1 : 0 // RSI üst bant çizgisini aşağı doğru kestiğinde satış yap.
'RSI ↘ MA' => rsi_MA_val==-1 ? -1 : 0 // RSI MA çizgisini aşağı doğru kestiğinde satış yap.
'RSI ↘ 50' => rsi_center==-1 ? -1 : 0 // RSI merkez çizgisini aşağı doğru kestiğinde satış yap.
=> 0
rsi_value = rsi_long==1 ? 1 : rsi_short==-1 ? -1 : 0
rsi_value = rsi_calc(close)
// MA
is_ema200 = input.bool(true, title="EMA 200 üstünde Long işlem aç")
ma_length1 = input(20, 'MA length1')
ma_length2 = input(50, 'MA length2')
ma_length3 = input(200, 'MA length3')
is_ma_lines = input.bool(true, title="MA çizgileri")
ma_11 = ta.ema(close, ma_length1)
ma_12 = ta.ema(close, ma_length2)
ma_13 = ta.ema(close, ma_length3)
plot(is_ma_lines ? ma_11 : na, title="MA src1", color=color.blue, linewidth=1)
plot(is_ma_lines ? ma_12 : na, title="MA src2", color=color.orange, linewidth=2)
plot(is_ma_lines ? ma_13 : na, title="MA src3", color=color.black, linewidth=3)
var long_exit_vals = "Long işlem çıkış değerleri"
sl_method = input.string('Short', title="Long işlem çıkış yöntemi", options=['Stop loss', 'Short', 'Both'], group=long_exit_vals)
// Zarar durdur için ATR giriş değerleri
atr_period = input.int(14, 'Zarar durdur ATR periyodu', minval=7, step=1, group=long_exit_vals)
atr_multiplier = input.float(3, 'Zarar durdur ATR çarpanı', minval=1.5, step=0.1, group=long_exit_vals)
// Backtest periyodu
var backtest = "Backtest periyodu"
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)
var int long_no = 0
var int close_no = 0
// ATR hesaplama
atr_long = ta.atr(atr_period)
// İz süren stop hesaplama
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
ema_200 = ta.ema(close, 200)
rsi_long = rsi_value==1 and (is_ema200 and not na(ema_200) ? (close>ema_200 ? true : false) : true)
entry_long = rsi_long
rsi_short = rsi_value==-1
entry_short = rsi_short
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
// Zaman aralığını metein olarak alma
switch
period=="1" => time_str := '1 dakika'
period=="3" => time_str := '3 dakika'
period=="5" => time_str := '5 dakika'
period=="15" => time_str := '15 dakika'
period=="30" => time_str := '30 dakika'
period=="45" => time_str := '45 dakika'
period=="60" => time_str := '1 saat'
period=="120" => time_str := '2 saat'
period=="180" => time_str := '3 saat'
period=="240" => time_str := '4 saat'
str.pos(period, "D")>=0 => time_str := '1 gün'
str.pos(period, "W")>=0 => time_str := '1 hafta'
str.pos(period, "M")>=0 => time_str := '1 ay'
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 RSI (" + 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, 'Periyot', 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, 'İlk sermaye', 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, 'Karlı yüzde (%)', 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, 'Net kar (%)', 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, 'Net kar', 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, 'Açılan işlemler', 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, 'Kapanan işlemler', 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, 'Başlangıç tarihi', 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, 'Bitiş tarihi', 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, 'İlk fiyat', 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, 'Son fiyat', 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, 'Net kar (%)', 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, 'Net kar', 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. Long işlem için, RSI değerinin hareketli ortalama değerini yukarı doğru kesmesi, short işlem RSI değerinin üst bant değerini (70) yukarı doğru kesmesi esas alınmıştır.