FO MA CROSS Strategy Templateコード全文
//@version=6
import kabutech/FO_Util/53 as util
strategy(
"FO MA CROSS Strategy Template",
overlay=true,
initial_capital=10000000,
default_qty_value=1
)
// ====================
// ■ 市場設定
// ====================
marketTypeInput = input.string(
"JP_FUT",
title="市場タイプ",
options=["JP_STOCK","JP_FUT"],
tooltip="市場に応じて発注禁止時間(昼休み・引け前)を自動制御します"
)
//====================================================
// ■ バックテスト期間
//====================================================
fromDays = input.int(
0,
"開始から除外日数",
minval = 0,
tooltip = "バックテスト開始日から指定日数を除外",
inline="バックテスト"
)
toDays = input.int(
0,
"終了から除外日数",
minval = 0,
tooltip = "最新日から指定日数を除外",
inline="バックテスト"
)
//====================================================
// ■ インジケータ設定
//====================================================
maType = input.string(
"SMA",
title="移動平均タイプ",
options=["SMA", "EMA"],
tooltip="SMA: 単純移動平均\nEMA: 指数平滑移動平均"
)
// SMA
maShortLen = input.int(5, "短期MA期間", inline="ma_len")
maLongLen = input.int(25, "長期MA期間", inline="ma_len")
// クロス後猶予
barsAfterCross = input.int(1, "クロス後エントリー許可本数", minval=0, maxval=20)
//====================================================
// ATR
//====================================================
atrLength = input.int(14, "ATR期間", inline="")
atrMultiplier = input.float(0, "ATR最小(0:無効)", step=0.1, inline="atr_filter", group="エントリーフィルター設定",
tooltip="")
atrMultiplierMax = input.float(0, "ATR最大(0:無効)", step=0.1, inline="atr_filter", group="エントリーフィルター設定",
tooltip="ローソク足のサイズをATRと比較するフィルター。\n0で無効化。\nATR×倍率以上・以下をフィルタ。")
//====================================================
// ■ VOLUME FILTER(出来高フィルター)
//====================================================
volLength = input.int(20, "出来高フィルター (0:無効)", group="エントリーフィルター設定")
volMultiplier = input.float(1.2, "出来高倍率", step=0.1, inline="vol", tooltip="平均×倍率【以上】の出来高(クライマックス)で許可", group="エントリーフィルター設定")
volLookback = input.int(3, "Lookback", minval=1, inline="vol", group="エントリーフィルター設定")
//====================================================
// ■ DAILY MA FILTER(日足トレンドフィルター)
//====================================================
dailyMaLength = input.int(
0,
"日足MA期間 (0:無効)",
minval = 0,
group = "エントリーフィルター設定",
tooltip = "日足移動平均を利用した上位足フィルター。\n0で無効化。"
)
//====================================================
// ■ SLOPE FILTER(傾きフィルター)
//====================================================
slopeLength = input.int(0, "傾き期間(0:無効)", inline="slope", group="エントリーフィルター設定",
tooltip="傾きの計算期間")
slopeThreshold = input.float(0.05, "閾値", step=0.01, inline="slope", group="エントリーフィルター設定",
tooltip="傾きがこの値未満ならレンジと判定\n値を大きくするとレンジ判定が広がる")
//====================================================
// ■ WICK FILTER(ヒゲ判定)
//====================================================
wickRatio = input.float(0.0, "Wick Ratio (0:off)", step=0.1, inline="wick", maxval=1.0,
tooltip="ローソク足のレンジに対するヒゲの割合(0.0〜1.0)。\n0で無効化。例)0.5 = レンジの50%以上がヒゲ", group="エントリーフィルター設定")
wickLookback = input.int(3, "Lookback", minval=1, inline="wick",
tooltip="直近何本以内に指定したヒゲが出現したかを判定します。\n1なら現在の足のみ。", group="エントリーフィルター設定")
//====================================================
// ■ DMI / ADX 統合設定
//====================================================
dmiMode = input.string(
"OFF",
"DMI方向モード",
options=["OFF", "TREND", "REVERSAL"],
inline="dmi_1",
group="エントリーフィルター設定"
)
dmiAdxLength = input.int(14, "DMI/ADX 共通期間", inline="dmi_1", minval=0, group="エントリーフィルター設定")
adxThreshMin = input.int(20, "ADX 下限 (0:無効)", inline="dmi_2", minval=0, group="エントリーフィルター設定")
adxThreshMax = input.int(0, "ADX上限 (0:無効)", inline="dmi_2", minval=0, group="エントリーフィルター設定")
//====================================================
// ■ CHOPPINESS FILTER(レンジ判定フィルター)
//====================================================
chopLength = input.int(9, "日足Chop期間 (0で無効)", inline="", group="エントリーフィルター設定")
chopThreshMin = input.float(0, "Chop下限", inline="Chop", group="エントリーフィルター設定")
chopThreshMax = input.float(61.8, "Chop上限", inline="Chop", group="エントリーフィルター設定")
//====================================================
// ■ 出口管理(ATR)
//====================================================
atrLimitMult = input.float(1.5, "ATR利確倍率", inline="exit1", step=0.1, group="出口管理")
atrStopMult = input.float(2.0, "損切り倍率", inline="exit2", step=0.1, group="出口管理")
// trailAtrMult = input.float(0.0, "トレール幅 (0で固定利確)", inline="exit2", step=0.1, group="出口管理")
maxStopPerc = input.float(2.0, "最大損切り(%)", inline="exit2", step=0.1, group="出口管理")
//====================================================
// ■ SESSION管理
//====================================================
useSessionFilter = input.bool(true, "エントリー時間制限", group="SESSION")
startHour = input.int(9, "開始", inline="s", group="SESSION")
startMinute = input.int(0, " ", inline="s", group="SESSION")
endHour = input.int(14, "終了", inline="e", group="SESSION")
endMinute = input.int(30, " ", inline="e", group="SESSION")
useSessionClose = input.bool(true, "引け決済", group="SESSION")
closeHour = input.int(15, "時", inline="c", group="SESSION")
closeMinute = input.int(0, "分", inline="c", group="SESSION")
//====================================================
// BASE CALCULATION
//====================================================
f_ma(src, len, type) =>
type == "EMA" ? ta.ema(src, len) : ta.sma(src, len)
maShort = f_ma(close, maShortLen, maType)
maLong = f_ma(close, maLongLen, maType)
// 傾き対象
slopeTarget = maLong
atrValue = ta.atr(atrLength)
safeATR = math.max(atrValue, syminfo.mintick)
// ■ クロス判定
goldenCross = ta.crossover(maShort, maLong)
deathCross = ta.crossunder(maShort, maLong)
barsFromGolden = ta.barssince(goldenCross)
barsFromDeath = ta.barssince(deathCross)
longTrigger = barsFromGolden >= 0 and
barsFromGolden <= barsAfterCross and
maShort > maLong and
close > open
shortTrigger = barsFromDeath >= 0 and
barsFromDeath <= barsAfterCross and
maShort < maLong and
close < open
//====================================================
// FILTER LOGIC(共通フィルターロジック)
//====================================================
// エントリー時間制御
allowEntry = util.f_allowEntry(useSessionFilter, startHour, startMinute, endHour, endMinute, marketTypeInput, fromDays, toDays)
// 出来高フィルター
volOK = util.f_volumeFilter(volLength, volMultiplier, 0, volLookback)
// ATRフィルター
rangeFilter = util.f_atrRangeFilter(high, low, safeATR, atrMultiplier, atrMultiplierMax)
// DMI/ADXフィルター
[dmiLongMode, dmiShortMode, adxOK] = util.f_dmiAdxFilter(dmiAdxLength, dmiMode != "OFF", adxThreshMin, adxThreshMax)
// CHOPフィルター
[chopVal, chopOK] = util.f_chopFilter(chopLength, chopThreshMin, chopThreshMax)
// フィルター統合
baseFilters = adxOK and chopOK and volOK and allowEntry and rangeFilter
//====================================================
// 各方向専用のフィルター
//====================================================
// 日足MTF
[allowDMALong, allowDMAShort, dmaValue] = util.f_dailyMAFilter(dailyMaLength)
// 傾きフィルター
[slope, slopeNorm, isRange, trendUpSlope, trendDownSlope] = util.f_slopeFilter(slopeTarget, slopeLength, slopeThreshold, safeATR)
// ヒゲフィルター
wickLongOK = util.f_wickFilter(wickRatio, -1, wickLookback)
wickShortOK = util.f_wickFilter(wickRatio, 1, wickLookback)
// DMIモード切り替え
longDmiOK = dmiMode == "REVERSAL" ? dmiShortMode : dmiLongMode
shortDmiOK = dmiMode == "REVERSAL" ? dmiLongMode : dmiShortMode
longFilter = longDmiOK and trendUpSlope and wickLongOK and allowDMALong
shortFilter = shortDmiOK and trendDownSlope and wickShortOK and allowDMAShort
//====================================================
// ■ シグナル
//====================================================
longSignal = longTrigger and longFilter and baseFilters and barstate.isconfirmed
shortSignal = shortTrigger and shortFilter and baseFilters and barstate.isconfirmed
// エントリー
util.f_executeEntry(longSignal, shortSignal)
//====================================================
// EXIT LOGIC(出口設計)
//====================================================
[longStop, shortStop, longLimit, shortLimit] = util.f_calcATRExit(
strategy.position_avg_price,
atrValue,
atrStopMult,
atrLimitMult,
maxStopPerc
)
strategy.exit("CLOSE_LONG", from_entry="LONG", stop=longStop, limit=longLimit)
strategy.exit("CLOSE_SHORT", from_entry="SHORT", stop=shortStop, limit=shortLimit)
// ====================
// ■ 引け決済
// ====================
util.f_executeSessionClose(useSessionClose, closeHour, closeMinute, marketTypeInput)
// ====================
// ■ 描画
// ====================
plot(maShort, color=color.blue, title="Short MA")
plot(maLong, color=color.red, title="Long MA")
// plot(dmaValue, color=color.green, title="day MA")
//====================================================
// STATUS DASHBOARD
//====================================================
var table board = table.new(position.bottom_right, 2, 4, bgcolor=color.new(color.black, 70))
// ヘッダー
table.cell(board, 0, 0, "項目", text_color=color.white, bgcolor=color.gray)
table.cell(board, 1, 0, "現在の状態", text_color=color.white, bgcolor=color.gray)
//----------------------------------
// ■ 市場
//----------------------------------
table.cell(board, 0, 1, "市場", text_color=color.white)
table.cell(board, 1, 1, marketTypeInput, text_color=color.yellow)
//----------------------------------
// ■ ポジション
//----------------------------------
posStr = strategy.position_size > 0 ? "LONG" : strategy.position_size < 0 ? "SHORT" : "FLAT"
posCol = strategy.position_size > 0 ? color.lime : strategy.position_size < 0 ? color.red : color.white
table.cell(board, 0, 2, "ポジション", text_color=color.white)
table.cell(board, 1, 2, posStr, text_color=posCol)
//----------------------------------
// ■ 利確・損切り目安
//----------------------------------
longActive = strategy.position_size > 0
shortActive = strategy.position_size < 0
tpStr =
longActive ? str.tostring(longLimit, format.mintick) :
shortActive ? str.tostring(shortLimit, format.mintick) :
"-"
slStr =
longActive ? str.tostring(longStop, format.mintick) :
shortActive ? str.tostring(shortStop, format.mintick) :
"-"
table.cell(board, 0, 3, "出口目安", text_color=color.white)
table.cell(board, 1, 3, "利確: " + tpStr + "\n損切: " + slStr, text_color=color.white)