策略名称:北向资金布林带动态调仓策略
1. **策略概述**
该策略基于北向资金(即通过沪港通和深港通进入A股市场的资金)的流动情况,结合布林带指标动态调整持仓。策略的核心逻辑是:当北向资金净流入突破布林带上轨时,买入北向资金增持比例最高的股票;当北向资金净流入跌破布林带下轨时,清空所有持仓。通过这种方式,策略试图捕捉北向资金流入的短期趋势,从而实现超额收益。
2. **策略逻辑**
- **基准设定**:策略以沪深300指数(000300.XSHG)作为基准,用于衡量策略的表现。
- **布林带计算**:
- 计算过去150个交易日的北向资金净流入数据。
- 计算布林带的中轨(均值)、上轨(均值 + 2倍标准差)和下轨(均值 - 2倍标准差)。
- **调仓逻辑**:
- **买入信号**:当北向资金净流入突破布林带上轨时,筛选北向资金增持比例最高的15只股票,并等权重买入。
- **卖出信号**:当北向资金净流入跌破布林带下轨时,清空所有持仓。
- **交易频率**:策略在每个交易日的9:30进行调仓操作。
3. **风险控制**
- **手续费设定**:买入时佣金为万分之三,卖出时佣金为万分之三加千分之一印花税,每笔交易佣金最低为5元。
- **持仓限制**:策略最多持有15只股票,避免过度分散投资。
- **动态止损**:当北向资金净流入跌破布林带下轨时,策略会自动清仓,避免进一步亏损。
4. **适用场景**
该策略适用于北向资金对A股市场有显著影响的时期,尤其是在北向资金流入趋势明显的情况下。策略的优势在于能够快速捕捉北向资金的短期趋势,适合中短期投资。
5. **策略优化建议**
- **参数优化**:可以调整布林带的计算窗口(如从150天调整为100天或200天)或标准差倍数(如从2倍调整为1.5倍或2.5倍),以适应不同的市场环境。
- **多因子结合**:可以在北向资金的基础上加入其他技术指标或基本面因子,进一步提升策略的稳定性。
策略关键词:
- 北向资金- 布林带- 动态调仓- 短期趋势- 沪深300
策略特点:
- **简单易行**:策略逻辑清晰,易于理解和实现。
- **动态调整**:根据北向资金的流动情况动态调整持仓,灵活应对市场变化。
- **风险可控**:通过布林带指标设置明确的买入和卖出信号,有效控制风险。
#from .API import *
# 导入函数库
from jqdata import *
import random
import pandas as pd
import numpy as np
import datetime as dt
# 初始化函数,设定基准等等
def initialize(context):
# 设定沪深300作为基准
set_benchmark('000300.XSHG')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 输出内容到日志 log.info()
log.info('初始函数开始运行且全局只运行一次')
# 过滤掉order系列API产生的比error级别低的log
log.set_level('order', 'error')
### 股票相关设定 ###
# 股票类每笔交易时的手续费是:买入时佣金万分之三,卖出时佣金万分之三加千分之一印花税, 每笔交易佣金最低扣5块钱
set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
g.max_stock_count =15
g.back_trade_days=40
g.top_money_in = []
g.window = 150
g.stdev_n = 2
g.mf, g.upper, g.lower = None, None, None
run_daily(before_market_open, time='07:00')
run_daily(reblance, '9:30')
def before_market_open(context):
pre_date = (context.current_dt - datetime.timedelta(1)).strftime('%Y-%m-%d')
g.mf, g.upper, g.lower = get_boll(pre_date)
log.info('北上资金均值:%.2f 北上资金上界:%.2f 北上资金下界:%.2f' % (g.mf, g.upper, g.lower))
def get_boll(end_date):
"""
获取北向资金布林带
"""
table = finance.STK_ML_QUOTA
q = query(
table.day, table.quota_daily, table.quota_daily_balance
).filter(
table.link_id.in_(['310001', '310002']), table.day<=end_date
).order_by(table.day)
money_df = finance.run_query(q)
money_df['net_amount'] = money_df['quota_daily'] - money_df['quota_daily_balance']
# 分组求和
money_df = money_df.groupby('day')[['net_amount']].sum().iloc[-g.window:]
mid = money_df['net_amount'].mean()
stdev = money_df['net_amount'].std()
upper = mid + g.stdev_n * stdev
lower = mid - g.stdev_n * stdev
mf = money_df['net_amount'].iloc[-1]
return mf, upper, lower
def calc_change(context):
table = finance.STK_HK_HOLD_INFO
q = query(table.day, table.name, table.code, table.share_ratio)\
.filter(table.link_id.in_(['310001', '310002']),
table.day.in_([context.previous_date]))
df = finance.run_query(q)
return df.sort_values(by='share_ratio',ascending=False)[:g.max_stock_count]['code'].values
