File size: 4,530 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
from flask import Flask, request, jsonify
import yfinance as yf
import pandas as pd
import numpy as np
import talib
import datetime



# Calculate EMA values
def calculate_ema(data, short_period=5, medium_period=20, long_period=50):
    close_prices = data['close']
    ema_short = talib.EMA(close_prices, timeperiod=short_period)
    ema_medium = talib.EMA(close_prices, timeperiod=medium_period)
    ema_long = talib.EMA(close_prices, timeperiod=long_period)
    return ema_short,ema_medium, ema_long

def detect_ema_crossover(ema20, ema50):    
    
    for i in range(len(ema20) - 1):
        older_ema20 = ema20[i]
        newer_ema20 = ema20[i + 1]
        older_ema50 = ema50[i]
        newer_ema50 = ema50[i + 1]
        
        # Bullish crossover - EMA 20 above EMA 50
        if older_ema20 <= older_ema50 and newer_ema20 > newer_ema50:
            return "Bullish"
        # Bearish crossover EMA 20 below EMA 50
        elif older_ema20 >= older_ema50 and newer_ema20 < newer_ema50:
            return "Bearish"
    
    return "Neutral"


def detect_ema_price_crossover(ema20, price, days=5):
    bullish_days = 0
    bearish_days = 0

    # Check the last N days
    for i in range(-days, 0):
        if price[i] > ema20[i]:
            bullish_days += 1
        elif price[i] < ema20[i]:
            bearish_days += 1

    # Final decision
    if bullish_days == days:
        return "Bullish"
    elif bearish_days == days:
        return "Bearish"
    else:
        return "Neutral"


def get_ema_average_slope_signal(ema_series, days=5, threshold=0.1):    

    total_slope = 0

    # Calculate slope for each of the last `days`
    for i in range(-days, -1):
        slope = ema_series[i + 1] - ema_series[i]
        total_slope += slope

    # Average slope
    avg_slope = total_slope / (days - 1)

    if avg_slope > threshold:
        return "Bullish"
    elif avg_slope < -threshold:
        return "Bearish"
    else:
        return "Neutral"

def triple_ema_strategy(ema_short, ema_medium, ema_long):
    
    if ema_short > ema_medium and ema_short > ema_long:
        return "Bullish"
    
    # Bearish condition: Short-term EMA crosses below medium and long-term EMAs
    elif ema_short < ema_medium and ema_short < ema_long:
        return "Bearish"
    
    # Neutral condition: EMAs are not aligned
    else:
        return "Neutral"


# Main strategy function using EMA crossover
def ema_strategies(data):
   
    ema5, ema_20, ema_50 = calculate_ema(data, short_period=5, medium_period=20, long_period=50)
    
    signals = {
        "EMA 20": round(ema_20.iloc[-1], 2),
        "EMA 50": round(ema_50.iloc[-1], 2),
        "EMA Crossover": detect_ema_crossover(ema_20[-5:], ema_50[-5:]),
        "EMA Price Crossover": detect_ema_price_crossover(ema_20[-5:], data['close'][-5:]),
        "EMA Slope": get_ema_average_slope_signal(ema_20[-5:]),
        "Triple EMA": triple_ema_strategy(ema5.iloc[-1], ema_20.iloc[-1], ema_50.iloc[-1])
    }

    weights = {
        "EMA Crossover": 30,
        "EMA Price Crossover": 25,
        "EMA Slope": 20,
        "Triple EMA": 25
    }

    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,ema5, ema_20, ema_50

# API-style function
def get_ema_trade_signal(data):
    ema_signals, overallscore, final_signal,ema5, ema_20, ema_50 = ema_strategies(data)

    ema5_series = pd.Series(ema5, index=data.index).dropna().tail(100)
    ema5_series.index = ema5_series.index.strftime('%Y-%m-%d')
    ema_20_series = pd.Series(ema_20, index=data.index).dropna().tail(100)
    ema_20_series.index = ema_20_series.index.strftime('%Y-%m-%d')
    ema_50_series = pd.Series(ema_50, index=data.index).dropna().tail(100)
    ema_50_series.index = ema_50_series.index.strftime('%Y-%m-%d')
    return {
        "ema_signals": ema_signals,
        "ema_score": overallscore,
        "ema_final_signal": final_signal,
        "EMA_5": ema5_series.round(2).to_dict(),
        "EMA_20": ema_20_series.round(2).to_dict(),
        "EMA_50": ema_50_series.round(2).to_dict()

    }