import json import openai import requests from pydantic import ValidationError from models.market_data import MarketData from models.suggestion import ( TradeSuggestion, TradeDirection, TakeProfitPoints, RecommendationType, ) class AIService: @staticmethod def _prepare_prompt( symbol, leverage, trade_amount, market_data: MarketData, current_price: float ): klines = [ { "timestamp": k.timestamp, "open": k.open, "high": k.high, "low": k.low, "close": k.close, "volume": k.volume, } for k in market_data.klines ] return f""" You are an expert crypto futures trader. Based on market data, suggest a trade for {symbol}. Current Price: ${current_price} Leverage: {leverage}x Amount: ${trade_amount} Market Data: {json.dumps(klines, indent=2)} Only return valid JSON: {{ "direction": "long" or "short", "entry_price": float, "recommended_leverage": int (10-75), "take_profit": {{ "first": float, "second": float, "third": float }}, "recommendation": "It is recommended to enter the transaction." or "It is not recommended to enter into a transaction." or "Entering the trade with caution" }} """ def _parse_response( self, response: str, symbol: str, current_price: float, trade_amount: float ): try: if response.startswith("```json"): response = response[7:] if response.endswith("```"): response = response[:-3] data = json.loads(response) rec_map = { "It is recommended to enter the transaction.": RecommendationType.RECOMMENDED, "It is not recommended to enter into a transaction.": RecommendationType.NOT_RECOMMENDED, "Entering the trade with caution": RecommendationType.CAUTIOUS, } return TradeSuggestion( symbol=symbol, direction=TradeDirection(data["direction"]), entry_price=float(data["entry_price"]), recommended_leverage=int(data["recommended_leverage"]), take_profit=TakeProfitPoints(**data["take_profit"]), recommendation=rec_map.get( data["recommendation"], RecommendationType.CAUTIOUS ), current_price=current_price, trade_amount=trade_amount, ) except Exception as e: raise ValueError(f"Failed to parse AI response: {e}\nRaw: {response}") def generate( self, symbol, leverage, trade_amount, market_data, current_price, provider, openai_key, hf_token, ): prompt = self._prepare_prompt( symbol, leverage, trade_amount, market_data, current_price ) if provider == "OpenAI": openai.api_key = openai_key try: res = openai.ChatCompletion.create( model="gpt-3.5-turbo", messages=[ { "role": "system", "content": "You are a crypto trading expert.", }, {"role": "user", "content": prompt}, ], temperature=0.2, ) content = res.choices[0].message.content return self._parse_response( content, symbol, current_price, trade_amount ) except Exception as e: print(f"OpenAI Error: {e}") return None elif provider == "HuggingFace": try: headers = {"Authorization": f"Bearer {hf_token}"} data = {"inputs": prompt} url = "https://api-inference.huggingface.co/models/tiiuae/falcon-7b" res = requests.post(url, headers=headers, json=data) response = res.json() text = response[0]["generated_text"] return self._parse_response(text, symbol, current_price, trade_amount) except Exception as e: print(f"HuggingFace Error: {e}") return None