agent-Specialization/users/wangchen06/project/quant_trading/策略示例.py
2025-11-14 16:44:12 +08:00

325 lines
12 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
"""
掘金量化策略示例
包含多种经典量化策略的实现
"""
from gm.api import *
import numpy as np
import pandas as pd
from datetime import datetime
# 设置token需要替换为实际的token
set_token('your_token_here')
# 策略1: 双均线策略
def init(context):
"""初始化函数"""
# 设置标的股票
context.symbol = 'SZSE.000001' # 平安银行
# 设置均线周期
context.short_period = 5
context.long_period = 20
# 设置交易参数
context.order_size = 100 # 每次交易股数
print('策略初始化完成')
def on_bar(context, bars):
"""K线触发函数"""
# 获取历史数据
recent_bars = history(context.symbol, frequency='1d', count=context.long_period + 1, end_time=bars[0].bob, df=True)
if len(recent_bars) < context.long_period + 1:
return
# 计算均线
short_ma = recent_bars['close'].iloc[-context.short_period:].mean()
long_ma = recent_bars['close'].iloc[-context.long_period:].mean()
# 获取当前持仓
position = context.account().position(symbol=context.symbol, side=PositionSide_Long)
# 交易逻辑
if short_ma > long_ma and position is None:
# 金叉,买入
order_volume(symbol=context.symbol, volume=context.order_size, side=OrderSide_Buy,
order_type=OrderType_Market, position_effect=PositionEffect_Open)
print(f'买入信号: 短期均线{short_ma:.2f} > 长期均线{long_ma:.2f}')
elif short_ma < long_ma and position is not None:
# 死叉,卖出
order_volume(symbol=context.symbol, volume=position.volume, side=OrderSide_Sell,
order_type=OrderType_Market, position_effect=PositionEffect_Close)
print(f'卖出信号: 短期均线{short_ma:.2f} < 长期均线{long_ma:.2f}')
# 策略2: 布林带均值回归策略
class BollingerBandStrategy:
def __init__(self, symbol, period=20, std_dev=2, order_size=100):
self.symbol = symbol
self.period = period
self.std_dev = std_dev
self.order_size = order_size
def calculate_bollinger_bands(self, data):
"""计算布林带"""
sma = data['close'].rolling(window=self.period).mean()
std = data['close'].rolling(window=self.period).std()
upper_band = sma + (std * self.std_dev)
lower_band = sma - (std * self.std_dev)
return upper_band, lower_band, sma
def generate_signals(self, context, bars):
"""生成交易信号"""
# 获取历史数据
data = history(self.symbol, frequency='1d', count=self.period + 1, end_time=bars[0].bob, df=True)
if len(data) < self.period + 1:
return
# 计算布林带
upper_band, lower_band, sma = self.calculate_bollinger_bands(data)
# 获取当前价格
current_price = bars[0].close
# 获取当前持仓
position = context.account().position(symbol=self.symbol, side=PositionSide_Long)
# 交易信号
if current_price <= lower_band.iloc[-1] and position is None:
# 价格触及下轨,买入
order_volume(symbol=self.symbol, volume=self.order_size, side=OrderSide_Buy,
order_type=OrderType_Market, position_effect=PositionEffect_Open)
print(f'布林带买入: 价格{current_price:.2f} <= 下轨{lower_band.iloc[-1]:.2f}')
elif current_price >= upper_band.iloc[-1] and position is not None:
# 价格触及上轨,卖出
order_volume(symbol=self.symbol, volume=position.volume, side=OrderSide_Sell,
order_type=OrderType_Market, position_effect=PositionEffect_Close)
print(f'布林带卖出: 价格{current_price:.2f} >= 上轨{upper_band.iloc[-1]:.2f}')
# 策略3: RSI超买超卖策略
class RSIStrategy:
def __init__(self, symbol, period=14, overbought=70, oversold=30, order_size=100):
self.symbol = symbol
self.period = period
self.overbought = overbought
self.oversold = oversold
self.order_size = order_size
def calculate_rsi(self, data):
"""计算RSI指标"""
delta = data['close'].diff()
gain = (delta.where(delta > 0, 0)).rolling(window=self.period).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=self.period).mean()
rs = gain / loss
rsi = 100 - (100 / (1 + rs))
return rsi
def generate_signals(self, context, bars):
"""生成交易信号"""
# 获取历史数据
data = history(self.symbol, frequency='1d', count=self.period + 1, end_time=bars[0].bob, df=True)
if len(data) < self.period + 1:
return
# 计算RSI
rsi = self.calculate_rsi(data)
current_rsi = rsi.iloc[-1]
# 获取当前持仓
position = context.account().position(symbol=self.symbol, side=PositionSide_Long)
# 交易信号
if current_rsi <= self.oversold and position is None:
# RSI超卖买入
order_volume(symbol=self.symbol, volume=self.order_size, side=OrderSide_Buy,
order_type=OrderType_Market, position_effect=PositionEffect_Open)
print(f'RSI买入: RSI={current_rsi:.2f} <= 超卖线{self.oversold}')
elif current_rsi >= self.overbought and position is not None:
# RSI超买卖出
order_volume(symbol=self.symbol, volume=position.volume, side=OrderSide_Sell,
order_type=OrderType_Market, position_effect=PositionEffect_Close)
print(f'RSI卖出: RSI={current_rsi:.2f} >= 超买线{self.overbought}')
# 策略4: 多因子选股策略
class MultiFactorStrategy:
def __init__(self, symbols, factors, order_size=100):
self.symbols = symbols
self.factors = factors
self.order_size = order_size
self.position_dict = {}
def get_fundamental_data(self, symbols, date):
"""获取基本面数据"""
# 这里需要根据实际的财务数据API来获取数据
# 示例返回模拟数据
fundamental_data = {}
for symbol in symbols:
fundamental_data[symbol] = {
'pe': np.random.uniform(10, 30), # 市盈率
'pb': np.random.uniform(1, 5), # 市净率
'roe': np.random.uniform(5, 20), # 净资产收益率
'growth': np.random.uniform(0, 50) # 营收增长率
}
return fundamental_data
def calculate_factor_scores(self, fundamental_data):
"""计算因子得分"""
scores = {}
for symbol, data in fundamental_data.items():
score = 0
# PE因子得分越低越好
if data['pe'] < 15:
score += 25
elif data['pe'] < 25:
score += 15
else:
score += 5
# PB因子得分越低越好
if data['pb'] < 2:
score += 25
elif data['pb'] < 3:
score += 15
else:
score += 5
# ROE因子得分越高越好
if data['roe'] > 15:
score += 25
elif data['roe'] > 10:
score += 15
else:
score += 5
# 增长率因子得分(越高越好)
if data['growth'] > 30:
score += 25
elif data['growth'] > 15:
score += 15
else:
score += 5
scores[symbol] = score
return scores
def select_stocks(self, context, date):
"""选股逻辑"""
# 获取基本面数据
fundamental_data = self.get_fundamental_data(self.symbols, date)
# 计算因子得分
scores = self.calculate_factor_scores(fundamental_data)
# 排序并选择得分最高的股票
sorted_stocks = sorted(scores.items(), key=lambda x: x[1], reverse=True)
selected_stocks = [stock[0] for stock in sorted_stocks[:5]] # 选择前5名
return selected_stocks
def rebalance_portfolio(self, context, selected_stocks):
"""调仓"""
# 获取当前持仓
current_positions = context.account().positions()
# 卖出不在选中列表中的股票
for position in current_positions:
if position.symbol not in selected_stocks:
order_volume(symbol=position.symbol, volume=position.volume, side=OrderSide_Sell,
order_type=OrderType_Market, position_effect=PositionEffect_Close)
print(f'卖出: {position.symbol}')
# 买入选中的股票
for symbol in selected_stocks:
position = context.account().position(symbol=symbol, side=PositionSide_Long)
if position is None:
order_volume(symbol=symbol, volume=self.order_size, side=OrderSide_Buy,
order_type=OrderType_Market, position_effect=PositionEffect_Open)
print(f'买入: {symbol}')
# 策略5: 网格交易策略
class GridTradingStrategy:
def __init__(self, symbol, grid_size=0.02, grid_levels=10, order_size=100):
self.symbol = symbol
self.grid_size = grid_size # 网格大小(百分比)
self.grid_levels = grid_levels # 网格层数
self.order_size = order_size
self.grids = [] # 存储网格价格
self.positions = {} # 存储网格持仓
def initialize_grids(self, current_price):
"""初始化网格"""
self.grids = []
for i in range(-self.grid_levels // 2, self.grid_levels // 2 + 1):
grid_price = current_price * (1 + i * self.grid_size)
self.grids.append(grid_price)
print(f'网格初始化完成,价格范围: {min(self.grids):.2f} - {max(self.grids):.2f}')
def generate_signals(self, context, bars):
"""生成网格交易信号"""
current_price = bars[0].close
# 如果网格未初始化,则初始化
if not self.grids:
self.initialize_grids(current_price)
return
# 检查每个网格
for i, grid_price in enumerate(self.grids):
# 检查是否触发买入信号(价格跌破网格)
if current_price <= grid_price * (1 - self.grid_size / 2):
if i not in self.positions:
order_volume(symbol=self.symbol, volume=self.order_size, side=OrderSide_Buy,
order_type=OrderType_Market, position_effect=PositionEffect_Open)
self.positions[i] = self.order_size
print(f'网格买入: 价格={current_price:.2f}, 网格={grid_price:.2f}')
# 检查是否触发卖出信号(价格上涨到上一网格)
elif current_price >= grid_price * (1 + self.grid_size / 2):
if i in self.positions:
order_volume(symbol=self.symbol, volume=self.positions[i], side=OrderSide_Sell,
order_type=OrderType_Market, position_effect=PositionEffect_Close)
del self.positions[i]
print(f'网格卖出: 价格={current_price:.2f}, 网格={grid_price:.2f}')
# 主函数:运行策略
if __name__ == '__main__':
'''
strategy_id策略ID, 由系统生成
filename文件名, 请与本文件名保持一致
mode运行模式, 实时模式:MODE_LIVE回测模式:MODE_BACKTEST
token绑定计算机的ID, 可在系统设置-密钥管理中生成
backtest_start_time回测开始时间
backtest_end_time回测结束时间
backtest_adjust股票复权方式, 不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST
backtest_initial_cash回测初始资金
backtest_commission_ratio回测佣金比例
backtest_slippage_ratio回测滑点比例
'''
run(strategy_id='your_strategy_id',
filename='策略示例.py',
mode=MODE_BACKTEST,
token='your_token_here',
backtest_start_time='2020-01-01 08:00:00',
backtest_end_time='2020-12-31 16:00:00',
backtest_adjust=ADJUST_PREV,
backtest_initial_cash=100000,
backtest_commission_ratio=0.0001,
backtest_slippage_ratio=0.0001)