
Chiến lược sử dụng chỉ số TSI làm tín hiệu giao dịch chính. Chiến lược tạo ra tín hiệu mở vị trí khi chỉ số TSI giao nhau với đường tín hiệu của nó và chỉ số TSI ở dưới giới hạn thấp hơn hoặc cao hơn giới hạn. Chiến lược cũng sử dụng các chỉ số như EMA và ATR để tối ưu hóa hiệu suất của chiến lược. Chiến lược chỉ hoạt động trong một khoảng thời gian giao dịch cụ thể và đặt tần số giao dịch tối thiểu để kiểm soát giao dịch quá mức.
Chiến lược này dựa trên chỉ số TSI làm trung tâm, tạo ra tín hiệu giao dịch thông qua giao thoa giữa TSI và đường tín hiệu. Đồng thời giới hạn thời gian giao dịch và tần số giao dịch để kiểm soát rủi ro. Ưu điểm của chiến lược là logic đơn giản và rõ ràng, dừng lỗ kịp thời.
/*backtest
start: 2024-05-30 00:00:00
end: 2024-06-06 00:00:00
period: 5m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © nikgavalas
//@version=5
strategy("TSI Entries", overlay=true, margin_long=100, margin_short=100)
//
// INPUTS
//
// Define the start and end hours for trading
string sessionInput = input("1000-1530", "Session")
// Day of the week.
string daysInput = input.string("23456", tooltip = "1 = Sunday, 7 = Saturday")
// Minimum number of bar's between entries
requiredBarsBetweenEntries = input.int(12, "Required Bars Between Entries")
// Show debug labels
bool showDebugLabels = input.bool(false, "Show Debug Labels")
//
// FUNCTIONS
//
//@function Define the triple exponential moving average function
tema(src, len) => tema = 3 * ta.ema(src, len) - 3 * ta.ema(ta.ema(src, len), len) + ta.ema(ta.ema(ta.ema(src, len), len), len)
//@function Atr with EMA
atr_ema(length) =>
trueRange = na(high[1])? high-low : math.max(math.max(high - low, math.abs(high - close[1])), math.abs(low - close[1]))
//true range can be also calculated with ta.tr(true)
ta.ema(trueRange, length)
//@function Check if time is in range
timeinrange() =>
sessionString = sessionInput + ":" + daysInput
inSession = not na(time(timeframe.period, sessionString, "America/New_York"))
//@function Displays text passed to `txt` when called.
debugLabel(txt, color, y, style) =>
if (showDebugLabels)
label.new(bar_index, y, text = txt, color = color, style = style, textcolor = color.black, size = size.small)
//
// INDICATOR CODE
//
long = input(title="TSI Long Length", defval=8)
short = input(title="TSI Short Length", defval=8)
signal = input(title="TSI Signal Length", defval=3)
lowerLine = input(title="TSI Lower Line", defval=-50)
upperLine = input(title="TSI Upper Line", defval=50)
price = close
double_smooth(src, long, short) =>
fist_smooth = ta.ema(src, long)
ta.ema(fist_smooth, short)
pc = ta.change(price)
double_smoothed_pc = double_smooth(pc, long, short)
double_smoothed_abs_pc = double_smooth(math.abs(pc), long, short)
tsiValue = 100 * (double_smoothed_pc / double_smoothed_abs_pc)
signalValue = ta.ema(tsiValue, signal)
//
// COMMON VARIABLES
//
var color trendColor = na
var int lastEntryBar = na
bool tradeAllowed = timeinrange() == true and (na(lastEntryBar) or bar_index - lastEntryBar > requiredBarsBetweenEntries)
//
// CROSSOVER
//
bool crossOver = ta.crossover(tsiValue, signalValue)
bool crossUnder = ta.crossunder(tsiValue,signalValue)
if (tradeAllowed)
if (signalValue < lowerLine and crossOver == true)
strategy.entry("Up", strategy.long)
lastEntryBar := bar_index
else if (signalValue > upperLine and crossUnder == true)
strategy.entry("Down", strategy.short)
lastEntryBar := bar_index
//
// EXITS
//
if (strategy.position_size > 0 and crossUnder == true)
strategy.close("Up", qty_percent = 100)
else if (strategy.position_size < 0 and crossOver == true)
strategy.close("Down", qty_percent = 100)