pytrade-backend / priceactionstrategies.py
Oviya
Track binaries via Git LFS (analysedata.xlsx, TA_Lib wheel)
66dc1bf
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
}