//@version=5 indicator("TSUBAKI 5M S1.0 チャート表示サインEA版", shorttitle="TSUBAKI 5M EA", overlay=false, max_labels_count=500, max_lines_count=500) // ===================================================== // TSUBAKI 5M 専用 // ・5分足をメインに、チャート上に実際に表示されたサインだけ通知 // ・TradingViewのWebhook URLは http://128.22.126.239/all-sign-live を使用 // ・アラート条件は「Any alert() function call」を選択 // ・AIがチャート外のエントリーを作る仕様ではありません // ・TP/SL通知は結果通知・AI学習用。新規発注対象ではない // ===================================================== // ===================================================== // Webhook / Discord設定 // ===================================================== secretKey = input.string("CHANGE_ME_SECRET", "Webhook認証キー", display=display.none) systemName = input.string("TSUBAKI_5M_CHART_SIGNAL_EA", "システム名", display=display.none) strategyName = input.string("TSUBAKI_5M_CHART_SIGNAL", "サーバー集計用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("1", "短期足(1分)", display=display.none) tfMain = input.timeframe("5", "メイン足(5分)", display=display.none) tfTrend = input.timeframe("15", "方向確認足(15分)", display=display.none) useLong = input.bool(true, "LONGサインを使う", display=display.none) useShort = input.bool(true, "SHORTサインを使う", 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, "15分方向フィルター", display=display.none) useEmaFilter = input.bool(true, "EMA位置フィルター", display=display.none) useCandleFilter = input.bool(true, "ローソク足方向フィルター", display=display.none) cooldownBarsMany = input.int(3, "クールダウン:多め", minval=0, display=display.none) cooldownBarsNormal = input.int(6, "クールダウン:標準", minval=0, display=display.none) cooldownBarsFew = input.int(10, "クールダウン:少なめ", 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(6, "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.55, "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(1.5, "最大リスクATR倍率", minval=0.2, maxval=5.0, step=0.1, display=display.none) // ===================================================== // 表示設定 // ===================================================== showFastRci = input.bool(true, "1分RCI表示", display=display.none) showMainRci = input.bool(true, "5分RCI表示", display=display.none) showTrendRci = input.bool(false, "15分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 // ===================================================== // 5分足チャートサインエンジン // ===================================================== 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 longSignal = barstate.isconfirmed and canEnter and cooldownOk and rawLongSignal and longScore >= scoreMin and longRiskOk shortSignal = 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\":\"S1.3\"," json := json + "\"operation_mode\":\"chart_display_signal_ea\"," 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\"," 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通知文作成(5分足チャート表示サインEA用) // Python側が読み取れるJSON直送形式に固定 // ENTRY通知だけを発注対象にする想定。チャートに出たfinalLong/finalShortのみ通知 // 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 // finalLong / finalShort が成立し、チャートに表示されるサインだけ通知 // AI判断だけのチャート外エントリー通知は行わない // ===================================================== 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, "1分RCI", color=color.new(color.aqua, 0), linewidth=1, display=display.pane) plot(showMainRci ? mainRci : na, "5分RCI", color=color.new(color.blue, 0), linewidth=2, display=display.pane) plot(showTrendRci ? trendRci : na, "15分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 5M", 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)