Pinaコード(15分足)
nakasato
もしくは、以下をコピーしてお使いください。
//@version=5
indicator("TSUBAKI 15M S1.0 チャート表示サインEA版", shorttitle="TSUBAKI 15M EA", overlay=false, max_labels_count=500, max_lines_count=500)
// =====================================================
// TSUBAKI 15M 専用
// ・15分足チャートに実際に表示されたサインだけ通知
// ・TradingViewのWebhook URLは http://128.22.126.239/15m-live を使用
// ・アラート条件は「Any alert() function call」を選択
// ・TP/SL通知は結果通知・AI学習用。新規発注対象ではない
// =====================================================
// =====================================================
// Webhook / Discord設定
// =====================================================
secretKey = input.string("CHANGE_ME_SECRET", "Webhook認証キー", display=display.none)
systemName = input.string("TSUBAKI_15M_CHART_SIGNAL_EA", "システム名", display=display.none)
strategyName = input.string("TSUBAKI_15M", "サーバー集計用strategy", display=display.none)
sourceName = input.string("chart_signal", "通知ソース", display=display.none)
sendEntryAlert = input.bool(true, "ENTRYアラート送信", display=display.none)
sendExitAlert = input.bool(true, "TP/SLアラート送信(EA学習用ON)", display=display.none)
// =====================================================
// 基本設定
// =====================================================
rciLen = input.int(9, "RCI期間", minval=2, display=display.none)
tfFast = input.timeframe("5", "短期足", display=display.none)
tfMain = input.timeframe("15", "メイン足", display=display.none)
tfTrend = input.timeframe("60", "方向確認足", display=display.none)
useLong = input.bool(true, "LONGサインを使う", display=display.none)
useShort = input.bool(true, "SHORTサインを使う", display=display.none)
useChartTimeframeGuard = input.bool(true, "15分足チャート専用(他足ではサイン停止)", display=display.none)
// =====================================================
// 採用設定
// =====================================================
signalMode = input.string("標準", "サイン感度", options=["多め", "標準", "少なめ"], display=display.none)
longRciZone = input.int(-50, "LONG反転RCI水準", minval=-100, maxval=0, display=display.none)
shortRciZone = input.int(50, "SHORT反転RCI水準", minval=0, maxval=100, display=display.none)
useTrendFilter = input.bool(true, "上位足方向フィルター", display=display.none)
useEmaFilter = input.bool(true, "EMA位置フィルター", display=display.none)
useCandleFilter = input.bool(true, "ローソク足方向フィルター", display=display.none)
cooldownBarsMany = input.int(1, "クールダウン:多め", minval=0, display=display.none)
cooldownBarsNormal = input.int(2, "クールダウン:標準", minval=0, display=display.none)
cooldownBarsFew = input.int(4, "クールダウン:少なめ", minval=0, display=display.none)
cooldownBars = signalMode == "多め" ? cooldownBarsMany : signalMode == "標準" ? cooldownBarsNormal : cooldownBarsFew
// =====================================================
// EMA / ATR / TP SL
// =====================================================
emaFastLen = input.int(20, "EMA短期", display=display.none)
emaMidLen = input.int(75, "EMA中期", display=display.none)
emaSlowLen = input.int(200, "EMA長期", display=display.none)
atrLen = input.int(14, "ATR期間", display=display.none)
swingLookback = input.int(8, "SL用直近高安値本数", minval=2, maxval=50, display=display.none)
slBufferAtr = input.float(0.22, "SLバッファATR倍率", minval=0.0, maxval=3.0, step=0.01, display=display.none)
tpRR = input.float(0.80, "TP RR", minval=0.1, maxval=3.0, step=0.05, display=display.none)
useMinRiskFilter = input.bool(true, "小さすぎる損切り幅を除外", display=display.none)
minRiskAtr = input.float(0.30, "最低リスクATR倍率", minval=0.05, maxval=3.0, step=0.01, display=display.none)
useMaxRiskFilter = input.bool(true, "大きすぎる損切り幅を除外", display=display.none)
maxRiskAtr = input.float(2.0, "最大リスクATR倍率", minval=0.2, maxval=5.0, step=0.1, display=display.none)
// =====================================================
// 表示設定
// =====================================================
showFastRci = input.bool(true, "5分RCI表示", display=display.none)
showMainRci = input.bool(true, "15分RCI表示", display=display.none)
showTrendRci = input.bool(false, "60分RCI表示", display=display.none)
showChartEntry = input.bool(true, "価格チャートにENTRY表示", display=display.none)
showResultMarker = input.bool(true, "TP/SL到達表示", display=display.none)
showPanelSignal = input.bool(true, "下段に三角サイン表示", display=display.none)
showEntryPrice = input.bool(false, "ENTRY価格表示", display=display.none)
showResultPrice = input.bool(false, "TP/SL価格表示", display=display.none)
showBg = input.bool(true, "サイン背景ハイライト", display=display.none)
showTable = input.bool(false, "勝率パネル表示", display=display.none)
showEmaOnChart = input.bool(true, "価格チャートにEMA表示", display=display.none)
showEma20 = input.bool(true, "EMA20表示", display=display.none)
showEma75 = input.bool(true, "EMA75表示", display=display.none)
showEma200 = input.bool(false, "EMA200表示", display=display.none)
resultMode = input.string("保守的:SL優先", "同一足でTP/SL両方到達時", options=["保守的:SL優先", "楽観的:TP優先"], display=display.none)
// =====================================================
// RCI関数
// =====================================================
rci(src, len) =>
d = 0.0
for i = 0 to len - 1
rank_price = 0
rank_time = len - i
for j = 0 to len - 1
if src[j] < src[i]
rank_price += 1
d += math.pow(rank_time - (rank_price + 1), 2)
1 - 6 * d / (len * (math.pow(len, 2) - 1))
// =====================================================
// MTF取得
// =====================================================
fastOpen = request.security(syminfo.tickerid, tfFast, open, barmerge.gaps_off, barmerge.lookahead_off)
fastHigh = request.security(syminfo.tickerid, tfFast, high, barmerge.gaps_off, barmerge.lookahead_off)
fastLow = request.security(syminfo.tickerid, tfFast, low, barmerge.gaps_off, barmerge.lookahead_off)
fastClose = request.security(syminfo.tickerid, tfFast, close, barmerge.gaps_off, barmerge.lookahead_off)
fastRci = request.security(syminfo.tickerid, tfFast, rci(close, rciLen) * 100, barmerge.gaps_off, barmerge.lookahead_off)
mainOpen = request.security(syminfo.tickerid, tfMain, open, barmerge.gaps_off, barmerge.lookahead_off)
mainHigh = request.security(syminfo.tickerid, tfMain, high, barmerge.gaps_off, barmerge.lookahead_off)
mainLow = request.security(syminfo.tickerid, tfMain, low, barmerge.gaps_off, barmerge.lookahead_off)
mainClose = request.security(syminfo.tickerid, tfMain, close, barmerge.gaps_off, barmerge.lookahead_off)
mainRci = request.security(syminfo.tickerid, tfMain, rci(close, rciLen) * 100, barmerge.gaps_off, barmerge.lookahead_off)
mainAtr = request.security(syminfo.tickerid, tfMain, ta.atr(atrLen), barmerge.gaps_off, barmerge.lookahead_off)
mainEma20 = request.security(syminfo.tickerid, tfMain, ta.ema(close, emaFastLen), barmerge.gaps_off, barmerge.lookahead_off)
mainEma75 = request.security(syminfo.tickerid, tfMain, ta.ema(close, emaMidLen), barmerge.gaps_off, barmerge.lookahead_off)
mainEma200 = request.security(syminfo.tickerid, tfMain, ta.ema(close, emaSlowLen), barmerge.gaps_off, barmerge.lookahead_off)
mainEma20Past = request.security(syminfo.tickerid, tfMain, ta.ema(close, emaFastLen)[2], barmerge.gaps_off, barmerge.lookahead_off)
trendClose = request.security(syminfo.tickerid, tfTrend, close, barmerge.gaps_off, barmerge.lookahead_off)
trendRci = request.security(syminfo.tickerid, tfTrend, rci(close, rciLen) * 100, barmerge.gaps_off, barmerge.lookahead_off)
trendEma20 = request.security(syminfo.tickerid, tfTrend, ta.ema(close, emaFastLen), barmerge.gaps_off, barmerge.lookahead_off)
trendEma75 = request.security(syminfo.tickerid, tfTrend, ta.ema(close, emaMidLen), barmerge.gaps_off, barmerge.lookahead_off)
// =====================================================
// 方向判定
// =====================================================
trendUp = trendClose > trendEma75 and trendEma20 >= trendEma75
trendDown = trendClose < trendEma75 and trendEma20 <= trendEma75
mainUp = mainClose > mainEma75
mainDown = mainClose < mainEma75
mainEmaSlopeUp = mainEma20 > mainEma20Past
mainEmaSlopeDown = mainEma20 < mainEma20Past
fastBull = fastClose > fastOpen
fastBear = fastClose < fastOpen
mainBull = mainClose > mainOpen
mainBear = mainClose < mainOpen
// =====================================================
// RCI反転
// =====================================================
fastRising = fastRci > fastRci[1]
fastFalling = fastRci < fastRci[1]
mainRising = mainRci > mainRci[1]
mainFalling = mainRci < mainRci[1]
fastLongTurn = fastRci <= longRciZone and fastRising
fastShortTurn = fastRci >= shortRciZone and fastFalling
mainLongTurn = mainRci <= longRciZone and mainRising
mainShortTurn = mainRci >= shortRciZone and mainFalling
fastLongCross = ta.crossover(fastRci, -30)
fastShortCross = ta.crossunder(fastRci, 30)
mainLongCross = ta.crossover(mainRci, -30)
mainShortCross = ta.crossunder(mainRci, 30)
// =====================================================
// EMA付近
// =====================================================
emaDistance = math.abs(mainClose - mainEma20)
nearEma20 = emaDistance <= mainAtr * 0.45
longEmaOk = not useEmaFilter or mainClose >= mainEma20 or nearEma20
shortEmaOk = not useEmaFilter or mainClose <= mainEma20 or nearEma20
longCandleOk = not useCandleFilter or fastBull or mainBull
shortCandleOk = not useCandleFilter or fastBear or mainBear
longTrendOk = not useTrendFilter or trendUp or mainUp
shortTrendOk = not useTrendFilter or trendDown or mainDown
// =====================================================
// スキャルエンジン
// =====================================================
longEngineA = longTrendOk and longEmaOk and longCandleOk and (fastLongTurn or fastLongCross) and mainRising
shortEngineA = shortTrendOk and shortEmaOk and shortCandleOk and (fastShortTurn or fastShortCross) and mainFalling
longEngineB = (not useTrendFilter or not trendDown) and longEmaOk and longCandleOk and mainLongTurn and fastRising
shortEngineB = (not useTrendFilter or not trendUp) and shortEmaOk and shortCandleOk and mainShortTurn and fastFalling
longEngineC = mainUp and mainEmaSlopeUp and nearEma20 and fastRising and fastBull
shortEngineC = mainDown and mainEmaSlopeDown and nearEma20 and fastFalling and fastBear
rawLongSignal = useLong and (longEngineA or longEngineB or longEngineC)
rawShortSignal = useShort and (shortEngineA or shortEngineB or shortEngineC)
// =====================================================
// スコア
// =====================================================
longScore = 0
shortScore = 0
longScore += trendUp ? 2 : 0
shortScore += trendDown ? 2 : 0
longScore += mainUp ? 1 : 0
shortScore += mainDown ? 1 : 0
longScore += mainEmaSlopeUp ? 1 : 0
shortScore += mainEmaSlopeDown ? 1 : 0
longScore += fastLongTurn ? 2 : 0
shortScore += fastShortTurn ? 2 : 0
longScore += mainLongTurn ? 2 : 0
shortScore += mainShortTurn ? 2 : 0
longScore += fastBull ? 1 : 0
shortScore += fastBear ? 1 : 0
longScore += nearEma20 ? 1 : 0
shortScore += nearEma20 ? 1 : 0
longScore += longEngineA ? 2 : 0
shortScore += shortEngineA ? 2 : 0
longScore += longEngineB ? 1 : 0
shortScore += shortEngineB ? 1 : 0
longScore += longEngineC ? 1 : 0
shortScore += shortEngineC ? 1 : 0
scoreMin = signalMode == "多め" ? 4 : signalMode == "標準" ? 5 : 6
// =====================================================
// クールダウン
// =====================================================
var int lastSignalBar = na
cooldownOk = na(lastSignalBar) or bar_index - lastSignalBar > cooldownBars
// =====================================================
// SL / TP
// =====================================================
swingLow = request.security(syminfo.tickerid, tfMain, ta.lowest(low, swingLookback), barmerge.gaps_off, barmerge.lookahead_off)
swingHigh = request.security(syminfo.tickerid, tfMain, ta.highest(high, swingLookback), barmerge.gaps_off, barmerge.lookahead_off)
longSl = swingLow - mainAtr * slBufferAtr
shortSl = swingHigh + mainAtr * slBufferAtr
longRisk = mainClose - longSl
shortRisk = shortSl - mainClose
longTp = mainClose + longRisk * tpRR
shortTp = mainClose - shortRisk * tpRR
longRiskOk = longRisk > syminfo.mintick and (not useMinRiskFilter or longRisk >= mainAtr * minRiskAtr) and (not useMaxRiskFilter or longRisk <= mainAtr * maxRiskAtr)
shortRiskOk = shortRisk > syminfo.mintick and (not useMinRiskFilter or shortRisk >= mainAtr * minRiskAtr) and (not useMaxRiskFilter or shortRisk <= mainAtr * maxRiskAtr)
// =====================================================
// 仮想ポジション管理
// =====================================================
var bool virtualActive = false
var string virtualSide = "NONE"
var float virtualEntry = na
var float virtualSl = na
var float virtualTp = na
var int virtualEntryBar = na
var int virtualScore = 0
// =====================================================
// ENTRYとTP/SLを点線で結ぶための保持変数
// =====================================================
var int activeEntryBarIndex = na
var float activeEntryPriceForLine = na
var string activeEntrySideForLine = "NONE"
// =====================================================
// 勝率カウント
// =====================================================
var int totalTrades = 0
var int winTrades = 0
var int lossTrades = 0
var int longTrades = 0
var int longWins = 0
var int longLosses = 0
var int shortTrades = 0
var int shortWins = 0
var int shortLosses = 0
var int currentWinStreak = 0
var int currentLossStreak = 0
var int maxWinStreak = 0
var int maxLossStreak = 0
var string lastResult = "なし"
winRate = totalTrades > 0 ? winTrades * 100.0 / totalTrades : na
longWinRate = longTrades > 0 ? longWins * 100.0 / longTrades : na
shortWinRate = shortTrades > 0 ? shortWins * 100.0 / shortTrades : na
// =====================================================
// 最終サイン
// =====================================================
canEnter = not virtualActive
chartTfOk = not useChartTimeframeGuard or timeframe.period == tfMain
// 重要:チャート上に実際に出る finalLong / finalShort のみ通知する
// AI側でチャート未表示のエントリーを追加通知しない前提
longSignal = chartTfOk and barstate.isconfirmed and canEnter and cooldownOk and rawLongSignal and longScore >= scoreMin and longRiskOk
shortSignal = chartTfOk and barstate.isconfirmed and canEnter and cooldownOk and rawShortSignal and shortScore >= scoreMin and shortRiskOk
finalLong = longSignal and not shortSignal or longSignal and shortSignal and longScore >= shortScore
finalShort = shortSignal and not longSignal or longSignal and shortSignal and shortScore > longScore
// =====================================================
// TP / SL判定
// =====================================================
longTpHit = virtualActive and virtualSide == "LONG" and high >= virtualTp
longSlHit = virtualActive and virtualSide == "LONG" and low <= virtualSl
shortTpHit = virtualActive and virtualSide == "SHORT" and low <= virtualTp
shortSlHit = virtualActive and virtualSide == "SHORT" and high >= virtualSl
longExitTp = virtualActive and virtualSide == "LONG" and bar_index > virtualEntryBar and (resultMode == "楽観的:TP優先" ? longTpHit : longTpHit and not longSlHit)
longExitSl = virtualActive and virtualSide == "LONG" and bar_index > virtualEntryBar and (resultMode == "保守的:SL優先" ? longSlHit : longSlHit and not longTpHit)
shortExitTp = virtualActive and virtualSide == "SHORT" and bar_index > virtualEntryBar and (resultMode == "楽観的:TP優先" ? shortTpHit : shortTpHit and not shortSlHit)
shortExitSl = virtualActive and virtualSide == "SHORT" and bar_index > virtualEntryBar and (resultMode == "保守的:SL優先" ? shortSlHit : shortSlHit and not shortTpHit)
// =====================================================
// JSON作成
// =====================================================
makeJson(eventType, side, resultText, score, entryPrice, slPrice, tpPrice, exitPrice, exitReason) =>
riskValue = math.abs(entryPrice - slPrice)
rewardValue = math.abs(tpPrice - entryPrice)
actualRR = riskValue > 0 ? rewardValue / riskValue : na
string json = "{"
json := json + "\"secret\":\"" + secretKey + "\","
json := json + "\"system\":\"" + systemName + "\","
json := json + "\"strategy\":\"" + strategyName + "\","
json := json + "\"source\":\"" + sourceName + "\","
json := json + "\"version\":\"15M_S1.0\","
json := json + "\"operation_mode\":\"chart_display_signal_15m_ea\","
json := json + "\"route\":\"15m-live\","
json := json + "\"event_type\":\"" + eventType + "\","
json := json + "\"event_id\":\"" + syminfo.ticker + "_" + str.tostring(time) + "_chart_" + side + "_" + resultText + "\","
json := json + "\"symbol\":\"" + syminfo.ticker + "\","
json := json + "\"tickerid\":\"" + syminfo.tickerid + "\","
json := json + "\"bar_time\":" + str.tostring(time) + ","
json := json + "\"bar_index\":" + str.tostring(bar_index) + ","
json := json + "\"timeframe_chart\":\"" + timeframe.period + "\","
json := json + "\"timeframe\":\"" + tfMain + "\","
json := json + "\"tf_fast\":\"" + tfFast + "\","
json := json + "\"tf_main\":\"" + tfMain + "\","
json := json + "\"tf_trend\":\"" + tfTrend + "\","
json := json + "\"side\":\"" + side + "\","
json := json + "\"engine\":\"chart_display_signal_15m\","
json := json + "\"tier\":\"" + resultText + "\","
json := json + "\"score\":" + str.tostring(score) + ","
json := json + "\"entry\":" + str.tostring(entryPrice) + ","
json := json + "\"sl\":" + str.tostring(slPrice) + ","
json := json + "\"tp\":" + str.tostring(tpPrice) + ","
json := json + "\"exit_price\":" + str.tostring(exitPrice) + ","
json := json + "\"exit_reason\":\"" + exitReason + "\","
json := json + "\"result\":\"" + resultText + "\","
json := json + "\"risk\":" + str.tostring(riskValue) + ","
json := json + "\"reward\":" + str.tostring(rewardValue) + ","
json := json + "\"actual_rr\":" + str.tostring(actualRR) + ","
json := json + "\"tp_rr_setting\":" + str.tostring(tpRR) + ","
json := json + "\"rci_fast\":" + str.tostring(fastRci) + ","
json := json + "\"rci_main\":" + str.tostring(mainRci) + ","
json := json + "\"rci_trend\":" + str.tostring(trendRci) + ","
json := json + "\"trend_up\":" + str.tostring(trendUp) + ","
json := json + "\"trend_down\":" + str.tostring(trendDown) + ","
json := json + "\"main_up\":" + str.tostring(mainUp) + ","
json := json + "\"main_down\":" + str.tostring(mainDown) + ","
json := json + "\"near_ema20\":" + str.tostring(nearEma20) + ","
json := json + "\"win_rate\":" + str.tostring(winRate) + ","
json := json + "\"total_trades\":" + str.tostring(totalTrades) + ","
json := json + "\"wins\":" + str.tostring(winTrades) + ","
json := json + "\"losses\":" + str.tostring(lossTrades)
json := json + "}"
json
// =====================================================
// TradingView通知文作成(15分足チャート表示サインEA用)
// Python側が読み取れるJSON直送形式に固定
// ENTRY通知だけを発注対象にする想定
// TP/SL通知は結果通知・AI学習用。Python Bot側では新規発注しない
// =====================================================
makeTvMessage(side, resultText, entryPrice, slPrice, tpPrice, jsonText) =>
// TradingView → 中継サーバー(main_full_v2.py)へJSONを直接送る
// Discord用の文章はサーバー側でAI判定・DB保存・勝率集計後に生成する
jsonText
drawResultLine(entryBar, entryPrice, exitBar, exitPrice, isTp) =>
line.new(x1=entryBar, y1=entryPrice, x2=exitBar, y2=exitPrice, xloc=xloc.bar_index, extend=extend.none, color=isTp ? color.new(color.lime, 0) : color.new(color.red, 0), style=line.style_dotted, width=2, force_overlay=true)
// =====================================================
// TP / SL到達
// =====================================================
if longExitTp
if not na(activeEntryBarIndex) and not na(activeEntryPriceForLine)
drawResultLine(activeEntryBarIndex, activeEntryPriceForLine, bar_index, virtualTp, true)
if showResultMarker
label.new(bar_index, high, showResultPrice ? "TP\n" + str.tostring(virtualTp, format.mintick) : "TP", style=label.style_label_down, textcolor=color.white, color=color.new(color.lime, 0), size=size.tiny, force_overlay=true)
winTrades += 1
longWins += 1
currentWinStreak += 1
currentLossStreak := 0
maxWinStreak := math.max(maxWinStreak, currentWinStreak)
lastResult := "LONG 勝ち"
if sendExitAlert
jsonLongTp = makeJson("notify", "LONG", "TP", virtualScore, virtualEntry, virtualSl, virtualTp, virtualTp, "take_profit")
alert(makeTvMessage("LONG", "TP", virtualEntry, virtualSl, virtualTp, jsonLongTp), alert.freq_once_per_bar_close)
virtualActive := false
virtualSide := "NONE"
activeEntryBarIndex := na
activeEntryPriceForLine := na
activeEntrySideForLine := "NONE"
if longExitSl
if not na(activeEntryBarIndex) and not na(activeEntryPriceForLine)
drawResultLine(activeEntryBarIndex, activeEntryPriceForLine, bar_index, virtualSl, false)
if showResultMarker
label.new(bar_index, low, showResultPrice ? "SL\n" + str.tostring(virtualSl, format.mintick) : "SL", style=label.style_label_up, textcolor=color.white, color=color.new(color.red, 0), size=size.tiny, force_overlay=true)
lossTrades += 1
longLosses += 1
currentLossStreak += 1
currentWinStreak := 0
maxLossStreak := math.max(maxLossStreak, currentLossStreak)
lastResult := "LONG 負け"
if sendExitAlert
jsonLongSl = makeJson("notify", "LONG", "SL", virtualScore, virtualEntry, virtualSl, virtualTp, virtualSl, "stop_loss")
alert(makeTvMessage("LONG", "SL", virtualEntry, virtualSl, virtualTp, jsonLongSl), alert.freq_once_per_bar_close)
virtualActive := false
virtualSide := "NONE"
if shortExitTp
if not na(activeEntryBarIndex) and not na(activeEntryPriceForLine)
drawResultLine(activeEntryBarIndex, activeEntryPriceForLine, bar_index, virtualTp, true)
if showResultMarker
label.new(bar_index, low, showResultPrice ? "TP\n" + str.tostring(virtualTp, format.mintick) : "TP", style=label.style_label_up, textcolor=color.white, color=color.new(color.lime, 0), size=size.tiny, force_overlay=true)
winTrades += 1
shortWins += 1
currentWinStreak += 1
currentLossStreak := 0
maxWinStreak := math.max(maxWinStreak, currentWinStreak)
lastResult := "SHORT 勝ち"
if sendExitAlert
jsonShortTp = makeJson("notify", "SHORT", "TP", virtualScore, virtualEntry, virtualSl, virtualTp, virtualTp, "take_profit")
alert(makeTvMessage("SHORT", "TP", virtualEntry, virtualSl, virtualTp, jsonShortTp), alert.freq_once_per_bar_close)
virtualActive := false
virtualSide := "NONE"
if shortExitSl
if not na(activeEntryBarIndex) and not na(activeEntryPriceForLine)
drawResultLine(activeEntryBarIndex, activeEntryPriceForLine, bar_index, virtualSl, false)
if showResultMarker
label.new(bar_index, high, showResultPrice ? "SL\n" + str.tostring(virtualSl, format.mintick) : "SL", style=label.style_label_down, textcolor=color.white, color=color.new(color.red, 0), size=size.tiny, force_overlay=true)
lossTrades += 1
shortLosses += 1
currentLossStreak += 1
currentWinStreak := 0
maxLossStreak := math.max(maxLossStreak, currentLossStreak)
lastResult := "SHORT 負け"
if sendExitAlert
jsonShortSl = makeJson("notify", "SHORT", "SL", virtualScore, virtualEntry, virtualSl, virtualTp, virtualSl, "stop_loss")
alert(makeTvMessage("SHORT", "SL", virtualEntry, virtualSl, virtualTp, jsonShortSl), alert.freq_once_per_bar_close)
virtualActive := false
virtualSide := "NONE"
// =====================================================
// ENTRY
// =====================================================
if finalLong
if showChartEntry
label.new(bar_index, mainClose, showEntryPrice ? "LONG\n" + str.tostring(mainClose, format.mintick) : "LONG", style=label.style_label_up, textcolor=color.white, color=color.new(color.lime, 0), size=size.small, force_overlay=true)
virtualActive := true
virtualSide := "LONG"
virtualEntry := mainClose
virtualSl := longSl
virtualTp := longTp
virtualEntryBar := bar_index
virtualScore := longScore
activeEntryBarIndex := bar_index
activeEntryPriceForLine := mainClose
activeEntrySideForLine := "LONG"
totalTrades += 1
longTrades += 1
lastSignalBar := bar_index
if sendEntryAlert
jsonLongEntry = makeJson("notify", "LONG", "ENTRY", longScore, mainClose, longSl, longTp, mainClose, "entry")
alert(makeTvMessage("LONG", "ENTRY", mainClose, longSl, longTp, jsonLongEntry), alert.freq_once_per_bar_close)
if finalShort
if showChartEntry
label.new(bar_index, mainClose, showEntryPrice ? "SHORT\n" + str.tostring(mainClose, format.mintick) : "SHORT", style=label.style_label_down, textcolor=color.white, color=color.new(color.red, 0), size=size.small, force_overlay=true)
virtualActive := true
virtualSide := "SHORT"
virtualEntry := mainClose
virtualSl := shortSl
virtualTp := shortTp
virtualEntryBar := bar_index
virtualScore := shortScore
activeEntryBarIndex := bar_index
activeEntryPriceForLine := mainClose
activeEntrySideForLine := "SHORT"
totalTrades += 1
shortTrades += 1
lastSignalBar := bar_index
if sendEntryAlert
jsonShortEntry = makeJson("notify", "SHORT", "ENTRY", shortScore, mainClose, shortSl, shortTp, mainClose, "entry")
alert(makeTvMessage("SHORT", "ENTRY", mainClose, shortSl, shortTp, jsonShortEntry), alert.freq_once_per_bar_close)
// =====================================================
// 背景
// =====================================================
bgcolor(showBg and finalLong ? color.new(color.lime, 92) : na)
bgcolor(showBg and finalShort ? color.new(color.red, 92) : na)
// =====================================================
// 価格チャートEMA
// =====================================================
plot(showEmaOnChart and showEma20 ? mainEma20 : na, "EMA20", color=color.new(color.yellow, 0), linewidth=1, force_overlay=true, display=display.pane)
plot(showEmaOnChart and showEma75 ? mainEma75 : na, "EMA75", color=color.new(color.orange, 0), linewidth=2, force_overlay=true, display=display.pane)
plot(showEmaOnChart and showEma200 ? mainEma200 : na, "EMA200", color=color.new(color.purple, 0), linewidth=2, force_overlay=true, display=display.pane)
// =====================================================
// RCIパネル
// =====================================================
hline(0, "0", color=color.gray)
hline(60, "+60", color=color.new(color.red, 0), linestyle=hline.style_dashed)
hline(30, "+30", color=color.new(color.red, 40), linestyle=hline.style_dashed)
hline(-30, "-30", color=color.new(color.blue, 40), linestyle=hline.style_dashed)
hline(-60, "-60", color=color.new(color.blue, 0), linestyle=hline.style_dashed)
hline(80, "+80", color=color.gray, linestyle=hline.style_dotted)
hline(-80, "-80", color=color.gray, linestyle=hline.style_dotted)
plot(showFastRci ? fastRci : na, "5分RCI", color=color.new(color.aqua, 0), linewidth=1, display=display.pane)
plot(showMainRci ? mainRci : na, "15分RCI", color=color.new(color.blue, 0), linewidth=2, display=display.pane)
plot(showTrendRci ? trendRci : na, "60分RCI", color=color.new(color.yellow, 0), linewidth=1, display=display.pane)
longZoneTop = plot(-30, display=display.none)
longZoneBottom = plot(-60, display=display.none)
shortZoneTop = plot(60, display=display.none)
shortZoneBottom = plot(30, display=display.none)
fill(longZoneTop, longZoneBottom, color=color.new(color.blue, 88))
fill(shortZoneTop, shortZoneBottom, color=color.new(color.red, 88))
plotshape(showPanelSignal and finalLong, title="LONG", style=shape.triangleup, location=location.bottom, color=color.new(color.lime, 0), size=size.small)
plotshape(showPanelSignal and finalShort, title="SHORT", style=shape.triangledown, location=location.top, color=color.new(color.red, 0), size=size.small)
// =====================================================
// 勝率パネル:初期OFF
// =====================================================
var table t = table.new(position.top_right, 2, 12, border_width=1)
if showTable and barstate.islast
table.cell(t, 0, 0, "TSUBAKI 15M", text_color=color.white, bgcolor=color.new(color.black, 0))
table.cell(t, 1, 0, "S1.0", text_color=color.white, bgcolor=color.new(color.black, 0))
table.cell(t, 0, 1, "総数", text_color=color.white)
table.cell(t, 1, 1, str.tostring(totalTrades), text_color=color.white)
table.cell(t, 0, 2, "勝ち / 負け", text_color=color.white)
table.cell(t, 1, 2, str.tostring(winTrades) + " / " + str.tostring(lossTrades), text_color=color.white)
table.cell(t, 0, 3, "勝率", text_color=color.white)
table.cell(t, 1, 3, na(winRate) ? "計測中" : str.tostring(winRate, "#.0") + "%", text_color=color.white)
table.cell(t, 0, 4, "LONG勝率", text_color=color.white)
table.cell(t, 1, 4, na(longWinRate) ? "計測中" : str.tostring(longWinRate, "#.0") + "%", text_color=color.white)
table.cell(t, 0, 5, "SHORT勝率", text_color=color.white)
table.cell(t, 1, 5, na(shortWinRate) ? "計測中" : str.tostring(shortWinRate, "#.0") + "%", text_color=color.white)
table.cell(t, 0, 6, "LONG数", text_color=color.white)
table.cell(t, 1, 6, str.tostring(longTrades), text_color=color.white)
table.cell(t, 0, 7, "SHORT数", text_color=color.white)
table.cell(t, 1, 7, str.tostring(shortTrades), text_color=color.white)
table.cell(t, 0, 8, "連勝 / 連敗", text_color=color.white)
table.cell(t, 1, 8, str.tostring(currentWinStreak) + " / " + str.tostring(currentLossStreak), text_color=color.white)
table.cell(t, 0, 9, "最大連勝/連敗", text_color=color.white)
table.cell(t, 1, 9, str.tostring(maxWinStreak) + " / " + str.tostring(maxLossStreak), text_color=color.white)
table.cell(t, 0, 10, "仮想ポジ", text_color=color.white)
table.cell(t, 1, 10, virtualActive ? virtualSide : "なし", text_color=color.white)
table.cell(t, 0, 11, "直近結果", text_color=color.white)
table.cell(t, 1, 11, lastResult, text_color=color.white)