This commit is contained in:
zhutoutoutousan
2026-01-05 05:37:33 +01:00
parent 7d41b04aef
commit 5b44e14211
79 changed files with 19884 additions and 0 deletions
@@ -0,0 +1,32 @@
SSE Index Multi-Timeframe RSI Momentum Strategy with EMA Distance Trading
Strategy Overview:
This advanced momentum-based trading system is specifically designed for the Shanghai Stock Exchange (SSE) Index, capturing RSI bounce opportunities across multiple timeframes while incorporating sophisticated EMA distance-based entries. The strategy combines traditional RSI oversold/overbought analysis with modern volatility-adjusted position management.
Core Trading Logic:
Weekly RSI Signals: Large position entries (10% equity) when weekly RSI crosses above 30 after being oversold, targeting major trend reversals
Daily RSI Signals: Medium position entries (5% equity) when daily RSI crosses above 30, capturing short-term momentum shifts
EMA Distance Entries: Strategic entries (7.5% equity) when price extends 50+ pips from 200 EMA while remaining above it, exploiting mean reversion opportunities
Risk Management System:
Partial Profit Taking: Both RSI positions scale out 25% when daily RSI becomes overbought (>70), allowing multiple profit captures
Complete Weekly Exits: All weekly positions close when weekly RSI becomes overbought, ensuring trend-following discipline
EMA Crossover Exits: EMA distance trades exit cleanly when price crosses below 50 EMA, providing responsive trend change detection
Emergency Exit: Master exit when EMA crosses above price, protecting all positions during major trend reversals
Advanced Features:
Concurrent Position Management: Up to 100 pyramiding positions across three distinct entry strategies
Multi-Timeframe Analysis: Seamlessly integrates weekly and daily RSI data regardless of chart timeframe
Real-Time Monitoring: Comprehensive information table displaying RSI levels, EMA distances, position quantities, and trade counts
Visual Feedback System: Color-coded entry/exit signals with background highlighting for immediate market condition recognition
Ideal Market Conditions:
Optimized for volatile, emotion-driven markets like Chinese equities where RSI bounces from oversold levels frequently create profitable momentum shifts. The strategy's multiple entry mechanisms ensure comprehensive market coverage while sophisticated exit rules protect capital during adverse conditions.
Technical Requirements:
Recommended for SSE Composite Index, SSE 50, or related Chinese equity ETFs
Best performance on daily charts with sufficient historical data
Suitable for accounts with minimum $10,000 capital for effective position sizing
This strategy represents a complete trading system combining technical analysis fundamentals with modern risk management principles, specifically calibrated for the unique characteristics of Chinese equity markets.
@@ -0,0 +1,202 @@
//@version=6
strategy("SSE Index RSI Bounce Strategy", overlay=true, default_qty_type=strategy.percent_of_equity, initial_capital=10000, pyramiding=100, calc_on_every_tick=false, calc_on_order_fills=false)
// Input parameters
rsi_length = input.int(17, "RSI Length", minval=1)
rsi_oversold = input.int(27, "RSI Oversold Level", minval=1, maxval=50)
rsi_overbought = input.int(86, "RSI Overbought Level", minval=50, maxval=100)
ema_length = input.int(177, "EMA Length", minval=1)
weekly_position_size = input.float(14.0, "Weekly Signal Position Size (%)", minval=0.1, maxval=100)
daily_position_size = input.float(11.0, "Daily Signal Position Size (%)", minval=0.1, maxval=100)
partial_exit_percent = input.float(41.0, "Partial Exit Percentage on Daily RSI Overbought (%)", minval=10.0, maxval=50.0)
// New EMA Distance Trading Parameters
ema_distance_threshold = input.float(16.0, "EMA Distance Threshold (Pips)", minval=1.0, maxval=1000.0)
ema_distance_position_size = input.float(53, "EMA Distance Position Size (%)", minval=0.1, maxval=100)
// EMA Distance Exit Parameters
ema_exit_period = input.int(34, "EMA Exit Period", minval=10, maxval=200)
enable_volume_confirmation = input.bool(true, "Require Volume Confirmation for EMA Exit")
// Calculate indicators
rsi_daily = ta.rsi(close, rsi_length)
rsi_weekly = request.security(syminfo.tickerid, "1W", ta.rsi(close, rsi_length))
ema_200 = ta.ema(close, ema_length)
ema_exit = ta.ema(close, ema_exit_period)
// EMA Distance Trading Logic
pip_size = syminfo.mintick * 10 // Adjust pip size based on instrument
price_ema_distance = math.abs(close - ema_200) / pip_size
ema_distance_entry = price_ema_distance >= ema_distance_threshold * 100 and close > ema_200 // Only enter when price above EMA
// RSI bounce conditions - back to original crossover logic
// Weekly RSI bounce: RSI was below 30 and now crosses above 30
rsi_weekly_prev = request.security(syminfo.tickerid, "1W", ta.rsi(close, rsi_length)[1])
weekly_bounce = rsi_weekly_prev < rsi_oversold and rsi_weekly > rsi_oversold
// Daily RSI bounce: RSI was below 30 and now crosses above 30
daily_bounce = rsi_daily[1] < rsi_oversold and rsi_daily > rsi_oversold
// Overbought conditions for exits - keep as crossovers for exits
daily_rsi_overbought = rsi_daily > rsi_overbought and rsi_daily[1] <= rsi_overbought
weekly_rsi_overbought = rsi_weekly > rsi_overbought and rsi_weekly_prev <= rsi_overbought
// EMA exit condition: EMA was above price but now below price
ema_above_price_prev = ema_200[1] > close[1]
ema_below_price_now = ema_200 < close
ema_exit_condition = ema_above_price_prev and ema_below_price_now
// EMA Distance exit condition - EMA crossover exit
// Price crosses below shorter period EMA (more responsive than 200 EMA)
price_above_ema_exit_prev = close[1] > ema_exit[1]
price_below_ema_exit_now = close < ema_exit
ema_crossover_exit = price_above_ema_exit_prev and price_below_ema_exit_now
// Optional volume confirmation
volume_confirmation = not enable_volume_confirmation or volume > ta.sma(volume, 20)
ema_distance_exit_condition = ema_crossover_exit and volume_confirmation
// Track positions separately with counters for multiple trades
var int weekly_trade_count = 0
var int daily_trade_count = 0
var int ema_distance_trade_count = 0
var float weekly_position_qty = 0.0
var float daily_position_qty = 0.0
var float ema_distance_position_qty = 0.0
// Entry conditions - allow multiple concurrent trades
weekly_entry = weekly_bounce
daily_entry = daily_bounce
// Strategy execution - ensure ALL signals result in trades
if weekly_entry
strategy.entry("Weekly_Long", strategy.long, qty=weekly_position_size, comment="Weekly RSI Bounce #" + str.tostring(weekly_trade_count + 1), alert_message="Weekly Entry")
weekly_trade_count := weekly_trade_count + 1
weekly_position_qty := weekly_position_qty + weekly_position_size
if daily_entry
strategy.entry("Daily_Long", strategy.long, qty=daily_position_size, comment="Daily RSI Bounce #" + str.tostring(daily_trade_count + 1), alert_message="Daily Entry")
daily_trade_count := daily_trade_count + 1
daily_position_qty := daily_position_qty + daily_position_size
if ema_distance_entry
strategy.entry("EMA_Distance_Long", strategy.long, qty=ema_distance_position_size, comment="EMA Distance Entry #" + str.tostring(ema_distance_trade_count + 1), alert_message="EMA Distance Entry")
ema_distance_trade_count := ema_distance_trade_count + 1
ema_distance_position_qty := ema_distance_position_qty + ema_distance_position_size
// Debug - show actual entry attempts
if weekly_entry
label.new(bar_index, high + (high - low) * 0.1, "WEEKLY ENTRY ATTEMPT",
color=color.green, textcolor=color.white, size=size.normal, style=label.style_label_down)
if daily_entry
label.new(bar_index, high + (high - low) * 0.15, "DAILY ENTRY ATTEMPT",
color=color.blue, textcolor=color.white, size=size.normal, style=label.style_label_down)
if ema_distance_entry
label.new(bar_index, high + (high - low) * 0.2, "EMA DISTANCE: " + str.tostring(price_ema_distance, "#.#") + " pips",
color=color.purple, textcolor=color.white, size=size.normal, style=label.style_label_down)
// Partial exit for weekly positions on daily RSI overbought
if daily_rsi_overbought and weekly_position_qty > 0
exit_qty = weekly_position_qty * (partial_exit_percent / 100)
strategy.close("Weekly_Long", qty=exit_qty, comment="Weekly Partial Exit Daily OB")
weekly_position_qty := math.max(0, weekly_position_qty - exit_qty)
// Partial exit for daily positions on daily RSI overbought
if daily_rsi_overbought and daily_position_qty > 0
exit_qty_daily = daily_position_qty * (partial_exit_percent / 100)
strategy.close("Daily_Long", qty=exit_qty_daily, comment="Daily Partial Exit OB")
daily_position_qty := math.max(0, daily_position_qty - exit_qty_daily)
// Complete exit for weekly positions on weekly RSI overbought
if weekly_rsi_overbought and weekly_position_qty > 0
strategy.close("Weekly_Long", comment="Complete Exit Weekly OB")
weekly_position_qty := 0.0
weekly_trade_count := 0
// Exit all positions when EMA crosses from above price to below price
if ema_exit_condition and strategy.position_size > 0
strategy.close_all("EMA Cross Exit")
weekly_position_qty := 0.0
daily_position_qty := 0.0
ema_distance_position_qty := 0.0
weekly_trade_count := 0
daily_trade_count := 0
ema_distance_trade_count := 0
// Exit EMA distance positions when price crosses below EMA (anti-crossover)
if ema_distance_exit_condition and ema_distance_position_qty > 0
strategy.close("EMA_Distance_Long", comment="EMA Distance Anti-Cross Exit")
ema_distance_position_qty := 0.0
ema_distance_trade_count := 0
// Plotting
plot(ema_200, "200 EMA", color=color.orange, linewidth=2)
plot(ema_exit, "EMA Exit", color=color.purple, linewidth=1, style=plot.style_line)
plot(rsi_daily, "Daily RSI", color=color.blue, display=display.data_window)
plot(rsi_weekly, "Weekly RSI", color=color.red, display=display.data_window)
// Plot RSI levels
hline(rsi_oversold, "Oversold Level", color=color.red, linestyle=hline.style_dashed)
hline(rsi_overbought, "Overbought Level", color=color.green, linestyle=hline.style_dashed)
// Background color for RSI conditions
bgcolor(weekly_bounce ? color.new(color.green, 90) : na, title="Weekly RSI Bounce")
bgcolor(daily_bounce ? color.new(color.blue, 90) : na, title="Daily RSI Bounce")
bgcolor(daily_rsi_overbought and (weekly_position_qty > 0 or daily_position_qty > 0) ? color.new(color.yellow, 90) : na, title="Daily RSI Overbought (Partial Exit)")
bgcolor(weekly_rsi_overbought and weekly_position_qty > 0 ? color.new(color.orange, 90) : na, title="Weekly RSI Overbought (Complete Exit)")
bgcolor(ema_exit_condition and strategy.position_size > 0 ? color.new(color.red, 90) : na, title="EMA Cross Exit")
bgcolor(ema_distance_exit_condition and ema_distance_position_qty > 0 ? color.new(color.maroon, 90) : na, title="EMA Distance Anti-Cross Exit")
bgcolor(ema_distance_entry ? color.new(color.purple, 90) : na, title="EMA Distance Entry")
// Plot entry and exit signals with enhanced debugging
plotshape(weekly_entry, "Weekly Entry", shape.triangleup, location.belowbar, color.green, size=size.normal)
plotshape(daily_entry, "Daily Entry", shape.triangleup, location.belowbar, color.blue, size=size.small)
plotshape(ema_distance_entry, "EMA Distance Entry", shape.triangleup, location.belowbar, color.purple, size=size.normal)
plotshape(daily_rsi_overbought and (weekly_position_qty > 0 or daily_position_qty > 0), "Partial Exit Both", shape.circle, location.abovebar, color.yellow, size=size.small)
plotshape(weekly_rsi_overbought and weekly_position_qty > 0, "Complete Exit Weekly OB", shape.triangledown, location.abovebar, color.orange, size=size.normal)
plotshape(ema_exit_condition and strategy.position_size > 0, "EMA Cross Exit", shape.triangledown, location.abovebar, color.red, size=size.large)
plotshape(ema_distance_exit_condition and ema_distance_position_qty > 0, "EMA Distance Anti-Cross Exit", shape.triangledown, location.abovebar, color.maroon, size=size.normal)
// Debug labels to show when conditions are met
if weekly_bounce
label.new(bar_index, low - (high - low) * 0.1, "W-RSI: " + str.tostring(rsi_weekly, "#.##"),
color=color.green, textcolor=color.white, size=size.small, style=label.style_label_up)
if daily_bounce
label.new(bar_index, low - (high - low) * 0.05, "D-RSI: " + str.tostring(rsi_daily, "#.##"),
color=color.blue, textcolor=color.white, size=size.small, style=label.style_label_up)
// Table to show current status
var table info_table = table.new(position.top_right, 2, 12, bgcolor=color.white, border_width=1)
if barstate.islast
table.cell(info_table, 0, 0, "Indicator", bgcolor=color.gray, text_color=color.white)
table.cell(info_table, 1, 0, "Value", bgcolor=color.gray, text_color=color.white)
table.cell(info_table, 0, 1, "Daily RSI", bgcolor=color.white)
table.cell(info_table, 1, 1, str.tostring(rsi_daily, "#.##"), bgcolor=color.white)
table.cell(info_table, 0, 2, "Weekly RSI", bgcolor=color.white)
table.cell(info_table, 1, 2, str.tostring(rsi_weekly, "#.##"), bgcolor=color.white)
table.cell(info_table, 0, 3, "200 EMA", bgcolor=color.white)
table.cell(info_table, 1, 3, str.tostring(ema_200, "#.##"), bgcolor=color.white)
table.cell(info_table, 0, 4, "EMA Distance", bgcolor=color.white)
table.cell(info_table, 1, 4, str.tostring(price_ema_distance, "#.#") + " pips", bgcolor=color.white)
table.cell(info_table, 0, 5, "EMA Exit Level", bgcolor=color.white)
table.cell(info_table, 1, 5, str.tostring(ema_exit, "#.##"), bgcolor=color.white)
table.cell(info_table, 0, 6, "Total Position", bgcolor=color.white)
table.cell(info_table, 1, 6, strategy.position_size > 0 ? "Long" : "None",
bgcolor=strategy.position_size > 0 ? color.green : color.white)
table.cell(info_table, 0, 7, "Total Size", bgcolor=color.white)
table.cell(info_table, 1, 7, str.tostring(strategy.position_size, "#.####"), bgcolor=color.white)
table.cell(info_table, 0, 8, "Weekly Qty", bgcolor=color.white)
table.cell(info_table, 1, 8, str.tostring(weekly_position_qty, "#.####"),
bgcolor=weekly_position_qty > 0 ? color.green : color.white)
table.cell(info_table, 0, 9, "Daily Qty", bgcolor=color.white)
table.cell(info_table, 1, 9, str.tostring(daily_position_qty, "#.####"),
bgcolor=daily_position_qty > 0 ? color.blue : color.white)
table.cell(info_table, 0, 10, "EMA Distance Qty", bgcolor=color.white)
table.cell(info_table, 1, 10, str.tostring(ema_distance_position_qty, "#.####"),
bgcolor=ema_distance_position_qty > 0 ? color.purple : color.white)
table.cell(info_table, 0, 11, "Trade Counts", bgcolor=color.white)
table.cell(info_table, 1, 11, "W:" + str.tostring(weekly_trade_count) + " D:" + str.tostring(daily_trade_count) + " E:" + str.tostring(ema_distance_trade_count), bgcolor=color.white)
@@ -0,0 +1,255 @@
//@version=6
strategy("SSE Index RSI Bounce Strategy - Enhanced", overlay=true, default_qty_type=strategy.percent_of_equity, initial_capital=10000, pyramiding=100, calc_on_every_tick=false, calc_on_order_fills=false)
// Input parameters
rsi_length = input.int(17, "RSI Length", minval=1)
rsi_oversold = input.int(27, "RSI Oversold Level", minval=1, maxval=50)
rsi_overbought = input.int(86, "RSI Overbought Level", minval=50, maxval=100)
ema_length = input.int(177, "EMA Length", minval=1)
weekly_position_size = input.float(14.0, "Weekly Signal Position Size (%)", minval=0.1, maxval=100)
daily_position_size = input.float(11.0, "Daily Signal Position Size (%)", minval=0.1, maxval=100)
partial_exit_percent = input.float(41.0, "Partial Exit Percentage on Daily RSI Overbought (%)", minval=10.0, maxval=50.0)
// Enhanced EMA Distance Trading Parameters
ema_distance_threshold = input.float(16.0, "EMA Distance Threshold (Pips)", minval=1.0, maxval=1000.0)
ema_distance_position_size = input.float(53, "EMA Distance Position Size (%)", minval=0.1, maxval=100)
// New EMA Alignment Filter Parameters
fast_ema_length = input.int(21, "Fast EMA Length", minval=5, maxval=50)
slow_ema_length = input.int(55, "Slow EMA Length", minval=20, maxval=200)
ema_alignment_threshold = input.float(15000.0, "EMA Alignment Threshold (Pips)", minval=0.5, maxval=500000.0, tooltip="Minimum distance required between fast and slow EMAs")
ema_alignment_direction = input.string("both", "EMA Alignment Direction", options=["both", "above", "below"], tooltip="Direction for EMA alignment check")
// Price Proximity Filter Parameters
price_proximity_threshold = input.float(535.0, "Price Proximity Threshold (Pips)", minval=1.0, maxval=100000.0, tooltip="Minimum distance required between price and 200 EMA to allow trades")
// EMA Distance Exit Parameters
ema_exit_period = input.int(34, "EMA Exit Period", minval=10, maxval=200)
enable_volume_confirmation = input.bool(true, "Require Volume Confirmation for EMA Exit")
// Calculate indicators
rsi_daily = ta.rsi(close, rsi_length)
rsi_weekly = request.security(syminfo.tickerid, "1W", ta.rsi(close, rsi_length))
ema_200 = ta.ema(close, ema_length)
ema_exit = ta.ema(close, ema_exit_period)
// Enhanced EMA Distance Trading Logic with Alignment Filter
pip_size = syminfo.mintick * 10 // Adjust pip size based on instrument
price_ema_distance = math.abs(close - ema_200) / pip_size
// Calculate fast and slow EMAs for alignment check
fast_ema = ta.ema(close, fast_ema_length)
slow_ema = ta.ema(close, slow_ema_length)
ema_alignment_distance = math.abs(fast_ema - slow_ema) / pip_size
// EMA Alignment Filter Logic
ema_alignment_ok = false
if ema_alignment_direction == "both"
ema_alignment_ok := ema_alignment_distance >= ema_alignment_threshold
else if ema_alignment_direction == "above"
ema_alignment_ok := fast_ema > slow_ema and ema_alignment_distance >= ema_alignment_threshold
else if ema_alignment_direction == "below"
ema_alignment_ok := fast_ema < slow_ema and ema_alignment_distance >= ema_alignment_threshold
// Price Proximity Filter - prevent trades when price is too close to 200 EMA
price_proximity_ok = price_ema_distance >= price_proximity_threshold * 100
// Enhanced EMA Distance Entry with Alignment Filter and Price Proximity
ema_distance_entry = price_ema_distance >= ema_distance_threshold * 100 and close > ema_200 and ema_alignment_ok and price_proximity_ok
// RSI bounce conditions - back to original crossover logic
// Weekly RSI bounce: RSI was below 30 and now crosses above 30
rsi_weekly_prev = request.security(syminfo.tickerid, "1W", ta.rsi(close, rsi_length)[1])
weekly_bounce = rsi_weekly_prev < rsi_oversold and rsi_weekly > rsi_oversold
// Daily RSI bounce: RSI was below 30 and now crosses above 30
daily_bounce = rsi_daily[1] < rsi_oversold and rsi_daily > rsi_oversold
// Apply price proximity filter to RSI signals as well
weekly_entry = weekly_bounce and price_proximity_ok
daily_entry = daily_bounce and price_proximity_ok
// Overbought conditions for exits - keep as crossovers for exits
daily_rsi_overbought = rsi_daily > rsi_overbought and rsi_daily[1] <= rsi_overbought
weekly_rsi_overbought = rsi_weekly > rsi_overbought and rsi_weekly_prev <= rsi_overbought
// EMA exit condition: EMA was above price but now below price
ema_above_price_prev = ema_200[1] > close[1]
ema_below_price_now = ema_200 < close
ema_exit_condition = ema_above_price_prev and ema_below_price_now
// EMA Distance exit condition - EMA crossover exit
// Price crosses below shorter period EMA (more responsive than 200 EMA)
price_above_ema_exit_prev = close[1] > ema_exit[1]
price_below_ema_exit_now = close < ema_exit
ema_crossover_exit = price_above_ema_exit_prev and price_below_ema_exit_now
// Optional volume confirmation
volume_confirmation = not enable_volume_confirmation or volume > ta.sma(volume, 20)
ema_distance_exit_condition = ema_crossover_exit and volume_confirmation
// Track positions separately with counters for multiple trades
var int weekly_trade_count = 0
var int daily_trade_count = 0
var int ema_distance_trade_count = 0
var float weekly_position_qty = 0.0
var float daily_position_qty = 0.0
var float ema_distance_position_qty = 0.0
// Strategy execution - ensure ALL signals result in trades
if weekly_entry
strategy.entry("Weekly_Long", strategy.long, qty=weekly_position_size, comment="Weekly RSI Bounce #" + str.tostring(weekly_trade_count + 1), alert_message="Weekly Entry")
weekly_trade_count := weekly_trade_count + 1
weekly_position_qty := weekly_position_qty + weekly_position_size
if daily_entry
strategy.entry("Daily_Long", strategy.long, qty=daily_position_size, comment="Daily RSI Bounce #" + str.tostring(daily_trade_count + 1), alert_message="Daily Entry")
daily_trade_count := daily_trade_count + 1
daily_position_qty := daily_position_qty + daily_position_size
if ema_distance_entry
strategy.entry("EMA_Distance_Long", strategy.long, qty=ema_distance_position_size, comment="EMA Distance Entry #" + str.tostring(ema_distance_trade_count + 1), alert_message="EMA Distance Entry")
ema_distance_trade_count := ema_distance_trade_count + 1
ema_distance_position_qty := ema_distance_position_qty + ema_distance_position_size
// Debug - show actual entry attempts
if weekly_entry
label.new(bar_index, high + (high - low) * 0.1, "WEEKLY ENTRY ATTEMPT",
color=color.green, textcolor=color.white, size=size.normal, style=label.style_label_down)
if daily_entry
label.new(bar_index, high + (high - low) * 0.15, "DAILY ENTRY ATTEMPT",
color=color.blue, textcolor=color.white, size=size.normal, style=label.style_label_down)
if ema_distance_entry
label.new(bar_index, high + (high - low) * 0.2, "EMA DISTANCE: " + str.tostring(price_ema_distance, "#.#") + " pips\nALIGNMENT: " + str.tostring(ema_alignment_distance, "#.#") + " pips",
color=color.purple, textcolor=color.white, size=size.normal, style=label.style_label_down)
// Show alignment filter status
if not ema_alignment_ok and price_ema_distance >= ema_distance_threshold * 100 and close > ema_200 and price_proximity_ok
label.new(bar_index, high + (high - low) * 0.25, "ALIGNMENT BLOCKED\nFast-Slow: " + str.tostring(ema_alignment_distance, "#.#") + " pips\nRequired: " + str.tostring(ema_alignment_threshold) + " pips",
color=color.red, textcolor=color.white, size=size.small, style=label.style_label_down)
// Show price proximity filter status
if not price_proximity_ok and (weekly_bounce or daily_bounce or (price_ema_distance >= ema_distance_threshold * 100 and close > ema_200 and ema_alignment_ok))
label.new(bar_index, high + (high - low) * 0.3, "PROXIMITY BLOCKED\nPrice-EMA: " + str.tostring(price_ema_distance, "#.#") + " pips\nRequired: " + str.tostring(price_proximity_threshold) + " pips",
color=color.orange, textcolor=color.white, size=size.small, style=label.style_label_down)
// Partial exit for weekly positions on daily RSI overbought
if daily_rsi_overbought and weekly_position_qty > 0
exit_qty = weekly_position_qty * (partial_exit_percent / 100)
strategy.close("Weekly_Long", qty=exit_qty, comment="Weekly Partial Exit Daily OB")
weekly_position_qty := math.max(0, weekly_position_qty - exit_qty)
// Partial exit for daily positions on daily RSI overbought
if daily_rsi_overbought and daily_position_qty > 0
exit_qty_daily = daily_position_qty * (partial_exit_percent / 100)
strategy.close("Daily_Long", qty=exit_qty_daily, comment="Daily Partial Exit OB")
daily_position_qty := math.max(0, daily_position_qty - exit_qty_daily)
// Complete exit for weekly positions on weekly RSI overbought
if weekly_rsi_overbought and weekly_position_qty > 0
strategy.close("Weekly_Long", comment="Complete Exit Weekly OB")
weekly_position_qty := 0.0
weekly_trade_count := 0
// Exit all positions when EMA crosses from above price to below price
if ema_exit_condition and strategy.position_size > 0
strategy.close_all("EMA Cross Exit")
weekly_position_qty := 0.0
daily_position_qty := 0.0
ema_distance_position_qty := 0.0
weekly_trade_count := 0
daily_trade_count := 0
ema_distance_trade_count := 0
// Exit EMA distance positions when price crosses below EMA (anti-crossover)
if ema_distance_exit_condition and ema_distance_position_qty > 0
strategy.close("EMA_Distance_Long", comment="EMA Distance Anti-Cross Exit")
ema_distance_position_qty := 0.0
ema_distance_trade_count := 0
// Plotting
plot(ema_200, "200 EMA", color=color.orange, linewidth=2)
plot(ema_exit, "EMA Exit", color=color.purple, linewidth=1, style=plot.style_line)
plot(fast_ema, "Fast EMA", color=color.lime, linewidth=1, style=plot.style_line)
plot(slow_ema, "Slow EMA", color=color.navy, linewidth=1, style=plot.style_line)
plot(rsi_daily, "Daily RSI", color=color.blue, display=display.data_window)
plot(rsi_weekly, "Weekly RSI", color=color.red, display=display.data_window)
// Plot RSI levels
hline(rsi_oversold, "Oversold Level", color=color.red, linestyle=hline.style_dashed)
hline(rsi_overbought, "Overbought Level", color=color.green, linestyle=hline.style_dashed)
// Background color for RSI conditions
bgcolor(weekly_bounce ? color.new(color.green, 90) : na, title="Weekly RSI Bounce")
bgcolor(daily_bounce ? color.new(color.blue, 90) : na, title="Daily RSI Bounce")
bgcolor(daily_rsi_overbought and (weekly_position_qty > 0 or daily_position_qty > 0) ? color.new(color.yellow, 90) : na, title="Daily RSI Overbought (Partial Exit)")
bgcolor(weekly_rsi_overbought and weekly_position_qty > 0 ? color.new(color.orange, 90) : na, title="Weekly RSI Overbought (Complete Exit)")
bgcolor(ema_exit_condition and strategy.position_size > 0 ? color.new(color.red, 90) : na, title="EMA Cross Exit")
bgcolor(ema_distance_exit_condition and ema_distance_position_qty > 0 ? color.new(color.maroon, 90) : na, title="EMA Distance Anti-Cross Exit")
bgcolor(ema_distance_entry ? color.new(color.purple, 90) : na, title="EMA Distance Entry")
bgcolor(not ema_alignment_ok and price_ema_distance >= ema_distance_threshold * 100 and close > ema_200 and price_proximity_ok ? color.new(color.red, 95) : na, title="EMA Alignment Blocked")
bgcolor(not price_proximity_ok and (weekly_bounce or daily_bounce or (price_ema_distance >= ema_distance_threshold * 100 and close > ema_200 and ema_alignment_ok)) ? color.new(color.orange, 95) : na, title="Price Proximity Blocked")
// Plot entry and exit signals with enhanced debugging
plotshape(weekly_entry, "Weekly Entry", shape.triangleup, location.belowbar, color.green, size=size.normal)
plotshape(daily_entry, "Daily Entry", shape.triangleup, location.belowbar, color.blue, size=size.small)
plotshape(ema_distance_entry, "EMA Distance Entry", shape.triangleup, location.belowbar, color.purple, size=size.normal)
plotshape(daily_rsi_overbought and (weekly_position_qty > 0 or daily_position_qty > 0), "Partial Exit Both", shape.circle, location.abovebar, color.yellow, size=size.small)
plotshape(weekly_rsi_overbought and weekly_position_qty > 0, "Complete Exit Weekly OB", shape.triangledown, location.abovebar, color.orange, size=size.normal)
plotshape(ema_exit_condition and strategy.position_size > 0, "EMA Cross Exit", shape.triangledown, location.abovebar, color.red, size=size.large)
plotshape(ema_distance_exit_condition and ema_distance_position_qty > 0, "EMA Distance Anti-Cross Exit", shape.triangledown, location.abovebar, color.maroon, size=size.normal)
// Debug labels to show when conditions are met
if weekly_bounce
label.new(bar_index, low - (high - low) * 0.1, "W-RSI: " + str.tostring(rsi_weekly, "#.##"),
color=color.green, textcolor=color.white, size=size.small, style=label.style_label_up)
if daily_bounce
label.new(bar_index, low - (high - low) * 0.05, "D-RSI: " + str.tostring(rsi_daily, "#.##"),
color=color.blue, textcolor=color.white, size=size.small, style=label.style_label_up)
// Enhanced Table to show current status with alignment info
var table info_table = table.new(position.top_right, 2, 16, bgcolor=color.white, border_width=1)
if barstate.islast
table.cell(info_table, 0, 0, "Indicator", bgcolor=color.gray, text_color=color.white)
table.cell(info_table, 1, 0, "Value", bgcolor=color.gray, text_color=color.white)
table.cell(info_table, 0, 1, "Daily RSI", bgcolor=color.white)
table.cell(info_table, 1, 1, str.tostring(rsi_daily, "#.##"), bgcolor=color.white)
table.cell(info_table, 0, 2, "Weekly RSI", bgcolor=color.white)
table.cell(info_table, 1, 2, str.tostring(rsi_weekly, "#.##"), bgcolor=color.white)
table.cell(info_table, 0, 3, "200 EMA", bgcolor=color.white)
table.cell(info_table, 1, 3, str.tostring(ema_200, "#.##"), bgcolor=color.white)
table.cell(info_table, 0, 4, "Fast EMA", bgcolor=color.white)
table.cell(info_table, 1, 4, str.tostring(fast_ema, "#.##"), bgcolor=color.white)
table.cell(info_table, 0, 5, "Slow EMA", bgcolor=color.white)
table.cell(info_table, 1, 5, str.tostring(slow_ema, "#.##"), bgcolor=color.white)
table.cell(info_table, 0, 6, "EMA Alignment", bgcolor=color.white)
table.cell(info_table, 1, 6, str.tostring(ema_alignment_distance, "#.#") + " pips",
bgcolor=ema_alignment_ok ? color.green : color.red)
table.cell(info_table, 0, 7, "Price Proximity", bgcolor=color.white)
table.cell(info_table, 1, 7, str.tostring(price_ema_distance, "#.#") + " pips",
bgcolor=price_proximity_ok ? color.green : color.orange)
table.cell(info_table, 0, 8, "EMA Exit Level", bgcolor=color.white)
table.cell(info_table, 1, 8, str.tostring(ema_exit, "#.##"), bgcolor=color.white)
table.cell(info_table, 0, 9, "Total Position", bgcolor=color.white)
table.cell(info_table, 1, 9, strategy.position_size > 0 ? "Long" : "None",
bgcolor=strategy.position_size > 0 ? color.green : color.white)
table.cell(info_table, 0, 10, "Total Size", bgcolor=color.white)
table.cell(info_table, 1, 10, str.tostring(strategy.position_size, "#.####"), bgcolor=color.white)
table.cell(info_table, 0, 11, "Weekly Qty", bgcolor=color.white)
table.cell(info_table, 1, 11, str.tostring(weekly_position_qty, "#.####"),
bgcolor=weekly_position_qty > 0 ? color.green : color.white)
table.cell(info_table, 0, 12, "Daily Qty", bgcolor=color.white)
table.cell(info_table, 1, 12, str.tostring(daily_position_qty, "#.####"),
bgcolor=daily_position_qty > 0 ? color.blue : color.white)
table.cell(info_table, 0, 13, "EMA Distance Qty", bgcolor=color.white)
table.cell(info_table, 1, 13, str.tostring(ema_distance_position_qty, "#.####"),
bgcolor=ema_distance_position_qty > 0 ? color.purple : color.white)
table.cell(info_table, 0, 14, "Trade Counts", bgcolor=color.white)
table.cell(info_table, 1, 14, "W:" + str.tostring(weekly_trade_count) + " D:" + str.tostring(daily_trade_count) + " E:" + str.tostring(ema_distance_trade_count), bgcolor=color.white)
table.cell(info_table, 0, 15, "Trade Status", bgcolor=color.white)
table.cell(info_table, 1, 15, price_proximity_ok ? "Allowed" : "Blocked",
bgcolor=price_proximity_ok ? color.green : color.orange)