Spaces:
Runtime error
Runtime error
Upload 4 files
Browse files- README.md +15 -9
- app.py +328 -0
- fibonacci_price_targets.ipynb +0 -0
- requirements.txt +10 -0
README.md
CHANGED
@@ -1,13 +1,19 @@
|
|
1 |
---
|
2 |
-
title: Fibonacci Price Target
|
3 |
-
emoji: π
|
4 |
-
colorFrom: blue
|
5 |
-
colorTo: green
|
6 |
-
sdk: gradio
|
7 |
-
sdk_version: 4.19.1
|
8 |
-
app_file: app.py
|
9 |
-
pinned: false
|
10 |
license: apache-2.0
|
|
|
|
|
|
|
|
|
|
|
11 |
---
|
|
|
|
|
|
|
|
|
|
|
12 |
|
13 |
-
|
|
|
|
|
|
|
|
|
|
1 |
---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
license: apache-2.0
|
3 |
+
title: Fibonacci Price Targets
|
4 |
+
sdk: gradio
|
5 |
+
emoji: π
|
6 |
+
colorFrom: green
|
7 |
+
colorTo: purple
|
8 |
---
|
9 |
+
# Fibonacci Price Targets
|
10 |
+
This repository contains a Python script that calculates potential price targets for financial assets based on Fibonacci retracement and extension levels.
|
11 |
+
|
12 |
+
## Key Features
|
13 |
+
* Flexible Inputs: The script allows users to specify the following:
|
14 |
|
15 |
+
* Asset's historical price data (e.g., OHLC data in a CSV format)
|
16 |
+
* The starting and ending points for the Fibonacci calculation
|
17 |
+
* Fibonacci retracement levels (e.g., 0.236, 0.382, 0.5, 0.618, 0.786)
|
18 |
+
* Fibonacci extension levels (e.g., 1.0, 1.382, 1.618, 2.618)
|
19 |
+
* Clear Visualization: The script generates a plot of the asset's price chart with the calculated Fibonacci levels overlaid, aiding in visual analysis.
|
app.py
ADDED
@@ -0,0 +1,328 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import requests
|
3 |
+
import pandas as pd
|
4 |
+
import math
|
5 |
+
import os
|
6 |
+
import matplotlib.pyplot as plt
|
7 |
+
from alpha_vantage.timeseries import TimeSeries
|
8 |
+
|
9 |
+
#symbol = 'NRDS'
|
10 |
+
#target_profit_price = 9.34
|
11 |
+
#interval = 'daily' # Specify the desired interval ('intraday', 'daily', 'weekly')
|
12 |
+
#start_date = '2023-01-01' # Specify the start date for historical data
|
13 |
+
#buy_signal = False
|
14 |
+
|
15 |
+
def get_current_stock_price(api_key, symbol):
|
16 |
+
url = f"https://finnhub.io/api/v1/quote?symbol={symbol}&token={api_key}"
|
17 |
+
response = requests.get(url)
|
18 |
+
print(response)
|
19 |
+
data = response.json()
|
20 |
+
return data['c'] # Current price
|
21 |
+
|
22 |
+
finnhub_api_key=os.environ['FINHUB_API_KEY']
|
23 |
+
|
24 |
+
|
25 |
+
def calculate_fibonacci_retracements(high, low):
|
26 |
+
# Adjust the Fibonacci ratios as needed
|
27 |
+
fibonacci_ratios = [0.236, 0.382, 0.5, 0.618, 0.786] # Example adjusted ratios
|
28 |
+
fibonacci_retracements = []
|
29 |
+
for i in range(40):
|
30 |
+
fibonacci_level = round((i+1)/(len(fibonacci_ratios)+1), 2) * fibonacci_ratios[i % len(fibonacci_ratios)]
|
31 |
+
fibonacci_retracements.append(fibonacci_level)
|
32 |
+
fibonacci_levels = {}
|
33 |
+
for r in fibonacci_retracements:
|
34 |
+
fibonacci_levels[f"{r * 100:.0f}%"] = round((low + high) - ((high - low) * r), 2)
|
35 |
+
return fibonacci_levels
|
36 |
+
|
37 |
+
from alpha_vantage.timeseries import TimeSeries
|
38 |
+
|
39 |
+
def fetch_historical_data(symbol, interval, output_size='compact', start_date=None):
|
40 |
+
# Replace with your AlphaVantage API key
|
41 |
+
api_key = os.environ['ALPHA_VANTAGE_API_KEY']
|
42 |
+
|
43 |
+
# Initialize the TimeSeries object
|
44 |
+
ts = TimeSeries(key=api_key, output_format='json')
|
45 |
+
|
46 |
+
# Map interval to the corresponding AlphaVantage function name
|
47 |
+
interval_mapping = {
|
48 |
+
'intraday': 'TIME_SERIES_INTRADAY',
|
49 |
+
'daily': 'TIME_SERIES_DAILY',
|
50 |
+
'weekly': 'TIME_SERIES_WEEKLY'
|
51 |
+
}
|
52 |
+
|
53 |
+
if interval not in interval_mapping:
|
54 |
+
raise ValueError("Invalid interval. Supported intervals: 'intraday', 'daily', 'weekly'")
|
55 |
+
|
56 |
+
# Define the function name based on the interval
|
57 |
+
function_name = interval_mapping[interval]
|
58 |
+
|
59 |
+
if interval == 'intraday':
|
60 |
+
# Adjust the interval as needed
|
61 |
+
interval = '5min'
|
62 |
+
|
63 |
+
# Fetch historical data
|
64 |
+
if interval == 'daily':
|
65 |
+
historical_data, meta_data = ts.get_daily_adjusted(symbol=symbol, outputsize=output_size)
|
66 |
+
elif interval == 'weekly':
|
67 |
+
historical_data, meta_data = ts.get_weekly_adjusted(symbol=symbol)
|
68 |
+
else:
|
69 |
+
# For intraday, you can specify the interval (e.g., '5min')
|
70 |
+
historical_data, meta_data = ts.get_intraday(symbol=symbol, interval=interval, outputsize=output_size)
|
71 |
+
|
72 |
+
return historical_data
|
73 |
+
|
74 |
+
import numpy as np
|
75 |
+
|
76 |
+
def calculate_support_resistance_levels(symbol, interval='weekly', output_size='compact'):
|
77 |
+
# Fetch historical price data from AlphaVantage
|
78 |
+
historical_data = fetch_historical_data(symbol, interval, output_size)
|
79 |
+
|
80 |
+
# Extract closing prices from historical data
|
81 |
+
closing_prices = [float(data['4. close']) for data in historical_data.values()]
|
82 |
+
print("Display historyical data")
|
83 |
+
print(closing_prices)
|
84 |
+
|
85 |
+
# Calculate moving averages (e.g., 50-day and 200-day)
|
86 |
+
moving_average_50 = np.mean(closing_prices[-50:])
|
87 |
+
moving_average_200 = np.mean(closing_prices[-200:])
|
88 |
+
|
89 |
+
# Calculate support and resistance levels
|
90 |
+
# You can customize your logic for defining these levels based on moving averages
|
91 |
+
# For example, support could be defined as the 50-day moving average, and resistance could be the 200-day moving average
|
92 |
+
support_level = moving_average_50
|
93 |
+
resistance_level = moving_average_200
|
94 |
+
|
95 |
+
return support_level, resistance_level
|
96 |
+
|
97 |
+
def calculate_entry_exit_points(symbol, target_profit_price, risk_percentage, account_balance, start_date, buy_signal_str):
|
98 |
+
# Convert string inputs to correct data types
|
99 |
+
print("Debugging information:")
|
100 |
+
|
101 |
+
print("target_profit_price:", target_profit_price)
|
102 |
+
print("risk_percentage:", risk_percentage)
|
103 |
+
print("account_balance:", account_balance)
|
104 |
+
|
105 |
+
current_price = get_current_stock_price(finnhub_api_key, symbol)
|
106 |
+
print("current_price:", current_price)
|
107 |
+
target_profit_price = float(target_profit_price)
|
108 |
+
risk_percentage = float(risk_percentage)
|
109 |
+
account_balance = float(account_balance)
|
110 |
+
buy_signal = buy_signal_str == "Buy"
|
111 |
+
print("buy_signal:", buy_signal)
|
112 |
+
|
113 |
+
|
114 |
+
|
115 |
+
# Fetch swing high and swing low using symbol, interval, and start date
|
116 |
+
swing_high, swing_low = get_swing_high_low(symbol, 'weekly', start_date)
|
117 |
+
|
118 |
+
# Calculate Fibonacci levels
|
119 |
+
fibonacci_levels = calculate_fibonacci_retracements(swing_high, swing_low)
|
120 |
+
|
121 |
+
# Calculate support and resistance levels
|
122 |
+
support_level, resistance_level = calculate_support_resistance_levels(symbol, 'weekly', start_date)
|
123 |
+
|
124 |
+
# Calculate entry and stop loss based on support and resistance
|
125 |
+
entry_point, stop_loss = calculate_entry_stop_loss(support_level, resistance_level, buy_signal)
|
126 |
+
|
127 |
+
# Calculate position size based on risk percentage and account balance
|
128 |
+
position_size = (risk_percentage / 100) * account_balance
|
129 |
+
|
130 |
+
# Calculate take profit based on Fibonacci levels and target price
|
131 |
+
take_profit, closest_levels = calculate_take_profit(target_profit_price, fibonacci_levels, buy_signal)
|
132 |
+
|
133 |
+
# Calculate profit in dollars for take profit and stop loss
|
134 |
+
if buy_signal:
|
135 |
+
profit_take_profit = (take_profit - entry_point) * position_size
|
136 |
+
profit_stop_loss = (entry_point - stop_loss) * position_size
|
137 |
+
else:
|
138 |
+
profit_take_profit = (entry_point - take_profit) * position_size
|
139 |
+
profit_stop_loss = (stop_loss - entry_point) * position_size
|
140 |
+
|
141 |
+
# Determine buy/sell flag
|
142 |
+
buy_sell_flag = "Buy" if buy_signal else "Sell"
|
143 |
+
|
144 |
+
return {
|
145 |
+
'Ticker': symbol,
|
146 |
+
'entry': entry_point,
|
147 |
+
'stop_loss': stop_loss,
|
148 |
+
'take_profit': take_profit,
|
149 |
+
'position_size': position_size,
|
150 |
+
'profit_take_profit': profit_take_profit,
|
151 |
+
'profit_stop_loss': profit_stop_loss,
|
152 |
+
'fibonacci_levels': fibonacci_levels,
|
153 |
+
'closest_levels': closest_levels,
|
154 |
+
'buy_sell_flag': buy_sell_flag
|
155 |
+
}
|
156 |
+
|
157 |
+
# Note: You would also need to adjust or create the calculate_profit function to handle profit calculation.
|
158 |
+
|
159 |
+
def calculate_entry_stop_loss(support_level, resistance_level, buy_signal):
|
160 |
+
# Calculate entry and stop loss based on support and resistance
|
161 |
+
if buy_signal:
|
162 |
+
entry_point = support_level
|
163 |
+
stop_loss = entry_point - (entry_point * 0.02) # Adjust the percentage as needed
|
164 |
+
else:
|
165 |
+
entry_point = resistance_level
|
166 |
+
stop_loss = entry_point + (entry_point * 0.02) # Adjust the percentage as needed
|
167 |
+
return entry_point, stop_loss
|
168 |
+
|
169 |
+
def calculate_take_profit(target_price, fibonacci_levels, buy_signal):
|
170 |
+
# Calculate take profit based on Fibonacci levels and target price
|
171 |
+
if buy_signal:
|
172 |
+
closest_levels = {k: v for k, v in fibonacci_levels.items() if v > target_price}
|
173 |
+
else:
|
174 |
+
closest_levels = {k: v for k, v in fibonacci_levels.items() if v < target_price}
|
175 |
+
|
176 |
+
take_profit_fibonacci_level = max(closest_levels.keys())
|
177 |
+
take_profit = closest_levels[take_profit_fibonacci_level]
|
178 |
+
|
179 |
+
return take_profit, closest_levels
|
180 |
+
|
181 |
+
def get_swing_high_low(symbol, interval, start_date):
|
182 |
+
print(symbol, interval, start_date)
|
183 |
+
# Fetch historical price data from AlphaVantage
|
184 |
+
historical_data = fetch_historical_data(symbol,interval, start_date=start_date)
|
185 |
+
print("prining historical data")
|
186 |
+
print(historical_data)
|
187 |
+
|
188 |
+
# Initialize variables to store swing high and swing low prices
|
189 |
+
swing_high = None
|
190 |
+
swing_low = None
|
191 |
+
|
192 |
+
# Iterate through historical data to find swing high and swing low
|
193 |
+
for date, price_data in historical_data.items():
|
194 |
+
high_price = float(price_data['2. high'])
|
195 |
+
low_price = float(price_data['3. low'])
|
196 |
+
|
197 |
+
if swing_high is None or high_price > swing_high:
|
198 |
+
swing_high = high_price
|
199 |
+
|
200 |
+
if swing_low is None or low_price < swing_low:
|
201 |
+
swing_low = low_price
|
202 |
+
|
203 |
+
return swing_high, swing_low
|
204 |
+
|
205 |
+
|
206 |
+
import gradio as gr
|
207 |
+
|
208 |
+
def interface_wrapper(symbol, target_profit_price, risk_percentage, account_balance, start_date, buy_signal):
|
209 |
+
# Your function logic here
|
210 |
+
|
211 |
+
# Dummy return for demonstration purposes
|
212 |
+
return {
|
213 |
+
"Entry Point": 100,
|
214 |
+
"Stop Loss": 90,
|
215 |
+
"Take Profit": 110,
|
216 |
+
"Position Size": 1000,
|
217 |
+
"Profit (Take Profit)": 100,
|
218 |
+
"Profit (Stop Loss)": -100,
|
219 |
+
"Fibonacci Levels": {"38.2%": 95, "61.8%": 105},
|
220 |
+
"Buy/Sell Flag": buy_signal
|
221 |
+
}
|
222 |
+
|
223 |
+
# Ensure inputs to Gradio interface are in the correct order and use the correct components
|
224 |
+
demo = gr.Interface(
|
225 |
+
fn=calculate_entry_exit_points,
|
226 |
+
inputs=[
|
227 |
+
gr.Textbox(label="Stock Symbol"), # symbol
|
228 |
+
gr.Number(label="Target Profit Price"), # target_profit_price
|
229 |
+
gr.Slider(label="Risk Percentage", minimum=0, maximum=100, step=0.1), # risk_percentage, with default at 2%
|
230 |
+
gr.Number(label="Account Balance"), # account_balance, with default
|
231 |
+
gr.Textbox(label="Start Date", placeholder="YYYY-MM-DD"), # start_date, with default
|
232 |
+
gr.Radio(choices=["Buy", "Sell"], label="Buy/Sell Signal") # buy_signal, with default
|
233 |
+
],
|
234 |
+
outputs=gr.JSON(label="Results"),
|
235 |
+
description="Enter the necessary information to calculate entry and exit points for stock trading."
|
236 |
+
)
|
237 |
+
|
238 |
+
demo.launch(share=True) # share=True to create a public link
|
239 |
+
|
240 |
+
|
241 |
+
def plot_trade(entry, stop_loss, take_profit, fibonacci_json):
|
242 |
+
# Parse the Fibonacci levels from JSON
|
243 |
+
fibonacci_levels = json.loads(fibonacci_json)
|
244 |
+
|
245 |
+
# Prepare data for plotting
|
246 |
+
fib_levels = list(fibonacci_levels.values())
|
247 |
+
fib_labels = list(fibonacci_levels.keys())
|
248 |
+
|
249 |
+
# Initialize the plot
|
250 |
+
plt.figure(figsize=(10, 6))
|
251 |
+
plt.title("Trade Setup with Fibonacci Levels")
|
252 |
+
|
253 |
+
# Plot Fibonacci levels
|
254 |
+
for i, level in enumerate(fib_levels):
|
255 |
+
plt.axhline(y=level, linestyle='--', color='gray', alpha=0.5)
|
256 |
+
plt.text(len(fib_labels) + 1, level, f"{fib_labels[i]}: {level}", verticalalignment='center')
|
257 |
+
|
258 |
+
# Plot entry, stop_loss, and take_profit
|
259 |
+
plt.axhline(y=entry, color='blue', label='Entry')
|
260 |
+
plt.axhline(y=stop_loss, color='red', label='Stop Loss')
|
261 |
+
plt.axhline(y=take_profit, color='green', label='Take Profit')
|
262 |
+
|
263 |
+
plt.legend()
|
264 |
+
plt.xlabel("Fibonacci Levels")
|
265 |
+
plt.ylabel("Price")
|
266 |
+
plt.tight_layout()
|
267 |
+
|
268 |
+
# Save the plot to a temporary file and return its path
|
269 |
+
plt_path = "/mnt/data/trade_setup.png"
|
270 |
+
plt.savefig(plt_path)
|
271 |
+
plt.close()
|
272 |
+
|
273 |
+
return plt_path
|
274 |
+
|
275 |
+
# Example usage
|
276 |
+
#current_price = get_current_stock_price(finnhub_api_key, symbol)
|
277 |
+
# start_date = '2023-01-01'
|
278 |
+
# swing_high, swing_low = get_swing_high_low(symbol, 'weekly', start_date)
|
279 |
+
# print(f"Swing High: {swing_high}, Swing Low: {swing_low}")
|
280 |
+
# risk_percentage = 1finnhub_api_key
|
281 |
+
# account_balance = 10000
|
282 |
+
|
283 |
+
# entry_exit_points = calculate_entry_exit_points(current_price=current_price, target_price=target_profit_price, risk_percentage=1, account_balance=10000, swing_high=swing_high, swing_low=swing_low,buy_signal=buy_signal)
|
284 |
+
|
285 |
+
# Printing the output
|
286 |
+
# print("Current Price:", current_price)
|
287 |
+
# print("Price Target:", target_profit_price)
|
288 |
+
# print("Entry Price:", entry_exit_points['entry'])
|
289 |
+
# print("Stop Loss:", entry_exit_points['stop_loss'])
|
290 |
+
# print("Take Profit:", entry_exit_points['take_profit'])
|
291 |
+
# print("Position Size:", entry_exit_points['position_size'])
|
292 |
+
# print("Profit (Take Profit): $", entry_exit_points['profit_take_profit'])
|
293 |
+
# print("Profit (Stop Loss): $", entry_exit_points['profit_stop_loss'])
|
294 |
+
# print("Fibonacci Levels:", entry_exit_points['fibonacci_levels'])
|
295 |
+
# Print the closest levels and their associated prices for debugging
|
296 |
+
# if buy_signal:
|
297 |
+
# print(f"Closest levels for Buy (targeting {target_profit_price}): {entry_exit_points['closest_levels']}")
|
298 |
+
# else:
|
299 |
+
# print(f"Closest levels for Sell (targeting {target_profit_price}): {entry_exit_points['closest_levels']}")
|
300 |
+
# print("Buy/Sell Flag:", entry_exit_points['buy_sell_flag'])
|
301 |
+
|
302 |
+
|
303 |
+
# Print the structure of entry_exit_points['closest_levels']
|
304 |
+
|
305 |
+
# Extract levels and prices from entry_exit_points['closest_levels'] dictionary
|
306 |
+
# levels = list(entry_exit_points['closest_levels'].keys())
|
307 |
+
# prices = list(entry_exit_points['closest_levels'].values())
|
308 |
+
|
309 |
+
# Create a bar chart
|
310 |
+
# plt.figure(figsize=(10, 6))
|
311 |
+
# plt.bar(levels, prices, color='blue' if buy_signal else 'red')
|
312 |
+
# plt.xlabel("Fibonacci Levels")
|
313 |
+
# plt.ylabel("Price")
|
314 |
+
# plt.title("Average Price at Fibonacci Levels")
|
315 |
+
# plt.xticks(rotation=45)
|
316 |
+
|
317 |
+
# Show the chart
|
318 |
+
# plt.show()
|
319 |
+
|
320 |
+
# print(entry_exit_points['closest_levels'])
|
321 |
+
# for key, value in entry_exit_points['closest_levels'].items():
|
322 |
+
# print(f"Property: {key}, Value: {value}")
|
323 |
+
# Check if it's a buy or sell signal and adjust the title accordingly
|
324 |
+
# if buy_signal:
|
325 |
+
# title = f"Closest Levels for Buy (targeting {target_profit_price})"
|
326 |
+
# else:
|
327 |
+
# title = f"Closest Levels for Sell (targeting {target_profit_price})"
|
328 |
+
|
fibonacci_price_targets.ipynb
ADDED
The diff for this file is too large to render.
See raw diff
|
|
requirements.txt
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
numpy
|
2 |
+
pandas
|
3 |
+
pandas_datareader
|
4 |
+
matplotlib
|
5 |
+
scipy
|
6 |
+
seaborn
|
7 |
+
alpha_vantage
|
8 |
+
gradio
|
9 |
+
gradio_client
|
10 |
+
boto3
|