量化交易系统开发-实时行情自动化交易-8.21.无限易平台

19年创业做过一年的量化交易但没有成功,作为交易系统的开发人员积累了一些经验,最近想重新研究交易系统,一边整理一边写出来一些思考供大家参考,也希望跟做量化的朋友有更多的交流和合作。

接下来会对于无限易平台介绍。

无限易是一款专业化的量化交易平台,提供从策略开发、回测到模拟交易和实盘部署的一站式解决方案。平台支持Python编程语言,并具备完善的数据接口、算法引擎以及多种工具模块,方便开发者快速构建和测试量化交易策略。

本文将通过经典的“双均线策略”作为示例,演示在无限易平台上的量化交易开发与回测过程。


1. 策略背景:双均线策略

策略逻辑

双均线策略是一种趋势跟随策略,利用短期均线和长期均线的交叉关系生成交易信号:

  • 买入信号:短期均线上穿长期均线(黄金交叉)。
  • 卖出信号:短期均线下穿长期均线(死亡交叉)。
适用场景
  • 优势:适用于趋势性市场,有助于捕捉主要价格波动。
  • 局限:在震荡行情中可能产生较多的错误信号。

2. 策略开发

无限易量化平台支持基于Python的策略开发。以下为完整的策略实现流程和代码。

(1)初始化环境

在策略中初始化参数和必要的模块。

# 引入必要模块
import easytrader as et
import pandas as pd
import numpy as np

# 策略参数设置
SHORT_PERIOD = 10  # 短期均线周期
LONG_PERIOD = 50   # 长期均线周期
INITIAL_CAPITAL = 100000  # 初始资金
STOCK_CODE = '000001'  # 交易标的,平安银行
(2)获取历史数据

通过无限易的数据接口加载交易标的的历史行情数据。

# 加载股票历史数据
def load_stock_data(stock_code, start_date, end_date):
    # 示例:通过平台接口获取数据
    data = et.get_stock_data(stock_code, start_date=start_date, end_date=end_date)
    data = data[['date', 'close']]
    data.rename(columns={'date': 'Date', 'close': 'Close'}, inplace=True)
    data['Date'] = pd.to_datetime(data['Date'])
    data.set_index('Date', inplace=True)
    return data

# 获取数据
start_date = '2020-01-01'
end_date = '2022-01-01'
data = load_stock_data(STOCK_CODE, start_date, end_date)
(3)计算均线

利用Pandas计算短期均线和长期均线。

# 计算短期和长期均线
data['Short_MA'] = data['Close'].rolling(window=SHORT_PERIOD).mean()
data['Long_MA'] = data['Close'].rolling(window=LONG_PERIOD).mean()
(4)生成交易信号

通过比较短期均线和长期均线生成买卖信号。

# 生成交易信号
data['Signal'] = 0
data.loc[data['Short_MA'] > data['Long_MA'], 'Signal'] = 1  # 买入信号
data.loc[data['Short_MA'] <= data['Long_MA'], 'Signal'] = -1  # 卖出信号
(5)执行回测逻辑

模拟交易过程,计算资金曲线和持仓情况。

# 初始化回测变量
data['Position'] = 0  # 持仓状态
data['Cash'] = INITIAL_CAPITAL  # 初始资金
data['Portfolio'] = INITIAL_CAPITAL  # 总资产

# 回测逻辑
holdings = 0  # 持仓数量
entry_price = 0  # 入场价格

for i in range(1, len(data)):
    current_signal = data.iloc[i]['Signal']
    current_price = data.iloc[i]['Close']
    
    # 买入逻辑
    if current_signal == 1 and holdings == 0:
        holdings = data.iloc[i - 1]['Cash'] // current_price
        data.at[data.index[i], 'Cash'] = data.iloc[i - 1]['Cash'] - holdings * current_price
        data.at[data.index[i], 'Position'] = holdings
        entry_price = current_price  # 记录买入价格

    # 卖出逻辑
    elif current_signal == -1 and holdings > 0:
        data.at[data.index[i], 'Cash'] = data.iloc[i - 1]['Cash'] + holdings * current_price
        holdings = 0
        data.at[data.index[i], 'Position'] = holdings

    # 计算资产总值
    data.at[data.index[i], 'Portfolio'] = data.iloc[i]['Cash'] + holdings * current_price

3. 策略优化

(1)参数优化

通过调整短期和长期均线的周期长度,寻找最佳参数组合。

# 参数优化
best_params = None
best_return = -np.inf

for short_period in range(5, 20):
    for long_period in range(30, 100):
        if short_period >= long_period:
            continue
        # 重新计算均线
        data['Short_MA'] = data['Close'].rolling(window=short_period).mean()
        data['Long_MA'] = data['Close'].rolling(window=long_period).mean()
        
        # 回测逻辑与上述一致...
        # 计算最终收益率
        final_value = data.iloc[-1]['Portfolio']
        total_return = (final_value - INITIAL_CAPITAL) / INITIAL_CAPITAL
        if total_return > best_return:
            best_return = total_return
            best_params = (short_period, long_period)

print(f"最佳参数:短期均线={best_params[0]}, 长期均线={best_params[1]}, 收益率={best_return:.2%}")
(2)添加风险管理

在策略中引入止盈和止损机制,进一步优化收益风险比。

# 风险管理:止盈与止损
TAKE_PROFIT = 0.1  # 止盈10%
STOP_LOSS = 0.05   # 止损5%

# 在回测逻辑中添加止盈止损
for i in range(1, len(data)):
    current_signal = data.iloc[i]['Signal']
    current_price = data.iloc[i]['Close']

    if holdings > 0:
        pnl = (current_price - entry_price) / entry_price
        # 止盈逻辑
        if pnl >= TAKE_PROFIT:
            data.at[data.index[i], 'Cash'] = data.iloc[i - 1]['Cash'] + holdings * current_price
            holdings = 0
            data.at[data.index[i], 'Position'] = holdings
        # 止损逻辑
        elif pnl <= -STOP_LOSS:
            data.at[data.index[i], 'Cash'] = data.iloc[i - 1]['Cash'] + holdings * current_price
            holdings = 0
            data.at[data.index[i], 'Position'] = holdings

4. 完整代码

以下为完整代码实现:

import easytrader as et
import pandas as pd
import numpy as np

# 参数设置
SHORT_PERIOD = 10
LONG_PERIOD = 50
INITIAL_CAPITAL = 100000
STOCK_CODE = '000001'

# 数据加载
def load_stock_data(stock_code, start_date, end_date):
    data = et.get_stock_data(stock_code, start_date=start_date, end_date=end_date)
    data = data[['date', 'close']]
    data.rename(columns={'date': 'Date', 'close': 'Close'}, inplace=True)
    data['Date'] = pd.to_datetime(data['Date'])
    data.set_index('Date', inplace=True)
    return data

# 主函数
start_date = '2020-01-01'
end_date = '2022-01-01'
data = load_stock_data(STOCK_CODE, start_date, end_date)
data['Short_MA'] = data['Close'].rolling(window=SHORT_PERIOD).mean()
data['Long_MA'] = data['Close'].rolling(window=LONG_PERIOD).mean()

data['Signal'] = 0
data.loc[data['Short_MA'] > data['Long_MA'], 'Signal'] = 1
data.loc[data['Short_MA'] <= data['Long_MA'], 'Signal'] = -1

data['Position'] = 0
data['Cash'] = INITIAL_CAPITAL
data['Portfolio'] = INITIAL_CAPITAL

holdings = 0
entry_price = 0
for i in range(1, len(data)):
    current_signal = data.iloc[i]['Signal']
    current_price = data.iloc[i]['Close']
    
    if current_signal == 1 and holdings == 0:
        holdings = data.iloc[i - 1]['Cash'] // current_price
        data.at[data.index[i], 'Cash'] = data.iloc[i - 1]['Cash'] - holdings * current_price
        data.at[data.index[i], 'Position'] = holdings
        entry_price = current_price
    elif current_signal == -1 and holdings > 0:
        data.at[data.index[i], 'Cash'] = data.iloc[i - 1