106 lines
3.6 KiB
Python
106 lines
3.6 KiB
Python
from typing import Optional, List, Dict, Any
|
|
import httpx
|
|
|
|
|
|
class MiniMaxLLM:
|
|
def __init__(self, api_key: str, model: str = "MiniMax-M2.7", **kwargs):
|
|
self.api_key = api_key
|
|
self.model = model
|
|
self.base_url = "https://api.minimax.io/v1"
|
|
|
|
def _call(self, messages: List[Dict[str, str]], **kwargs) -> str:
|
|
headers = {
|
|
"Authorization": f"Bearer {self.api_key}",
|
|
"Content-Type": "application/json",
|
|
}
|
|
payload = {
|
|
"model": self.model,
|
|
"messages": messages,
|
|
"temperature": kwargs.get("temperature", 0.7),
|
|
"max_tokens": kwargs.get("max_tokens", 2048),
|
|
}
|
|
with httpx.Client(timeout=60.0) as client:
|
|
response = client.post(
|
|
f"{self.base_url}/text/chatcompletion_v2",
|
|
headers=headers,
|
|
json=payload,
|
|
)
|
|
response.raise_for_status()
|
|
return response.json()["choices"][0]["message"]["content"]
|
|
|
|
def call(self, messages: List[Dict[str, str]], **kwargs) -> str:
|
|
return self._call(messages, **kwargs)
|
|
|
|
|
|
class MiniMaxConnector:
|
|
def __init__(self, api_key: str, model: str = "MiniMax-M2.7"):
|
|
self.api_key = api_key
|
|
self.model = model
|
|
|
|
def chat(self, messages: list[dict], **kwargs) -> str:
|
|
formatted_messages = []
|
|
for msg in messages:
|
|
if isinstance(msg, dict):
|
|
formatted_messages.append(
|
|
{
|
|
"role": msg.get("role", "user"),
|
|
"content": msg.get("content", str(msg)),
|
|
}
|
|
)
|
|
else:
|
|
formatted_messages.append({"role": "user", "content": str(msg)})
|
|
|
|
llm = MiniMaxLLM(api_key=self.api_key, model=self.model)
|
|
return llm.call(formatted_messages, **kwargs)
|
|
|
|
def parse_strategy(
|
|
self, user_message: str, conversation_history: list[dict] = None
|
|
) -> dict:
|
|
system_prompt = """You are a trading strategy designer. Parse the user's natural language request into a JSON strategy_config object.
|
|
|
|
Supported conditions (MVP):
|
|
- price_drop: Token price drops by X% (requires: token, threshold)
|
|
- price_rise: Token price rises by X% (requires: token, threshold)
|
|
- volume_spike: Trading volume increases X% (requires: token, threshold)
|
|
- price_level: Price crosses above/below X (requires: token, price, direction)
|
|
|
|
Output ONLY valid JSON with this schema:
|
|
{
|
|
"conditions": [
|
|
{
|
|
"type": "price_drop|price_rise|volume_spike|price_level",
|
|
"token": "TOKEN_SYMBOL",
|
|
"chain": "bsc",
|
|
"threshold": number, // for price_drop, price_rise, volume_spike
|
|
"price": number, // for price_level
|
|
"direction": "above|below", // for price_level
|
|
"timeframe": "1h"
|
|
}
|
|
],
|
|
"actions": [
|
|
{
|
|
"type": "buy|sell|notify"
|
|
}
|
|
]
|
|
}
|
|
|
|
If the user wants a condition not in the supported list, ask for clarification.
|
|
"""
|
|
|
|
messages = [{"role": "system", "content": system_prompt}]
|
|
if conversation_history:
|
|
for msg in conversation_history:
|
|
messages.append(
|
|
{"role": msg.get("role", "user"), "content": msg.get("content", "")}
|
|
)
|
|
messages.append({"role": "user", "content": user_message})
|
|
|
|
response = self.chat(messages)
|
|
try:
|
|
import json
|
|
|
|
result = json.loads(response)
|
|
return result
|
|
except json.JSONDecodeError:
|
|
return {"error": "Failed to parse strategy", "raw_response": response}
|