joaco7172 commited on
Commit
2e5d983
·
verified ·
1 Parent(s): 0be50a9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +14 -45
app.py CHANGED
@@ -48,7 +48,6 @@ SYSTEM_PROMPT = "You are a seasoned stock market analyst. Your task is to list t
48
 
49
 
50
  def print_gpu_utilization():
51
-
52
  nvmlInit()
53
  handle = nvmlDeviceGetHandleByIndex(0)
54
  info = nvmlDeviceGetMemoryInfo(handle)
@@ -56,37 +55,31 @@ def print_gpu_utilization():
56
 
57
 
58
  def get_curday():
59
-
60
  return date.today().strftime("%Y-%m-%d")
61
 
62
 
63
  def n_weeks_before(date_string, n):
64
-
65
  date = datetime.strptime(date_string, "%Y-%m-%d") - timedelta(days=7*n)
66
-
67
  return date.strftime("%Y-%m-%d")
68
 
69
 
70
  def get_stock_data(stock_symbol, steps):
71
-
72
  stock_data = yf.download(stock_symbol, steps[0], steps[-1])
73
  if len(stock_data) == 0:
74
  raise gr.Error(f"Failed to download stock price data for symbol {stock_symbol} from yfinance!")
75
 
76
- # print(stock_data)
77
-
78
  dates, prices = [], []
79
- available_dates = stock_data.index.format()
80
 
81
  for date in steps[:-1]:
82
  for i in range(len(stock_data)):
83
  if available_dates[i] >= date:
84
- prices.append(stock_data['Close'][i])
85
  dates.append(datetime.strptime(available_dates[i], "%Y-%m-%d"))
86
  break
87
 
88
  dates.append(datetime.strptime(available_dates[-1], "%Y-%m-%d"))
89
- prices.append(stock_data['Close'][-1])
90
 
91
  return pd.DataFrame({
92
  "Start Date": dates[:-1], "End Date": dates[1:],
@@ -95,13 +88,12 @@ def get_stock_data(stock_symbol, steps):
95
 
96
 
97
  def get_news(symbol, data):
98
-
99
  news_list = []
100
 
101
- for end_date, row in data.iterrows():
102
  start_date = row['Start Date'].strftime('%Y-%m-%d')
103
  end_date = row['End Date'].strftime('%Y-%m-%d')
104
- time.sleep(1) # control qpm
105
  weekly_news = finnhub_client.company_news(symbol, _from=start_date, to=end_date)
106
  if len(weekly_news) == 0:
107
  raise gr.Error(f"No company news found for symbol {symbol} from finnhub!")
@@ -121,7 +113,6 @@ def get_news(symbol, data):
121
 
122
 
123
  def get_company_prompt(symbol):
124
-
125
  profile = finnhub_client.company_profile2(symbol=symbol)
126
  if not profile:
127
  raise gr.Error(f"Failed to find company profile for symbol {symbol} from finnhub!")
@@ -142,7 +133,7 @@ def get_prompt_by_row(symbol, row):
142
  start_date, end_date, symbol, term, row['Start Price'], row['End Price'])
143
 
144
  news = row["News"]
145
- news = ["[Headline]: {}\n[Summary]: {}\n".format(
146
  n['headline'], n['summary']) for n in news if n['date'][:8] <= end_date.replace('-', '') and \
147
  not n['summary'].startswith("Looking for stock market analysis and research with proves results?")]
148
 
@@ -153,20 +144,19 @@ def get_prompt_by_row(symbol, row):
153
  else:
154
  basics = "[Basic Financials]:\n\nNo basic financial reported."
155
 
156
- return head, news, basics
 
157
 
158
  def sample_news(news, k=5):
159
-
160
  return [news[i] for i in sorted(random.sample(range(len(news)), k))]
161
 
162
 
163
  def latest_news(news, k=5):
164
- # Sort news by date in descending order and select the latest k items
165
  sorted_news = sorted(news, key=lambda x: x['date'], reverse=True)
166
  return sorted_news[:k]
167
 
168
- def get_current_basics(symbol, curday):
169
 
 
170
  basic_financials = finnhub_client.company_basic_financials(symbol, 'all')
171
  if not basic_financials['series']:
172
  raise gr.Error(f"Failed to find basic financials for symbol {symbol} from finnhub!")
@@ -191,7 +181,6 @@ def get_current_basics(symbol, curday):
191
 
192
 
193
  def get_all_prompts_online(symbol, data, curday, with_basics=True):
194
-
195
  company_prompt = get_company_prompt(symbol)
196
 
197
  prev_rows = []
@@ -203,10 +192,7 @@ def get_all_prompts_online(symbol, data, curday, with_basics=True):
203
  prompt = ""
204
  for i in range(-len(prev_rows), 0):
205
  prompt += "\n" + prev_rows[i][0]
206
- latest_news_items = latest_news(
207
- prev_rows[i][1],
208
- min(5, len(prev_rows[i][1]))
209
- )
210
  if latest_news_items:
211
  prompt += "\n".join(latest_news_items)
212
  else:
@@ -227,8 +213,8 @@ def get_all_prompts_online(symbol, data, curday, with_basics=True):
227
 
228
  return info, prompt
229
 
230
- def construct_prompt(ticker, curday, n_weeks, use_basics):
231
 
 
232
  try:
233
  steps = [n_weeks_before(curday, n) for n in range(n_weeks + 1)][::-1]
234
  except Exception:
@@ -237,25 +223,20 @@ def construct_prompt(ticker, curday, n_weeks, use_basics):
237
  data = get_stock_data(ticker, steps)
238
  data = get_news(ticker, data)
239
  data['Basics'] = [json.dumps({})] * len(data)
240
- # print(data)
241
 
242
  info, prompt = get_all_prompts_online(ticker, data, curday, use_basics)
243
 
244
  prompt = B_INST + B_SYS + SYSTEM_PROMPT + E_SYS + prompt + E_INST
245
- # print(prompt)
246
 
247
  return info, prompt
248
 
249
 
250
  def predict(ticker, date, n_weeks, use_basics):
251
-
252
  print_gpu_utilization()
253
 
254
  info, prompt = construct_prompt(ticker, date, n_weeks, use_basics)
255
 
256
- inputs = tokenizer(
257
- prompt, return_tensors='pt', padding=False
258
- )
259
  inputs = {key: value.to(model.device) for key, value in inputs.items()}
260
 
261
  print("Inputs loaded onto devices.")
@@ -308,20 +289,8 @@ demo = gr.Interface(
308
  label="Response"
309
  )
310
  ],
311
- title="FinGPT-Forecaster",
312
- description="""FinGPT-Forecaster takes random market news and optional basic financials related to the specified company from the past few weeks as input and responds with the company's **positive developments** and **potential concerns**. Then it gives out a **prediction** of stock price movement for the coming week and its **analysis** summary.
313
-
314
- This model is finetuned on Llama2-7b-chat-hf with LoRA on the past year's DOW30 market data but **welcomes any ticker symbol**.
315
- Company profile & Market news & Basic financials & Stock prices are retrieved using **yfinance & finnhub**.
316
- For more detailed and customized implementation, refer to our FinGPT project: <https://github.com/AI4Finance-Foundation/FinGPT>
317
-
318
- This demo has been downgraded to using **T4 with 8-bit inference** due to cost considerations, speed & performance may be affected.
319
-
320
- ⚠️Warning: This is just a demo showing what this model can do. During each individual inference, company news is **randomly sampled** from all the news from designated weeks, which might result in **different predictions for the same period**.
321
- We suggest users deploy the [original model](https://huggingface.co/FinGPT/fingpt-forecaster_dow30_llama2-7b_lora) or clone this space and inference with more carefully selected news in their favorable ways.
322
- Setting do_sample=False or modifying the temperature during the generation process also helps stabilize the prediction result.
323
-
324
- **Disclaimer: Nothing herein is financial advice, and NOT a recommendation to trade real money. Please use common sense and always first consult a professional before trading or investing.**
325
  """
326
  )
327
 
 
48
 
49
 
50
  def print_gpu_utilization():
 
51
  nvmlInit()
52
  handle = nvmlDeviceGetHandleByIndex(0)
53
  info = nvmlDeviceGetMemoryInfo(handle)
 
55
 
56
 
57
  def get_curday():
 
58
  return date.today().strftime("%Y-%m-%d")
59
 
60
 
61
  def n_weeks_before(date_string, n):
 
62
  date = datetime.strptime(date_string, "%Y-%m-%d") - timedelta(days=7*n)
 
63
  return date.strftime("%Y-%m-%d")
64
 
65
 
66
  def get_stock_data(stock_symbol, steps):
 
67
  stock_data = yf.download(stock_symbol, steps[0], steps[-1])
68
  if len(stock_data) == 0:
69
  raise gr.Error(f"Failed to download stock price data for symbol {stock_symbol} from yfinance!")
70
 
 
 
71
  dates, prices = [], []
72
+ available_dates = stock_data.index.astype(str).tolist()
73
 
74
  for date in steps[:-1]:
75
  for i in range(len(stock_data)):
76
  if available_dates[i] >= date:
77
+ prices.append(stock_data['Close'].iloc[i])
78
  dates.append(datetime.strptime(available_dates[i], "%Y-%m-%d"))
79
  break
80
 
81
  dates.append(datetime.strptime(available_dates[-1], "%Y-%m-%d"))
82
+ prices.append(stock_data['Close'].iloc[-1])
83
 
84
  return pd.DataFrame({
85
  "Start Date": dates[:-1], "End Date": dates[1:],
 
88
 
89
 
90
  def get_news(symbol, data):
 
91
  news_list = []
92
 
93
+ for _, row in data.iterrows():
94
  start_date = row['Start Date'].strftime('%Y-%m-%d')
95
  end_date = row['End Date'].strftime('%Y-%m-%d')
96
+ time.sleep(1) # control qpm
97
  weekly_news = finnhub_client.company_news(symbol, _from=start_date, to=end_date)
98
  if len(weekly_news) == 0:
99
  raise gr.Error(f"No company news found for symbol {symbol} from finnhub!")
 
113
 
114
 
115
  def get_company_prompt(symbol):
 
116
  profile = finnhub_client.company_profile2(symbol=symbol)
117
  if not profile:
118
  raise gr.Error(f"Failed to find company profile for symbol {symbol} from finnhub!")
 
133
  start_date, end_date, symbol, term, row['Start Price'], row['End Price'])
134
 
135
  news = row["News"]
136
+ news_formatted = ["[Headline]: {}\n[Summary]: {}\n".format(
137
  n['headline'], n['summary']) for n in news if n['date'][:8] <= end_date.replace('-', '') and \
138
  not n['summary'].startswith("Looking for stock market analysis and research with proves results?")]
139
 
 
144
  else:
145
  basics = "[Basic Financials]:\n\nNo basic financial reported."
146
 
147
+ return head, news_formatted, basics
148
+
149
 
150
  def sample_news(news, k=5):
 
151
  return [news[i] for i in sorted(random.sample(range(len(news)), k))]
152
 
153
 
154
  def latest_news(news, k=5):
 
155
  sorted_news = sorted(news, key=lambda x: x['date'], reverse=True)
156
  return sorted_news[:k]
157
 
 
158
 
159
+ def get_current_basics(symbol, curday):
160
  basic_financials = finnhub_client.company_basic_financials(symbol, 'all')
161
  if not basic_financials['series']:
162
  raise gr.Error(f"Failed to find basic financials for symbol {symbol} from finnhub!")
 
181
 
182
 
183
  def get_all_prompts_online(symbol, data, curday, with_basics=True):
 
184
  company_prompt = get_company_prompt(symbol)
185
 
186
  prev_rows = []
 
192
  prompt = ""
193
  for i in range(-len(prev_rows), 0):
194
  prompt += "\n" + prev_rows[i][0]
195
+ latest_news_items = latest_news(prev_rows[i][1], min(5, len(prev_rows[i][1])))
 
 
 
196
  if latest_news_items:
197
  prompt += "\n".join(latest_news_items)
198
  else:
 
213
 
214
  return info, prompt
215
 
 
216
 
217
+ def construct_prompt(ticker, curday, n_weeks, use_basics):
218
  try:
219
  steps = [n_weeks_before(curday, n) for n in range(n_weeks + 1)][::-1]
220
  except Exception:
 
223
  data = get_stock_data(ticker, steps)
224
  data = get_news(ticker, data)
225
  data['Basics'] = [json.dumps({})] * len(data)
 
226
 
227
  info, prompt = get_all_prompts_online(ticker, data, curday, use_basics)
228
 
229
  prompt = B_INST + B_SYS + SYSTEM_PROMPT + E_SYS + prompt + E_INST
 
230
 
231
  return info, prompt
232
 
233
 
234
  def predict(ticker, date, n_weeks, use_basics):
 
235
  print_gpu_utilization()
236
 
237
  info, prompt = construct_prompt(ticker, date, n_weeks, use_basics)
238
 
239
+ inputs = tokenizer(prompt, return_tensors='pt', padding=False)
 
 
240
  inputs = {key: value.to(model.device) for key, value in inputs.items()}
241
 
242
  print("Inputs loaded onto devices.")
 
289
  label="Response"
290
  )
291
  ],
292
+ title="Pro Capital",
293
+ description="""Implementation**
 
 
 
 
 
 
 
 
 
 
 
 
294
  """
295
  )
296