90 lines
3.2 KiB
Python
90 lines
3.2 KiB
Python
from abc import ABC, abstractmethod
|
|
from loguru import logger
|
|
from typing import List, Dict, Any
|
|
import json
|
|
|
|
from utils.redis_client import RedisClient
|
|
from utils.database_manager import DatabaseManager
|
|
|
|
class BaseSync(ABC):
|
|
"""同步基类"""
|
|
|
|
def __init__(self):
|
|
self.redis_client = RedisClient()
|
|
self.db_manager = DatabaseManager()
|
|
self.computer_name = None # 从配置读取
|
|
|
|
@abstractmethod
|
|
async def sync(self):
|
|
"""执行同步"""
|
|
pass
|
|
|
|
def get_accounts_from_redis(self) -> Dict[str, Dict]:
|
|
"""从Redis获取账号配置"""
|
|
try:
|
|
if self.computer_name is None:
|
|
from config.settings import COMPUTER_NAME
|
|
self.computer_name = COMPUTER_NAME
|
|
|
|
# 从Redis获取数据
|
|
result = self.redis_client.client.hgetall(f"{self.computer_name}_strategy_api")
|
|
if not result:
|
|
logger.warning(f"未找到 {self.computer_name} 的策略API配置")
|
|
return {}
|
|
|
|
accounts_dict = {}
|
|
for exchange_name, accounts_json in result.items():
|
|
try:
|
|
accounts = json.loads(accounts_json)
|
|
if not accounts:
|
|
continue
|
|
|
|
# 格式化交易所ID
|
|
exchange_id = self.format_exchange_id(exchange_name)
|
|
|
|
for account_id, account_info in accounts.items():
|
|
parsed_account = self.parse_account(exchange_id, account_id, account_info)
|
|
if parsed_account:
|
|
accounts_dict[account_id] = parsed_account
|
|
|
|
except json.JSONDecodeError as e:
|
|
logger.error(f"解析交易所 {exchange_name} 的JSON数据失败: {e}")
|
|
continue
|
|
|
|
return accounts_dict
|
|
|
|
except Exception as e:
|
|
logger.error(f"获取账户信息失败: {e}")
|
|
return {}
|
|
|
|
def format_exchange_id(self, key: str) -> str:
|
|
"""格式化交易所ID"""
|
|
key = key.lower().strip()
|
|
|
|
# 交易所名称映射
|
|
exchange_mapping = {
|
|
'metatrader': 'mt5',
|
|
'binance_spot_test': 'binance',
|
|
'binance_spot': 'binance',
|
|
'binance': 'binance',
|
|
'gate_spot': 'gate',
|
|
'okex': 'okx'
|
|
}
|
|
|
|
return exchange_mapping.get(key, key)
|
|
|
|
def parse_account(self, exchange_id: str, account_id: str, account_info: str) -> Dict:
|
|
"""解析账号信息"""
|
|
try:
|
|
source_account_info = json.loads(account_info)
|
|
account_data = {
|
|
'exchange_id': exchange_id,
|
|
'k_id': account_id,
|
|
'st_id': int(source_account_info.get('st_id', 0)),
|
|
'add_time': int(source_account_info.get('add_time', 0))
|
|
}
|
|
return {**source_account_info, **account_data}
|
|
|
|
except json.JSONDecodeError as e:
|
|
logger.error(f"解析账号 {account_id} 数据失败: {e}")
|
|
return {} |