File size: 7,056 Bytes
66dc1bf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
import yfinance as yf
import pandas as pd
import numpy as np
import datetime
import talib


# Calculate Support and Resistance using Pivot Points
def calculate_support_resistance(data):
    # Pivot Point Calculation
    data['Pivot'] = (data['high'] + data['low'] + data['close']) / 3
    # Support and Resistance Calculations
    data['Support1'] = (2 * data['Pivot']) - data['high']
    data['Resistance1'] = (2 * data['Pivot']) - data['low']
   
    return data

#Strategy 1: Reversal strategy - find the difference between close and support/resistance and find the tolerance value based on ATR if it is less than tolernace value and check the candlestick pattern - based on the return bullish/bearish/neutral
def detect_reversal(df, support, resistance):
    df['Signal'] = 'Neutral'  # Default is neutral
    
    close_prices = df['close'].to_numpy().flatten()
    high_prices = df['high'].to_numpy().flatten()
    low_prices = df['low'].to_numpy().flatten()
    open_prices = df['open'].to_numpy().flatten()
    
    # Use common reversal patterns
    hammer = talib.CDLHAMMER(open_prices, high_prices, low_prices, close_prices)
    engulfing = talib.CDLENGULFING(open_prices, high_prices, low_prices, close_prices)
    shooting_star = talib.CDLSHOOTINGSTAR(open_prices, high_prices, low_prices, close_prices)
    doji = talib.CDLDOJI(open_prices, high_prices, low_prices, close_prices)
    morning_star = talib.CDLMORNINGSTAR(open_prices, high_prices, low_prices, close_prices)
    evening_star = talib.CDLEVENINGSTAR(open_prices, high_prices, low_prices, close_prices)
    piercing_line = talib.CDLPIERCING(open_prices, high_prices, low_prices, close_prices)
    harami = talib.CDLHARAMI(open_prices, high_prices, low_prices, close_prices)
    df['ATR'] = talib.ATR(high_prices, low_prices, close_prices, timeperiod=14)
    tolerance = df['ATR'].iloc[-1] * 2  
    for i in range(1, len(df)):
        close = close_prices[i]
        
        # Detect Bullish Reversal
        if abs(close - support[i]) <= tolerance:
            if hammer[i] > 0 or engulfing[i] > 0 or doji[i] > 0 or morning_star[i] > 0 or piercing_line[i] > 0 or harami[i] > 0:
                df.loc[df.index[i], 'Signal'] = 'Bullish'
        
        # Detect Bearish Reversal
        if abs(close - resistance[i]) <= tolerance:
            if shooting_star[i] < 0 or engulfing[i] < 0 or doji[i] < 0 or evening_star[i] < 0 or piercing_line[i] < 0 or harami[i] < 0:
                df.loc[df.index[i], 'Signal'] = 'Bearish'

    return df


# Strategy 2: Breakout Trading - the previous day should be above to resistance/support and break the support and resistance and crossed
def detect_breakouts(df):    
    support_level = df['Support1'].iloc[-1]
    resistance_level = df['Resistance1'].iloc[-1]    
    
    if df['close'].iloc[-1] > resistance_level and df['close'].iloc[-2] <= resistance_level:
       return "Bullish"

    elif df['close'].iloc[-1] < resistance_level and df['close'].iloc[-2] >= resistance_level:
       return "Bearish"

    elif df['close'].iloc[-1] > support_level and df['close'].iloc[-2] <= support_level:
       return "Bullish"

    elif df['close'].iloc[-1] < support_level and df['close'].iloc[-2] >= support_level:
       return "Bearish"

    return "Neutral"

# Strategy 3: Flip Zone 
def detect_flip_zone(df):
   
    support_level = df['Support1'].iloc[-1]
    resistance_level = df['Resistance1'].iloc[-1]

    if df['close'].iloc[-3] < support_level and df['close'].iloc[-2] >= support_level and df['close'].iloc[-1] > support_level:
      return "Bullish"

    elif df['close'].iloc[-3] > support_level and df['close'].iloc[-2] <= support_level and df['close'].iloc[-1] < support_level:
      return "Bearish"

    elif df['close'].iloc[-3] < resistance_level and df['close'].iloc[-2] >= resistance_level and df['close'].iloc[-1] > resistance_level:
      return "Bullish"

    elif df['close'].iloc[-3] > resistance_level and df['close'].iloc[-2] <= resistance_level and df['close'].iloc[-1] < resistance_level:
      return "Bearish"       
   
    
    return "Neutral"

# Strategy 4: SR RETEST - bounceup and bouncedown
def detect_sr_retest(df):
   
    support_level = df['Support1'].iloc[-1]
    resistance_level = df['Resistance1'].iloc[-1]

    # Retest Strategy: Bullish Retest - Price breaks above resistance and then tests it as support
    if df['close'].iloc[-4] < resistance_level and df['close'].iloc[-3] >= resistance_level and df['close'].iloc[-2] < df['close'].iloc[-3] and df['close'].iloc[-2] < df['close'].iloc[-1]:
        return "Bearish"  

    elif df['close'].iloc[-4] > resistance_level and df['close'].iloc[-3] <= resistance_level and df['close'].iloc[-2] > df['close'].iloc[-3] and df['close'].iloc[-2] > df['close'].iloc[-1]:
        return "Bullish"

    elif df['close'].iloc[-4] < support_level and df['close'].iloc[-3] >= support_level and df['close'].iloc[-2] < df['close'].iloc[-3] and df['close'].iloc[-2] < df['close'].iloc[-1]:
        return "Bullish"  

    elif df['close'].iloc[-4] > support_level and df['close'].iloc[-3] <= support_level and df['close'].iloc[-2] > df['close'].iloc[-3] and df['close'].iloc[-2] > df['close'].iloc[-1]:
        return "Bearish"     
   
    
    return "Neutral"


# Final Signal Calculation
def support_resistance_strategy(data):
   

    # Calculate Support and Resistance levels using Pivot Points
    data = calculate_support_resistance(data)
    # Calculate the market trend based on price and support/resistance
    breakout = detect_breakouts(data)
    reversal = detect_reversal(data, data['Support1'].to_numpy(), data['Resistance1'].to_numpy())
    flip = detect_flip_zone(data)
    
    sr_retest = detect_sr_retest(data)
    

    # Weight the signals for a final decision (example weighting)
    signals = {
        "Support1": round(data['Support1'].iloc[-1], 2),
        "Resistance1": round(data['Resistance1'].iloc[-1], 2),
        "Breakout": breakout,
        "Reversal": reversal['Signal'].iloc[-1],  
        "Flip": flip,        
        "SR_Retest":sr_retest       
        
    }

    weights = {
        "Breakout": 35,
        "Reversal": 25,  
        "Flip": 20,
        "SR_Retest":20       
    }

    total_score = 0
    for strategy, weight in weights.items():
        signal = signals[strategy]
        if signal == "Bullish":
            total_score += weight
        elif signal == "Neutral":
            total_score += weight * 0.5

    overall_percentage = round((total_score / sum(weights.values())) * 100, 2)

    if overall_percentage >= 60:
        final_signal = "Buy"
    elif overall_percentage <= 40:
        final_signal = "DBuy"
    else:
        final_signal = "Neutral"

    return signals, overall_percentage, final_signal

# API-style function
def get_support_resistance_signal(data):
    sr_signals, overallscore, final_signal = support_resistance_strategy(data)
    return {
        "support_resistance_signals": sr_signals,
        "sr_score": overallscore,
        "sr_final_signal": final_signal
    }