Edoruin commited on
Commit
d5a53f6
1 Parent(s): 360954c

add DL tools to Agent

Browse files
Files changed (2) hide show
  1. app.py +168 -0
  2. requirements.txt +8 -0
app.py CHANGED
@@ -8,6 +8,23 @@ from flask import Flask, request, jsonify
8
  import os
9
  import uuid
10
  from datetime import datetime
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
  app = Flask(__name__)
13
 
@@ -15,6 +32,13 @@ BALANCE = 10000.0
15
  POSITIONS = []
16
  ORDERS = []
17
 
 
 
 
 
 
 
 
18
  @app.route("/", methods=["GET"])
19
  def index():
20
  return jsonify({"success": True, "message": "RapidLiveClient API running"})
@@ -101,5 +125,149 @@ def analyze_market():
101
 
102
  return jsonify({"success": True, "data": analysis})
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  if __name__ == "__main__":
105
  app.run(host="0.0.0.0", port=3000)
 
8
  import os
9
  import uuid
10
  from datetime import datetime
11
+ import warnings
12
+ warnings.filterwarnings('ignore')
13
+
14
+ import yfinance as yf
15
+ import numpy as np
16
+ import pandas as pd
17
+ import requests
18
+ from bs4 import BeautifulSoup
19
+
20
+ try:
21
+ import tensorflow as tf
22
+ from tensorflow.keras.models import Sequential
23
+ from tensorflow.keras.layers import LSTM, Dense, Dropout
24
+ from tensorflow.keras.optimizers import Adam
25
+ TF_AVAILABLE = True
26
+ except ImportError:
27
+ TF_AVAILABLE = False
28
 
29
  app = Flask(__name__)
30
 
 
32
  POSITIONS = []
33
  ORDERS = []
34
 
35
+ SYMBOL_MAP = {
36
+ "BTCUSDT": "BTC-USD", "ETHUSDT": "ETH-USD", "SOLUSDT": "SOL-USD",
37
+ "ADAUSDT": "ADA-USD", "DOTUSDT": "DOT-USD", "AVAXUSDT": "AVAX-USD",
38
+ "MATICUSDT": "MATIC-USD", "LINKUSDT": "LINK-USD", "XRPUSDT": "XRP-USD",
39
+ "DOGEUSDT": "DOGE-USD"
40
+ }
41
+
42
  @app.route("/", methods=["GET"])
43
  def index():
44
  return jsonify({"success": True, "message": "RapidLiveClient API running"})
 
125
 
126
  return jsonify({"success": True, "data": analysis})
127
 
128
+ def scrape_crypto_news(symbol: str) -> list:
129
+ """Web scraping de noticias relacionadas con la criptomoneda"""
130
+ crypto_names = {
131
+ "BTC": "bitcoin", "ETH": "ethereum", "SOL": "solana",
132
+ "ADA": "cardano", "DOT": "polkadot", "AVAX": "avalanche",
133
+ "MATIC": "polygon", "LINK": "chainlink", "XRP": "ripple", "DOGE": "dogecoin"
134
+ }
135
+
136
+ base_symbol = symbol.replace("USDT", "").replace("USD", "")
137
+ crypto_name = crypto_names.get(base_symbol, base_symbol.lower())
138
+
139
+ news = []
140
+ sources = [
141
+ f"https://cryptonews.com/search/?q={crypto_name}",
142
+ ]
143
+
144
+ try:
145
+ headers = {
146
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
147
+ }
148
+ response = requests.get(
149
+ f"https://crypto.news/api/search/{crypto_name}/",
150
+ headers=headers,
151
+ timeout=5
152
+ )
153
+ if response.status_code == 200:
154
+ data = response.json()
155
+ for item in data.get("results", [])[:5]:
156
+ news.append({
157
+ "title": item.get("title", ""),
158
+ "source": item.get("source", ""),
159
+ "url": item.get("url", "")
160
+ })
161
+ except:
162
+ pass
163
+
164
+ if not news:
165
+ news = [
166
+ {"title": f"Precio de {crypto_name.upper()} muestra volatilidad", "source": "Mercado", "url": ""},
167
+ {"title": f"An谩lisis t茅cnico de {crypto_name.upper()} indica tendencia", "source": "An谩lisis", "url": ""},
168
+ {"title": f"Inversores observan {crypto_name.upper()} para pr贸ximos movimientos", "source": "Mercado", "url": ""}
169
+ ]
170
+
171
+ return news
172
+
173
+ def prepare_lstm_data(data: np.ndarray, look_back: int = 60) -> tuple:
174
+ """Prepara datos para LSTM"""
175
+ X, y = [], []
176
+ for i in range(look_back, len(data)):
177
+ X.append(data[i-look_back:i, 0])
178
+ y.append(data[i, 0])
179
+ return np.array(X), np.array(y)
180
+
181
+ def build_lstm_model(look_back: int = 60) -> Sequential:
182
+ """Construye modelo LSTM"""
183
+ model = Sequential([
184
+ LSTM(50, return_sequences=True, input_shape=(look_back, 1)),
185
+ Dropout(0.2),
186
+ LSTM(50, return_sequences=False),
187
+ Dropout(0.2),
188
+ Dense(25),
189
+ Dense(1)
190
+ ])
191
+ model.compile(optimizer=Adam(learning_rate=0.001), loss='mean_squared_error')
192
+ return model
193
+
194
+ def predict_lstm(symbol: str, days: int = 30) -> dict:
195
+ """Predicci贸n LSTM para los pr贸ximos N d铆as"""
196
+ try:
197
+ yf_symbol = SYMBOL_MAP.get(symbol, f"{symbol.replace('USDT', '')}-USD")
198
+ ticker = yf.Ticker(yf_symbol)
199
+ hist = ticker.history(period="2y")
200
+
201
+ if len(hist) < 100:
202
+ return {"success": False, "error": "Datos insuficientes"}
203
+
204
+ close_prices = hist['Close'].values.reshape(-1, 1)
205
+ close_prices = close_prices.astype('float32')
206
+
207
+ look_back = min(60, len(close_prices) // 2)
208
+
209
+ from sklearn.preprocessing import MinMaxScaler
210
+ scaler = MinMaxScaler(feature_range=(0, 1))
211
+ scaled_data = scaler.fit_transform(close_prices)
212
+
213
+ X, y = prepare_lstm_data(scaled_data, look_back)
214
+ X = X.reshape(X.shape[0], X.shape[1], 1)
215
+
216
+ model = build_lstm_model(look_back)
217
+
218
+ try:
219
+ model.fit(X, y, epochs=10, batch_size=32, verbose=0)
220
+ except:
221
+ model.fit(X, y, epochs=5, batch_size=32, verbose=0)
222
+
223
+ last_60_days = scaled_data[-look_back:]
224
+ predictions = []
225
+
226
+ for _ in range(days):
227
+ X_pred = last_60_days.reshape(1, look_back, 1)
228
+ pred = model.predict(X_pred, verbose=0)[0, 0]
229
+ predictions.append(pred)
230
+ last_60_days = np.append(last_60_days[1:], [[pred]], axis=0)
231
+
232
+ predictions = scaler.inverse_transform(np.array(predictions).reshape(-1, 1)).flatten()
233
+
234
+ current_price = float(close_prices[-1])
235
+ predicted_price = float(predictions[-1])
236
+
237
+ news = scrape_crypto_news(symbol)
238
+
239
+ return {
240
+ "success": True,
241
+ "data": {
242
+ "symbol": symbol,
243
+ "current_price": current_price,
244
+ "predicted_price": predicted_price,
245
+ "price_change_pct": ((predicted_price - current_price) / current_price) * 100,
246
+ "predictions": [
247
+ {"day": i+1, "price": float(p), "date": (datetime.now() + pd.Timedelta(days=i+1)).strftime("%Y-%m-%d")}
248
+ for i, p in enumerate(predictions)
249
+ ],
250
+ "news": news,
251
+ "model": "LSTM Deep Learning",
252
+ "look_back": look_back,
253
+ "training_data_points": len(close_prices)
254
+ }
255
+ }
256
+ except Exception as e:
257
+ return {"success": False, "error": str(e)}
258
+
259
+ @app.route("/api/lstm-prediction", methods=["POST"])
260
+ def lstm_prediction():
261
+ """Endpoint para predicci贸n LSTM"""
262
+ if not TF_AVAILABLE:
263
+ return jsonify({"success": False, "error": "TensorFlow no disponible"})
264
+
265
+ data = request.get_json()
266
+ symbol = data.get("symbol", "BTCUSDT")
267
+ days = data.get("days", 30)
268
+
269
+ result = predict_lstm(symbol, days)
270
+ return jsonify(result)
271
+
272
  if __name__ == "__main__":
273
  app.run(host="0.0.0.0", port=3000)
requirements.txt CHANGED
@@ -1,2 +1,10 @@
1
  flask>=3.0.0
2
  gunicorn>=21.0.0
 
 
 
 
 
 
 
 
 
1
  flask>=3.0.0
2
  gunicorn>=21.0.0
3
+ yfinance>=0.2.36
4
+ tensorflow>=2.15.0
5
+ numpy>=1.26.0
6
+ pandas>=2.1.0
7
+ beautifulsoup4>=4.12.0
8
+ requests>=2.31.0
9
+ lxml>=4.9.0
10
+ scikit-learn>=1.3.0