期货交易策略自动化实现

期货交易策略自动化实现

1. 项目概述

本项目旨在为期货交易客户开发一个自动化交易系统,基于Python实现其交易策略。系统将包含数据获取、策略逻辑、风险控制、订单执行和绩效分析等模块,实现全自动化的期货交易。

2. 系统架构设计

2.1 系统组件

  • 数据模块:实时市场数据获取与处理
  • 策略模块:交易逻辑实现
  • 风控模块:资金管理与风险控制
  • 执行模块:订单生成与执行
  • 监控模块:实时监控与报警
  • 回测模块:历史数据测试与优化

2.2 技术栈

  • 编程语言:Python 3.8+
  • 数据获取:Tushare、AkShare、API接口
  • 数据库:MySQL/PostgreSQL/SQLite
  • 可视化:Matplotlib、Plotly、PyQt5
  • 并发处理:Asyncio、Multiprocessing
  • 部署:Docker、Linux服务器

3. 数据模块实现

3.1 数据获取类

python 复制代码
import pandas as pd
import numpy as np
import akshare as ak
import tushare as ts
import requests
import time
import json
from datetime import datetime, timedelta
import sqlite3
import logging

class DataFetcher:
    def __init__(self, config_path="config.json"):
        self.logger = logging.getLogger(__name__)
        self.load_config(config_path)
        self.setup_database()
        
    def load_config(self, config_path):
        """加载配置文件"""
        try:
            with open(config_path, 'r') as f:
                self.config = json.load(f)
            self.logger.info("配置文件加载成功")
        except FileNotFoundError:
            self.logger.error("配置文件未找到,使用默认配置")
            self.config = {
                "database": {
                    "path": "futures_data.db"
                },
                "data_sources": {
                    "preferred": "akshare",
                    "backup": "tushare"
                }
            }
    
    def setup_database(self):
        """设置数据库连接"""
        self.db_path = self.config['database']['path']
        self.conn = sqlite3.connect(self.db_path)
        self.create_tables()
    
    def create_tables(self):
        """创建数据表"""
        cursor = self.conn.cursor()
        
        # 创建期货合约信息表
        cursor.execute('''
        CREATE TABLE IF NOT EXISTS futures_info (
            symbol TEXT PRIMARY KEY,
            name TEXT,
            exchange TEXT,
            contract_multiplier REAL,
            margin_ratio REAL,
            min_price_move REAL,
            list_date TEXT,
            delist_date TEXT,
            update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
        ''')
        
        # 创建日线数据表
        cursor.execute('''
        CREATE TABLE IF NOT EXISTS daily_data (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            symbol TEXT,
            trade_date TEXT,
            open REAL,
            high REAL,
            low REAL,
            close REAL,
            volume INTEGER,
            open_interest REAL,
            turnover REAL,
            settlement REAL,
            pre_settlement REAL,
            change REAL,
            change_rate REAL,
            update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            UNIQUE(symbol, trade_date)
        )
        ''')
        
        # 创建分钟线数据表
        cursor.execute('''
        CREATE TABLE IF NOT EXISTS minute_data (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            symbol TEXT,
            datetime TEXT,
            open REAL,
            high REAL,
            low REAL,
            close REAL,
            volume INTEGER,
            open_interest REAL,
            period TEXT,
            update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            UNIQUE(symbol, datetime, period)
        )
        ''')
        
        self.conn.commit()
        self.logger.info("数据库表创建完成")
    
    def fetch_futures_list(self, exchange=None):
        """获取期货合约列表"""
        try:
            if self.config['data_sources']['preferred'] == 'akshare':
                futures_list = ak.futures_zh_spot()
                # 数据处理和存储
                futures_list.to_sql('futures_info', self.conn, if_exists='replace', index=False)
                self.logger.info(f"获取期货列表成功,共{len(futures_list)}个合约")
                return futures_list
            else:
                # 其他数据源实现
                pass
        except Exception as e:
            self.logger.error(f"获取期货列表失败: {str(e)}")
            return self.fetch_futures_list_backup(exchange)
    
    def fetch_daily_data(self, symbol, start_date, end_date):
        """获取日线数据"""
        try:
            if self.config['data_sources']['preferred'] == 'akshare':
                df = ak.futures_zh_daily(symbol=symbol, start_date=start_date, end_date=end_date)
                df['symbol'] = symbol
                df.to_sql('daily_data', self.conn, if_exists='append', index=False)
                self.logger.info(f"获取{symbol}日线数据成功,共{len(df)}条记录")
                return df
            else:
                # 其他数据源实现
                pass
        except Exception as e:
            self.logger.error(f"获取{symbol}日线数据失败: {str(e)}")
            return self.fetch_daily_data_backup(symbol, start_date, end_date)
    
    def fetch_realtime_data(self, symbols):
        """获取实时行情数据"""
        realtime_data = {}
        for symbol in symbols:
            try:
                # 实现实时数据获取逻辑
                # 这里使用模拟数据
                realtime_data[symbol] = {
                    'datetime': datetime.now(),
                    'last_price': np.random.uniform(1000, 5000),
                    'volume': np.random.randint(100, 10000),
                    'open_interest': np.random.uniform(1000, 50000),
                    'bid_price': np.random.uniform(1000, 5000),
                    'ask_price': np.random.uniform(1000, 5000),
                    'bid_volume': np.random.randint(1, 100),
                    'ask_volume': np.random.randint(1, 100)
                }
            except Exception as e:
                self.logger.error(f"获取{symbol}实时数据失败: {str(e)}")
        
        return realtime_data
    
    def fetch_daily_data_backup(self, symbol, start_date, end_date):
        """备用数据源获取日线数据"""
        # 实现备用数据源逻辑
        pass
    
    def cleanup(self):
        """清理资源"""
        if self.conn:
            self.conn.close()

3.2 数据处理类

python 复制代码
class DataProcessor:
    def __init__(self, data_fetcher):
        self.data_fetcher = data_fetcher
        self.logger = logging.getLogger(__name__)
    
    def calculate_technical_indicators(self, df, symbol):
        """计算技术指标"""
        try:
            # 确保数据按时间排序
            df = df.sort_values('trade_date')
            
            # 移动平均线
            df['ma5'] = df['close'].rolling(window=5).mean()
            df['ma10'] = df['close'].rolling(window=10).mean()
            df['ma20'] = df['close'].rolling(window=20).mean()
            df['ma60'] = df['close'].rolling(window=60).mean()
            
            # 指数移动平均线
            df['ema12'] = df['close'].ewm(span=12).mean()
            df['ema26'] = df['close'].ewm(span=26).mean()
            df['macd'] = df['ema12'] - df['ema26']
            df['macd_signal'] = df['macd'].ewm(span=9).mean()
            df['macd_hist'] = df['macd'] - df['macd_signal']
            
            # 相对强弱指数
            delta = df['close'].diff()
            gain = (delta.where(delta > 0, 0)).rolling(window=14).mean()
            loss = (-delta.where(delta < 0, 0)).rolling(window=14).mean()
            rs = gain / loss
            df['rsi'] = 100 - (100 / (1 + rs))
            
            # 布林带
            df['bb_middle'] = df['close'].rolling(window=20).mean()
            bb_std = df['close'].rolling(window=20).std()
            df['bb_upper'] = df['bb_middle'] + 2 * bb_std
            df['bb_lower'] = df['bb_middle'] - 2 * bb_std
            
            # 平均真实范围
            high_low = df['high'] - df['low']
            high_close = np.abs(df['high'] - df['close'].shift())
            low_close = np.abs(df['low'] - df['close'].shift())
            ranges = pd.concat([high_low, high_close, low_close], axis=1)
            true_range = ranges.max(axis=1)
            df['atr'] = true_range.rolling(window=14).mean()
            
            # 动量指标
            df['momentum'] = df['close'] - df['close'].shift(4)
            
            self.logger.info(f"技术指标计算完成: {symbol}")
            return df
            
        except Exception as e:
            self.logger.error(f"计算技术指标失败: {str(e)}")
            return df
    
    def detect_patterns(self, df, symbol):
        """检测价格形态"""
        patterns = {}
        
        # 检测支撑阻力位
        patterns['support_resistance'] = self.find_support_resistance(df)
        
        # 检测趋势
        patterns['trend'] = self.detect_trend(df)
        
        # 检测价格形态(头肩顶、双底等)
        patterns['price_patterns'] = self.detect_price_patterns(df)
        
        return patterns
    
    def find_support_resistance(self, df, window=20):
        """寻找支撑阻力位"""
        # 实现支撑阻力位检测逻辑
        support_levels = []
        resistance_levels = []
        
        # 简化实现:使用近期高点和低点
        for i in range(window, len(df) - window):
            window_high = df['high'].iloc[i-window:i+window].max()
            window_low = df['low'].iloc[i-window:i+window].min()
            
            if df['high'].iloc[i] == window_high:
                resistance_levels.append((df.index[i], df['high'].iloc[i]))
            elif df['low'].iloc[i] == window_low:
                support_levels.append((df.index[i], df['low'].iloc[i]))
        
        return {
            'support': support_levels[-5:],  # 返回最近5个支撑位
            'resistance': resistance_levels[-5:]  # 返回最近5个阻力位
        }
    
    def detect_trend(self, df):
        """检测趋势"""
        # 使用移动平均线判断趋势
        if len(df) < 20:
            return "震荡"
        
        current_close = df['close'].iloc[-1]
        ma20 = df['ma20'].iloc[-1]
        ma60 = df['ma60'].iloc[-1]
        
        if current_close > ma20 > ma60:
            return "强势上涨"
        elif current_close > ma20 and ma20 > ma60:
            return "上涨"
        elif ma60 > ma20 > current_close:
            return "强势下跌"
        elif ma60 > ma20 and ma20 > current_close:
            return "下跌"
        else:
            return "震荡"
    
    def detect_price_patterns(self, df):
        """检测价格形态"""
        # 实现价格形态检测逻辑
        patterns = []
        
        # 这里可以添加头肩顶、双底、三角形等形态检测
        
        return patterns

4. 策略模块实现

4.1 策略基类

python 复制代码
from abc import ABC, abstractmethod
import talib

class TradingStrategy(ABC):
    def __init__(self, name, params):
        self.name = name
        self.params = params
        self.logger = logging.getLogger(__name__)
        self.positions = {}
        self.signals = {}
    
    @abstractmethod
    def generate_signals(self, data):
        """生成交易信号"""
        pass
    
    @abstractmethod
    def calculate_position_size(self, signal, account_info):
        """计算仓位大小"""
        pass
    
    def update_params(self, new_params):
        """更新策略参数"""
        self.params.update(new_params)
        self.logger.info(f"策略参数已更新: {new_params}")
    
    def backtest(self, historical_data, initial_capital=1000000):
        """策略回测"""
        # 实现回测逻辑
        pass

4.2 均线交叉策略

python 复制代码
class MovingAverageCrossoverStrategy(TradingStrategy):
    def __init__(self, params=None):
        if params is None:
            params = {
                'fast_ma_period': 5,
                'slow_ma_period': 20,
                'stop_loss_pct': 0.02,
                'take_profit_pct': 0.04,
                'trailing_stop_pct': 0.01
            }
        super().__init__("Moving Average Crossover", params)
    
    def generate_signals(self, data):
        """生成均线交叉信号"""
        signals = {}
        
        for symbol, df in data.items():
            if len(df) < self.params['slow_ma_period']:
                continue
            
            # 计算移动平均线
            fast_ma = df['close'].rolling(window=self.params['fast_ma_period']).mean()
            slow_ma = df['close'].rolling(window=self.params['slow_ma_period']).mean()
            
            current_fast_ma = fast_ma.iloc[-1]
            current_slow_ma = slow_ma.iloc[-1]
            prev_fast_ma = fast_ma.iloc[-2]
            prev_slow_ma = slow_ma.iloc[-2]
            
            # 生成信号
            signal = {
                'symbol': symbol,
                'timestamp': df.index[-1],
                'price': df['close'].iloc[-1],
                'action': 'hold',
                'strength': 0,
                'stop_loss': None,
                'take_profit': None
            }
            
            # 金叉:快线上穿慢线
            if prev_fast_ma <= prev_slow_ma and current_fast_ma > current_slow_ma:
                signal['action'] = 'buy'
                signal['strength'] = (current_fast_ma - current_slow_ma) / current_slow_ma
                # 设置止损止盈
                signal['stop_loss'] = signal['price'] * (1 - self.params['stop_loss_pct'])
                signal['take_profit'] = signal['price'] * (1 + self.params['take_profit_pct'])
            
            # 死叉:快线下穿慢线
            elif prev_fast_ma >= prev_slow_ma and current_fast_ma < current_slow_ma:
                signal['action'] = 'sell'
                signal['strength'] = (current_slow_ma - current_fast_ma) / current_slow_ma
                # 设置止损止盈
                signal['stop_loss'] = signal['price'] * (1 + self.params['stop_loss_pct'])
                signal['take_profit'] = signal['price'] * (1 - self.params['take_profit_pct'])
            
            signals[symbol] = signal
        
        self.signals = signals
        return signals
    
    def calculate_position_size(self, signal, account_info):
        """基于风险管理的仓位计算"""
        if signal['action'] == 'hold':
            return 0
        
        # 计算风险金额(账户资金的2%)
        risk_amount = account_info['equity'] * 0.02
        
        # 计算每点价值(需要根据具体合约调整)
        point_value = 10  # 假设每点价值10元
        
        # 计算止损点数
        if signal['action'] == 'buy':
            stop_loss_points = (signal['price'] - signal['stop_loss']) / point_value
        else:
            stop_loss_points = (signal['stop_loss'] - signal['price']) / point_value
        
        # 避免除零错误
        if stop_loss_points <= 0:
            return 0
        
        # 计算合约数量
        position_size = risk_amount / (stop_loss_points * point_value)
        
        # 考虑最大仓位限制
        max_position = account_info['equity'] * 0.1 / signal['price']  # 单品种不超过10%
        position_size = min(position_size, max_position)
        
        return int(position_size)

4.3 动量策略

python 复制代码
class MomentumStrategy(TradingStrategy):
    def __init__(self, params=None):
        if params is None:
            params = {
                'rsi_period': 14,
                'rsi_overbought': 70,
                'rsi_oversold': 30,
                'macd_fast': 12,
                'macd_slow': 26,
                'macd_signal': 9,
                'stop_loss_pct': 0.015,
                'take_profit_pct': 0.03
            }
        super().__init__("Momentum Strategy", params)
    
    def generate_signals(self, data):
        """生成动量信号"""
        signals = {}
        
        for symbol, df in data.items():
            if len(df) < max(self.params['rsi_period'], self.params['macd_slow'] + self.params['macd_signal']):
                continue
            
            # 计算技术指标
            rsi = self.calculate_rsi(df['close'], self.params['rsi_period'])
            macd, macd_signal, macd_hist = self.calculate_macd(
                df['close'], 
                self.params['macd_fast'], 
                self.params['macd_slow'], 
                self.params['macd_signal']
            )
            
            current_rsi = rsi.iloc[-1]
            current_macd = macd.iloc[-1]
            current_macd_signal = macd_signal.iloc[-1]
            prev_macd = macd.iloc[-2]
            prev_macd_signal = macd_signal.iloc[-2]
            
            signal = {
                'symbol': symbol,
                'timestamp': df.index[-1],
                'price': df['close'].iloc[-1],
                'action': 'hold',
                'strength': 0,
                'rsi': current_rsi,
                'macd': current_macd,
                'macd_hist': macd_hist.iloc[-1],
                'stop_loss': None,
                'take_profit': None
            }
            
            # 生成买入信号:RSI超卖或MACD金叉
            buy_condition = (
                (current_rsi < self.params['rsi_oversold']) or
                (prev_macd <= prev_macd_signal and current_macd > current_macd_signal)
            )
            
            # 生成卖出信号:RSI超买或MACD死叉
            sell_condition = (
                (current_rsi > self.params['rsi_overbought']) or
                (prev_macd >= prev_macd_signal and current_macd < current_macd_signal)
            )
            
            if buy_condition:
                signal['action'] = 'buy'
                signal['strength'] = self.calculate_signal_strength(signal, 'buy')
                signal['stop_loss'] = signal['price'] * (1 - self.params['stop_loss_pct'])
                signal['take_profit'] = signal['price'] * (1 + self.params['take_profit_pct'])
            
            elif sell_condition:
                signal['action'] = 'sell'
                signal['strength'] = self.calculate_signal_strength(signal, 'sell')
                signal['stop_loss'] = signal['price'] * (1 + self.params['stop_loss_pct'])
                signal['take_profit'] = signal['price'] * (1 - self.params['take_profit_pct'])
            
            signals[symbol] = signal
        
        self.signals = signals
        return signals
    
    def calculate_rsi(self, prices, period):
        """计算RSI指标"""
        delta = prices.diff()
        gain = (delta.where(delta > 0, 0)).rolling(window=period).mean()
        loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean()
        rs = gain / loss
        rsi = 100 - (100 / (1 + rs))
        return rsi
    
    def calculate_macd(self, prices, fast_period, slow_period, signal_period):
        """计算MACD指标"""
        ema_fast = prices.ewm(span=fast_period).mean()
        ema_slow = prices.ewm(span=slow_period).mean()
        macd = ema_fast - ema_slow
        macd_signal = macd.ewm(span=signal_period).mean()
        macd_hist = macd - macd_signal
        return macd, macd_signal, macd_hist
    
    def calculate_signal_strength(self, signal, action):
        """计算信号强度"""
        strength = 0
        
        if action == 'buy':
            # RSI越低,买入信号越强
            rsi_strength = max(0, (self.params['rsi_oversold'] - signal['rsi']) / self.params['rsi_oversold'])
            # MACD柱状线越负,买入信号越强
            macd_strength = max(0, -signal['macd_hist'] / (signal['price'] * 0.01))  # 标准化
            
            strength = (rsi_strength * 0.6 + macd_strength * 0.4) * 100
        
        else:  # sell
            # RSI越高,卖出信号越强
            rsi_strength = max(0, (signal['rsi'] - self.params['rsi_overbought']) / (100 - self.params['rsi_overbought']))
            # MACD柱状线越正,卖出信号越强
            macd_strength = max(0, signal['macd_hist'] / (signal['price'] * 0.01))  # 标准化
            
            strength = (rsi_strength * 0.6 + macd_strength * 0.4) * 100
        
        return min(strength, 100)  # 限制在0-100范围内
    
    def calculate_position_size(self, signal, account_info):
        """基于波动率的仓位计算"""
        if signal['action'] == 'hold':
            return 0
        
        # 计算ATR(平均真实范围)
        # 这里简化处理,实际需要计算ATR
        atr = signal['price'] * 0.01  # 假设ATR为价格的1%
        
        # 计算风险金额(账户资金的1.5%)
        risk_amount = account_info['equity'] * 0.015
        
        # 计算合约数量
        position_size = risk_amount / (atr * 1.5)  # 1.5倍ATR作为止损
        
        # 考虑最大仓位限制
        max_position = account_info['equity'] * 0.08 / signal['price']  # 单品种不超过8%
        position_size = min(position_size, max_position)
        
        return int(position_size)

4.4 策略组合管理

python 复制代码
class StrategyManager:
    def __init__(self, strategies, weights=None):
        self.strategies = strategies
        self.weights = weights or [1/len(strategies)] * len(strategies)
        self.logger = logging.getLogger(__name__)
        self.combined_signals = {}
    
    def generate_combined_signals(self, data):
        """生成组合信号"""
        all_signals = {}
        
        # 收集所有策略的信号
        for i, strategy in enumerate(self.strategies):
            signals = strategy.generate_signals(data)
            for symbol, signal in signals.items():
                if symbol not in all_signals:
                    all_signals[symbol] = []
                all_signals[symbol].append({
                    'strategy': strategy.name,
                    'signal': signal,
                    'weight': self.weights[i]
                })
        
        # 组合信号
        combined_signals = {}
        for symbol, signal_list in all_signals.items():
            combined_signal = self.combine_signals(signal_list)
            combined_signals[symbol] = combined_signal
        
        self.combined_signals = combined_signals
        return combined_signals
    
    def combine_signals(self, signal_list):
        """组合多个策略的信号"""
        if not signal_list:
            return None
        
        # 初始化组合信号
        combined = {
            'symbol': signal_list[0]['signal']['symbol'],
            'timestamp': signal_list[0]['signal']['timestamp'],
            'price': signal_list[0]['signal']['price'],
            'action': 'hold',
            'strength': 0,
            'component_signals': [],
            'stop_loss': None,
            'take_profit': None
        }
        
        buy_strength = 0
        sell_strength = 0
        total_weight = 0
        
        for item in signal_list:
            signal = item['signal']
            weight = item['weight']
            
            combined['component_signals'].append({
                'strategy': item['strategy'],
                'action': signal['action'],
                'strength': signal['strength']
            })
            
            if signal['action'] == 'buy':
                buy_strength += signal['strength'] * weight
                total_weight += weight
            elif signal['action'] == 'sell':
                sell_strength += signal['strength'] * weight
                total_weight += weight
        
        if total_weight > 0:
            if buy_strength > sell_strength:
                combined['action'] = 'buy'
                combined['strength'] = buy_strength / total_weight
            elif sell_strength > buy_strength:
                combined['action'] = 'sell'
                combined['strength'] = sell_strength / total_weight
        
        # 设置止损止盈(使用加权平均)
        stop_loss_sum = 0
        take_profit_sum = 0
        weight_sum = 0
        
        for item in signal_list:
            signal = item['signal']
            weight = item['weight']
            
            if signal['stop_loss'] is not None and signal['action'] == combined['action']:
                stop_loss_sum += signal['stop_loss'] * weight
                take_profit_sum += signal['take_profit'] * weight
                weight_sum += weight
        
        if weight_sum > 0:
            combined['stop_loss'] = stop_loss_sum / weight_sum
            combined['take_profit'] = take_profit_sum / weight_sum
        
        return combined
    
    def update_strategy_weights(self, new_weights):
        """更新策略权重"""
        if len(new_weights) != len(self.strategies):
            self.logger.error("权重数量与策略数量不匹配")
            return False
        
        self.weights = new_weights
        self.logger.info(f"策略权重已更新: {new_weights}")
        return True

5. 风险控制模块

5.1 风控管理器

python 复制代码
class RiskManager:
    def __init__(self, config):
        self.config = config
        self.logger = logging.getLogger(__name__)
        self.violations = []
    
    def check_position_risk(self, positions, account_info):
        """检查持仓风险"""
        risks = {
            'max_position_risk': self.check_max_position_risk(positions, account_info),
            'sector_exposure': self.check_sector_exposure(positions, account_info),
            'liquidity_risk': self.check_liquidity_risk(positions),
            'leverage_risk': self.check_leverage_risk(positions, account_info)
        }
        
        # 检查是否有风险违规
        has_violation = any(risks.values())
        if has_violation:
            self.logger.warning("发现风险违规,需要调整仓位")
            self.violations.append({
                'timestamp': datetime.now(),
                'risks': risks
            })
        
        return risks
    
    def check_max_position_risk(self, positions, account_info):
        """检查单品种最大仓位风险"""
        violation = False
        for symbol, position in positions.items():
            position_value = position['quantity'] * position['current_price']
            position_ratio = position_value / account_info['equity']
            
            if position_ratio > self.config['max_position_ratio']:
                self.logger.warning(
                    f"品种{symbol}仓位超过限制: {position_ratio:.2%} > "
                    f"{self.config['max_position_ratio']:.2%}"
                )
                violation = True
        
        return violation
    
    def check_sector_exposure(self, positions, account_info):
        """检查行业暴露风险"""
        # 这里需要根据期货品种的行业分类进行检查
        # 简化实现:假设所有品种属于同一行业
        total_exposure = sum(
            pos['quantity'] * pos['current_price'] 
            for pos in positions.values()
        )
        
        exposure_ratio = total_exposure / account_info['equity']
        violation = exposure_ratio > self.config['max_sector_exposure']
        
        if violation:
            self.logger.warning(
                f"行业暴露超过限制: {exposure_ratio:.2%} > "
                f"{self.config['max_sector_exposure']:.2%}"
            )
        
        return violation
    
    def check_liquidity_risk(self, positions):
        """检查流动性风险"""
        # 实现流动性检查逻辑
        # 这里简化处理
        return False
    
    def check_leverage_risk(self, positions, account_info):
        """检查杠杆风险"""
        total_position_value = sum(
            pos['quantity'] * pos['current_price'] 
            for pos in positions.values()
        )
        
        leverage = total_position_value / account_info['equity']
        violation = leverage > self.config['max_leverage']
        
        if violation:
            self.logger.warning(
                f"杠杆超过限制: {leverage:.2f} > {self.config['max_leverage']}"
            )
        
        return violation
    
    def generate_risk_adjustment(self, signals, positions, account_info):
        """生成风险调整建议"""
        adjustments = []
        
        # 检查现有持仓的风险
        risk_result = self.check_position_risk(positions, account_info)
        
        # 如果有风险违规,生成减仓建议
        if any(risk_result.values()):
            for symbol, position in positions.items():
                position_value = position['quantity'] * position['current_price']
                position_ratio = position_value / account_info['equity']
                
                if position_ratio > self.config['max_position_ratio']:
                    target_value = account_info['equity'] * self.config['max_position_ratio']
                    reduce_quantity = position['quantity'] - (target_value / position['current_price'])
                    
                    adjustments.append({
                        'symbol': symbol,
                        'action': 'reduce',
                        'quantity': max(0, int(reduce_quantity)),
                        'reason': '超过单品种仓位限制'
                    })
        
        # 对新信号进行风险检查
        for symbol, signal in signals.items():
            if signal['action'] == 'hold':
                continue
            
            # 计算拟建仓价值
            proposed_size = signal.get('proposed_quantity', 0)
            proposed_value = proposed_size * signal['price']
            proposed_ratio = proposed_value / account_info['equity']
            
            # 检查是否超过单品种限制
            if proposed_ratio > self.config['max_position_ratio']:
                max_value = account_info['equity'] * self.config['max_position_ratio']
                max_quantity = int(max_value / signal['price'])
                
                adjustments.append({
                    'symbol': symbol,
                    'action': 'adjust',
                    'original_quantity': proposed_size,
                    'adjusted_quantity': max_quantity,
                    'reason': '超过单品种仓位限制'
                })
            
            # 检查是否会导致行业暴露超标
            current_exposure = sum(
                pos['quantity'] * pos['current_price'] 
                for pos in positions.values()
            )
            new_exposure = current_exposure + proposed_value
            
            if new_exposure / account_info['equity'] > self.config['max_sector_exposure']:
                max_additional = (account_info['equity'] * self.config['max_sector_exposure'] - current_exposure)
                max_quantity = int(max_additional / signal['price'])
                
                adjustments.append({
                    'symbol': symbol,
                    'action': 'adjust',
                    'original_quantity': proposed_size,
                    'adjusted_quantity': min(proposed_size, max_quantity),
                    'reason': '超过行业暴露限制'
                })
        
        return adjustments

5.2 资金管理类

python 复制代码
class MoneyManager:
    def __init__(self, config):
        self.config = config
        self.logger = logging.getLogger(__name__)
        self.performance_history = []
    
    def calculate_position_size(self, signal, account_info, risk_per_trade=0.02):
        """基于风险的仓位计算"""
        if signal['action'] == 'hold':
            return 0
        
        # 计算风险金额
        risk_amount = account_info['equity'] * risk_per_trade
        
        # 计算止损距离
        if signal['stop_loss'] is None:
            # 如果没有设置止损,使用默认百分比
            stop_loss_pct = self.config['default_stop_loss_pct']
            stop_loss_distance = signal['price'] * stop_loss_pct
        else:
            stop_loss_distance = abs(signal['price'] - signal['stop_loss'])
        
        # 避免除零错误
        if stop_loss_distance <= 0:
            return 0
        
        # 计算每点价值(需要根据具体合约调整)
        point_value = self.get_point_value(signal['symbol'])
        
        # 计算合约数量
        position_size = risk_amount / (stop_loss_distance * point_value)
        
        # 考虑最大仓位限制
        max_position = account_info['equity'] * self.config['max_position_ratio'] / signal['price']
        position_size = min(position_size, max_position)
        
        return int(position_size)
    
    def get_point_value(self, symbol):
        """获取每点价值"""
        # 这里需要根据具体期货合约设置每点价值
        # 简化实现:根据合约代码判断
        if 'IF' in symbol:  # 股指期货
            return 300
        elif 'IC' in symbol:
            return 200
        elif 'IH' in symbol:
            return 300
        elif 'AU' in symbol:  # 黄金
            return 1000
        elif 'AG' in symbol:  # 白银
            return 15
        else:  # 默认
            return 10
    
    def update_account_info(self, account_info, trades, market_data):
        """更新账户信息"""
        # 计算持仓市值
        positions_value = 0
        floating_pnl = 0
        
        for symbol, position in account_info['positions'].items():
            if symbol in market_data:
                current_price = market_data[symbol]['last_price']
                position_value = position['quantity'] * current_price
                positions_value += position_value
                
                # 计算浮动盈亏
                cost = position['quantity'] * position['avg_cost']
                floating_pnl += position_value - cost
        
        # 更新账户信息
        account_info['positions_value'] = positions_value
        account_info['floating_pnl'] = floating_pnl
        account_info['equity'] = account_info['cash'] + positions_value
        account_info['update_time'] = datetime.now()
        
        return account_info
    
    def record_performance(self, account_info, timestamp):
        """记录绩效数据"""
        performance = {
            'timestamp': timestamp,
            'equity': account_info['equity'],
            'cash': account_info['cash'],
            'positions_value': account_info['positions_value'],
            'floating_pnl': account_info['floating_pnl'],
            'drawdown': self.calculate_drawdown(account_info['equity'])
        }
        
        self.performance_history.append(performance)
        return performance
    
    def calculate_drawdown(self, current_equity):
        """计算回撤"""
        if not self.performance_history:
            return 0
        
        peak_equity = max([p['equity'] for p in self.performance_history])
        drawdown = (peak_equity - current_equity) / peak_equity if peak_equity > 0 else 0
        return drawdown

6. 订单执行模块

6.1 订单管理器

python 复制代码
class OrderManager:
    def __init__(self, broker_api, config):
        self.broker_api = broker_api
        self.config = config
        self.logger = logging.getLogger(__name__)
        self.order_history = []
        self.pending_orders = []
    
    def create_order(self, symbol, action, quantity, price=None, order_type='limit', 
                    stop_loss=None, take_profit=None, validity='day'):
        """创建订单"""
        order = {
            'order_id': self.generate_order_id(),
            'symbol': symbol,
            'action': action,
            'quantity': quantity,
            'order_type': order_type,
            'price': price,
            'stop_loss': stop_loss,
            'take_profit': take_profit,
            'validity': validity,
            'status': 'pending',
            'create_time': datetime.now(),
            'update_time': datetime.now()
        }
        
        self.pending_orders.append(order)
        self.logger.info(f"创建订单: {order}")
        
        return order
    
    def execute_orders(self, market_data):
        """执行挂单"""
        executed_orders = []
        
        for order in self.pending_orders[:]:
            if self.check_order_conditions(order, market_data):
                # 执行订单
                result = self.execute_order(order, market_data)
                if result['status'] == 'filled':
                    executed_orders.append(order)
                    self.pending_orders.remove(order)
                    self.order_history.append(order)
        
        return executed_orders
    
    def check_order_conditions(self, order, market_data):
        """检查订单执行条件"""
        symbol = order['symbol']
        if symbol not in market_data:
            return False
        
        current_price = market_data[symbol]['last_price']
        
        if order['order_type'] == 'market':
            return True
        
        elif order['order_type'] == 'limit':
            if order['action'] == 'buy':
                return current_price <= order['price']
            else:  # sell
                return current_price >= order['price']
        
        elif order['order_type'] == 'stop':
            if order['action'] == 'buy':
                return current_price >= order['price']
            else:  # sell
                return current_price <= order['price']
        
        return False
    
    def execute_order(self, order, market_data):
        """执行单个订单"""
        symbol = order['symbol']
        current_price = market_data[symbol]['last_price']
        
        # 模拟执行
        execution_price = current_price
        if order['order_type'] == 'limit' and order['price'] is not None:
            execution_price = order['price']
        
        order['status'] = 'filled'
        order['execution_price'] = execution_price
        order['execution_time'] = datetime.now()
        order['update_time'] = datetime.now()
        
        self.logger.info(f"订单执行: {order['order_id']} {order['action']} {order['quantity']} "
                        f"{symbol} @ {execution_price}")
        
        return order
    
    def cancel_order(self, order_id):
        """取消订单"""
        for order in self.pending_orders:
            if order['order_id'] == order_id:
                order['status'] = 'cancelled'
                order['update_time'] = datetime.now()
                self.pending_orders.remove(order)
                self.order_history.append(order)
                self.logger.info(f"订单取消: {order_id}")
                return True
        
        self.logger.warning(f"订单不存在或已完成: {order_id}")
        return False
    
    def generate_order_id(self):
        """生成订单ID"""
        timestamp = int(datetime.now().timestamp() * 1000)
        random_suffix = np.random.randint(1000, 9999)
        return f"ORD{timestamp}{random_suffix}"
    
    def get_order_status(self, order_id):
        """获取订单状态"""
        for order in self.pending_orders + self.order_history:
            if order['order_id'] == order_id:
                return order['status']
        
        return 'not_found'

6.2 经纪商API接口

python 复制代码
class BrokerAPI:
    def __init__(self, config):
        self.config = config
        self.logger = logging.getLogger(__name__)
        self.connected = False
    
    def connect(self):
        """连接经纪商API"""
        try:
            # 这里实现实际的API连接逻辑
            # 模拟连接过程
            time.sleep(1)
            self.connected = True
            self.logger.info("经纪商API连接成功")
            return True
        except Exception as e:
            self.logger.error(f"经纪商API连接失败: {str(e)}")
            return False
    
    def disconnect(self):
        """断开连接"""
        self.connected = False
        self.logger.info("经纪商API已断开")
    
    def get_account_info(self):
        """获取账户信息"""
        if not self.connected:
            self.logger.warning("API未连接,无法获取账户信息")
            return None
        
        # 模拟账户信息
        account_info = {
            'account_id': self.config['account_id'],
            'equity': np.random.uniform(800000, 1200000),
            'cash': np.random.uniform(500000, 800000),
            'positions_value': np.random.uniform(200000, 400000),
            'floating_pnl': np.random.uniform(-50000, 50000),
            'update_time': datetime.now()
        }
        
        return account_info
    
    def get_positions(self):
        """获取持仓信息"""
        if not self.connected:
            self.logger.warning("API未连接,无法获取持仓信息")
            return {}
        
        # 模拟持仓数据
        symbols = ['IF2401', 'IC2401', 'AU2402', 'AG2403']
        positions = {}
        
        for symbol in symbols:
            if np.random.random() > 0.7:  # 30%概率有持仓
                quantity = np.random.randint(1, 10)
                avg_cost = np.random.uniform(3000, 6000)
                
                positions[symbol] = {
                    'symbol': symbol,
                    'quantity': quantity,
                    'avg_cost': avg_cost,
                    'current_price': avg_cost * np.random.uniform(0.9, 1.1)
                }
        
        return positions
    
    def place_order(self, symbol, action, quantity, price=None, order_type='limit'):
        """下达订单"""
        if not self.connected:
            self.logger.warning("API未连接,无法下达订单")
            return None
        
        # 模拟下单
        order_id = f"BROKER{int(time.time() * 1000)}{np.random.randint(1000, 9999)}"
        
        order = {
            'order_id': order_id,
            'symbol': symbol,
            'action': action,
            'quantity': quantity,
            'order_type': order_type,
            'price': price,
            'status': 'pending',
            'place_time': datetime.now()
        }
        
        self.logger.info(f"经纪商下单: {order}")
        return order
    
    def cancel_order(self, order_id):
        """取消订单"""
        if not self.connected:
            self.logger.warning("API未连接,无法取消订单")
            return False
        
        self.logger.info(f"经纪商取消订单: {order_id}")
        return True
    
    def get_market_data(self, symbols):
        """获取市场数据"""
        if not self.connected:
            self.logger.warning("API未连接,无法获取市场数据")
            return {}
        
        market_data = {}
        for symbol in symbols:
            market_data[symbol] = {
                'last_price': np.random.uniform(3000, 6000),
                'volume': np.random.randint(1000, 10000),
                'open_interest': np.random.uniform(10000, 50000),
                'bid_price': np.random.uniform(3000, 6000),
                'ask_price': np.random.uniform(3000, 6000),
                'bid_volume': np.random.randint(1, 100),
                'ask_volume': np.random.randint(1, 100),
                'timestamp': datetime.now()
            }
        
        return market_data

7. 监控与日志模块

7.1 系统监控器

python 复制代码
class SystemMonitor:
    def __init__(self, config):
        self.config = config
        self.logger = logging.getLogger(__name__)
        self.metrics = {
            'system_health': 'normal',
            'last_check_time': datetime.now(),
            'performance_metrics': {},
            'risk_metrics': {}
        }
        self.alert_history = []
    
    def check_system_health(self, trading_engine):
        """检查系统健康状态"""
        current_time = datetime.now()
        health_status = 'normal'
        issues = []
        
        # 检查数据连接
        if not trading_engine.data_fetcher.conn:
            issues.append("数据库连接异常")
            health_status = 'warning'
        
        # 检查API连接
        if not trading_engine.broker_api.connected:
            issues.append("经纪商API连接异常")
            health_status = 'critical'
        
        # 检查策略运行状态
        for strategy in trading_engine.strategy_manager.strategies:
            if not hasattr(strategy, 'signals') or not strategy.signals:
                issues.append(f"策略{strategy.name}信号生成异常")
                health_status = 'warning'
        
        # 检查内存使用
        import psutil
        memory_usage = psutil.virtual_memory().percent
        if memory_usage > 90:
            issues.append(f"内存使用率过高: {memory_usage}%")
            health_status = 'warning'
        
        # 更新监控指标
        self.metrics.update({
            'system_health': health_status,
            'last_check_time': current_time,
            'memory_usage': memory_usage,
            'active_issues': issues
        })
        
        # 如果有严重问题,发送警报
        if health_status == 'critical' and issues:
            self.send_alert(f"系统严重异常: {', '.join(issues)}")
        
        return health_status, issues
    
    def monitor_performance(self, account_info, trades):
        """监控交易绩效"""
        performance_metrics = {
            'total_return': (account_info['equity'] - self.config['initial_capital']) / self.config['initial_capital'],
            'daily_return': 0,
            'sharpe_ratio': self.calculate_sharpe_ratio(account_info),
            'max_drawdown': self.calculate_max_drawdown(account_info),
            'win_rate': self.calculate_win_rate(trades),
            'profit_factor': self.calculate_profit_factor(trades),
            'position_ratio': account_info['positions_value'] / account_info['equity']
        }
        
        self.metrics['performance_metrics'] = performance_metrics
        return performance_metrics
    
    def calculate_sharpe_ratio(self, account_info):
        """计算夏普比率"""
        # 简化实现
        return np.random.uniform(0.5, 2.0)
    
    def calculate_max_drawdown(self, account_info):
        """计算最大回撤"""
        # 简化实现
        return np.random.uniform(0.05, 0.15)
    
    def calculate_win_rate(self, trades):
        """计算胜率"""
        if not trades:
            return 0
        
        winning_trades = [t for t in trades if t.get('pnl', 0) > 0]
        return len(winning_trades) / len(trades)
    
    def calculate_profit_factor(self, trades):
        """计算盈利因子"""
        if not trades:
            return 0
        
        gross_profit = sum(t.get('pnl', 0) for t in trades if t.get('pnl', 0) > 0)
        gross_loss = abs(sum(t.get('pnl', 0) for t in trades if t.get('pnl', 0) < 0))
        
        if gross_loss == 0:
            return float('inf')
        
        return gross_profit / gross_loss
    
    def send_alert(self, message, level='critical'):
        """发送警报"""
        alert = {
            'timestamp': datetime.now(),
            'level': level,
            'message': message,
            'acknowledged': False
        }
        
        self.alert_history.append(alert)
        self.logger.warning(f"系统警报[{level}]: {message}")
        
        # 这里可以实现邮件、短信等报警方式
        if level == 'critical':
            self.send_email_alert(message)
    
    def send_email_alert(self, message):
        """发送邮件警报"""
        # 实现邮件发送逻辑
        pass
    
    def generate_report(self, period='daily'):
        """生成监控报告"""
        report = {
            'period': period,
            'generated_time': datetime.now(),
            'system_health': self.metrics['system_health'],
            'performance_metrics': self.metrics['performance_metrics'],
            'risk_metrics': self.metrics['risk_metrics'],
            'recent_alerts': self.alert_history[-10:],  # 最近10条警报
            'recommendations': self.generate_recommendations()
        }
        
        return report
    
    def generate_recommendations(self):
        """生成系统优化建议"""
        recommendations = []
        
        if self.metrics['system_health'] != 'normal':
            recommendations.append("检查并修复系统异常状态")
        
        if self.metrics['performance_metrics'].get('max_drawdown', 0) > 0.1:
            recommendations.append("当前回撤较大,建议降低仓位或调整策略")
        
        if self.metrics['performance_metrics'].get('win_rate', 0) < 0.4:
            recommendations.append("胜率较低,建议优化策略参数或更换策略")
        
        return recommendations

7.2 日志配置

python 复制代码
def setup_logging(log_level=logging.INFO, log_file='trading_system.log'):
    """配置日志系统"""
    # 创建日志格式
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    )
    
    # 创建文件处理器
    file_handler = logging.FileHandler(log_file)
    file_handler.setFormatter(formatter)
    file_handler.setLevel(log_level)
    
    # 创建控制台处理器
    console_handler = logging.StreamHandler()
    console_handler.setFormatter(formatter)
    console_handler.setLevel(log_level)
    
    # 配置根日志记录器
    root_logger = logging.getLogger()
    root_logger.setLevel(log_level)
    root_logger.addHandler(file_handler)
    root_logger.addHandler(console_handler)
    
    # 避免第三方库的过多日志
    logging.getLogger('urllib3').setLevel(logging.WARNING)
    logging.getLogger('requests').setLevel(logging.WARNING)
    
    return root_logger

8. 主交易引擎

python 复制代码
class TradingEngine:
    def __init__(self, config_path="config.json"):
        # 加载配置
        self.load_config(config_path)
        
        # 设置日志
        self.logger = setup_logging(
            log_level=getattr(logging, self.config.get('log_level', 'INFO')),
            log_file=self.config.get('log_file', 'trading_system.log')
        )
        
        # 初始化组件
        self.initialize_components()
        
        # 运行状态
        self.running = False
        self.trading_enabled = self.config.get('trading_enabled', False)
        
        self.logger.info("交易引擎初始化完成")
    
    def load_config(self, config_path):
        """加载配置文件"""
        try:
            with open(config_path, 'r') as f:
                self.config = json.load(f)
        except FileNotFoundError:
            self.logger.warning("配置文件未找到,使用默认配置")
            self.config = {
                "log_level": "INFO",
                "log_file": "trading_system.log",
                "trading_enabled": False,
                "risk_management": {
                    "max_position_ratio": 0.1,
                    "max_sector_exposure": 0.3,
                    "max_leverage": 3,
                    "default_stop_loss_pct": 0.02
                },
                "data_update_interval": 60,
                "trading_symbols": ["IF2401", "IC2401", "AU2402", "AG2403"]
            }
    
    def initialize_components(self):
        """初始化所有组件"""
        # 数据模块
        self.data_fetcher = DataFetcher()
        self.data_processor = DataProcessor(self.data_fetcher)
        
        # 经纪商API
        self.broker_api = BrokerAPI(self.config.get('broker', {}))
        
        # 订单管理
        self.order_manager = OrderManager(self.broker_api, self.config)
        
        # 策略管理
        self.strategies = [
            MovingAverageCrossoverStrategy(),
            MomentumStrategy()
        ]
        self.strategy_manager = StrategyManager(self.strategies)
        
        # 风险管理
        self.risk_manager = RiskManager(self.config.get('risk_management', {}))
        self.money_manager = MoneyManager(self.config.get('risk_management', {}))
        
        # 系统监控
        self.monitor = SystemMonitor(self.config)
        
        # 账户信息
        self.account_info = {
            'equity': self.config.get('initial_capital', 1000000),
            'cash': self.config.get('initial_capital', 1000000),
            'positions_value': 0,
            'floating_pnl': 0,
            'positions': {}
        }
        
        # 交易历史
        self.trade_history = []
        
        self.logger.info("所有组件初始化完成")
    
    def connect_to_broker(self):
        """连接经纪商API"""
        success = self.broker_api.connect()
        if success:
            # 获取最新的账户信息和持仓
            self.update_account_info()
        
        return success
    
    def update_account_info(self):
        """更新账户信息"""
        broker_account_info = self.broker_api.get_account_info()
        broker_positions = self.broker_api.get_positions()
        
        if broker_account_info:
            self.account_info.update(broker_account_info)
        
        if broker_positions:
            self.account_info['positions'] = broker_positions
        
        self.logger.info(f"账户信息更新完成: 净值={self.account_info['equity']:.2f}")
    
    def fetch_market_data(self):
        """获取市场数据"""
        symbols = self.config.get('trading_symbols', [])
        market_data = self.broker_api.get_market_data(symbols)
        
        # 补充历史数据计算技术指标
        historical_data = {}
        for symbol in symbols:
            # 这里应该从数据库获取历史数据
            # 简化实现:使用模拟数据
            historical_data[symbol] = self.generate_sample_data(symbol)
        
        # 计算技术指标
        processed_data = {}
        for symbol, df in historical_data.items():
            processed_data[symbol] = self.data_processor.calculate_technical_indicators(df, symbol)
        
        return market_data, processed_data
    
    def generate_sample_data(self, symbol, days=100):
        """生成样本数据(用于测试)"""
        dates = pd.date_range(end=datetime.now(), periods=days, freq='D')
        prices = np.random.normal(5000, 500, days).cumsum() + 4000
        
        df = pd.DataFrame({
            'trade_date': dates,
            'open': prices * np.random.uniform(0.99, 1.01, days),
            'high': prices * np.random.uniform(1.0, 1.02, days),
            'low': prices * np.random.uniform(0.98, 1.0, days),
            'close': prices,
            'volume': np.random.randint(1000, 10000, days),
            'open_interest': np.random.uniform(10000, 50000, days)
        })
        
        df.set_index('trade_date', inplace=True)
        return df
    
    def run_strategies(self, processed_data):
        """运行策略生成信号"""
        signals = self.strategy_manager.generate_combined_signals(processed_data)
        
        # 计算建议仓位
        for symbol, signal in signals.items():
            if signal['action'] != 'hold':
                position_size = self.money_manager.calculate_position_size(
                    signal, self.account_info
                )
                signal['proposed_quantity'] = position_size
        
        return signals
    
    def apply_risk_management(self, signals):
        """应用风险管理"""
        # 检查风险并调整信号
        risk_adjustments = self.risk_manager.generate_risk_adjustment(
            signals, self.account_info['positions'], self.account_info
        )
        
        # 应用调整
        for adjustment in risk_adjustments:
            symbol = adjustment['symbol']
            if symbol in signals:
                if adjustment['action'] == 'reduce':
                    # 生成减仓信号
                    signals[symbol] = {
                        'symbol': symbol,
                        'action': 'sell',
                        'quantity': adjustment['quantity'],
                        'price': self.account_info['positions'][symbol]['current_price'],
                        'reason': adjustment['reason']
                    }
                elif adjustment['action'] == 'adjust':
                    # 调整建议仓位
                    signals[symbol]['proposed_quantity'] = adjustment['adjusted_quantity']
                    signals[symbol]['risk_adjustment'] = adjustment['reason']
        
        return signals
    
    def execute_trades(self, signals, market_data):
        """执行交易"""
        executed_orders = []
        
        for symbol, signal in signals.items():
            if signal['action'] == 'hold':
                continue
            
            # 确定订单数量和价格
            quantity = signal.get('proposed_quantity', 0)
            if quantity <= 0:
                continue
            
            # 确定订单类型和价格
            order_type = 'limit'
            price = market_data[symbol]['ask_price'] if signal['action'] == 'buy' else market_data[symbol]['bid_price']
            
            # 创建订单
            order = self.order_manager.create_order(
                symbol=symbol,
                action=signal['action'],
                quantity=quantity,
                price=price,
                order_type=order_type,
                stop_loss=signal.get('stop_loss'),
                take_profit=signal.get('take_profit')
            )
            
            # 执行订单
            executed = self.order_manager.execute_orders(market_data)
            executed_orders.extend(executed)
            
            # 记录交易
            for order in executed:
                self.record_trade(order)
        
        return executed_orders
    
    def record_trade(self, order):
        """记录交易"""
        trade = {
            'trade_id': f"TRD{int(time.time() * 1000)}{np.random.randint(1000, 9999)}",
            'order_id': order['order_id'],
            'symbol': order['symbol'],
            'action': order['action'],
            'quantity': order['quantity'],
            'price': order['execution_price'],
            'timestamp': order['execution_time'],
            'commission': self.calculate_commission(order),
            'slippage': self.calculate_slippage(order)
        }
        
        self.trade_history.append(trade)
        self.logger.info(f"交易记录: {trade}")
        
        return trade
    
    def calculate_commission(self, order):
        """计算手续费"""
        # 简化实现:按固定比例计算
        commission_rate = 0.0003  # 万分之三
        return order['execution_price'] * order['quantity'] * commission_rate
    
    def calculate_slippage(self, order):
        """计算滑点"""
        # 简化实现:按固定比例计算
        slippage_rate = 0.0001  # 万分之一
        return order['execution_price'] * order['quantity'] * slippage_rate
    
    def run_cycle(self):
        """运行一个交易周期"""
        self.logger.info("开始交易周期")
        
        try:
            # 1. 更新账户信息
            self.update_account_info()
            
            # 2. 获取市场数据
            market_data, processed_data = self.fetch_market_data()
            
            # 3. 运行策略生成信号
            signals = self.run_strategies(processed_data)
            
            # 4. 应用风险管理
            signals = self.apply_risk_management(signals)
            
            # 5. 执行交易
            if self.trading_enabled:
                executed_orders = self.execute_trades(signals, market_data)
                self.logger.info(f"本轮执行 {len(executed_orders)} 个订单")
            else:
                self.logger.info("交易未启用,仅模拟运行")
            
            # 6. 更新账户信息
            self.update_account_info()
            
            # 7. 监控系统状态
            system_health, issues = self.monitor.check_system_health(self)
            
            # 8. 记录绩效
            self.monitor.monitor_performance(self.account_info, self.trade_history)
            
            # 9. 生成报告
            if self.config.get('generate_reports', True):
                report = self.monitor.generate_report()
                self.logger.info(f"系统报告生成完成: 健康状态={system_health}")
            
            self.logger.info("交易周期完成")
            return True
            
        except Exception as e:
            self.logger.error(f"交易周期执行失败: {str(e)}")
            self.monitor.send_alert(f"交易周期执行失败: {str(e)}", 'critical')
            return False
    
    def start(self):
        """启动交易引擎"""
        self.logger.info("启动交易引擎")
        
        # 连接经纪商API
        if not self.connect_to_broker():
            self.logger.error("无法连接经纪商API,系统退出")
            return False
        
        self.running = True
        
        # 主循环
        while self.running:
            try:
                cycle_start = time.time()
                
                # 运行交易周期
                success = self.run_cycle()
                
                # 计算下次运行时间
                cycle_time = time.time() - cycle_start
                sleep_time = max(0, self.config.get('data_update_interval', 60) - cycle_time)
                
                if sleep_time > 0:
                    self.logger.info(f"等待 {sleep_time:.1f} 秒后继续")
                    time.sleep(sleep_time)
                
            except KeyboardInterrupt:
                self.logger.info("用户中断,停止交易引擎")
                self.stop()
                break
            except Exception as e:
                self.logger.error(f"交易引擎运行异常: {str(e)}")
                self.monitor.send_alert(f"交易引擎运行异常: {str(e)}", 'critical')
                time.sleep(60)  # 异常后等待1分钟再继续
    
    def stop(self):
        """停止交易引擎"""
        self.logger.info("停止交易引擎")
        self.running = False
        self.broker_api.disconnect()
        
        # 生成最终报告
        report = self.monitor.generate_report()
        self.logger.info(f"最终报告: 总盈亏={(self.account_info['equity'] - self.config.get('initial_capital', 1000000)):.2f}")

9. 系统部署与运行

9.1 配置文件示例

json 复制代码
{
    "log_level": "INFO",
    "log_file": "trading_system.log",
    "initial_capital": 1000000,
    "trading_enabled": false,
    "generate_reports": true,
    "data_update_interval": 60,
    "trading_symbols": ["IF2401", "IC2401", "AU2402", "AG2403"],
    "broker": {
        "account_id": "123456789",
        "api_key": "your_api_key",
        "secret_key": "your_secret_key",
        "server_url": "https://api.broker.com"
    },
    "risk_management": {
        "max_position_ratio": 0.1,
        "max_sector_exposure": 0.3,
        "max_leverage": 3,
        "default_stop_loss_pct": 0.02,
        "risk_per_trade": 0.02
    },
    "strategies": {
        "moving_average": {
            "fast_ma_period": 5,
            "slow_ma_period": 20,
            "stop_loss_pct": 0.02,
            "take_profit_pct": 0.04
        },
        "momentum": {
            "rsi_period": 14,
            "rsi_overbought": 70,
            "rsi_oversold": 30,
            "macd_fast": 12,
            "macd_slow": 26,
            "macd_signal": 9
        }
    },
    "email_alerts": {
        "enabled": true,
        "smtp_server": "smtp.gmail.com",
        "smtp_port": 587,
        "username": "your_email@gmail.com",
        "password": "your_password",
        "recipients": ["alert@yourcompany.com"]
    }
}

9.2 主程序入口

python 复制代码
def main():
    """主程序入口"""
    print("期货自动化交易系统启动中...")
    
    # 创建交易引擎实例
    engine = TradingEngine("config.json")
    
    try:
        # 启动交易引擎
        engine.start()
    except Exception as e:
        print(f"系统运行异常: {e}")
        logging.error(f"系统运行异常: {e}", exc_info=True)
    finally:
        # 确保资源清理
        if hasattr(engine, 'data_fetcher'):
            engine.data_fetcher.cleanup()
        print("系统已退出")

if __name__ == "__main__":
    main()

9.3 系统测试与验证

python 复制代码
class SystemTester:
    def __init__(self, engine):
        self.engine = engine
        self.logger = logging.getLogger(__name__)
    
    def run_backtest(self, start_date, end_date, initial_capital=1000000):
        """运行回测"""
        self.logger.info(f"开始回测: {start_date} 至 {end_date}")
        
        # 获取历史数据
        historical_data = self.fetch_historical_data(start_date, end_date)
        
        # 初始化回测账户
        backtest_account = {
            'equity': initial_capital,
            'cash': initial_capital,
            'positions_value': 0,
            'positions': {},
            'history': []
        }
        
        # 按时间顺序运行策略
        results = []
        for timestamp, data_snapshot in historical_data.items():
            # 运行策略
            signals = self.engine.strategy_manager.generate_combined_signals({timestamp: data_snapshot})
            
            # 执行交易(模拟)
            trades = self.execute_backtest_trades(signals, backtest_account, data_snapshot)
            
            # 更新账户
            self.update_backtest_account(backtest_account, trades, data_snapshot)
            
            # 记录结果
            results.append({
                'timestamp': timestamp,
                'equity': backtest_account['equity'],
                'signals': signals,
                'trades': trades
            })
        
        # 生成回测报告
        report = self.generate_backtest_report(results, initial_capital)
        
        self.logger.info(f"回测完成: 最终净值={backtest_account['equity']:.2f}")
        return report
    
    def fetch_historical_data(self, start_date, end_date):
        """获取历史数据"""
        # 实现历史数据获取逻辑
        historical_data = {}
        # 这里应该是实际的数据获取代码
        return historical_data
    
    def execute_backtest_trades(self, signals, account, market_data):
        """执行回测交易"""
        trades = []
        # 实现回测交易逻辑
        return trades
    
    def update_backtest_account(self, account, trades, market_data):
        """更新回测账户"""
        # 实现账户更新逻辑
        pass
    
    def generate_backtest_report(self, results, initial_capital):
        """生成回测报告"""
        report = {
            'initial_capital': initial_capital,
            'final_equity': results[-1]['equity'] if results else initial_capital,
            'total_return': (results[-1]['equity'] - initial_capital) / initial_capital if results else 0,
            'total_trades': sum(len(r['trades']) for r in results),
            'winning_trades': 0,
            'losing_trades': 0,
            'max_drawdown': self.calculate_max_drawdown([r['equity'] for r in results]),
            'sharpe_ratio': self.calculate_sharpe_ratio(results),
            'performance_by_period': self.calculate_periodic_returns(results)
        }
        
        return report
    
    def calculate_max_drawdown(self, equity_curve):
        """计算最大回撤"""
        if not equity_curve:
            return 0
        
        peak = equity_curve[0]
        max_dd = 0
        
        for equity in equity_curve:
            if equity > peak:
                peak = equity
            dd = (peak - equity) / peak
            if dd > max_dd:
                max_dd = dd
        
        return max_dd
    
    def calculate_sharpe_ratio(self, results):
        """计算夏普比率"""
        # 简化实现
        returns = []
        for i in range(1, len(results)):
            daily_return = (results[i]['equity'] - results[i-1]['equity']) / results[i-1]['equity']
            returns.append(daily_return)
        
        if not returns:
            return 0
        
        avg_return = np.mean(returns)
        std_return = np.std(returns)
        
        if std_return == 0:
            return 0
        
        return avg_return / std_return * np.sqrt(252)  # 年化夏普比率
    
    def calculate_periodic_returns(self, results):
        """计算周期收益"""
        periodic_returns = {
            'daily': [],
            'weekly': [],
            'monthly': []
        }
        # 实现周期收益计算
        return periodic_returns

10. 总结与展望

本系统实现了一个完整的期货自动化交易框架,包含以下主要特点:

10.1 系统特点

  1. 模块化设计:各功能模块独立,便于维护和扩展
  2. 多策略支持:支持多种交易策略的组合使用
  3. 全面风控:包含多层次的风险管理系统
  4. 实时监控:完整的系统监控和报警机制
  5. 回测功能:支持历史数据回测和策略优化

10.2 未来改进方向

  1. 机器学习集成:加入机器学习算法进行信号优化
  2. 高频交易支持:优化系统性能支持高频交易
  3. 多市场支持:扩展支持股票、期权等多市场交易
  4. 云端部署:支持云端部署和分布式运行
  5. 移动监控:开发移动端监控应用

10.3 风险提示

  1. 实际交易前必须进行充分回测和模拟交易
  2. 实时交易需考虑网络延迟和系统稳定性
  3. 策略参数需要根据市场变化定期优化
  4. 建议初期使用小资金进行实盘测试

该系统为期货交易提供了一个强大的自动化交易平台,但需要注意的是,任何交易策略都无法保证100%盈利,实际使用时需要根据市场情况不断调整和优化策略参数。


注意:本文档提供的代码为示例代码,实际交易使用前需要进行充分的测试和验证。期货交易具有高风险,请谨慎使用自动化交易系统。

相关推荐
GeeLark7 小时前
自动化Reddit 效率已ready
人工智能·ai·自动化
耐达讯通信技术7 小时前
耐达讯自动化Profibus集线器与机械手臂:工业仙途的双剑奇侠
网络·物联网·网络协议·自动化·信息与通信
白熊1887 小时前
【论文精读】基于YOLOv3算法的高速公路火灾检测
算法·yolo·yolov3
__Bolide__7 小时前
【不说废话】pytorch张量相对于numpy数组的优势
人工智能·pytorch·numpy
HABuo7 小时前
【C++进阶篇】学习C++就看这篇--->多态超详解
c语言·开发语言·c++·后端·学习
驱动探索者7 小时前
Linux arm cache 入门
linux·运维·arm开发·cache
嘀咕博客7 小时前
VideoPoet:Google发布的用于视频生成的大语言模型
人工智能·语言模型·音视频·ai工具
l1t8 小时前
利用DeepSeek编写验证xlsx格式文件中是否启用sharedStrings.xml对读写效率影响python程序
xml·开发语言·python·算法·xlsx
key_Go8 小时前
09.《路由基础知识解析和实践》
运维·服务器·网络·智能路由器