Kラインに基づく双方向ブレークスルー取引戦略


作成日: 2024-01-30 17:27:01 最終変更日: 2024-01-30 17:27:01
コピー: 4 クリック数: 647
1
フォロー
1617
フォロワー

Kラインに基づく双方向ブレークスルー取引戦略

概要

これは,K線に基づく二方向の突破取引戦略である.これは,K線の現在の終値が,前2つのK線の最高値と最低値のいずれも突破したときに,取引シグナルを生成する.

戦略原則

この戦略の基本的な論理は:

  1. 牛の信号の定義はbull = close > open and close > math.max(close[2], open[2]) and low[1] < low[2] and high[1] < high[2]つまり,現在のK線の閉盘価格は開盘価格より大きく,前2つのK線の最高価格より大きく,そして現在のK線の最低価格は前1つのK線の最低価格より低いということです.

  2. クマの信号の定義はbear = close < open and close < math.min(close[2], open[2]) and low[1] > low[2] and high[1] > high[2]つまり,現在のK線の閉盤価格は開盤価格より小さく,前2つのK線の最低価格より小さく,現在のK線の最高価格は前1つのK線の最高価格より高くなります.

  3. 牛の合図を鳴らしたら,多めに,熊の合図を鳴らしたら,空いてください.

  4. ストップ・ローズとストップ・ストップを設定できます.

この戦略は,二方向の突破の特性を利用し,重要な価格区間を突破してトレンドの変化を判断し,取引信号を生成する.

優位分析

これは比較的シンプルで直感的な突破策で,以下の利点があります.

  1. 論理が明快で理解しやすい 実現の限界は低い

  2. 突破は一般的な取引シグナルであり,トレンドを形成しやすい.

  3. バイアード取引をすることで,利得の機会が増えます.

  4. リスク管理のための柔軟な止損停止設定.

リスク分析

この戦略にはいくつかのリスクがあります.

  1. 双方向の取引はリスクが高いので,注意深く監視する必要があります.

  2. 突破口は誤った信号を誘発しやすい.

  3. パラメータの設定を間違えた場合,過剰な取引が発生する可能性があります.

  4. ストップダストの誤った設定は,利益の拡大にも影響する.

リスクの低減に適した品種を選んでパラメータを最適化できます.

最適化の方向

この戦略は以下の点で最適化できます.

  1. 突破周期パラメータ,ストップダメージストップ幅など,最適化パラメータ.

  2. フィルタリング条件を追加し,ブレーカーや振動などの誤信号を回避します.

  3. トレンド指数と組み合わせて,円盤整合を回避する.

  4. 資金管理の最適化とポジションアルゴリズムの改善

  5. 各種は異なるパラメータで,それぞれテスト・最適化を行うことができます.

要約する

これは,2方向の突破思想に基づく単純な戦略である.論理的明晰さと実行しやすさの利点があるが,一定の監視リスクもある.パラメータと条件の最適化により,優れた戦略効果が得られる見込みである.

ストラテジーソースコード
/*backtest
start: 2023-12-01 00:00:00
end: 2023-12-31 23:59:59
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5

// # ========================================================================= #
// #                   |   Strategy  |
// # ========================================================================= #

SystemName = "Strategy Template Autoview"
TradeId = "S"
// These values are used both in the strategy() header and in the script's relevant inputs as default values so they match.
// Unless these values match in the script's Inputs and the TV backtesting Properties, results between them cannot be compared.
InitCapital = 1000000
InitPosition = 2
InitCommission = 0.075
InitPyramidMax = 1
CalcOnorderFills = false
ProcessOrdersOnClose = true // display the signals one candle earlier
CalcOnEveryTick = true // forward testing
//CloseEntriesRule = "ANY"

strategy(title=SystemName, shorttitle=SystemName, 
 overlay=true, pyramiding=InitPyramidMax, initial_capital=InitCapital, default_qty_type=strategy.fixed, process_orders_on_close=ProcessOrdersOnClose,
 default_qty_value=InitPosition, commission_type=strategy.commission.percent, commission_value=InitCommission, calc_on_order_fills=CalcOnorderFills, 
 calc_on_every_tick=CalcOnEveryTick, 
 precision=6, max_lines_count=500, max_labels_count=500)

// # ========================================================================= #
// # ========================================================================= #
// #                   ||   Alerts  ||
// # ========================================================================= #
// # ========================================================================= #

show_alerts_debug = input.bool(true, title = "Show Alerts Debug Label?", group = "Debug")

//i_alert_txt_entry_long = input.text_area(defval = "", title = "Long Entry Message", group = "Alerts")
//i_alert_txt_entry_short = input.text_area(defval = "", title = "Short Entry Message", group = "Alerts")
//i_alert_txt_exit_long = input.text_area(defval = "", title = "Long Exit Message", group = "Alerts")
//i_alert_txt_exit_short = input.text_area(defval = "", title = "Short Exit Message", group = "Alerts")

i_broker_mode = input.string("DEMO", title = "Use Demo or Live Broker", options=["DEMO", "LIVE"], group = "Automation")
i_broker_name = input.string("Tradovate", title = "Broker Name", options=["Tradovate", "AscendEX", "Binance", "Binance Futures", "Binance US", "Binance Delivery", "Kraken", "Deribit", "Poloniex", "Okcoin", "Bitfinex", "Oanda", "Kucoin", "Okex", "Bybit", "FTX", "Bitmex", "Alpaca", "Gemini"], group = "Automation")

i_enable_trades = input.bool(true, title = "Enable trades?", group = "Automation", tooltip = "If not enabled, disables live trades, but more importantly, it will output what Autoview is going to do when you go live.")

i_account_name = input.string("*", title = "Account Name", group = "Automation")
i_symbol_name  = input.string("btcusd_perp", title = "Symbol Name", group = "Automation")
nb_contracts = input.int(2, title = "Nb Contracts", group = "Automation")

use_delay = input.bool(false, title = "Use Delay between orders", group = "Automation", inline = "delay")
i_delay_qty = input.int(1, title = "Delay in seconds", group = "Automation", inline = "delay")

i_use_borrow_repay   = input.bool(false, title = "Use Borrow/Repay Mode?", group = "Binance Automation")
i_asset_borrow_repay = input.string("BTC", title = "Asset to Borrow/Repay", group = "Binance Automation")
i_qty_borrow_repay   = input.float(1., title = "Quantity of assets to borrow?", group = "Binance Automation")

// # ========================================================================= #
// # ========================================================================= #
// #                   ||   Dates Range Filtering  ||
// # ========================================================================= #
// # ========================================================================= #

DateFilter = input(false, "Date Range Filtering", group="Date")

// ————— Syntax coming from https://www.tradingview.com/blog/en/new-parameter-for-date-input-added-to-pine-21812/
i_startTime = input(defval = timestamp("01 Jan 2019 13:30 +0000"), title = "Start Time", group="Date")
i_endTime = input(defval = timestamp("30 Dec 2021 23:30 +0000"), title = "End Time", group="Date")

TradeDateIsAllowed() => true


// # ========================================================================= #
// #                   |   Custom Exits |
// # ========================================================================= #

//use_custom_exit = input.bool(true, title = "Use Custom Exits?", group = "Custom Exits")

// # ========================================================================= #
// #                   |   Stop Loss |
// # ========================================================================= #

use_sl        = input.string("None", title = "Select Stop Loss Mode", options=["None", "Percent", "Price"], group = "Stop Loss")
sl_input_perc = input.float(3, minval = 0, title = "Stop Loss (%)", group = "Stop Loss (%)") * 0.01
sl_input_pips = input.float(30, minval = 0, title = "Stop Loss (USD)", group = "Stop Loss (USD)")

// # ========================================================================= #
// #                   |   Take Profit |
// # ========================================================================= #

use_tp       = input.string("None", title = "Select Take Profit Mode", options=["None", "Percent", "Price"], group = "Take Profit")
tp_input_perc = input.float(3, minval = 0, title = "Take Profit (%)", group = "Take Profit (%)") * 0.01
tp_input_pips = input.float(30, minval = 0, title = "Take Profit (USD)", group = "Take Profit (USD)")


// # ========================================================================= #
// #                   |   Consolidated Entries |
// # ========================================================================= #

bull = close > open and close > math.max(close[2], open[2]) and low[1] < low[2] and high[1] < high[2] // low < low[1] and low[1] < low[2] 
bear = close < open and close < math.min(close[2], open[2]) and low[1] > low[2] and high[1] > high[2] // low < low[1] and low[1] < low[2] 

// # ========================================================================= #
// #       |   Entry Price |
// # ========================================================================= #

entry_long_price  = ta.valuewhen(condition=bull and strategy.position_size[1] <= 0, source=close, occurrence=0)
entry_short_price = ta.valuewhen(condition=bear and strategy.position_size[1] >= 0, source=close, occurrence=0)

var float entry_price = 0.

if bull
    entry_price := entry_long_price
if bear
    entry_price := entry_short_price

// # ========================================================================= #
// #                   ||   Global Trend Variables ||
// # ========================================================================= #

T1_sinceUP = ta.barssince(bull)
T1_sinceDN = ta.barssince(bear)

T1_nUP = ta.crossunder(T1_sinceUP,T1_sinceDN)
T1_nDN = ta.crossover(T1_sinceUP,T1_sinceDN)

T1_sinceNUP = ta.barssince(T1_nUP)
T1_sinceNDN = ta.barssince(T1_nDN)

T1_BuyTrend  = T1_sinceDN > T1_sinceUP
T1_SellTrend = T1_sinceDN < T1_sinceUP

T1_SellToBuy   = T1_BuyTrend and T1_SellTrend[1]
T1_BuyToSell   = T1_SellTrend and T1_BuyTrend[1]
T1_ChangeTrend = T1_BuyToSell or T1_SellToBuy

// # ========================================================================= #
// #                   |   Stop Loss |
// # ========================================================================= #

var float final_SL_Long  = 0.
var float final_SL_Short = 0.

if use_sl == "Percent"
    final_SL_Long := entry_long_price * (1 - sl_input_perc)
    final_SL_Short := entry_short_price * (1 + sl_input_perc)
else if use_sl == "Price"
    final_SL_Long := entry_long_price - (sl_input_pips)
    final_SL_Short := entry_short_price + (sl_input_pips)

plot(strategy.position_size > 0 and use_sl != "None" ? final_SL_Long : na, title = "SL Long", color = color.fuchsia, linewidth=2, style=plot.style_linebr)
plot(strategy.position_size < 0 and use_sl != "None" ? final_SL_Short : na, title = "SL Short", color = color.fuchsia, linewidth=2, style=plot.style_linebr)

// # ========================================================================= #
// #                   |   Take Profit |
// # ========================================================================= #

var float final_TP_Long  = 0.
var float final_TP_Short = 0.

if use_tp == "Percent"
    final_TP_Long := entry_long_price   * (1 + tp_input_perc)
    final_TP_Short := entry_short_price * (1 - tp_input_perc)
else if use_tp == "Price"
    final_TP_Long := entry_long_price   + (tp_input_pips)
    final_TP_Short := entry_short_price - (tp_input_pips)

plot(strategy.position_size > 0 and use_tp != "None" ? final_TP_Long : na, title = "TP Long", color = color.orange, linewidth=2, style=plot.style_linebr)
plot(strategy.position_size < 0 and use_tp != "None" ? final_TP_Short : na, title = "TP Short", color = color.orange, linewidth=2, style=plot.style_linebr)

// # ========================================================================= #
// #                   |   AutoView Calls |
// # ========================================================================= #

float quantity = nb_contracts

string product_type_ticker = i_symbol_name

var string broker_mode = ""

if i_broker_mode == "DEMO"

    broker_mode := switch i_broker_name
        "Tradovate" => "tradovatesim"
        "Ascendex"  => "ascendex-sandbox"
        "Binance Futures" => "binancefuturestestnet"
        "Binance Delivery" => "binancedeliverytestnet"
        "Oanda" => "oandapractice"
        "Bitmex" => "bitmextestnet"
        "Bybit" => "bybittestnet"
        "Alpaca" => "alpacapaper"
        "Kucoin" => "kucoinsandbox"
        "Deribit" => "deribittestnet"
        "Gemini" => "gemini-sandbox"
        => i_broker_name

else // "LIVE"

    broker_mode := switch i_broker_name
        "Tradovate" => "tradovate"
        "Ascendex"  => "ascendex"
        "Binance Futures" => "binancefutures"
        "Binance Delivery" => "binancedelivery"
        "Binance" => "binance"
        "Oanda" => "oanda"
        "Kraken" => "kraken"
        "Deribit" => "deribit"
        "Bitfinex" => "bitfinex"
        "Poloniex" => "poloniex"
        "Bybit" => "bybit"
        "Okcoin" => "okcoin"
        "Kucoin" => "kucoin"
        "FTX" => "ftx"
        "Bitmex" => "bitmex"
        "Alpaca" => "alpaca"
        "Gemini" => "gemini"
        => i_broker_name

enable_trades = i_enable_trades ? "" : " d=1"
string delay_qty = use_delay ? " delay=" + str.tostring(i_delay_qty) : ""

i_alert_txt_entry_long = "a=" + i_account_name + " e=" + broker_mode + " s=" + product_type_ticker + enable_trades + " b=short c=position t=market" + 
 "\n a=" + i_account_name + " e=" + broker_mode + " s=" + product_type_ticker + " b=long q=" + str.tostring(quantity, "#") + " t=market" + enable_trades + delay_qty
 
i_alert_txt_entry_short = "a=" + i_account_name + " e=" + broker_mode + " s=" + product_type_ticker + enable_trades + " b=long c=position t=market" + 
 "\n a=" + i_account_name + " e=" + broker_mode + " s=" + product_type_ticker + " b=short q=" + str.tostring(quantity, "#") + " t=market" + enable_trades + delay_qty

var string temp_txt_SL_long = ""
var string temp_txt_SL_short = ""

var string temp_txt_TP_long = ""
var string temp_txt_TP_short = ""

if use_sl == "Percent"

    temp_txt_SL_long  := "sl=-" + str.tostring(sl_input_perc * 100) + "%"
    temp_txt_SL_short := "sl=" + str.tostring(sl_input_perc * 100) + "%"

else if use_sl == "Price"

    temp_txt_SL_long  := "fsl=" + str.tostring(final_SL_Long)
    temp_txt_SL_short := "fsl=" + str.tostring(final_SL_Short)

if use_tp == "Percent"

    temp_txt_TP_long := "p=" + str.tostring(tp_input_perc * 100) + "%" 
    temp_txt_TP_short := "p=-" + str.tostring(tp_input_perc * 100) + "%" 

else if use_tp == "Price"

    temp_txt_TP_long  := "fpx=" + str.tostring(final_TP_Long)
    temp_txt_TP_short := "fpx=" + str.tostring(final_TP_Short)  

i_alert_txt_exit_SL_long  = "a=" + i_account_name + " e=" + broker_mode + " s=" + product_type_ticker + " b=long c=position t=market " + temp_txt_SL_long + enable_trades 
i_alert_txt_exit_SL_short = "a=" + i_account_name + " e=" + broker_mode + " s=" + product_type_ticker + " b=short c=position t=market " + temp_txt_SL_short + enable_trades 
i_alert_txt_exit_TP_long  = "a=" + i_account_name + " e=" + broker_mode + " s=" + product_type_ticker + " b=long c=position t=market " + temp_txt_TP_long + enable_trades 
i_alert_txt_exit_TP_short = "a=" + i_account_name + " e=" + broker_mode + " s=" + product_type_ticker + " b=short c=position t=market " + temp_txt_TP_short + enable_trades 

string final_alert_txt_entry_long = i_alert_txt_entry_long
string final_alert_txt_entry_short = i_alert_txt_entry_short

if i_use_borrow_repay and i_broker_name == "Binance"

    final_alert_txt_entry_long := "a=" + i_account_name + " e=" + broker_mode + "y=borrow w=" + i_asset_borrow_repay + " q=" + str.tostring(i_qty_borrow_repay, "#") + enable_trades +
     "\n a=" + i_account_name + " e=" + broker_mode + " s=" + product_type_ticker + enable_trades + " b=short c=position t=market" + delay_qty +
     "\n a=" + i_account_name + " e=" + broker_mode + " s=" + product_type_ticker + " b=long q=" + str.tostring(quantity, "#") + " t=market" + enable_trades + delay_qty +
     "\n a=" + i_account_name + " e=" + broker_mode + "y=repay w=" + i_asset_borrow_repay + " q=" + str.tostring(i_qty_borrow_repay, "#") + enable_trades

    final_alert_txt_entry_short := "a=" + i_account_name + " e=" + broker_mode + "y=borrow w=" + i_asset_borrow_repay + " q=" + str.tostring(i_qty_borrow_repay, "#") + enable_trades +
     "\n a=" + i_account_name + " e=" + broker_mode + " s=" + product_type_ticker + enable_trades + " b=long c=position t=market" + delay_qty +
     "\n a=" + i_account_name + " e=" + broker_mode + " s=" + product_type_ticker + " b=short q=" + str.tostring(quantity, "#") + " t=market" + enable_trades + delay_qty +
     "\n a=" + i_account_name + " e=" + broker_mode + "y=repay w=" + i_asset_borrow_repay + " q=" + str.tostring(i_qty_borrow_repay, "#") + enable_trades

//i_alert_txt_entry_long  := final_alert_txt_entry_long
//i_alert_txt_entry_short := final_alert_txt_entry_short

if show_alerts_debug and barstate.islastconfirmedhistory

    var label lblTest = na

    label.delete(lblTest)

    string label_txt = i_alert_txt_entry_long

    if use_sl != "None"
        label_txt := label_txt + "\n" + i_alert_txt_exit_SL_long

    if use_tp != "None"
        label_txt := label_txt + "\n" + i_alert_txt_exit_TP_long

    t = time + (time - time[1]) * 25

    lblTest := label.new(
     x            = t,
     y            = ta.highest(50),
     text         = label_txt,
     xloc         = xloc.bar_time,
     yloc         = yloc.price,
     color        = color.new(color = color.gray, transp = 0),
     style        = label.style_label_left,
     textcolor    = color.new(color = color.white, transp = 0),
     size         =  size.large
     )

// # ========================================================================= #
// #                   |   Strategy Calls and Alerts |
// # ========================================================================= #

if bull and TradeDateIsAllowed() 

    strategy.entry(id = "Long", direction =  strategy.long, comment = "Long", alert_message = i_alert_txt_entry_long, qty = nb_contracts)
    alert(i_alert_txt_entry_long, alert.freq_once_per_bar)
    
else if bear and TradeDateIsAllowed()
    strategy.entry(id = "Short", direction =  strategy.short, comment = "Short", alert_message = i_alert_txt_entry_short, qty = nb_contracts)
    alert(i_alert_txt_entry_short, alert.freq_once_per_bar)

//quantity := quantity * 2

strategy.exit(id = "Exit Long",  from_entry = "Long",  stop = (use_sl != "None") ? final_SL_Long : na,  comment_loss = "Long Exit SL", alert_loss  = (use_sl != "None") ? i_alert_txt_exit_SL_long : na,   limit = (use_tp != "None") ? final_TP_Long  : na, comment_profit = "Long Exit TP", alert_profit = (use_tp != "None") ? i_alert_txt_exit_TP_long : na)   
strategy.exit(id = "Exit Short", from_entry = "Short", stop = (use_sl != "None") ? final_SL_Short : na, comment_loss = "Short Exit SL", alert_loss = (use_sl != "None") ? i_alert_txt_exit_SL_short : na, limit = (use_tp != "None") ? final_TP_Short : na, comment_profit = "Short Exit TP", alert_profit = (use_tp != "None") ? i_alert_txt_exit_TP_short : na)   

if strategy.position_size > 0 and low < final_SL_Long and use_sl != "None"
    alert(i_alert_txt_exit_SL_long, alert.freq_once_per_bar)

else if strategy.position_size < 0 and high > final_SL_Short and use_sl != "None"
    alert(i_alert_txt_exit_SL_short, alert.freq_once_per_bar)

if strategy.position_size > 0 and high > final_TP_Long and use_tp != "None"
    alert(i_alert_txt_exit_TP_long, alert.freq_once_per_bar)

else if strategy.position_size < 0 and low < final_TP_Short and use_tp != "None"
    alert(i_alert_txt_exit_TP_short, alert.freq_once_per_bar)

// # ========================================================================= #
// #                   |   Reset Variables |
// # ========================================================================= #