量化交易系统开发-实时行情自动化交易-8.20.东方财富平台

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

接下来会对于东方财富平台介绍。

东方财富是一家集金融数据、投资资讯与交易功能于一体的综合性平台。近年来,东方财富提供了量化交易接口和开发环境,支持用户编写、测试和优化量化交易策略。其量化平台支持Python语言,并结合自身的数据资源优势,为用户提供方便快捷的量化交易服务。

本文通过一个经典的“双均线策略”实例,演示如何在东方财富平台上进行量化交易策略的开发与回测。


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

策略逻辑

双均线策略是一种趋势跟随策略,通过短期均线和长期均线的交叉关系来生成买卖信号:

  • 买入信号:短期均线上穿长期均线(黄金交叉)。
  • 卖出信号:短期均线下穿长期均线(死亡交叉)。
适用场景
  • 优势:适用于趋势性市场,如股票市场或商品期货市场的单边行情。
  • 局限:在震荡市场中可能导致较高的信号噪声。

2. 策略开发

东方财富量化交易平台采用Python语言进行策略开发。以下是基于双均线策略的完整实现过程和代码。

(1)初始化策略

首先,设置策略的初始参数,包括短期和长期均线的周期,以及交易标的。

# 引入所需模块
import efinance as ef
import pandas as pd

# 初始化策略参数
SHORT_WINDOW = 10  # 短期均线周期
LONG_WINDOW = 50   # 长期均线周期
INITIAL_CAPITAL = 100000  # 初始资金
STOCK_SYMBOL = '600519'  # 交易标的:贵州茅台
(2)获取历史数据

东方财富提供了丰富的数据接口,可以轻松获取股票的历史行情数据。

# 获取贵州茅台的历史数据
def get_stock_data(symbol, start_date, end_date):
    data = ef.stock.get_quote_history(symbol, beg=start_date, end=end_date)
    data = data[['日期', '收盘']]
    data.rename(columns={'日期': 'Date', '收盘': '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 = get_stock_data(STOCK_SYMBOL, start_date, end_date)
(3)计算均线

根据历史数据计算短期和长期移动平均线。

# 计算短期和长期均线
data['Short_MA'] = data['Close'].rolling(window=SHORT_WINDOW).mean()
data['Long_MA'] = data['Close'].rolling(window=LONG_WINDOW).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  # 卖出信号

3. 策略回测

通过模拟交易过程计算策略的盈亏情况。

扫描二维码关注公众号,回复: 17560423 查看本文章
(1)初始化回测环境

设定初始资金、持仓状态和交易记录。

# 初始化回测变量
data['Position'] = 0  # 持仓状态
data['Cash'] = INITIAL_CAPITAL  # 初始资金
data['Portfolio'] = INITIAL_CAPITAL  # 总资产
(2)执行回测逻辑

在每个交易日,根据信号调整持仓,更新账户资金和总资产。

# 回测逻辑
holdings = 0  # 初始持仓数量
for i in range(1, len(data)):
    # 当天的交易信号
    signal = data.iloc[i]['Signal']
    price = data.iloc[i]['Close']
    
    # 买入逻辑
    if signal == 1 and data.iloc[i - 1]['Position'] == 0:
        holdings = data.iloc[i - 1]['Cash'] // price  # 可购买的股票数量
        data.at[data.index[i], 'Cash'] = data.iloc[i - 1]['Cash'] - holdings * price
        data.at[data.index[i], 'Position'] = holdings
    
    # 卖出逻辑
    elif signal == -1 and data.iloc[i - 1]['Position'] > 0:
        data.at[data.index[i], 'Cash'] = data.iloc[i - 1]['Cash'] + data.iloc[i - 1]['Position'] * price
        data.at[data.index[i], 'Position'] = 0
    
    # 计算总资产
    current_holdings = data.iloc[i]['Position'] * price
    data.at[data.index[i], 'Portfolio'] = current_holdings + data.iloc[i]['Cash']
(3)记录交易结果

回测完成后,保存策略的每日资金和持仓情况。

# 保存回测结果
data[['Close', 'Short_MA', 'Long_MA', 'Signal', 'Position', 'Cash', 'Portfolio']].to_csv('backtest_results.csv')

4. 策略优化

(1)参数优化

为了提高策略的表现,可以对短期均线和长期均线的参数进行优化,例如:

  • 短期均线范围:5至15天。
  • 长期均线范围:30至60天。
# 网格搜索优化参数
best_params = None
best_return = -float('inf')

for short_window in range(5, 16):
    for long_window in range(30, 61):
        if short_window >= long_window:
            continue
        # 重新计算均线
        data['Short_MA'] = data['Close'].rolling(window=short_window).mean()
        data['Long_MA'] = data['Close'].rolling(window=long_window).mean()
        # 同样的回测逻辑...
        # 计算最终收益率
        final_portfolio = data.iloc[-1]['Portfolio']
        total_return = (final_portfolio - INITIAL_CAPITAL) / INITIAL_CAPITAL
        if total_return > best_return:
            best_return = total_return
            best_params = (short_window, long_window)

print(f"最佳参数: 短期均线={best_params[0]}, 长期均线={best_params[1]}, 收益率={best_return}")
(2)添加止盈止损机制

进一步优化策略,加入止盈和止损规则,以控制风险。

# 止盈止损逻辑
TAKE_PROFIT = 0.1  # 止盈10%
STOP_LOSS = 0.05   # 止损5%

# 回测时在买入和卖出逻辑中添加以下代码
if signal == 1 and data.iloc[i - 1]['Position'] == 0:
    entry_price = price  # 记录入场价格

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