-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgpt_parser.py
More file actions
265 lines (218 loc) · 9.61 KB
/
gpt_parser.py
File metadata and controls
265 lines (218 loc) · 9.61 KB
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
import os
import json
from typing import Dict, Any, Optional
from openai import OpenAI
from datetime import datetime
class GPTQuantConnectParser:
"""
Parser que usa GPT para convertir descripciones en lenguaje natural
a código QuantConnect Python
"""
def __init__(self):
self.client = OpenAI(api_key=os.getenv('OPENAI_API_KEY'))
self.model = "gpt-4o-mini" # Usar modelo más económico
def parse_strategy_description(self, description: str, backtest_params: Dict[str, Any] = None) -> str:
"""
Convierte una descripción en lenguaje natural a código QuantConnect
"""
if not backtest_params:
backtest_params = {}
# Parámetros por defecto
symbol = backtest_params.get('symbol', 'SPY')
initial_capital = backtest_params.get('initial_capital', 100000)
start_date = backtest_params.get('start_date', '2021-01-01')
end_date = backtest_params.get('end_date', '2024-01-01')
benchmark = backtest_params.get('benchmark', 'SPY')
# Crear el prompt para GPT
prompt = self._create_quantconnect_prompt(
description, symbol, initial_capital, start_date, end_date, benchmark
)
try:
response = self.client.chat.completions.create(
model=self.model,
messages=[
{
"role": "system",
"content": "Eres un experto en QuantConnect y trading algorítmico. Tu trabajo es convertir descripciones de estrategias de trading en código Python válido para QuantConnect."
},
{
"role": "user",
"content": prompt
}
],
temperature=0.3, # Baja temperatura para código más consistente
max_tokens=2000
)
return response.choices[0].message.content.strip()
except Exception as e:
# Si falla GPT, devolver código básico
return self._generate_fallback_code(description, symbol, initial_capital, start_date, end_date, benchmark)
def _format_date_for_lean(self, date_str: str) -> str:
"""Formatea una fecha para usar en código LEAN sin ceros iniciales"""
year, month, day = date_str.split('-')
return f"{year}, {int(month)}, {int(day)}"
def _create_quantconnect_prompt(self, description: str, symbol: str, initial_capital: int,
start_date: str, end_date: str, benchmark: str) -> str:
"""Crea el prompt específico para QuantConnect"""
return f"""
Eres un experto en QuantConnect y trading algorítmico. Convierte la siguiente descripción de estrategia de trading en código Python funcional para QuantConnect.
DESCRIPCIÓN: "{description}"
PARÁMETROS:
- Símbolo: {symbol}
- Capital: ${initial_capital:,}
- Período: {start_date} a {end_date}
- Benchmark: {benchmark}
INSTRUCCIONES:
1. Analiza la descripción e identifica todos los indicadores técnicos mencionados
2. Identifica las condiciones de entrada y salida exactas
3. Implementa la gestión de riesgo si se menciona (stop loss, take profit)
4. Genera código Python completo y funcional para QuantConnect
5. Usa los períodos correctos de los indicadores (5-day, 10-day, 20-day, etc.)
6. Incluye logging para debugging
FORMATO DE CÓDIGO REQUERIDO:
```python
from AlgorithmImports import *
class TradingStrategy(QCAlgorithm):
def Initialize(self):
# Configuración básica
self.SetStartDate({self._format_date_for_lean(start_date)})
self.SetEndDate({self._format_date_for_lean(end_date)})
self.SetCash({initial_capital})
self.symbol = self.AddEquity("{symbol}", Resolution.Daily).Symbol
self.SetBenchmark("{benchmark}")
# Indicadores técnicos
# (agregar aquí los indicadores necesarios)
# Warm up
self.SetWarmUp(20)
def OnData(self, data):
if self.IsWarmingUp:
return
# Lógica de trading aquí
# (implementar las condiciones de entrada y salida)
def OnOrderEvent(self, orderEvent):
if orderEvent.Status == OrderStatus.Filled:
self.Debug(f"Order filled: {{orderEvent}}")
def OnEndOfAlgorithm(self):
self.Debug("Algorithm completed")
```
IMPORTANTE:
- Solo devuelve el código Python completo
- No incluyas explicaciones ni markdown
- El código debe ser ejecutable directamente en QuantConnect
- Implementa exactamente lo que se describe en la estrategia
"""
def _generate_fallback_code(self, description: str, symbol: str, initial_capital: int,
start_date: str, end_date: str, benchmark: str) -> str:
"""Genera código básico si GPT falla"""
start_formatted = self._format_date_for_lean(start_date)
end_formatted = self._format_date_for_lean(end_date)
return f'''from AlgorithmImports import *
class TradingStrategy(QCAlgorithm):
def Initialize(self):
# Set start and end dates
self.SetStartDate({start_formatted})
self.SetEndDate({end_formatted})
self.SetCash({initial_capital})
# Add equity data
self.symbol = self.AddEquity("{symbol}", Resolution.Daily).Symbol
# Set benchmark
self.SetBenchmark("{benchmark}")
# Initialize indicators
self.rsi = self.RSI(self.symbol, 14)
self.sma20 = self.SMA(self.symbol, 20)
# Set up warm up period
self.SetWarmUp(20)
def OnData(self, data):
# Skip if warming up
if self.IsWarmingUp:
return
if not self.rsi.IsReady or not self.sma20.IsReady:
return
# Basic RSI strategy
if not self.Portfolio.Invested:
if self.rsi.Current.Value < 30:
self.SetHoldings(self.symbol, 1.0)
else:
if self.rsi.Current.Value > 70:
self.Liquidate(self.symbol)
def OnOrderEvent(self, orderEvent):
if orderEvent.Status == OrderStatus.Filled:
self.Debug(f"Order filled: {{orderEvent}}")
def OnEndOfAlgorithm(self):
self.Debug("Algorithm completed")'''
def generate_strategy_templates(self) -> list:
"""Genera templates de estrategias usando GPT"""
templates = [
{
'id': 'rsi_mean_reversion',
'name': 'RSI Mean Reversion',
'description': 'Buy when RSI is below 30, sell when RSI is above 70',
'category': 'Mean Reversion'
},
{
'id': 'moving_average_crossover',
'name': 'Moving Average Crossover',
'description': 'Buy when price crosses above 20-day SMA, sell when it crosses below',
'category': 'Trend Following'
},
{
'id': 'bollinger_bands',
'name': 'Bollinger Bands',
'description': 'Buy when price touches lower band, sell when it touches upper band',
'category': 'Mean Reversion'
},
{
'id': 'macd_crossover',
'name': 'MACD Crossover',
'description': 'Buy when MACD crosses above signal line, sell when it crosses below',
'category': 'Trend Following'
},
{
'id': 'momentum_strategy',
'name': 'Momentum Strategy',
'description': 'Buy when price is above 50-day SMA and RSI > 50, sell when conditions reverse',
'category': 'Momentum'
}
]
return templates
def analyze_strategy_complexity(self, description: str) -> Dict[str, Any]:
"""Analiza la complejidad de una estrategia usando GPT"""
prompt = f"""
Analiza la siguiente descripción de estrategia de trading y determina su complejidad:
DESCRIPCIÓN: "{description}"
Proporciona un análisis en formato JSON con:
- complexity_level: "basic", "intermediate", "advanced"
- required_indicators: lista de indicadores necesarios
- risk_level: "low", "medium", "high"
- estimated_performance: estimación de rendimiento esperado
- recommended_timeframe: timeframe recomendado
- market_conditions: condiciones de mercado ideales
Solo devuelve el JSON, sin explicaciones adicionales.
"""
try:
response = self.client.chat.completions.create(
model=self.model,
messages=[
{
"role": "system",
"content": "Eres un analista de trading experto. Analiza estrategias y proporciona métricas de complejidad y riesgo."
},
{
"role": "user",
"content": prompt
}
],
temperature=0.2,
max_tokens=500
)
return json.loads(response.choices[0].message.content.strip())
except Exception as e:
# Fallback analysis
return {
"complexity_level": "basic",
"required_indicators": ["RSI", "SMA"],
"risk_level": "medium",
"estimated_performance": "moderate",
"recommended_timeframe": "daily",
"market_conditions": "trending"
}