「株テック | Kabutech Lab.」は、日本株トレードを初心者向けに解説するメディアです。

ツールの使い方や考え方、環境構築方法を学ぶ場として、主に以下の内容を解説しています:

  • TradingViewを使ったバックテスト・ストラテジーの実践情報
    (プログラミング知識がなくても始めやすい検証ツールです)
  • 三菱UFJ eスマート証券のkabu APIを使った環境構築
    (日本株の発注が可能な数少ないAPI接続サービスです)

バックテストは自作プログラム(Pandasなど)で応用可能、発注は他の証券会社のRSSなどでも対応できます。
特定の証券会社やツールを強く推奨するものではありません。

以下の点にご留意ください:

  • 個別銘柄の売買や投資判断の助言は行いません。
  • サンプルのストラテジーやコードは学習・検証用の参考資料であり、実際の売買や利益を保証しません。
  • バックテストは過去データに基づく結果であり、将来の成果を保証しません。
  • 自動売買環境はエラーハンドリングと十分な整備が必須です。
  • 市場変動、システム障害、予期せぬ遅延やエラーなどのリスクがあります。

投資はあくまで自己責任です。リスクを理解して慎重に取り組んでください。

当サイトでは一部アフィリエイト広告を利用しています (プライバシーポリシー)。

ご質問はこちらまでお気軽にどうぞ。

無料公開 | FO SMA CROSS Strategy Template | 実戦向けフィルター搭載 TradingView戦略

🧭 はじめての方へ:基礎 → 実践 → 設計 → 検証 → 理論。最短で再現性に辿り着くためのロードマップ
👉️ Kabutech Lab.のおすすめの進め方

実戦運用を意識したフィルター搭載版 TradingView戦略テンプレート

本テンプレートは、移動平均クロス戦略をベースにした実戦向けの ストラテジー テンプレートです。

TradingView 単体での バックテスト はもちろん、FO(Flex Order)と連携することで実口座への自動発注にも対応できます。

📊 参考バックテストサマリー(TOPIX採用の主要個別銘柄 / 1分足 / 100株)

SMA戦略のバックテスト結果
検証項目 実戦想定(スリッページ3) 参考値(スリッページ0)
プロフィットファクター 1.717 2.188
勝率 57.83% 62.42%
総損益 +17,880.00 JPY +24,280.00 JPY
最大ドローダウン -3,120 JPY -2,380 JPY

FO Simple SMA Templateとの違い

本テンプレートは、FO Simple SMA Templateの売買ロジックをベースに、 実運用を想定したフィルター群や検証機能を追加した発展版です。

  • 相場環境の選別
  • エントリー 条件の絞り込み
  • ダマシシグナルの低減

などを検証できる構成になっています。

まずは FO Simple SMA Template で全体の流れを理解し、その後に本テンプレートでフィルターによる改善効果を検証してみてください。

👉 FO Simple SMA Template

このストラテジーでできること

エントリー

  • SMA / EMA 切り替え
  • ゴールデンクロス (GC)
  • デッドクロス (DC)
  • クロス後○本以内 エントリー

フィルター機能

  • 出来高 フィルター
  • ヒゲ フィルター
  • DMI 方向フィルター
  • ADX トレンド 強度フィルター
  • Choppinessフィルター

出口管理

  • ATR 損切り
  • ATR 利確
  • ATR トレーリングストップ
  • 最大損失率制限

運用機能

  • エントリー 時間制御
  • 引け 決済
  • TradingView アラート 対応
  • FO連携対応

FO SMA CROSS Strategy Templateコード全文

//@version=6
import kabutech/FO_Util/33 as util

strategy(
    "FO SMA CROSS Strategy Template",
    overlay=true,
    initial_capital=10000000,
    default_qty_value=1
)

// ====================
// ■ 市場設定
// ====================
marketTypeInput = input.string(
     "JP_FUT",
     title="市場タイプ",
     options=["JP_STOCK","JP_FUT"],
     tooltip="市場に応じて発注禁止時間(昼休み・引け前)を自動制御します"
)

// ====================
// ■ インジケータ設定
// ====================
maType = input.string(
    "SMA",
    title="移動平均タイプ",
    options=["SMA", "EMA"],
    tooltip="SMA: 単純移動平均\nEMA: 指数平滑移動平均"
)

// SMA
maShortLen = input.int(5,  "短期MA期間")
maLongLen  = input.int(25, "長期MA期間")

// クロス後猶予
barsAfterCross = input.int(1, "クロス後エントリー許可本数", minval=0, maxval=20)

//====================================================
// ■ 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="エントリーフィルター設定")

//====================================================
// ■ 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="エントリーフィルター設定")

//====================================================
// ■ ADX FILTER(トレンド強度フィルター)
//====================================================
dmiMode = input.string(
     "OFF",
     "DMI方向モード",
     options=["OFF", "TREND", "REVERSAL"],
     inline="dmi_1"
)
dmiAdxLength = input.int(14, "DMI/ADX 共通期間", inline="dmi_1", group="", minval=0)
adxThresh    = input.int(25, "ADX 閾値 (0でADX無効)", inline="dmi_2", group="", minval=0)
adxFilterInput = input.string("以下", "ADX 条件", options=["以上", "以下"], inline="dmi_2", group="",
     tooltip="以上: ADXが閾値以上の時にエントリー(トレンド追随)\n以下: ADXが閾値以下の時にエントリー(レンジ・保ち合い)")

//====================================================
// ■ CHOPPINESS FILTER(レンジ判定フィルター)
//====================================================
chopLength = input.int(0, "Chop期間 (0で無効)", inline="")
chopThresh = input.float(61.8, "Chop閾値", inline="Chop")
chopFilterInput = input.string("以上", "Chop 条件", options=["以上", "以下"], inline="Chop", group="",
     tooltip="以上: Chopが閾値以上の時にエントリー(もみ合い・レンジ)\n以下: Chopが閾値以下の時にエントリー(強いトレンド中)")

//====================================================
// ■ 出口管理(ATR)
//====================================================
atrLength    = input.int(14, "ATR期間", group="出口管理")
atrLimitMult = input.float(1.5, "固定利確/追従発動倍率", step=0.1, group="出口管理")
atrStopMult  = input.float(2.0, "損切り倍率", step=0.1, group="出口管理")
trailAtrMult = input.float(0.0, "トレール幅 (0で固定利確)", step=0.1, group="出口管理")
maxStopPerc  = input.float(2.0, "最大損切り(%)", 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")

// ====================
// ■ 指標計算
// ====================
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)

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 = (
     barsAfterCross == 0
     ? goldenCross
     : (barsFromGolden >= 0 and barsFromGolden <= barsAfterCross)
) and close > open

shortTrigger = (
     barsAfterCross == 0
     ? deathCross
     : (barsFromDeath >= 0 and barsFromDeath <= barsAfterCross)
) and close < open

// ====================
// 各種フィルター
// ====================
// 出来高フィルター
volOK = util.f_volumeFilter(volLength, volMultiplier, volLookback, "above")

// ヒゲフィルター
wickLongOK  = util.f_wickFilter(wickRatio, -1, wickLookback)
wickShortOK = util.f_wickFilter(wickRatio,  1, wickLookback)

// エントリー時間制御
allowEntry = util.f_allowEntry(useSessionFilter, startHour, startMinute, endHour, endMinute, marketTypeInput)

// DMI/ADXフィルター
adxFilterMode  = (adxFilterInput == "以上") ? "above" : "below"
[dmiLongMode, dmiShortMode, adxOK] = util.f_dmiAdxFilter(dmiAdxLength, dmiMode != "OFF", adxThresh, adxFilterMode)

// DMIモード切り替え
longDmiOK = dmiMode == "REVERSAL" ? dmiShortMode : dmiLongMode
shortDmiOK = dmiMode == "REVERSAL" ? dmiLongMode : dmiShortMode

// CHOPフィルター
chopFilterMode = (chopFilterInput == "以上") ? "above" : "below"
[chopVal, chopOK] = util.f_chopFilter(chopLength, chopThresh, chopFilterMode)

// フィルター統合
allFilters = adxOK and chopOK and volOK and allowEntry

// ====================
// ■ シグナル
// ====================
longSignal = longTrigger and wickLongOK and longDmiOK and allFilters and barstate.isconfirmed
shortSignal = shortTrigger and wickShortOK and shortDmiOK and allFilters and barstate.isconfirmed

// ====================
// ■ エントリー
// ====================
util.f_executeEntry(longSignal, shortSignal)

//====================================================
// EXIT LOGIC(出口設計)
//====================================================
var float highest = na
var float lowest  = na

[longStop, shortStop, longLimit, shortLimit, _highest, _lowest] = util.f_calcATRExit(
        strategy.position_avg_price,
        atrValue,
        highest,
        lowest,
        high[1],
        low[1],
        trailAtrMult,
        atrStopMult,
        atrLimitMult,
        strategy.position_size > 0,
        strategy.position_size < 0,
        maxStopPerc
    )

highest := _highest
lowest  := _lowest

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 SMA")
plot(maLong,  color=color.red,  title="Long SMA")

//====================================================
// 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)

クロス後エントリーに対応

一般的な移動平均クロス戦略では、クロス発生と同時に エントリー します。

しかし実際の相場では、

  • クロス直後に 押し目 が入る
  • クロス後に数本遅れて動き出す

といったケースも少なくありません。

本テンプレートでは、

barsAfterCross

を利用することで、

  • 「クロス後○本以内」

まで エントリー を許可できます。

これにより、単純なクロス戦略では取り逃しやすい局面も検証できるようになります。

SMA・EMAを切り替え可能

移動平均には様々な種類がありますが、本テンプレートでは代表的な

  • SMA
  • EMA

を切り替えて利用できます。

maType = input.string(
    "SMA",
    options=["SMA", "EMA"]
)

市場や銘柄・ 時間足 によって相性が変わるため、 バックテスト しながら比較検証できます。

ステータスダッシュボード搭載

チャート 右下には簡易ステータスダッシュボードを表示しています。

確認できる内容は以下の通りです。

  • 市場種別
  • 現在 ポジション
  • 利確価格目安
  • 損切り 価格目安

検証中に現在の戦略状態を把握しやすくするための補助機能です。

FO_Utilベースで構築

本テンプレートは、当ラボで公開している共通ライブラリ FO_Util を利用しています。

売買ロジックと共通処理を分離しているため、

  • エントリー 条件の変更
  • フィルター追加
  • 出口ロジック変更

などを比較的シンプルに行えます。

各フィルターや共通機能の詳細については、FO_Utilリファレンスをご覧ください。

👉 FO_Util ライブラリを見る

自動売買環境を構築するには?

ストラテジー の作成や バックテスト はできたけれど、

「実際にどうやって 自動売買 へ繋げるの?」

自動売買 の全体像や構築手順については、こちらの環境構築ガイドで詳しく解説しています。

👉 自動売買環境構築ガイドを見る

💡 自力構築も可能ですが

  • VPS の設定
  • サーバー保守
  • API 接続
  • 障害対応

など、実際に運用を始めるまでには想像以上にやることがあります。

  • まずは運用を始めたい
  • 環境構築より戦略開発に集中したい

という方は、構築済み環境のFO(Flex Order)という選択肢もあります。

FOで実口座へ接続する

TradingView バックテスト だけで終わらせず、そのまま実口座運用へ接続したい方はFO(Flex Order)をご利用ください。

TradingView
↓
Webhook
↓
FO(Flex Order)
↓
証券会社

という構成で 自動売買 環境を構築できます。

👉 FO(Flex Order)を見る

関連テンプレート

まずはシンプルな構成から学びたい方は、こちらもご覧ください。

👉 FO Simple SMA Template
👉 その他戦略テンプレート一覧を見る
🧭 はじめての方へ:基礎 → 実践 → 設計 → 検証 → 理論。最短で再現性に辿り着くためのロードマップ
👉️ Kabutech Lab.のおすすめの進め方

ストラテジー一覧

本ページでは、TradingViewで利用できるストラテジーを「指標 × ロジック(順張り・逆張り)」で整理しています。
自分のトレードスタイルや相場状況に合ったロジックを選択してください。

📈 テクニカル分析

テクニカル指標をTradingViewで実践活用

詳しく見る

🛠️ 自動売買の構築

TradingView, kabu API を使った環境構築

詳しく見る

📊 戦略設計

戦略を検証し、改善するための手法と実装

詳しく見る

🔧 ストラテジー作成

Pineスクリプトでの戦略実装をガイド

詳しく見る

📦 システム拡張

Slack連携/プロセス監視で安定・拡張

詳しく見る
FO 日本株自動売買 コピペで動く! 無料TradingViewストラテジー公開中

はじめての自動売買・Pine Scriptの学習におすすめ

背景画像
「戦略が、自律する。」