-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathget_ah_premium_data.py
More file actions
180 lines (141 loc) · 7.05 KB
/
Copy pathget_ah_premium_data.py
File metadata and controls
180 lines (141 loc) · 7.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# 克隆自聚宽文章:https://www.joinquant.com/post/68659
# 标题:低AH溢价选股策略
'''
# 低AH溢价选股策略
## 1. 选股逻辑说明
### 核心筛选条件:
- **AH溢价率排序**:查询所有AH股的溢价数据,按溢价率升序排序(溢价最低的股票优先)
- **停牌过滤**:排除当前处于停牌状态的股票
- **ST过滤**:排除ST股票
- **退市过滤**:排除名称中包含"退"字的股票
- **数量限制**:选择前5只股票作为最终持仓
### 参数设置:
- **持仓数量**:g.stocknum = 5(默认值)
- **调仓频率**:每周一9:30执行
- **资金分配**:等权重分配,每只股票占总资金的1/5
### 条件优先级:
1. AH溢价率排序(核心条件)
2. 停牌过滤
3. ST过滤
4. 退市过滤
5. 数量限制(取前5只)
## 2. 策略设计思路
### 理论依据:
- **AH股溢价收敛理论**:同一公司的A股和H股在长期内价格应趋于一致,低溢价的A股有向上收敛的潜力
- **价值投资原理**:选择相对估值较低的股票,符合价值投资理念
- **市场有效性**:利用AH股之间的价格差异,捕捉市场定价偏差带来的机会
### 市场洞察:
- 在A股市场相对H股市场溢价较高的环境下,选择低溢价的AH股可以获得相对安全的投资机会
- 低AH溢价股票通常具有较好的基本面和较高的投资价值
- 定期调仓可以及时捕捉溢价变化,保持策略的有效性
## 3. 优劣势分析
### 优势:
- **风险较低**:低溢价股票相对估值合理,下跌空间有限
- **逻辑简单**:策略逻辑清晰,易于理解和执行
- **分散投资**:持仓5只股票,分散单一股票风险
- **长期有效**:基于价值收敛理论,长期来看具有较好的稳定性
### 劣势:
- **牛市表现可能不及高弹性策略**:低溢价股票通常属于蓝筹股,在牛市中可能跑输中小创股票
- **依赖AH溢价数据**:策略效果受AH溢价数据质量和及时性影响
- **对市场环境敏感**:在极端市场情况下,AH溢价可能扩大,影响策略表现
### 适用场景:
- **震荡市**:表现最佳,能有效捕捉价值回归机会
- **熊市**:相对抗跌,提供较好的防御性
- **牛市**:可能跑输大盘,但仍能获得稳定收益
## 4. 盈利逻辑详解
### 收益来源:
- **价值回归**:低AH溢价股票向合理价值回归带来的收益
- **股息收益**:低溢价股票通常具有较好的分红能力
- **市场定价纠偏**:利用市场对AH股定价差异的纠正获得收益
### 收益实现路径:
1. 每周筛选AH溢价最低的5只股票
2. 等权重配置资金
3. 持有一周后重新评估,调整持仓
4. 通过持续的低溢价选股,捕捉价值回归机会
### 关键节点:
- **调仓时间点**:每周一开盘,确保及时调整持仓
- **资金分配**:严格执行等权重分配,控制单一股票风险
- **过滤条件**:确保所选股票具有良好的流动性和财务状况
## 5. 风险控制机制
### 止损机制:
- **隐含止损**:通过每周调仓,自动卖出不在买入列表中的股票,相当于间接止损
- **资金安全**:检查可用资金是否足够购买100股,避免因资金不足导致的交易失败
### 仓位管理:
- **等权重配置**:每只股票占总资金的1/5,避免单一股票过重
- **持仓数量限制**:固定持有5只股票,保持适度分散
### 极端市场处理:
- **流动性风险**:通过过滤停牌股票,确保所选股票具有良好的流动性
- **财务风险**:通过过滤ST和退市股票,避免财务状况恶化的股票
- **市场系统性风险**:在极端市场情况下,策略仍能通过价值筛选获得相对保护
'''
# 策略实现代码
from jqdata import finance
def initialize(context):
"""初始化函数,设置策略基本参数"""
# 设定沪深300作为基准
set_benchmark('000300.XSHG')
# True为开启动态复权模式,使用真实价格交易
set_option('use_real_price', True)
# 设定成交量比例
set_option('order_volume_ratio', 1)
# 股票类交易手续费设置
set_order_cost(OrderCost(open_tax=0, close_tax=0.001, \
open_commission=0.00015, close_commission=0.00015,\
close_today_commission=0, min_commission=0), type='stock')
# 持仓数量
g.stocknum = 5
# 运行函数,每周一9:30执行
run_weekly(trade, 1, time='9:30')
def trade(context):
"""交易函数,执行选股和调仓操作"""
# 设定查询条件,获取AH股票溢价数据并按溢价率排序
df = finance.run_query(
query(finance.STK_AH_PRICE_COMP.a_code, finance.STK_AH_PRICE_COMP.h_a_comp)
.filter(finance.STK_AH_PRICE_COMP.day == context.previous_date)
.order_by(finance.STK_AH_PRICE_COMP.h_a_comp)
)
# 提取A股代码列表
buy_list = list(df['a_code'])
# 过滤停牌/ST/退市股票
buy_list = filter_paused_stock(buy_list)
buy_list = filter_st_stock(buy_list)
buy_list = delisted_filter(buy_list)
# 选择前g.stocknum只股票
buy_list = buy_list[:g.stocknum]
# 卖出不在买入列表中的股票
for stk in context.portfolio.positions.keys():
if stk not in buy_list:
order_target_value(stk, 0)
log.info("sell %s ", stk)
# 买入在买入列表中但未持仓的股票
for stk in buy_list:
if stk not in context.portfolio.positions.keys():
# 获取当前价格
current_price = get_bars(stk, 1, '1m', ['close'], include_now=True, end_dt=context.current_dt, df=True).iloc[-1]['close']
total_cash = context.portfolio.available_cash
# 检查资金是否足够购买100股
if total_cash < current_price * 100:
continue # 不够买100股,跳过
# 计算每只股票的目标权重和目标价值
cw = 1.0 / g.stocknum
target_val = context.portfolio.total_value * cw
# 计算实际可用于购买的资金
order_cash = min(total_cash, target_val)
# 执行买入操作
ret = order_value(stk, order_cash)
if ret:
log.info("buy [%s], val:%s, cw:%s", stk, order_cash, cw) # 新买入
else:
log.info("Failed to buy stk[%s] value(%s) to weight:%s", stk, order_cash, cw) # 新买入失败
def filter_paused_stock(stock_list):
"""过滤停牌股票"""
current_data = get_current_data()
return [stock for stock in stock_list if not current_data[stock].paused]
def filter_st_stock(stock_list):
"""过滤ST股票"""
current_data = get_current_data()
return [stock for stock in stock_list if not current_data[stock].is_st] # 过滤st
def delisted_filter(stock_list):
"""过滤退市股票"""
current_data = get_current_data()
return [stock for stock in stock_list if not '退' in current_data[stock].name] # 过滤退市股票