from jqdata import *
import numpy as np
import pandas as pd
def initialize(context):
# 设置基准
set_benchmark('000300.XSHG')
# 设置滑点
set_slippage(PriceRelatedSlippage(0.002))
# 设置手续费
set_order_cost(OrderCost(open_tax=0, close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
# 设置运行时间
run_daily(select_stock, time='15:30', reference_security='000300.XSHG')
run_daily(market_open, time='9:15', reference_security='000300.XSHG')
run_daily(market_close, time='14:57', reference_security='000300.XSHG')
run_daily(after_market_analysis, time='18:00', reference_security='000300.XSHG')
# 初始化全局变量
g.current_stock = None
g.selected_stock = None
def check_strength_conditions(current_strength, prev_strength, daily_change):
"""检查单日数据是否满足关注条件"""
conditions_met = []
# 条件1: 日强度变化大于3
if daily_change > 3:
conditions_met.append("日强度变化大于3")
# 条件2: 强度得分大于6且日强度变化大于1.5
if current_strength > 6 and daily_change > 1.5:
conditions_met.append("强度得分大于6且日强度变化大于1.5")
# 条件3: 强度得分大于10且日强度变化大于1
if current_strength > 10 and daily_change > 1:
conditions_met.append("强度得分大于10且日强度变化大于1")
# 条件4: 当日强度得分大于13且前日强度得分小于13
if current_strength > 13 and prev_strength < 13:
conditions_met.append("当日强度得分大于13且前日强度得分小于13")
# 条件5: 强度变化大于6
if daily_change > 6:
conditions_met.append("强度变化大于6")
return conditions_met
def calculate_single_day_strength(close_data, offset=0):
"""计算单日强度值"""
ma5 = np.mean(close_data[-(5+offset):len(close_data)-offset])
ma13 = np.mean(close_data[-(13+offset):len(close_data)-offset])
ma20 = np.mean(close_data[-(20+offset):len(close_data)-offset])
ma60 = np.mean(close_data[-(60+offset):len(close_data)-offset])
ma5_prev = np.mean(close_data[-(6+offset):len(close_data)-(offset+1)])
ma13_prev = np.mean(close_data[-(14+offset):len(close_data)-(offset+1)])
ma20_prev = np.mean(close_data[-(21+offset):len(close_data)-(offset+1)])
ma60_prev = np.mean(close_data[-(61+offset):len(close_data)-(offset+1)])
ultra_short = np.arctan((ma5/ma5_prev - 1) * 100) * 57.3
short = np.arctan((ma13/ma13_prev - 1) * 100) * 57.3
medium = np.arctan((ma20/ma20_prev - 1) * 100) * 57.3
long = np.arctan((ma60/ma60_prev - 1) * 100) * 57.3
total_strength = (ultra_short/50 + short/40 + medium/21 + long/10)
return {
'strength': total_strength,
'ultra_short': ultra_short,
'short': short,
'medium': medium,
'long': long
}
def get_stock_strength(context):
"""获取股票强度数据"""
# 获取所有A股
stocks = list(get_all_securities(['stock']).index)
# 过滤科创板和ST股票
stocks = [s for s in stocks if not (
s.startswith(('688', '689', '833', '837', '870', '871', '872', '873', '920', '430')) or
'ST' in get_security_info(s).display_name
)]
# 过滤上市不足100天的股票
stocks = [s for s in stocks if (
(context.current_dt.date() - get_security_info(s).start_date).days > 100
)]
strength_scores = {}
for stock in stocks:
try:
# 获取过去121个交易日的收盘价
prices = get_price(stock, count=121, end_date=context.current_dt, fields=['close'], skip_paused=False, fq='pre')
close = prices['close'].values
today_strength = calculate_single_day_strength(close)
yesterday_strength = calculate_single_day_strength(close, offset=1)
strength_history = []
daily_changes = []
# 获取过去60个交易日的日期列表
trading_dates = prices.index.tolist()[-60:]
# 计算60天的历史强度值
for i in range(60):
day_strength = calculate_single_day_strength(close, offset=i)
strength_history.append({
'date': trading_dates[-i-1],
'strength': day_strength['strength']
})
# 计算强度变化(当日减去前一日)
for i in range(len(strength_history)-1):
current_day = strength_history[i]
prev_day = strength_history[i+1]
daily_changes.append({
'date': current_day['date'],
'change': current_day['strength'] - prev_day['strength'],
'current_strength': current_day['strength'],
'prev_strength': prev_day['strength']
})
strength_scores[stock] = {
'strength': today_strength['strength'],
'yesterday_strength': yesterday_strength['strength'],
'strength_history': strength_history,
'daily_changes': daily_changes
}
except Exception as e:
continue
return strength_scores
def select_stock(context):
"""选股函数"""
# 获取所有A股
stocks = list(get_all_securities(['stock']).index)
# 过滤科创板和ST股票
stocks = [s for s in stocks if not (
s.startswith(('688', '689', '833', '837', '870', '871', '872', '873', '920', '430')) or
'ST' in get_security_info(s).display_name
)]
# 过滤上市不足100天的股票
stocks = [s for s in stocks if (
(context.current_dt.date() - get_security_info(s).start_date).days > 100
)]
qualified_stocks = [] # 存储符合条件的股票
strength_scores = get_stock_strength(context) # 获取股票强度数据
for stock in stocks:
if stock not in strength_scores:
continue
stock_info = strength_scores[stock]
total_strength = stock_info['strength']
prev_strength = stock_info['yesterday_strength']
daily_change = total_strength - prev_strength
# 检查条件
if total_strength > 13:
conditions_met = check_strength_conditions(total_strength, prev_strength, daily_change)
qualified_stocks.append({
'code': stock,
'name': get_security_info(stock).display_name,
'strength': total_strength,
'conditions_met': conditions_met,
'daily_change': daily_change,
'prev_strength': prev_strength,
'highlight': daily_change > 4, # 标记日强度变化大于4的股票
'star_mark': daily_change > 6 # 标记日强度变化大于6的股票
})
# 输出符合条件的股票汇总
qualified_stocks.sort(key=lambda x: x['strength'], reverse=True) # 按强度得分排序
print("\n=== 符合选市场龙头股公式的股票的股票汇总 ===")
for stock in qualified_stocks:
highlight_mark = "⭐ [大星号关注]" if stock['star_mark'] else ""
print(f"{context.current_dt} 18:00:00 - INFO - 股票代码: {stock['code']} 股票名称: {stock['name']} 强度得分: {stock['strength']:.2f} 日强度变化: {stock['daily_change']:.2f} ({stock['strength']:.2f}-{stock['prev_strength']:.2f}) {highlight_mark}")
# 输出最近20个交易日历史数据
for stock in qualified_stocks:
stock_data = strength_scores[stock['code']]
print(f"\n最近20个交易日历史数据")
print(f"{context.current_dt} 15:30:00 - INFO - \n==================================================\n")
print(f"{context.current_dt} 15:30:00 - INFO - 股票代码: {stock['code']}\n")
print(f"{context.current_dt} 15:30:00 - INFO - 股票名称: {stock['name']}\n")
print(f"{context.current_dt} 15:30:00 - INFO - 当前总强度得分: {stock['strength']:.2f}\n")
print(f"{context.current_dt} 15:30:00 - INFO - \n最近20个交易日历史数据 日强度变化(当日-前日):\n")
# 只取最近20个交易日的数据
recent_changes = stock_data['daily_changes'][:20]
for change in recent_changes:
date = change['date']
# 检查当前强度和前一日强度是否满足条件
if change['current_strength'] is not None and change['prev_strength'] is not None: # 确保有交易数据
conditions_met = check_strength_conditions(change['current_strength'], change['prev_strength'], change['change'])
condition_mark = f" ⭐ [{', '.join(conditions_met)}]" if conditions_met else ""
# 获取截止到该日期的成交数据
prices = get_price(stock['code'], count=21, end_date=date, fields=['volume', 'money'], skip_paused=False, fq='pre')
volumes = prices['volume'].values
money = prices['money'].values
if len(volumes) >= 21:
# 计算均价
avg1 = money[-1] / volumes[-1] if volumes[-1] != 0 else 0 # 最近1日均价
avg3 = np.sum(money[-3:]) / np.sum(volumes[-3:]) if np.sum(volumes[-3:]) != 0 else 0 # 最近3日均价
avg5 = np.sum(money[-5:]) / np.sum(volumes[-5:]) if np.sum(volumes[-5:]) != 0 else 0 # 最近5日均价
avg10 = np.sum(money[-10:]) / np.sum(volumes[-10:]) if np.sum(volumes[-10:]) != 0 else 0 # 最近10日均价
avg20 = np.sum(money[-20:]) / np.sum(volumes[-20:]) if np.sum(volumes[-20:]) != 0 else 0 # 最近20日均价
# 前一周期的均价
prev_avg1 = money[-2] / volumes[-2] if volumes[-2] != 0 else 0
prev_avg3 = np.sum(money[-4:-1]) / np.sum(volumes[-4:-1]) if np.sum(volumes[-4:-1]) != 0 else 0
prev_avg5 = np.sum(money[-6:-1]) / np.sum(volumes[-6:-1]) if np.sum(volumes[-6:-1]) != 0 else 0
prev_avg10 = np.sum(money[-11:-1]) / np.sum(volumes[-11:-1]) if np.sum(volumes[-11:-1]) != 0 else 0
prev_avg20 = np.sum(money[-21:-1]) / np.sum(volumes[-21:-1]) if np.sum(volumes[-21:-1]) != 0 else 0
# 计算均比
ratio1 = ((avg1 - prev_avg1) / prev_avg1 * 100) if prev_avg1 != 0 else 0
ratio3 = ((avg3 - prev_avg3) / prev_avg3 * 100) if prev_avg3 != 0 else 0
ratio5 = ((avg5 - prev_avg5) / prev_avg5 * 100) if prev_avg5 != 0 else 0
ratio10 = ((avg10 - prev_avg10) / prev_avg10 * 100) if prev_avg10 != 0 else 0
ratio20 = ((avg20 - prev_avg20) / prev_avg20 * 100) if prev_avg20 != 0 else 0
else:
# 数据不足,无法计算
avg1 = avg3 = avg5 = avg10 = avg20 = 0
ratio1 = ratio3 = ratio5 = ratio10 = ratio20 = 0
print(f"{context.current_dt} 15:30:00 - INFO - {date.strftime('%Y-%m-%d')}日强度变化: {change['change']:.2f} "
f"({change['current_strength']:.2f}-{change['prev_strength']:.2f}){condition_mark} "
f"均价1: {avg1:.2f} 均价3: {avg3:.2f} 均价5: {avg5:.2f} 均价10: {avg10:.2f} 均价20: {avg20:.2f} "
f"均比1: {ratio1:.2f}% 均比3: {ratio3:.2f}% 均比5: {ratio5:.2f}% 均比10: {ratio10:.2f}% 均比20: {ratio20:.2f}%")
g.selected_stock = [stock['code'] for stock in qualified_stocks]
def market_open(context):
"""开盘时执行的函数"""
if g.selected_stock:
current_data = get_current_data()
for stock in g.selected_stock:
up_limit = current_data[stock].high_limit
cash = context.portfolio.available_cash * 0.5 / len(g.selected_stock)
if cash > 0:
order(stock, cash/up_limit, LimitOrderStyle(up_limit))
def market_close(context):
"""收盘前执行的函数"""
positions = context.portfolio.positions
current_data = get_current_data()
for stock in positions:
current_price = current_data[stock].last_price
up_limit = current_data[stock].high_limit
if current_price < up_limit:
down_limit = current_data[stock].low_limit
order(stock, -positions[stock].total_amount, LimitOrderStyle(down_limit))
def after_market_analysis(context):
"""收盘后市场分析"""
current_date = context.current_dt.date()
strength_scores = get_stock_strength(context)
print(f"\n{'='*20} {current_date} 市场分析报告 {'='*20}\n")
# 新增:输出日强度变化大于2.5且强度得分大于6的股票汇总
strong_change_stocks = [] # 用于存储日强度变化大于2.5且强度得分大于6的股票
for stock_code, stock_info in strength_scores.items():
stock_name = get_security_info(stock_code).display_name
latest_history = stock_info['strength_history'][0]
latest_change = stock_info['daily_changes'][0]
# 检查日强度变化是否大于2.5且强度得分大于6
if latest_change['change'] > 2.5 and latest_history['strength'] > 6:
strong_change_stocks.append({
'code': stock_code,
'name': stock_name,
'strength': latest_history['strength'],
'change': latest_change['change'],
'current_strength': latest_change['current_strength'],
'prev_strength': latest_change['prev_strength']
})
# 输出日强度变化大于2.5且强度得分大于6的股票汇总
if strong_change_stocks:
strong_change_stocks = sorted(strong_change_stocks, key=lambda x: (x['change'], x['strength']), reverse=True) # 按日强度变化和强度得分排序
print("=== 日强度变化大于2.5且强度得分大于6的股票汇总 ===\n")
for stock in strong_change_stocks:
print(f"{current_date} 18:00:00 - INFO - 股票代码: {stock['code']} 股票名称: {stock['name']} "
f"强度得分: {stock['strength']:.2f} 日强度变化: {stock['change']:.2f} "
f"({stock['current_strength']:.2f}-{stock['prev_strength']:.2f})")
else:
print("=== 日强度变化大于2.5且强度得分大于6的股票汇总 ===\n暂无符合条件的股票。")
# 输出最近20个交易日历史数据
for stock in strong_change_stocks:
stock_data = strength_scores[stock['code']]
print(f"\n最近20个交易日历史数据\n")
print(f"{current_date} 15:30:00 - INFO - \n==================================================\n")
print(f"{current_date} 15:30:00 - INFO - 股票代码: {stock['code']}\n")
print(f"{current_date} 15:30:00 - INFO - 股票名称: {stock['name']}\n")
print(f"{current_date} 15:30:00 - INFO - 当前总强度得分: {stock['strength']:.2f}\n")
print(f"{current_date} 15:30:00 - INFO - \n最近20个交易日历史数据 日强度变化(当日-前日):\n")
# 只取最近20个交易日的数据
recent_changes = stock_data['daily_changes'][:20]
for change in recent_changes:
date = change['date']
# 检查当前强度和前一日强度是否满足条件
if change['current_strength'] is not None and change['prev_strength'] is not None: # 确保有交易数据
conditions_met = check_strength_conditions(change['current_strength'], change['prev_strength'], change['change'])
condition_mark = f" ⭐ [{', '.join(conditions_met)}]" if conditions_met else ""
# 获取截止到该日期的成交数据
prices = get_price(stock['code'], count=21, end_date=date, fields=['volume', 'money'], skip_paused=False, fq='pre')
volumes = prices['volume'].values
money = prices['money'].values
if len(volumes) >= 21:
# 计算均价
avg1 = money[-1] / volumes[-1] if volumes[-1] != 0 else 0 # 最近1日均价
avg3 = np.sum(money[-3:]) / np.sum(volumes[-3:]) if np.sum(volumes[-3:]) != 0 else 0 # 最近3日均价
avg5 = np.sum(money[-5:]) / np.sum(volumes[-5:]) if np.sum(volumes[-5:]) != 0 else 0 # 最近5日均价
avg10 = np.sum(money[-10:]) / np.sum(volumes[-10:]) if np.sum(volumes[-10:]) != 0 else 0 # 最近10日均价
avg20 = np.sum(money[-20:]) / np.sum(volumes[-20:]) if np.sum(volumes[-20:]) != 0 else 0 # 最近20日均价
# 前一周期的均价
prev_avg1 = money[-2] / volumes[-2] if volumes[-2] != 0 else 0
prev_avg3 = np.sum(money[-4:-1]) / np.sum(volumes[-4:-1]) if np.sum(volumes[-4:-1]) != 0 else 0
prev_avg5 = np.sum(money[-6:-1]) / np.sum(volumes[-6:-1]) if np.sum(volumes[-6:-1]) != 0 else 0
prev_avg10 = np.sum(money[-11:-1]) / np.sum(volumes[-11:-1]) if np.sum(volumes[-11:-1]) != 0 else 0
prev_avg20 = np.sum(money[-21:-1]) / np.sum(volumes[-21:-1]) if np.sum(volumes[-21:-1]) != 0 else 0
# 计算均比
ratio1 = ((avg1 - prev_avg1) / prev_avg1 * 100) if prev_avg1 != 0 else 0
ratio3 = ((avg3 - prev_avg3) / prev_avg3 * 100) if prev_avg3 != 0 else 0
ratio5 = ((avg5 - prev_avg5) / prev_avg5 * 100) if prev_avg5 != 0 else 0
ratio10 = ((avg10 - prev_avg10) / prev_avg10 * 100) if prev_avg10 != 0 else 0
ratio20 = ((avg20 - prev_avg20) / prev_avg20 * 100) if prev_avg20 != 0 else 0
else:
# 数据不足,无法计算
avg1 = avg3 = avg5 = avg10 = avg20 = 0
ratio1 = ratio3 = ratio5 = ratio10 = ratio20 = 0
print(f"{current_date} 15:30:00 - INFO - {date.strftime('%Y-%m-%d')}日强度变化: {change['change']:.2f} "
f"({change['current_strength']:.2f}-{change['prev_strength']:.2f}){condition_mark} "
f"均价1: {avg1:.2f} 均价3: {avg3:.2f} 均价5: {avg5:.2f} 均价10: {avg10:.2f} 均价20: {avg20:.2f} "
f"均比1: {ratio1:.2f}% 均比3: {ratio3:.2f}% 均比5: {ratio5:.2f}% 均比10: {ratio10:.2f}% 均比20: {ratio20:.2f}%")
g.selected_stock = [stock['code'] for stock in strong_change_stocks]
1 符合选市场龙头股公式的股票的股票汇总 的数据 要输出
2 不要输出 日强度变化大于2.5且强度得分大于6的股票汇总 的数据3
3 对符合选市场龙头股公式的股票的股票进行 因子回测 ,用不同的深度机器学习
4 对不同的因子: 强度得分, 日强度变化,1日均价,3日均价, 5日均价,10日均价,20日均价,1日均价,3日均价,5日均价,10日均价,20日均价,volume, money,
5 输出不同的深度机器学习回测结果数据
6.建议的各因子的 最佳组合参数