风火编程--量化交易之聚宽DEMO

聚宽DEMO

包含仓位管理和风险管理

from jqdata import *

MA_WIN_1 = 10
MA_WIN_2 = 30

ATR_WIN_SIZE = 20
RISK_RATIO = 0.001


# 初始化函数,设定基准等等
def initialize(context):
    set_benchmark('000300.XSHG')
    set_option('use_real_price', True)
    # 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')

    # 定时运行函数
    run_daily(before_market_open, time='before_open', reference_security='000300.XSHG') 
    run_daily(market_open, time='every_bar', reference_security='000300.XSHG')
    run_daily(after_market_close, time='after_close', reference_security='000300.XSHG')
    
    g.stock_pool = get_index_stocks("000016.XSHG", date=context.current_dt)
    g.init_cash = context.portfolio.starting_cash  # 启动资金
    
    g.entry_dates = {code:None for code in g.stock_pool}

# 开盘前运行函数
def before_market_open(context):
    look_ahead_n = max(MA_WIN_1, MA_WIN_2) + 1
    g.up_cross_signaled = set()
    g.down_cross_signaled = set()
    for code in g.stock_pool:
        df = attribute_history(code, look_ahead_n, "1d", ["close"], skip_paused=True)  # 该函数返回结果不包括当天数据
        if len(df) != look_ahead_n:
            continue
        close = df["close"]
        ma_short = close.rolling(MA_WIN_1).mean()  # 短时均线
        ma_long = close.rolling(MA_WIN_2).mean()   # 长时均线
        uc_flags = (ma_short.shift(1) <= ma_long.shift(1)) & (ma_short > ma_long)  # 上穿标志
        dc_flags = (ma_short.shift(1) >= ma_long.shift(1)) & (ma_short < ma_long)  # 下穿标志
        if uc_flags.iloc[-1]:
            g.up_cross_signaled.add(code)
        if dc_flags.iloc[-1]:
            g.down_cross_signaled.add(code)

# 开盘时运行函数
def market_open(context):
    cur_dt = context.current_dt.date()  # 当前日期
    p = context.portfolio  # 资金账户
    current_data = get_current_data()

    each_cash = g.init_cash / len(g.stock_pool)  # 每只股票分配的资金
    
    # 卖出均线死叉信号的持仓股
    for code, pos in p.positions.items():
        if code in g.down_cross_signaled:
            order_target(code, 0)

    # 买入均线金叉信号的持仓股
    for code in g.up_cross_signaled:
        if code not in p.positions:
            if current_data[code].paused:
                continue
            df = attribute_history(code, ATR_WIN_SIZE+1, "1d", ["high", "low", "close"], skip_paused=True)
            if len(df) != ATR_WIN_SIZE+1:
                continue
            df["pdc"] = df["close"].shift(1)
            tr = df.apply(lambda x: max(x["high"]-x["low"], abs(x["high"]-x["pdc"]), abs(x["pdc"]-x["low"])), axis=1)
            atr = tr[-ATR_WIN_SIZE:].mean()
            num_to_buy = g.init_cash * RISK_RATIO / atr // 100 * 100
            order(code, num_to_buy)
            
            g.entry_dates[code] = cur_dt

    # 检查有无符合回撤止盈条件的持仓股
    for code, pos in p.positions.items():
        if current_data[code].paused:
            continue

        if pos.today_amount == 0 and pos.closeable_amount > 0:
            last_entry_date = g.entry_dates[code]
            prev_date = context.current_dt - timedelta(days=1)

            # 计算截止到前一天的HHV
            df = get_price(code, start_date=last_entry_date, end_date=prev_date, frequency="1d", fields=["high", "low", "open", "close"], skip_paused=True)
  
            hhv = df["high"].max()
            hhv_idx = df["high"].idxmax()
            drop_rate = (hhv - current_data[code].day_open) / hhv

            # 计算atr
            df["pdc"] = df["close"].shift(1)
            df["tr"] = df.apply(lambda x: max(x["high"]-x["low"], abs(x["high"]-x["pdc"]), abs(x["pdc"]-x["low"]))/x["high"], axis=1)
            df["atr"] = df["tr"].rolling(ATR_WIN_SIZE).mean()
            
            if drop_rate > df["atr"][hhv_idx]:
                order_target(code, 0)

# 收盘后运行函数  
def after_market_close(context):
    p = context.portfolio
    pos_level = p.positions_value / p.total_value
    record(pos_level=pos_level)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值