Spaces:
Running
Running
File size: 4,198 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 |
from flask import Flask, request, jsonify
import yfinance as yf
import pandas as pd
import numpy as np
import talib
import datetime
# Bollinger Band Calculation
def calculate_bollinger(data, period=20, stddev=2):
close = data['close']
upper, middle, lower = talib.BBANDS(close, timeperiod=period, nbdevup=stddev, nbdevdn=stddev, matype=0)
return upper, middle, lower
#BB Squeeze breakout/fade after low volatility
def detect_bb_squeeze(close, upper, lower, middle, lookback=20, perc=20):
bandwidth = (upper - lower) / middle
# 20th percentile over the lookback window
thresh = np.percentile(bandwidth.iloc[-lookback:], perc)
if bandwidth.iloc[-1] < thresh:
return "Neutral"
# otherwise fall back to a breakout rule
if close.iloc[-1] > upper.iloc[-1]:
return "Bullish"
elif close.iloc[-1] < lower.iloc[-1]:
return "Bearish"
return "Neutral"
# BB Breakout Detection
def detect_bb_breakout(close, upper, lower):
if close.iloc[-1] > upper.iloc[-1]:
return "Bullish"
elif close.iloc[-1] < lower.iloc[-1]:
return "Bearish"
return "Neutral"
# BB Breakout Reversal
def detect_bb_breakout_reversal(data, upper, lower, middle, lookahead=3):
i = len(data) - lookahead - 1
if i < 0:
return "Neutral"
row = data.iloc[i]
# Bullish Reversal
if row['close'] > upper.iloc[i]:
for j in range(1, lookahead + 1):
next_row = data.iloc[i + j]
if next_row['close'] < upper.iloc[i + j] and next_row['close'] > middle.iloc[i + j]:
return "Bullish"
# Bearish Reversal
elif row['close'] < lower.iloc[i]:
for j in range(1, lookahead + 1):
next_row = data.iloc[i + j]
if next_row['close'] > lower.iloc[i + j] and next_row['close'] < middle.iloc[i + j]:
return "Bearish"
return "Neutral"
# Middle Band Pullback
def detect_middle_band_pullback(close, middle, upper, lower, threshold=0.10, trend_lookback=3):
band_width = upper.iloc[-1] - lower.iloc[-1]
if abs(close.iloc[-1] - middle.iloc[-1]) < band_width * threshold:
trend_above = all(close.iloc[-i] > middle.iloc[-i] for i in range(2, 2 + trend_lookback))
trend_below = all(close.iloc[-i] < middle.iloc[-i] for i in range(2, 2 + trend_lookback))
if trend_above:
return "Bullish"
elif trend_below:
return "Bearish"
return "Neutral"
# Master strategy function
def bollinger_strategies(data):
upper, middle, lower = calculate_bollinger(data)
signals = {
"UpperBand": round(upper.iloc[-1], 2),
"MiddleBand": round(middle.iloc[-1], 2),
"LowerBand": round(lower.iloc[-1], 2),
"BB Squeeze": detect_bb_squeeze(data['close'], upper, lower, middle),
"BB Breakout": detect_bb_breakout(data['close'], upper, lower),
"BB Breakout Reversal": detect_bb_breakout_reversal(data, upper, lower, middle),
"Middle Band Pullback": detect_middle_band_pullback(data['close'], middle, upper, lower)
}
weights = {
"BB Squeeze": 30,
"BB Breakout": 25,
"BB Breakout Reversal": 25,
"Middle Band Pullback": 20
}
total_score = 0
for strategy, weight in weights.items():
signal = signals[strategy]
if "Bullish" in signal or "Breakout Up" in signal or "Squeeze" in signal or "Pullback" in signal:
total_score += weight
elif "Neutral" in signal or "No Breakout" in signal:
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_bollinger_trade_signal(data):
bb_signals, overall_score, final_signal = bollinger_strategies(data)
return {
"bollinger_signals": bb_signals,
"bollinger_score": overall_score,
"bollinger_final_signal": final_signal
}
|