
Die Strategie verwendet eine Stufen-Break-Methode, die unter bestimmten Breakout-Bedingungen mehr Freiraum erzeugt und eine automatische Rückmeldfunktion hat, um die beste Kombination von Parametern zu finden.
Die Eingabeparameter umfassen die Anzahl der Tage, die Stopp-Prozentzahl, die Stopp-Prozentzahl und automatische Rückmessparameter wie die Anzahl der Tage, die Stopp-Stopp-Range usw.
Die Rückmeldung erfolgt über verschiedene Kombinationen von Rückmeldungstagen, Stop-Loss-Prozentsätzen und Stop-Loss-Prozentsätzen und erfasst die Gewinn- und Verluste für jede Kombination.
Breakout-Signal-Urteil: Überschreiten Sie die Obergrenze des Schlusskurses, ohne den Börsengang zu erwarten. Unterschreiten Sie die Obergrenze des Schlusskurses, ohne den Börsengang zu erwarten, ohne den Börsengang zu tun.
Stopp-Konditionen: Stoppt der Spieler, wenn er nicht stoppt und die Stop-Line auslöst.
Stopp-Bedingungen: Der Stopp wird ausgespielt, wenn er nicht gestoppt wird und die Stopp-Leitung ausgelöst wird.
Die Ergebnisse der Rückmeldung werden in einer detaillierten Tabelle angezeigt, die nach der Gewinnrate oder dem Nettoergebnis oder der Anzahl der Transaktionen sortiert werden kann, die der Benutzer eingestellt hat.
Die automatische Rückmeldung ermöglicht die schnelle Suche nach der optimalen Parameterkombination ohne manuelle Tests.
Die Ergebnisse der Rückmeldungen können nach Gewinnrate, Netto-Gewinn und Anzahl der Transaktionen sortiert werden. Die Optimierung der Parameter, die den jeweiligen Bedürfnissen entsprechen, kann flexibel ausgewählt werden.
Die Ergebnisse werden visuell dargestellt.
Die Rückmessparameter können angepasst werden, um einen breiteren Parameterraum zu testen und die Gesamtoptimierung zu finden.
Strategische Handelsregeln sind einfach, klar und verständlich.
Kurze Rücklaufzeiten können zu unbeständigen Ergebnissen führen. Lösung: Längere Rücklaufzeiten einstellen.
Häufige Transaktionen können zu Schlupflücken führen, die sich auf die Gewinnspanne auswirken. Lösung: Entspannung der Stop-Loss-Marge.
Die Ergebnisse einer einzelnen Ware sind möglicherweise nicht repräsentativ. Lösung: Verschiedene Sorten werden getestet, um eine stabile Kombination von Parametern zu finden.
Eine Überoptimierung der Parameter kann zu einer Überpassung führen. Lösung: Überprüfen Sie die Stabilität der Parameter für verschiedene Sorten und Zeiträume.
Wenn die Transaktionskosten ignoriert werden, kann dies zu einer Abweichung der Rückmessung führen.
Hinzufügen von Optimierungsdimensionen für die Parameter, z. B. das Hinzufügen von mobilen Stop-Losses oder Handelsbeschränkungen.
Optimierung der Markteintrittsbedingungen in Kombination mit Trendindikator-Filtern.
Optimierung von Stop-Loss-Strategien wie dynamische Stopps oder Stop-Tracking
Die Optimierung von Algorithmen zur Unterstützung von Parametern, wie z. B. Machine Learning.
Optimierung der Code-Struktur und Verbesserung der Rückverfolgungsgeschwindigkeit
Stabilität der Parameter in mehreren Varietäten mit mehreren Zyklen.
Erwägen Sie die Integration von automatischen Transaktionen.
Die Strategie ist klar und leicht zu verstehen, die automatische Rückmessfunktion kann die Parameter schnell optimieren und zeigt, dass die Verlust- und Verlust-Situation für die Strategieverbesserung geeignet ist. Es besteht ein gewisses Risiko, das zu beachten ist, aber es kann durch ständige Verbesserung in vielfältiger Hinsicht optimiert werden.
/*backtest
start: 2023-09-16 00:00:00
end: 2023-10-16 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
// © -_-
//@version=5
// strategy("[-_-] LBAB", process_orders_on_close=true, overlay=true, max_labels_count=500, max_lines_count=500, max_boxes_count=500, default_qty_type=strategy.cash, default_qty_value=100, initial_capital=10000, commission_type=strategy.commission.percent, commission_value=0.075)
// Inputs
lookback = input.int(2, title="Lookback", minval=2, maxval=15)
tp = input.float(5, title="TP (%)", minval=1, maxval=10000)
sl = input.float(5, title="SL (% from Low)", minval=1, maxval=100)
com = input.float(0.075, title="Commission (%)", minval=0, maxval=50)
min_lookback_tr = input.float(2, title="Min Lookback", minval=1, maxval=500, inline="tr_lookback", group="Optimisation")
max_lookback_tr = input.float(5, title="Max Lookback", minval=1, maxval=500, inline="tr_lookback", group="Optimisation")
min_tp_tr = input.float(5, title="Min TP (%)", minval=1, maxval=10000, inline="tr_tp", group="Optimisation")
max_tp_tr = input.float(10, title="Max TP (%)", minval=1, maxval=10000, inline="tr_tp", group="Optimisation")
min_sl_tr = input.float(1, title="Min SL (%)", minval=1, maxval=100, inline="tr_sl", group="Optimisation")
max_sl_tr = input.float(5, title="Max SL (%)", minval=1, maxval=100, inline="tr_sl", group="Optimisation")
imp_perc_profit = input.bool(true, title="Percentage profitable", group="Optimisation")
imp_netprofit = input.bool(false, title="Net profit", group="Optimisation")
imp_numtrades = input.bool(false, title="Number of trades", group="Optimisation")
table_pos = input.string("Bottom Right", title="Position", options=["Top Left", "Top Center", "Top Right", "Middle Left", "Middle Center", "Middle Right", "Bottom Left", "Bottom Center", "Bottom Right"], group="Table")
table_font_size = input.string("Normal", title="Font size", options=["Auto", "Tiny", "Small", "Normal", "Large"], group="Table")
// Table parameters
table_pos_ = switch table_pos
"Top Left" => position.top_left
"Top Center" => position.top_center
"Top Right" => position.top_right
"Middle Left" => position.middle_left
"Middle Center" => position.middle_center
"Middle Right" => position.middle_right
"Bottom Left" => position.bottom_left
"Bottom Center" => position.bottom_center
"Bottom Right" => position.bottom_right
table_font_size_ = switch table_font_size
"Auto" => size.auto
"Tiny" => size.tiny
"Small" => size.small
"Normal" => size.normal
"Large" => size.large
// Sorting function (first element will be largest)
sortArr(arr, arr_index) =>
n = array.size(arr) - 1
for i = 0 to n - 1
for j = 0 to n - i - 1
if array.get(arr, j) < array.get(arr, j + 1)
temp = array.get(arr, j)
temp_index = array.get(arr_index, j)
array.set(arr, j, array.get(arr, j + 1))
array.set(arr, j + 1, temp)
array.set(arr_index, j, array.get(arr_index, j + 1))
array.set(arr_index, j + 1, temp_index)
// Safe checks
if min_lookback_tr > max_lookback_tr
runtime.error("Min Lookback must be less than Max Lookback")
if min_tp_tr > max_tp_tr
runtime.error("Min Take Profit must be less than Max Take Profit")
if min_sl_tr > max_sl_tr
runtime.error("Min Stop Loss must be less than Max Stop Loss")
//
tp_min_ = int(min_tp_tr / 1)
tp_max_ = int(max_tp_tr / 1)
sl_min_ = int(min_sl_tr / 1)
sl_max_ = int(max_sl_tr / 1)
// Size for arrays
arr_size = int((max_lookback_tr - min_lookback_tr + 1) * (tp_max_ - tp_min_ + 1) * (sl_max_ - sl_min_ + 1))
// Arrays
var arr_bi = array.new_int(arr_size, na) // bar_index of Smash Day
var arr_in_pos = array.new_bool(arr_size, false) // are we in a position?
var arr_params = array.new_string(arr_size, "")
var arr_wonlost = array.new_string(arr_size, "")
var arr_profit = array.new_float(arr_size, 0)
// Testing what parameters are best
index = 0
// Lookback
for lookback_i = min_lookback_tr to max_lookback_tr
// Take profit
for tp_i = tp_min_ to tp_max_
// Stop loss
for sl_i = sl_min_ to sl_max_
// Parameters of current iteration
lookback_ = lookback_i
tp_ = tp_i
sl_ = sl_i
//
if array.get(arr_params, index) == ""
array.set(arr_params, index, str.tostring(lookback_) + " " + str.tostring(tp_) + " " + str.tostring(sl_))
// Was there an entry?
was_edone = false
// If entry price reached
if not array.get(arr_in_pos, index) and not na(array.get(arr_bi, index))
if high >= high[bar_index - array.get(arr_bi, index)] and bar_index != array.get(arr_bi, index)
array.set(arr_in_pos, index, true)
was_edone := true
// If we're in a position
if array.get(arr_in_pos, index) and bar_index != array.get(arr_bi, index) and not was_edone
low_sl = low[bar_index - array.get(arr_bi, index)] * (1 - sl_ / 100)
high_ep = high[bar_index - array.get(arr_bi, index)]
high_tp = high_ep * (1 + tp_ / 100)
amount = 100
// Stop loss
if low <= low_sl
array.set(arr_in_pos, index, false)
array.set(arr_wonlost, index, array.get(arr_wonlost, index) + "0")
array.set(arr_profit, index, array.get(arr_profit, index) - math.abs(amount / high_ep * low_sl - amount) - com / 100 * amount * 2)
array.set(arr_bi, index, na)
// Take profit
if high >= high_tp
array.set(arr_in_pos, index, false)
array.set(arr_wonlost, index, array.get(arr_wonlost, index) + "1")
array.set(arr_profit, index, array.get(arr_profit, index) + math.abs(amount / high_ep * high_tp - amount) - com / 100 * amount * 2)
array.set(arr_bi, index, na)
// Entry condition
cond = barstate.isconfirmed and close < low[1] and high[1] < high[lookback_ + 1] //and not array.get(arr_in_pos, index)
// New entry price
if cond and not array.get(arr_in_pos, index)
array.set(arr_bi, index, bar_index)
// Update index
index := index + 1
// Checking the results
var table t = na
var result_index = array.new_int(0, na)
var result_arr_winrate = array.new_float(0, na)
var result_arr_tradenum = array.new_int(0, na)
var sort_array = array.new_float(0, na)
if (barstate.islast or barstate.islastconfirmedhistory) and na(t)
for i = 0 to array.size(arr_params) - 1
wins = 0
losses = 0
arr = array.get(arr_wonlost, i)
for j = 0 to str.length(arr) - 1
str_ = str.substring(arr, j, j + 1)
if str_ == "0"
losses := losses + 1
if str_ == "1"
wins := wins + 1
// Push percentage profitable trades
perc_profit = math.round(wins / (wins + losses) * 100, 2)
array.push(result_arr_winrate, perc_profit)
// Push number of trades
trade_num = str.length(array.get(arr_wonlost, i))
array.push(result_arr_tradenum, trade_num)
// Push index
array.push(result_index, i)
// For combined sorting
array.push(sort_array, (imp_netprofit ? array.get(arr_profit, i) : 1) * (imp_perc_profit ? perc_profit : 1) * (imp_numtrades ? trade_num : 1))
// Sort
sortArr(array.copy(sort_array), result_index)
t := table.new(columns=6, rows=13, bgcolor=color.white, border_color=color.new(color.blue, 0), border_width=1, frame_color=color.new(color.blue, 0), frame_width=1, position=table_pos_)
table.cell(t, 0, 0, "% Profitable" + (imp_perc_profit ? " ↓" : ""), bgcolor=imp_perc_profit ? color.rgb(23, 18, 25) : color.white, text_color=imp_perc_profit ? color.white : color.black, text_size=table_font_size_)
table.cell(t, 1, 0, "Net Profit" + (imp_netprofit ? " ↓" : ""), bgcolor=imp_netprofit ? color.rgb(23, 18, 25) : color.white, text_color=imp_netprofit ? color.white : color.black, text_size=table_font_size_)
table.cell(t, 2, 0, "# of trades" + (imp_numtrades ? " ↓" : ""), bgcolor=imp_numtrades ? color.rgb(23, 18, 25) : color.white, text_color=imp_numtrades ? color.white : color.black, text_size=table_font_size_)
table.cell(t, 3, 0, "Lookback", text_size=table_font_size_)
table.cell(t, 4, 0, "Take Profit %", text_size=table_font_size_)
table.cell(t, 5, 0, "Stop Loss %", text_size=table_font_size_)
counter = 0
forloop_counter = math.min(array.size(result_index) - 1, 10)
for i = 0 to forloop_counter
i_ = array.get(result_index, i)
params_ = str.split(array.get(arr_params, i_), " ")
col_ = color.new(color.blue, 75)
table.cell(t, 0, i + 1, str.tostring(array.get(result_arr_winrate, i_)) + "%", bgcolor=col_, text_size=table_font_size_)
table.cell(t, 1, i + 1, str.tostring(math.round(array.get(arr_profit, i_), 2)) + "$", bgcolor=col_, text_size=table_font_size_)
table.cell(t, 2, i + 1, str.tostring(array.get(result_arr_tradenum, i_)), bgcolor=col_, text_size=table_font_size_)
table.cell(t, 3, i + 1, array.get(params_, 0), bgcolor=col_, text_size=table_font_size_)
table.cell(t, 4, i + 1, array.get(params_, 1), bgcolor=col_, text_size=table_font_size_)
table.cell(t, 5, i + 1, array.get(params_, 2), bgcolor=col_, text_size=table_font_size_)
counter := counter + 1
// Warn if timeframe is <= 10 minutes
if timeframe.in_seconds(timeframe.period) <= 600
table.cell(t, 0, forloop_counter + 2, "Timeframe might be too low", bgcolor=color.orange, text_size=table_font_size_, tooltip="Selected timeframe might be too low and cause an error")
table.merge_cells(t, 0, forloop_counter + 2, 5, forloop_counter + 2)
// Strategy
var int bi = na
var int pos_bi = na
// Buy condition
cond = barstate.isconfirmed and close < low[1] and high[1] < high[lookback + 1] and strategy.position_size == 0
// Stop loss, Take profit
if strategy.position_size[1] == 0 and strategy.position_size > 0 and bar_index != bi
strategy.exit("TP/SL", "Long", stop=low[bar_index - bi] * (1 - sl / 100), limit=high[bar_index - bi] * (1 + tp / 100))
pos_bi := bar_index
// Buy
if cond
strategy.order("Long", strategy.long, stop=high)
bi := bar_index
// Box
if strategy.position_size[1] != 0 and strategy.position_size == 0
tn = strategy.closedtrades - 1
penp = strategy.closedtrades.entry_price(tn)
pexp = strategy.closedtrades.exit_price(tn)