from flask import Flask, request, jsonify import yfinance as yf import pandas as pd import numpy as np import datetime import talib # Candlestick Pattern Detection Strategy def candlestick_pattern_strategy(data): open_ = data['open'] high = data['high'] low = data['low'] close = data['close'] # Bullish Patterns bullish_patterns = [ talib.CDLENGULFING(open_, high, low, close), talib.CDLHAMMER(open_, high, low, close), talib.CDLMORNINGSTAR(open_, high, low, close), talib.CDLPIERCING(open_, high, low, close), talib.CDLINVERTEDHAMMER(open_, high, low, close), talib.CDL3WHITESOLDIERS(open_, high, low, close) ] # Bearish Patterns bearish_patterns = [ talib.CDLENGULFING(open_, high, low, close), talib.CDLSHOOTINGSTAR(open_, high, low, close), talib.CDLEVENINGSTAR(open_, high, low, close), talib.CDLDARKCLOUDCOVER(open_, high, low, close), talib.CDLHANGINGMAN(open_, high, low, close), talib.CDL3BLACKCROWS(open_, high, low, close) ] # Neutral Patterns neutral_patterns = [ talib.CDLDOJI(open_, high, low, close), talib.CDLSPINNINGTOP(open_, high, low, close), talib.CDLLONGLEGGEDDOJI(open_, high, low, close), talib.CDLHIGHWAVE(open_, high, low, close) ] # Check Bullish for pattern in bullish_patterns: if pattern.iloc[-1] > 0: return "Bullish" # Check Bearish for pattern in bearish_patterns: if pattern.iloc[-1] < 0: return "Bearish" # Check Neutral for pattern in neutral_patterns: if pattern.iloc[-1] != 0: return "Neutral" return "Neutral" #first day high value is higher than the second day and third day should be higher than second day def three_bar_triangle_breakout(data): high = data['high'] low = data['low'] close = data['close'] open_ = data['open'] # Bullish entry condition ENTRYLONG = ( close.iloc[-1] > open_.iloc[-1] and close.iloc[-1] > close.iloc[-2] and close.iloc[-1] > high.iloc[-2] and low.iloc[-2] > low.iloc[-4] and low.iloc[-3] > low.iloc[-4] and high.iloc[-2] < high.iloc[-4] and high.iloc[-3] < high.iloc[-4] ) # Bearish entry condition ENTRYSHORT = ( close.iloc[-1] < open_.iloc[-1] and close.iloc[-1] < close.iloc[-2] and close.iloc[-1] < low.iloc[-2] and low.iloc[-2] > low.iloc[-4] and low.iloc[-3] > low.iloc[-4] and high.iloc[-2] < high.iloc[-4] and high.iloc[-3] < high.iloc[-4] ) if ENTRYLONG: return "Bullish" elif ENTRYSHORT: return "Bearish" else: return "Neutral" def hh_ll_price_action_strategy(data, lookback_days=5): data = data.tail(lookback_days) is_higher_high = True is_higher_low = True is_lower_high = True is_lower_low = True for i in range(1, len(data)): if data['high'].iloc[i] <= data['high'].iloc[i - 1]: is_higher_high = False if data['low'].iloc[i] <= data['low'].iloc[i - 1]: is_higher_low = False if data['high'].iloc[i] >= data['high'].iloc[i - 1]: is_lower_high = False if data['low'].iloc[i] >= data['low'].iloc[i - 1]: is_lower_low = False if is_higher_high and is_higher_low: return "Bullish" elif is_lower_high and is_lower_low: return "Bearish" else: return "Neutral" def fvg_strategy(data, lookback_days=5): data = data.tail(lookback_days) for i in range(2, len(data)): high_candle1 = data['high'].iloc[i - 2] low_candle1 = data['low'].iloc[i - 2] high_candle3 = data['high'].iloc[i] low_candle3 = data['low'].iloc[i] # Bullish FVG: Gap between high of candle 1 and low of candle 3 if low_candle3 > high_candle1: return "Bullish" # Bearish FVG: Gap between low of candle 1 and high of candle 3 if high_candle3 < low_candle1: return "Bearish" return "Neutral" def bos_strategy(data, lookback_days=10): data = data.tail(lookback_days) highs = data['high'].tolist() lows = data['low'].tolist() # Recent high/low recent_high = highs[-1] previous_high = max(highs[:-1]) # Highest in previous candles recent_low = lows[-1] previous_low = min(lows[:-1]) # Lowest in previous candles # Check for bullish BOS (new high formed) if recent_high > previous_high: return "Bullish" # Check for bearish BOS (new low formed) if recent_low < previous_low: return "Bearish" return "Neutral" def choch_strategy(data, lookback_period=14): data = data.copy() # Calculate recent rolling highs and lows data['recent_high'] = data['high'].rolling(window=lookback_period).max() data['recent_low'] = data['low'].rolling(window=lookback_period).min() # Check for Bullish or Bearish CHoCH using the most recent candle if (data['high'].iloc[-1] < data['high'].iloc[-2]) and (data['low'].iloc[-1] < data['recent_low'].iloc[-2]): return "Bearish" elif (data['low'].iloc[-1] > data['low'].iloc[-2]) and (data['high'].iloc[-1] > data['recent_high'].iloc[-2]): return "Bullish" return "Neutral" def order_block_strategy(data, lookback_days=2): data = data.tail(lookback_days) previous = data.iloc[-2] current = data.iloc[-1] # Bullish Order Block: last bearish candle followed by a strong bullish move if previous['close'] < previous['open'] and current['close'] > current['open'] and current['close'] > previous['high']: return "Bullish" # Bearish Order Block: last bullish candle followed by a strong bearish move elif previous['close'] > previous['open'] and current['close'] < current['open'] and current['close'] < previous['low']: return "Bearish" return "Neutral" # Main strategy function using Candlestick def priceaction_strategies(data): candlestick_signal = candlestick_pattern_strategy(data) hh_hl = hh_ll_price_action_strategy(data) triangle_breakout = three_bar_triangle_breakout(data) fvg = fvg_strategy(data) bos = bos_strategy(data) choch = choch_strategy(data) order_block = order_block_strategy(data) signals = { "Candlestick Pattern": candlestick_signal, "HH_HL_LL_LH" : hh_hl, "Triangle Breakout": triangle_breakout, "Fair Value Gap": fvg, "BOS": bos, "CHoCH": choch, "Order_Block": order_block } weights = { "Candlestick Pattern": 15, "HH_HL_LL_LH": 15, "Triangle Breakout": 15, "Fair Value Gap": 10, "BOS": 20, "CHoCH": 15, "Order_Block": 10 } 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 for Candlestick Strategy def get_priceaction_trade_signal(data): priceaction_signals, overallscore, final_signal = priceaction_strategies(data) return { "priceaction_signals": priceaction_signals, "priceaction_score": overallscore, "priceaction_final_signal": final_signal }