Translations
Browse files- __pycache__/stocks.cpython-311.pyc +0 -0
- app.py +69 -71
__pycache__/stocks.cpython-311.pyc
CHANGED
|
Binary files a/__pycache__/stocks.cpython-311.pyc and b/__pycache__/stocks.cpython-311.pyc differ
|
|
|
app.py
CHANGED
|
@@ -26,68 +26,66 @@ class GradioInterface:
|
|
| 26 |
with gr.Row():
|
| 27 |
with gr.Column():
|
| 28 |
# Parâmetros da Estratégia de Trading
|
| 29 |
-
gr.Markdown("###
|
| 30 |
inputs = {}
|
| 31 |
-
inputs['rsi_period'] = gr.Number(value=14, label="
|
| 32 |
-
inputs['rsi_upper'] = gr.Number(value=70, label="
|
| 33 |
-
inputs['rsi_lower'] = gr.Number(value=30, label="
|
| 34 |
-
inputs['sma_short'] = gr.Number(value=50, label="SMA
|
| 35 |
-
inputs['sma_long'] = gr.Number(value=200, label="SMA
|
| 36 |
inputs['max_loss_percent'] = gr.Slider(0, 0.5, value=0.02, step=0.01, label="Stop Loss (%)")
|
| 37 |
inputs['take_profit_percent'] = gr.Slider(0, 0.5, value=0.05, step=0.01, label="Take Profit (%)")
|
| 38 |
-
inputs['position_size'] = gr.Slider(0.01, 1.0, value=0.1, step=0.01, label="
|
| 39 |
-
inputs['atr_period'] = gr.Number(value=14, label="
|
| 40 |
-
inputs['atr_multiplier'] = gr.Number(value=3, label="
|
| 41 |
-
inputs['confidence_threshold'] = gr.Number(value=70, label="
|
| 42 |
-
inputs['sentiment_threshold'] = gr.Number(value=50, label="
|
| 43 |
-
save_btn = gr.Button("
|
| 44 |
# Adicionando a explicação em Markdown
|
| 45 |
gr.Markdown("""
|
| 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 |
-
Se precisar ajustar os valores para um backtest, posso sugerir otimizações! 🚀
|
| 91 |
""")
|
| 92 |
|
| 93 |
save_btn.click(
|
|
@@ -107,19 +105,19 @@ class GradioInterface:
|
|
| 107 |
|
| 108 |
self.strategy_params = dict(zip(params, args))
|
| 109 |
print("Parâmetros atualizados:", self.strategy_params)
|
| 110 |
-
return gr.Info("
|
| 111 |
|
| 112 |
def create_main_interface(self):
|
| 113 |
with gr.Blocks() as main_interface:
|
| 114 |
with gr.Row():
|
| 115 |
with gr.Column():
|
| 116 |
-
ticker_input = gr.Text(label="Ticker (ex: VALE)", placeholder="
|
| 117 |
-
api_key_input = gr.Textbox(label="API Key (
|
| 118 |
-
fetch_new = gr.Dropdown([True, False], label="
|
| 119 |
-
initial_investment = gr.Number(10000, label="
|
| 120 |
-
years_back = gr.Number(5, label="
|
| 121 |
-
commission = gr.Number(0.001, label="
|
| 122 |
-
run_btn = gr.Button("
|
| 123 |
with gr.Column():
|
| 124 |
plot_output = gr.Plot()
|
| 125 |
with gr.Row():
|
|
@@ -149,7 +147,7 @@ class GradioInterface:
|
|
| 149 |
)
|
| 150 |
|
| 151 |
if not result:
|
| 152 |
-
return "
|
| 153 |
|
| 154 |
# Configurar simulação
|
| 155 |
end_date = datetime.now()
|
|
@@ -175,13 +173,13 @@ class GradioInterface:
|
|
| 175 |
progress = gr.Progress()
|
| 176 |
|
| 177 |
# Atualizar progresso
|
| 178 |
-
progress(0.3, desc="
|
| 179 |
|
| 180 |
# Executar simulação
|
| 181 |
bt_integration = st.BacktraderIntegration(analysis_result=result,strategy_params=custom_strategy_params)
|
| 182 |
bt_integration.add_data_feed(ticker, start_date, end_date)
|
| 183 |
|
| 184 |
-
progress(0.6, desc="
|
| 185 |
|
| 186 |
final_value, operation_logs = bt_integration.run_simulation(
|
| 187 |
initial_cash=initial_investment,
|
|
@@ -195,46 +193,46 @@ class GradioInterface:
|
|
| 195 |
parts = log.split(", ")
|
| 196 |
date = parts[0].strip()
|
| 197 |
details = ", ".join(parts[1:]).replace("BUY EXECUTED, ", "")
|
| 198 |
-
formatted_logs.append(f"- 🟢 **
|
| 199 |
elif "SELL EXECUTED" in log:
|
| 200 |
parts = log.split(", ")
|
| 201 |
date = parts[0].strip()
|
| 202 |
details = ", ".join(parts[1:]).replace("SELL EXECUTED, ", "")
|
| 203 |
-
formatted_logs.append(f"- 🔴 **
|
| 204 |
elif "TRADE PROFIT" in log:
|
| 205 |
parts = log.split(", ")
|
| 206 |
date = parts[0].strip()
|
| 207 |
details = ", ".join(parts[1:])
|
| 208 |
-
formatted_logs.append(f"- 📊 **
|
| 209 |
elif "Final Portfolio Value" in log:
|
| 210 |
continue # Ignora a linha final duplicada
|
| 211 |
|
| 212 |
# Adicionar seção de logs na saída
|
| 213 |
-
output_ops = "###
|
| 214 |
|
| 215 |
-
progress(0.9, desc="
|
| 216 |
|
| 217 |
# Extrair os valores do JSON de sentimento
|
| 218 |
sentiment = result['sentiment']['sentiment']
|
| 219 |
-
negative_sentiment = sentiment.get('
|
| 220 |
neutral_sentiment = sentiment.get('neutral', 0.0)
|
| 221 |
positive_sentiment = sentiment.get('positive', 0.0)
|
| 222 |
|
| 223 |
# Gerar saída formatada em Markdown
|
| 224 |
output = f"""
|
| 225 |
-
##
|
| 226 |
|
| 227 |
-
**
|
| 228 |
-
**
|
| 229 |
|
| 230 |
-
###
|
| 231 |
|
| 232 |
-
- **
|
| 233 |
-
- **
|
| 234 |
-
- **
|
| 235 |
|
| 236 |
- **RSI**: {result['technical']['rsi']:.1f}
|
| 237 |
-
- **
|
| 238 |
- **P/E Ratio**: {result['fundamental'].get('trailingPE', 'N/A')}
|
| 239 |
"""
|
| 240 |
|
|
@@ -258,7 +256,7 @@ class GradioInterface:
|
|
| 258 |
closes = datafeed.close.array
|
| 259 |
|
| 260 |
# Plot
|
| 261 |
-
plt.plot(dates, closes, label='
|
| 262 |
|
| 263 |
# Format dates
|
| 264 |
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
|
|
@@ -266,9 +264,9 @@ class GradioInterface:
|
|
| 266 |
plt.gcf().autofmt_xdate() # Rotate dates
|
| 267 |
|
| 268 |
# Add labels and grid
|
| 269 |
-
plt.title("
|
| 270 |
plt.xlabel("Data")
|
| 271 |
-
plt.ylabel("
|
| 272 |
plt.legend()
|
| 273 |
plt.grid(True, alpha=0.3)
|
| 274 |
|
|
@@ -280,7 +278,7 @@ interface = GradioInterface(pipeline)
|
|
| 280 |
|
| 281 |
demo = gr.TabbedInterface(
|
| 282 |
[interface.create_main_interface(), interface.create_settings_interface()],
|
| 283 |
-
["
|
| 284 |
title="Stock Analyst Pro"
|
| 285 |
)
|
| 286 |
|
|
|
|
| 26 |
with gr.Row():
|
| 27 |
with gr.Column():
|
| 28 |
# Parâmetros da Estratégia de Trading
|
| 29 |
+
gr.Markdown("### Parameters for Trading Strategy")
|
| 30 |
inputs = {}
|
| 31 |
+
inputs['rsi_period'] = gr.Number(value=14, label="RSI Period", minimum=1)
|
| 32 |
+
inputs['rsi_upper'] = gr.Number(value=70, label="RSI Upper Limit", minimum=0, maximum=100)
|
| 33 |
+
inputs['rsi_lower'] = gr.Number(value=30, label="RSI Lower Limit", minimum=0, maximum=100)
|
| 34 |
+
inputs['sma_short'] = gr.Number(value=50, label="SMA Short (period)")
|
| 35 |
+
inputs['sma_long'] = gr.Number(value=200, label="SMA Long (period)")
|
| 36 |
inputs['max_loss_percent'] = gr.Slider(0, 0.5, value=0.02, step=0.01, label="Stop Loss (%)")
|
| 37 |
inputs['take_profit_percent'] = gr.Slider(0, 0.5, value=0.05, step=0.01, label="Take Profit (%)")
|
| 38 |
+
inputs['position_size'] = gr.Slider(0.01, 1.0, value=0.1, step=0.01, label="Position Size(%)")
|
| 39 |
+
inputs['atr_period'] = gr.Number(value=14, label="ATR Period")
|
| 40 |
+
inputs['atr_multiplier'] = gr.Number(value=3, label="ATR Multiplier")
|
| 41 |
+
inputs['confidence_threshold'] = gr.Number(value=70, label="Confidence Threshold(%)", minimum=0, maximum=100)
|
| 42 |
+
inputs['sentiment_threshold'] = gr.Number(value=50, label="Sentiment Threshold(%)", minimum=0, maximum=100)
|
| 43 |
+
save_btn = gr.Button("Save Configuration")
|
| 44 |
# Adicionando a explicação em Markdown
|
| 45 |
gr.Markdown("""
|
| 46 |
+
## 📊 Explanation of Trading Strategy Parameters
|
| 47 |
|
| 48 |
+
These parameters configure technical indicators to assist in buy and sell decisions for assets.
|
| 49 |
|
| 50 |
+
### **📉 RSI (Relative Strength Index)**
|
| 51 |
+
The RSI is used to measure the strength of an asset's movement.
|
| 52 |
|
| 53 |
+
- **`rsi_period` (14)** → Number of periods to calculate the RSI (default: 14).
|
| 54 |
+
- **`rsi_upper` (70)** → If the RSI is greater than this value, it may indicate overbought conditions (sell signal).
|
| 55 |
+
- **`rsi_lower` (30)** → If the RSI is less than this value, it may indicate oversold conditions (buy signal).
|
| 56 |
|
| 57 |
+
---
|
| 58 |
|
| 59 |
+
### **📈 Simple Moving Averages (SMA)**
|
| 60 |
+
Indicators that smooth prices over time.
|
| 61 |
|
| 62 |
+
- **`sma_short` (50)** → Short-term moving average, used to capture short-term trends.
|
| 63 |
+
- **`sma_long` (200)** → Long-term moving average, used to capture long-term trends.
|
| 64 |
|
| 65 |
+
---
|
| 66 |
|
| 67 |
+
### **📉 Risk Management**
|
| 68 |
|
| 69 |
+
- **`max_loss_percent` (0.02)** → Stop Loss (loss limit). If the price falls more than 2%, the position is closed.
|
| 70 |
+
- **`take_profit_percent` (0.05)** → Take Profit (profit limit). If the price rises 5%, the position is closed.
|
| 71 |
+
- **`position_size` (0.1)** → Proportion of total capital to be used in a trade (10% of the balance).
|
| 72 |
|
| 73 |
+
---
|
| 74 |
|
| 75 |
+
### **📊 ATR (Average True Range) - Volatility**
|
| 76 |
+
The ATR is used to measure the volatility of an asset.
|
| 77 |
|
| 78 |
+
- **`atr_period` (14)** → Number of periods to calculate the ATR.
|
| 79 |
+
- **`atr_multiplier` (3)** → ATR multiplier, often used to define dynamic stop loss.
|
| 80 |
|
| 81 |
+
---
|
| 82 |
|
| 83 |
+
## **🚀 How Do These Parameters Affect the Strategy?**
|
| 84 |
|
| 85 |
+
- **If `rsi_lower` is lower (e.g., 20), the strategy will buy in more oversold regions.**
|
| 86 |
+
- **If `max_loss_percent` is too small, it may close trades prematurely.**
|
| 87 |
+
- **If `atr_multiplier` is larger, the stop loss will be wider, allowing for more volatility.**
|
| 88 |
+
- **If `sma_short` and `sma_long` are far apart, entries will be more conservative.**
|
|
|
|
|
|
|
| 89 |
""")
|
| 90 |
|
| 91 |
save_btn.click(
|
|
|
|
| 105 |
|
| 106 |
self.strategy_params = dict(zip(params, args))
|
| 107 |
print("Parâmetros atualizados:", self.strategy_params)
|
| 108 |
+
return gr.Info("Settings saved!")
|
| 109 |
|
| 110 |
def create_main_interface(self):
|
| 111 |
with gr.Blocks() as main_interface:
|
| 112 |
with gr.Row():
|
| 113 |
with gr.Column():
|
| 114 |
+
ticker_input = gr.Text(label="Ticker (ex: VALE)", placeholder="Insert a stock ticker based on Yahoo Finance")
|
| 115 |
+
api_key_input = gr.Textbox(label="API Key (required)", placeholder="Insert your API Key https://newsapi.org/")
|
| 116 |
+
fetch_new = gr.Dropdown([True, False], label="Check last news information online (Requires API)?", value=False)
|
| 117 |
+
initial_investment = gr.Number(10000, label="Initial Investiment (USD)")
|
| 118 |
+
years_back = gr.Number(5, label="Historical Data (years back)")
|
| 119 |
+
commission = gr.Number(0.001, label="Trade Commission (%)")
|
| 120 |
+
run_btn = gr.Button("Execute Analysis")
|
| 121 |
with gr.Column():
|
| 122 |
plot_output = gr.Plot()
|
| 123 |
with gr.Row():
|
|
|
|
| 147 |
)
|
| 148 |
|
| 149 |
if not result:
|
| 150 |
+
return "Something wrong is not right :)", None
|
| 151 |
|
| 152 |
# Configurar simulação
|
| 153 |
end_date = datetime.now()
|
|
|
|
| 173 |
progress = gr.Progress()
|
| 174 |
|
| 175 |
# Atualizar progresso
|
| 176 |
+
progress(0.3, desc="Preparing simulation...")
|
| 177 |
|
| 178 |
# Executar simulação
|
| 179 |
bt_integration = st.BacktraderIntegration(analysis_result=result,strategy_params=custom_strategy_params)
|
| 180 |
bt_integration.add_data_feed(ticker, start_date, end_date)
|
| 181 |
|
| 182 |
+
progress(0.6, desc="Executing simulation...")
|
| 183 |
|
| 184 |
final_value, operation_logs = bt_integration.run_simulation(
|
| 185 |
initial_cash=initial_investment,
|
|
|
|
| 193 |
parts = log.split(", ")
|
| 194 |
date = parts[0].strip()
|
| 195 |
details = ", ".join(parts[1:]).replace("BUY EXECUTED, ", "")
|
| 196 |
+
formatted_logs.append(f"- 🟢 **Buy** ({date}): {details}")
|
| 197 |
elif "SELL EXECUTED" in log:
|
| 198 |
parts = log.split(", ")
|
| 199 |
date = parts[0].strip()
|
| 200 |
details = ", ".join(parts[1:]).replace("SELL EXECUTED, ", "")
|
| 201 |
+
formatted_logs.append(f"- 🔴 **Sell** ({date}): {details}")
|
| 202 |
elif "TRADE PROFIT" in log:
|
| 203 |
parts = log.split(", ")
|
| 204 |
date = parts[0].strip()
|
| 205 |
details = ", ".join(parts[1:])
|
| 206 |
+
formatted_logs.append(f"- 📊 **Result** ({date}): {details}")
|
| 207 |
elif "Final Portfolio Value" in log:
|
| 208 |
continue # Ignora a linha final duplicada
|
| 209 |
|
| 210 |
# Adicionar seção de logs na saída
|
| 211 |
+
output_ops = "### Log :\n\n" + "\n".join(formatted_logs)
|
| 212 |
|
| 213 |
+
progress(0.9, desc="Generating final result...")
|
| 214 |
|
| 215 |
# Extrair os valores do JSON de sentimento
|
| 216 |
sentiment = result['sentiment']['sentiment']
|
| 217 |
+
negative_sentiment = sentiment.get('negative', 0.0)
|
| 218 |
neutral_sentiment = sentiment.get('neutral', 0.0)
|
| 219 |
positive_sentiment = sentiment.get('positive', 0.0)
|
| 220 |
|
| 221 |
# Gerar saída formatada em Markdown
|
| 222 |
output = f"""
|
| 223 |
+
## Recommendation: {result['recommendation']}
|
| 224 |
|
| 225 |
+
**Confidence**: {result['confidence']['total_confidence']:.2%}
|
| 226 |
+
**Simulation Summary**: {(final_value/initial_investment-1)*100:.2f}%
|
| 227 |
|
| 228 |
+
### Details:
|
| 229 |
|
| 230 |
+
- **Negative Sentiment**: {negative_sentiment:.2%}
|
| 231 |
+
- **Neutral Sentiment**: {neutral_sentiment:.2%}
|
| 232 |
+
- **Positive Sentiment**: {positive_sentiment:.2%}
|
| 233 |
|
| 234 |
- **RSI**: {result['technical']['rsi']:.1f}
|
| 235 |
+
- **Price vs SMA50**: {result['technical']['price_vs_sma']:.2%}
|
| 236 |
- **P/E Ratio**: {result['fundamental'].get('trailingPE', 'N/A')}
|
| 237 |
"""
|
| 238 |
|
|
|
|
| 256 |
closes = datafeed.close.array
|
| 257 |
|
| 258 |
# Plot
|
| 259 |
+
plt.plot(dates, closes, label='Close Price', linewidth=1.5)
|
| 260 |
|
| 261 |
# Format dates
|
| 262 |
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
|
|
|
|
| 264 |
plt.gcf().autofmt_xdate() # Rotate dates
|
| 265 |
|
| 266 |
# Add labels and grid
|
| 267 |
+
plt.title("Historical Price Data")
|
| 268 |
plt.xlabel("Data")
|
| 269 |
+
plt.ylabel("Price (USD)")
|
| 270 |
plt.legend()
|
| 271 |
plt.grid(True, alpha=0.3)
|
| 272 |
|
|
|
|
| 278 |
|
| 279 |
demo = gr.TabbedInterface(
|
| 280 |
[interface.create_main_interface(), interface.create_settings_interface()],
|
| 281 |
+
["Main Analysis", "Strategy Settings"],
|
| 282 |
title="Stock Analyst Pro"
|
| 283 |
)
|
| 284 |
|