pytrade-backend / atrstrategies.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
# Calculate ATR values
def calculate_atr(data):
atr = talib.ATR(data['high'], data['low'], data['close'], timeperiod=14)
return atr
# ATR Breakout Strategy (Price crossing ATR threshold)
def atr_breakout_strategy(data, atr, multiplier=2):
latest_close = data['close'].iloc[-2]
previous_close = data['close'].iloc[-1]
latest_atr = atr.iloc[-2]
threshold_up = latest_close + (multiplier * latest_atr)
threshold_down = latest_close - (multiplier * latest_atr)
# Bullish breakout (price moves above ATR threshold)
if previous_close > threshold_up:
return "Bullish"
# Bearish breakout (price moves below ATR threshold)
elif previous_close < threshold_down:
return "Bearish"
# No breakout, neutral
else:
return "Neutral"
def calculate_dynamic_threshold(atr, period=14):
atr_change = atr.pct_change(periods=period)
atr_std = atr_change.std()
dynamic_threshold = 2 * atr_std
return dynamic_threshold
# ATR Expansion Strategy (Confirming trend continuation)
def atr_expansion_strategy(data, atr, period=14, days_to_check=5):
dynamicthreshold = calculate_dynamic_threshold(atr, period)
atr_last = atr.iloc[-days_to_check:]
atr_expansion = atr_last[-1] > atr_last.mean() + dynamicthreshold
if atr_expansion:
if data['close'].iloc[-1] > data['close'].iloc[-2]:
return "Bullish"
elif data['close'].iloc[-1] < data['close'].iloc[-2]:
return "Bearish"
else:
return "Neutral"
return "Neutral"
# ATR Squeeze/Compression Strategy (Confirming trend continuation)
def atr_squeeze_strategy(data, atr, period=14, days_to_check=5):
dynamicthreshold = calculate_dynamic_threshold(atr, period)
atr_last = atr.iloc[-days_to_check:]
atr_compression = atr_last[-1] < atr_last.mean() - dynamicthreshold
resistance = data['high'].iloc[-days_to_check:].max()
support = data['low'].iloc[-days_to_check:].min()
if atr_compression:
if data['close'].iloc[-1] > resistance:
return "Bullish"
elif data['close'].iloc[-1] < support:
return "Bearish"
else:
return "Neutral"
return "Neutral"
# ATR Trend Reversal Strategy (ATR rising during price reversal)
def atr_trend_reversal_strategy(atr, price, days=5):
# Look at the change in price and ATR
price_diff = price.iloc[-1] - price.iloc[-days]
atr_diff = atr.iloc[-1] - atr.iloc[-days]
# If price is reversing (uptrend to downtrend or vice versa), and ATR is increasing
if price_diff > 0 and atr_diff > 0:
return "Bullish"
elif price_diff < 0 and atr_diff > 0:
return "Bearish"
return "Neutral"
# Main strategy function using ATR strategy
def atr_strategies(data):
atr = calculate_atr(data)
atr_breakout = atr_breakout_strategy(data, atr)
atr_expansion = atr_expansion_strategy(data,atr)
atr_squeeze = atr_squeeze_strategy(data,atr)
atr_trend_reversal = atr_trend_reversal_strategy(atr, data['close'])
# Collect signals
signals = {
"ATR": round(atr.iloc[-1], 2),
"ATR Breakout": atr_breakout,
"ATR Expansion": atr_expansion,
"ATR Squeeze": atr_squeeze,
"ATR Trend Reversal": atr_trend_reversal
}
weights = {
"ATR Breakout": 45,
"ATR Expansion": 15,
"ATR Squeeze": 15,
"ATR Trend Reversal": 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,atr
# API-style function to fetch ATR signals
def get_atr_trade_signal(data):
atr_signals, overallscore, final_signal,atr = atr_strategies(data)
atr_series = pd.Series(atr, index=data.index).dropna().tail(100)
atr_series.index = atr_series.index.strftime('%Y-%m-%d')
return {
"atr_signals": atr_signals,
"atr_score": overallscore,
"atr_final_signal": final_signal,
"atr_values": atr_series.round(2).to_dict()
}