Untitled
unknown
plain_text
7 months ago
6.6 kB
6
Indexable
module Analyzers
class SupportResistanceAnalysis < Base
def analyze
{
primary_support: @current.support_level.to_f.round(4),
primary_resistance: @current.resistance_level.to_f.round(4),
fib_price_position: fib_price_position,
pivot_position: pivot_position,
volatility_impact: volatility_impact,
order_flow: @current.order_flow,
vwap_position_status: vwap_position_status,
market_breadth: @current.market_breadth,
breadth_impact: breadth_impact,
support_volume_confirmation: support_volume_confirmation?,
resistance_volume_confirmation: resistance_volume_confirmation?,
support_price_rejection: support_price_rejection?,
resistance_price_rejection: resistance_price_rejection?,
fib_support_confluence: fib_support_confluence?,
fib_resistance_confluence: fib_resistance_confluence?,
above_ema_8: above_ema_8?,
above_ema_20: above_ema_20?,
above_ema_50: above_ema_50?,
above_sma_20: above_sma_20?,
ema_8_sr_quality: ema_8_sr_quality?,
ema_20_sr_quality: ema_20_sr_quality?,
ema_50_sr_quality: ema_50_sr_quality?,
bollinger_support_near_lower: bollinger_support_near_lower?,
bollinger_resistance_near_upper: bollinger_resistance_near_upper?,
bollinger_squeeze: bollinger_squeeze?,
keltner_support_near_lower: keltner_support_near_lower?,
keltner_resistance_near_upper: keltner_resistance_near_upper?,
ichimoku_support_near_tenkan: ichimoku_support_near_tenkan?,
ichimoku_resistance_near_kijun: ichimoku_resistance_near_kijun?,
ichimoku_cloud_support: ichimoku_cloud_support?,
ichimoku_cloud_resistance: ichimoku_cloud_resistance?
}
end
private
def fib_price_position
return nil unless fib_levels_present?
if @current.close.to_f > @current.fibonacci_38_2.to_f
:above_38
elsif @current.close.to_f > @current.fibonacci_50.to_f
:between_38_50
elsif @current.close.to_f > @current.fibonacci_61_8.to_f
:between_50_61
else
:below_61
end
end
def pivot_position
return nil unless @candles.size >= 1
pivot = ((@candles[-1].high + @candles[-1].low + @candles[-1].close) / 3.0).to_f.round(4)
if @current.close > pivot + (@candles[-1].high - @candles[-1].low)
:above_r2
elsif @current.close > pivot
:above_pivot
else
:below_pivot
end
end
def volatility_impact
return nil unless @history.size >= 10
current_atr_percentile = calculate_percentile(@current.atr, @history.last(10).map(&:atr))
if current_atr_percentile > 75
:high_volatility_breakout_likely
elsif current_atr_percentile < 25
:low_volatility_breakout_unlikely
else
:neutral_volatility
end
end
def vwap_position_status
@current.close.to_f > @current.vwap.to_f ? :above : :below
end
def breadth_impact
case @current.market_breadth
when 'bullish_breadth' then :supports_breakout
when 'bearish_breadth' then :supports_breakdown
else :neutral_impact
end
end
def support_volume_confirmation?
@current.volume_at_support > @history.last(3).map(&:volume_at_support).average
end
def resistance_volume_confirmation?
@current.volume_at_resistance > @history.last(3).map(&:volume_at_resistance).average
end
def support_price_rejection?
@candles.size >= 2 && @candles[-1].low <= @current.support_level && @candles[-1].close > @current.support_level
end
def resistance_price_rejection?
@candles.size >= 2 && @candles[-1].high >= @current.resistance_level && @candles[-1].close < @current.resistance_level
end
def fib_support_confluence?
(@current.support_level - @current.fibonacci_38_2).abs < @current.atr * 0.1
end
def fib_resistance_confluence?
(@current.resistance_level - @current.fibonacci_61_8).abs < @current.atr * 0.1
end
def above_ema_8?
@current.close > @current.ema_8
end
def above_ema_20?
@current.close > @current.ema_20
end
def above_ema_50?
@current.close > @current.ema_50
end
def above_sma_20?
@current.close > @current.sma_20
end
def ema_8_sr_quality?
(@current.ema_8 - @current.support_level).abs < @current.atr * 0.5 ||
(@current.resistance_level - @current.ema_8).abs < @current.atr * 0.5
end
def ema_20_sr_quality?
(@current.ema_20 - @current.support_level).abs < @current.atr * 0.5 ||
(@current.resistance_level - @current.ema_20).abs < @current.atr * 0.5
end
def ema_50_sr_quality?
(@current.ema_50 - @current.support_level).abs < @current.atr * 0.5 ||
(@current.resistance_level - @current.ema_50).abs < @current.atr * 0.5
end
def bollinger_support_near_lower?
(@current.support_level - @current.bollinger_lower).abs < @current.atr * 0.5
end
def bollinger_resistance_near_upper?
(@current.resistance_level - @current.bollinger_upper).abs < @current.atr * 0.5
end
def bollinger_squeeze?
(@current.bollinger_upper - @current.bollinger_lower) < (@current.keltner_upper - @current.keltner_lower)
end
def keltner_support_near_lower?
(@current.support_level - @current.keltner_lower).abs < @current.atr * 0.5
end
def keltner_resistance_near_upper?
(@current.resistance_level - @current.keltner_upper).abs < @current.atr * 0.5
end
def ichimoku_support_near_tenkan?
(@current.support_level - @current.ichimoku_tenkan_sen).abs < @current.atr * 0.5
end
def ichimoku_resistance_near_kijun?
(@current.resistance_level - @current.ichimoku_kijun_sen).abs < @current.atr * 0.5
end
def ichimoku_cloud_support?
@current.close > @current.ichimoku_senkou_span_a &&
@current.close > @current.ichimoku_senkou_span_b
end
def ichimoku_cloud_resistance?
@current.close < @current.ichimoku_senkou_span_a &&
@current.close < @current.ichimoku_senkou_span_b
end
def fib_levels_present?
@current.fibonacci_38_2 && @current.fibonacci_50 && @current.fibonacci_61_8
end
def calculate_percentile(value, data)
return nil if data.empty?
sorted = data.sort
n = sorted.size
rank = sorted.bsearch_index { |x| x >= value } || n
(rank.to_f / n * 100).round(2)
end
end
endEditor is loading...
Leave a Comment