朝比奈 幸太郎

光の音楽 "Curanz Sounds"

この世界を愛と調和の空間に

【Pine Script】無料で複数のインジケーターから複合的に売買シグナルを生成

この記事では、TradingViewプラットフォーム上で使用できる革新的なテクニカル分析について紹介します。

このインジケーターは複数のインジケーターを統合して、それぞれの条件を満たしたときに売買シグナルを生成するものです。

この記事で学べるスキル

複数のインジケーターから複合的に売買シグナルを生成するため、通常は別々に分析するべき売買根拠の収集が一瞬で行えるサンプルコードを知ることができます。
また、複数インジケーターの描画は通常有料版のみとなりますが、この方法を使えば無料版ユーザーでも同時に複数のインジケーターでトレード戦略を立てることができます。

複合インジケーターの特徴

  • 40以上のインジケーターから選択可能
  • 買いと売りのシグナルを条件ごとにカスタマイズ
  • 時間枠:5分、15分、1時間、4時間の短期トレード向き

通常、トレーディングビューでは数百のインジケーターが利用可能ですが、それらを個別に分析し、組み合わせるのは時間がかかり、複雑になることがあります。

カスタマイズ可能

トレーダーは40以上のインジケーターから選択し、自分の取引スタイルや戦略に合わせてカスタマイズできます。

これにより、より柔軟な分析が可能になります。

シグナルの自動生成

選択したインジケーターに基づいて、自動的に買いまたは売りのシグナルを生成します。

これにより、複数のインジケーターを手動で条件確認する時間を大幅に節約することができます。

アラート機能

特定の条件が満たされたときにアラートを設定することができ、トレーダーは市場を常に監視する必要がなくなります。

Pineスクリプトでの複合インジケーターの作成

基本設定
ここからは具体的にPineスクリプトのバージョンとインジケーターの基本情報を設定します。
//@version=4
study("Complex Indicator Integration", shorttitle="CII", overlay=true)
インジケーターの選択オプション
ユーザーが使用するインジケーターを選択できるように入力オプションを設定します。
useRSI = input(true, title="Use RSI?")
useMACD = input(true, title="Use MACD?")
useStochastic = input(false, title="Use Stochastic?")
各インジケーターの定義
選択可能な各インジケーターの計算式を定義します。
// RSI
rsiLength = input(14, title="RSI Length")
rsi = rsi(close, rsiLength)

// MACD
[macdLine, signalLine, _] = macd(close, 12, 26, 9)

// Stochastic
k = sma(stoch(close, high, low, 14), 3)
d = sma(k, 3)
複合シグナルの生成
選択されたインジケーターに基づいて複合シグナルを生成します。
buySignal = (useRSI and rsi < 30) or (useMACD and crossover(macdLine, signalLine)) or (useStochastic and crossover(k, d))
sellSignal = (useRSI and rsi > 70) or (useMACD and crossunder(macdLine, signalLine)) or (useStochastic and crossunder(k, d))
シグナルのプロット
生成したシグナルをチャート上に表示します。
plotshape(series=buySignal, title="Buy Signal", location=location.belowbar, color=color.green, style=shape.labelup, text="BUY")
plotshape(series=sellSignal, title="Sell Signal", location=location.abovebar, color=color.red, style=shape.labeldown, text="SELL")

統合したサンプルコード

まずはここまでを統合したサンプルコードをシェアしますので、実際にpine Scriptにてプロットしみてください。

//@version=4
study("Complex Indicator Integration", shorttitle="CII", overlay=true)

// インジケーターの選択オプション
useRSI = input(true, title="Use RSI?")
useMACD = input(true, title="Use MACD?")
useStochastic = input(false, title="Use Stochastic?")

// RSIの定義
rsiLength = input(14, title="RSI Length")
rsi = rsi(close, rsiLength)

// MACDの定義
[macdLine, signalLine, _] = macd(close, 12, 26, 9)

// ストキャスティクスの定義
k = sma(stoch(close, high, low, 14), 3)
d = sma(k, 3)

// 複合シグナルの生成
buySignal = (useRSI and rsi < 30) or (useMACD and crossover(macdLine, signalLine)) or (useStochastic and crossover(k, d))
sellSignal = (useRSI and rsi > 70) or (useMACD and crossunder(macdLine, signalLine)) or (useStochastic and crossunder(k, d))

// シグナルのプロット
plotshape(series=buySignal, title="Buy Signal", location=location.belowbar, color=color.green, style=shape.labelup, text="BUY")
plotshape(series=sellSignal, title="Sell Signal", location=location.abovebar, color=color.red, style=shape.labeldown, text="SELL")

実際にはもっと多くのインジケーターを定義できますが、まずはテストということでRSI、MACD、ストキャスティクスと似たジャンルの各インジケーターが特定の条件を満たしたときに買いまたは売りのシグナルを生成するコードになっています。

インジケーターの選択オプションを通じて、どのインジケーターを使用するかをトレーダーが選択できるようになっていますし、条件は数値を入れ替えるだけで簡単に再定義できます。

4種類でのサンプルコード

次に上記の3種類に加えてボリュームの根拠も追加してみます。

ボリュームがその20日平均を上回る場合に買いシグナルを、下回る場合に売りシグナルを生成するように設定しています。

これにより、ボリュームの変動をトレーディングシグナルの一部として組み込むことができます。

他のインジケーターと組み合わせることで、より複雑なトレーディング戦略を構築することが可能です。

//@version=4
study("Advanced Indicator Integration with Volume", shorttitle="AII-V", overlay=true)

// インジケーターの選択オプション
useRSI = input(true, title="Use RSI?")
useMACD = input(true, title="Use MACD?")
useStochastic = input(true, title="Use Stochastic?")
useVolume = input(false, title="Use Volume?")

// RSIの定義
rsiLength = input(14, title="RSI Length")
rsi = rsi(close, rsiLength)

// MACDの定義
[macdLine, signalLine, _] = macd(close, 12, 26, 9)

// ストキャスティクスの定義
k = sma(stoch(close, high, low, 14), 3)
d = sma(k, 3)

// ボリュームの定義
volAvg = sma(volume, 20)
volIncrease = volume > volAvg

// 複合シグナルの生成
buySignal = (useRSI and rsi < 30) or (useMACD and crossover(macdLine, signalLine)) or (useStochastic and crossover(k, d)) or (useVolume and volIncrease)
sellSignal = (useRSI and rsi > 70) or (useMACD and crossunder(macdLine, signalLine)) or (useStochastic and crossunder(k, d)) or (useVolume and not volIncrease)

// シグナルのプロット
plotshape(series=buySignal, title="Buy Signal", location=location.belowbar, color=color.green, style=shape.labelup, text="BUY")
plotshape(series=sellSignal, title="Sell Signal", location=location.abovebar, color=color.red, style=shape.labeldown, text="SELL")

より見やすくする

ローソク足はデフォルトでフル表示になっているかと思いますが、短期でマクロ分析したい場合などは、実態を非表示にするとみやすくなるのでおすすめです。

これはトレーディングビューのチャート設定から行えます。

また、シグナルももう少し見やすく改造してみました。

先述のものと見やすい方を採用してください。

//@version=4
study("Advanced Indicator Integration with Volume", shorttitle="AII-V", overlay=true)

// インジケーターの選択オプション
useRSI = input(true, title="Use RSI?")
useMACD = input(true, title="Use MACD?")
useStochastic = input(true, title="Use Stochastic?")
useVolume = input(false, title="Use Volume?")

// RSIの定義
rsiLength = input(14, title="RSI Length")
rsi = rsi(close, rsiLength)

// MACDの定義
[macdLine, signalLine, _] = macd(close, 12, 26, 9)

// ストキャスティクスの定義
k = sma(stoch(close, high, low, 14), 3)
d = sma(k, 3)

// ボリュームの定義
volAvg = sma(volume, 20)
volIncrease = volume > volAvg

// 複合シグナルの生成
buySignal = (useRSI and rsi < 30) or (useMACD and crossover(macdLine, signalLine)) or (useStochastic and crossover(k, d)) or (useVolume and volIncrease)
sellSignal = (useRSI and rsi > 70) or (useMACD and crossunder(macdLine, signalLine)) or (useStochastic and crossunder(k, d)) or (useVolume and not volIncrease)

// シグナルのプロット
plotshape(series=buySignal, title="Buy Signal", location=location.belowbar, color=color.green, style=shape.triangleup, text="LONG", textcolor=color.white)
plotshape(series=sellSignal, title="Sell Signal", location=location.abovebar, color=color.red, style=shape.triangledown, text="SHORT", textcolor=color.white)

時間足による違い

Pineスクリプトのコードは、基本的にすべての時間足で有効です。

TradingViewのPineスクリプトは、異なる時間足に対して柔軟に適用されるように設計されています。

したがって、同じコードを異なる時間足のチャートに適用しても、その時間足に基づいたデータでインジケーターが計算されます。

ただし、異なる時間足でのトレーディング戦略の有効性は、使用するインジケーターの性質やトレーディングスタイルによって異なります。

以下の点を考慮することが重要です。

  1. 市場のノイズ: 短い時間足(例えば1分や5分)では市場の「ノイズ」が多く、インジケーターのシグナルが頻繁に発生し、誤ったシグナルを生じる可能性が高まります。
  2. トレンドの確認: 長い時間足(例えば1日や1週間)では、より長期的なトレンドが明確になりますが、短期的な市場の動きを捉えるのが難しくなります。
  3. パラメータの調整: 異なる時間足で最適な結果を得るためには、インジケーターのパラメータ(例えば移動平均の期間やRSIの長さ)を調整することが有効です。
  4. トレーディングスタイル: スカルピング、デイトレーディング、スイングトレーディング、ポジショントレーディングなど、異なるトレーディングスタイルには異なる時間足が適しています。

同じコードを異なる時間足で使用することは可能ですが、最適なトレーディング結果を得るためには、時間足に応じてインジケーターの設定を微調整することが推奨されます。

また、どの時間足を使用するかは、個々のトレーディング目標とスタイルによって異なります。

アラートの設定

TradingViewのPineスクリプトでは、アラートはスクリプト内で直接設定するのではなく、TradingViewのユーザーインターフェースを通じて設定します。ただし、スクリプト内でアラート条件を作成することは可能です。

アラートを設定するには、以下の手順に従います:

  1. TradingViewのチャート上でスクリプトを実行します。
  2. チャートの上部にある「アラート」アイコンをクリックします。
  3. アラートを作成するダイアログボックスで、「条件」ドロップダウンメニューからあなたのカスタムインジケーターを選択します。
  4. 「Buy Signal」または「Sell Signal」など、アラートを設定したい条件を選択します。
  5. アラートの詳細(名前、通知方法、メッセージなど)を設定し、「作成」ボタンをクリックします。

スクリプト内でアラートをより明確にするために、alertcondition 関数を使用して条件を定義することができます。以下に例を示します:

//@version=4
study("Advanced Indicator Integration with Volume", shorttitle="AII-V", overlay=true)
// ...(他のコード)

// アラート条件の定義
alertcondition(buySignal, title="Buy Signal Alert", message="Buy Signal Detected")
alertcondition(sellSignal, title="Sell Signal Alert", message="Sell Signal Detected")

// ...(残りのコード)

この追加により、アラート設定時に「Buy Signal Alert」と「Sell Signal Alert」というオプションが利用可能になり、それぞれのシグナルが発生したときに通知を受け取ることができます。

設定のコツ?!

今回は似たようなジャンルのインジケーターで組んでみていますが、様々なジャンルのインジケーターを組み合わせて自分だけの根拠を作っていくことができます。

やはり数値を厳しくすればするほど、合致する条件は必然的に厳しくなりますのでシグナルは出にくくなりますが、甘くすれば短期の場合は特にやりにくかったりします。

自分の得意な時間軸を見つけて、時間軸に合わせてインジケーターの発動条件の数値も調整していくことで、精度の高いシグナルを生成することができます。

じっくり時間をかけて自分だけで複合インジケーターを作ってみてください。

そしてpine Scriptの最高に便利なところが、無料でできるということ。

やはり通常はインジケーターをたくさん出すことはできませんので、そういった面でもコスパ最高です。

Pythonでバックテストを行う

Pythonでこの条件にてバックテストを行うサンプルコードをシェアしておきましょう。

期間や条件などは各自変更してください。

pip install ta
pip install yfinance pandas ta
import yfinance as yf
import pandas as pd
import ta

# データの取得
symbol = "USDJPY=X"
start_date = "2017-01-01"
end_date = "2022-01-01"
df = yf.download(symbol, start=start_date, end=end_date)

# ピップスの定義
pip = 0.01
profit_target = 30 * pip
stop_loss = 50 * pip

# インジケーターの計算
df['rsi'] = ta.momentum.RSIIndicator(df['Close'], window=14).rsi()
df['macd'] = ta.trend.MACD(df['Close'], window_slow=26, window_fast=12).macd_diff()
df['stoch_k'] = ta.momentum.StochasticOscillator(df['High'], df['Low'], df['Close'], window=14, smooth_window=3).stoch()
df['vol_avg'] = df['Volume'].rolling(window=20).mean()
df['vol_increase'] = df['Volume'] > df['vol_avg']

# 複合シグナルの生成
df['buy_signal'] = (df['rsi'] < 30) | (df['macd'] > 0) | (df['stoch_k'] > 20) | df['vol_increase']
df['sell_signal'] = (df['rsi'] > 70) | (df['macd'] < 0) | (df['stoch_k'] < 80) | ~df['vol_increase']

# トレードの実行と結果の計算
def execute_trade(entry_price, trade_type, data):
    for price in data:
        if trade_type == 'buy':
            if price >= entry_price + profit_target or price <= entry_price - stop_loss:
                return price - entry_price
        elif trade_type == 'sell':
            if price <= entry_price - profit_target or price >= entry_price + stop_loss:
                return entry_price - price
    return 0

profits = []
for index in range(len(df)):
    row = df.iloc[index]
    if row['buy_signal']:
        data = df['Close'][index+1:index+51]
        profit = execute_trade(row['Close'], 'buy', data)
        profits.append(profit)
    elif row['sell_signal']:
        data = df['Close'][index+1:index+51]
        profit = execute_trade(row['Close'], 'sell', data)
        profits.append(profit)

# 勝ちトレードと負けトレードの数
wins = len([p for p in profits if p > 0])
losses = len([p for p in profits if p < 0])

print(f"Wins: {wins}, Losses: {losses}")

このバックテストではこの記事で定義した複合インジケーターで発生したシグナルに従ってトレードした場合の勝ちトレード数と負けトレード数を出力しています。

損切りは50pips利確を30pipsとしているので、実際に資産が増えたのか減ったのかを出力するためには正確なアプローチが必要になります。