聚宽交易系统4.0---涨停板一进二板三合一策略设置

聚宽4.0涨停板一进二板三合一策略设置

文章声明:本内容为个人的业余研究,和任何单位,机构没有关系,文章出现的股票代码,全部只是测试例子,不做投资参考,投资有风险,代码学习使用,不做商业用途

大家在使用聚宽交易系统4.0会遇到集合竞价下单的问题,我用涨停板策略为例子,教大家怎么样设置,我利用算法处理了集合竞价撤单问题,很多人在使用这个模型,反馈还是非常不错的,最近在运行的小市值3.0不错

撤单算法研究

图片

检查是否集合竞价函数

def check_is_jhjj():    '''    检查是否集合竞价    集合竞价不做撤单    9点15到9点30不撤单    14点57到59不撤单    '''    loc=time.localtime()    tm_hour=loc.tm_hour    tm_min=loc.tm_min    wo=loc.tm_wday    #早上集合竞价开始时间    zs_start_hour=9    zs_start_mini=15    #早上集合竞价结束时间    zs_end_hour=9    zs_end_mini=30    #下午时间    xw_start_hour=14    xw_start_mini=57    #下午集合竞价结束时间    xw_end_hour=14    xw_end_mini=59    if tm_hour==zs_start_hour and tm_hour==zs_end_hour and tm_min>=zs_start_mini and tm_min<zs_end_mini:        print("早上集合竞价时间")        return True    elif tm_hour==xw_start_hour and tm_hour==xw_end_hour and tm_min>=xw_start_mini and tm_min<=xw_end_mini:        print("下午集合竞价时间")        return True    else:        print('非集合竞价时间')        return False

交易时间处理,需要参加集合竞价交易,只需要把这个参数是否参数集合竞价改成是就可以

图片

源代码

def check_is_trader_date_1():    '''    检测是不是交易时间    '''    trader_time=text['交易时间段']    start_date=text['交易开始时间']    end_date=text['交易结束时间']    start_mi=text['开始交易分钟']    jhjj=text['是否参加集合竞价']    if jhjj=='是':        jhjj_time=15    else:        jhjj_time=30    loc=time.localtime()    tm_hour=loc.tm_hour    tm_min=loc.tm_min    wo=loc.tm_wday    if wo<=trader_time:        if tm_hour>=start_date and tm_hour<=end_date:            if tm_hour==9 and tm_min<jhjj_time:                return False                        elif tm_min>=start_mi:                return True            else:                return False        else:            return False        else:        print('周末')        return False

看一下策略的原理

策略是一个基于涨停板股票筛选和交易的短线策略,主要包含"一进二"、"首板低开"和"弱转强"三种交易模式。以下是策略的核心原理总结:

  1. 选股逻辑

    • 要求3日内涨幅<28%

    • 昨日收盘价不低于开盘价5%以上

    • 昨日成交额3-19亿

    • 集合竞价成交量占比>3%,高开2%-9%

    • 要求60日内相对位置低于50%

    • 昨日成交额≥1亿

    • 一进二:昨日涨停但前日未涨停的股票

    • 要求高开3%-6%,昨日成交额5.5-20亿

    • 总市值>70亿,流通市值<520亿

    • 上涨时未放量(rising on low volume)

    • 集合竞价成交量占比>3%

    • 每日9:01运行选股函数,筛选三种类型的股票:

    • 首板低开:昨日涨停但今日低开3%-5%的股票

    • 弱转强:昨日曾涨停但未封板的股票

  2. 交易执行

    • 在9:26按开盘价买入符合条件的股票

    • 资金分配:可用资金的30%以上时,均分买入所有符合条件的股票

  3. 卖出策略

    • 有盈利且未涨停时卖出

    • 或跌破5日均线时止损

    • 有盈利且未涨停时卖出

    • 60日内相对位置≥85%

    • 成交量放大(≥50%)

    • 回调位置低于黄金分割点(0.65)

    • 10:00:高位放量卖出

    • 11:25:上午止盈

    • 14:50:尾盘卖出

  4. 风险控制

    • 过滤ST股、停牌股、退市股、次新股(上市<50天)

    • 过滤科创板股票(只交易60/00/30开头股票)

    • 过滤一字涨停股票

    • 设置止损条件(跌破5日均线)

  5. 辅助功能

    • 每日发送选股结果通知

    • 记录详细交易日志

策略设置,聚宽设置,设置策略授权码,可以找我要就可以

比如:涨停板一进二板三合一

图片

点击回测看看回测结果

图片

我们看交易日志有集合竞价下单

图片

这个一个实时运行的高频策略,实时监测数据脉冲有盘中比如10点,11点卖出

图片

图片

图片

可以登录服务器看数据输入授权码

图片

实盘qmt设置,输入账户

图片

输入策略授权码比如:涨停板一进二板三合一

图片

先点击是否测试,选择是先测试一下,实盘改成否

图片

测试的没有问题,挂模型交易

图片

挂模型交易

图片

点击实盘模式点击运行

图片

运行的交易结果

图片

下单的结果,有订单检查,没有下单成功会重新下单

图片

委托记录

图片

图片

实盘把是否测试参数改成否就可以

图片

实盘运行的结果,今天17号没有交易信号

图片

策略源代码我和qmt我全部上传了知识星球可以下载使用,这个只是例子参考,怎么样在集合竞价下单交易设置,


from jqdata import *from jqfactor import *from jqlib.technical_analysis import *import datetime as dtimport pandas as pdfrom datetime import datetimefrom datetime import timedelta'''小果聚宽跟单系统原理替代,继承聚宽的交易函数类读取下单类的函数参数把交易数据发送到服务器把下面的全部源代码复制到聚宽策略的开头就可以实盘前先模拟盘测试一下数据把下面的内容全部复制到策略的开头就可以
服务器: http://101.34.65.108:8888/'''import requestsimport jsonimport pandas as pdfrom jqdata import *url='http://101.34.65.108'port=8888#自定义服务器编码url_code='63d85b6189e42cba63feea36381da615c31ad8e36ae420ed67f60f3598efc9ad'#记得把这个改成自己的一个策略一个,策略的名称找作者建立#支持同时给多个授权码发送信号password_list=['涨停板一进二板三合一']class joinquant_trader:    def __init__(self,url='http://101.34.65.108',                port=8888,                url_code='63d85b6189e42cba63feea36381da615c31ad8e36ae420ed67f60f3598efc9ad',                ):        '''        获取服务器数据        '''        self.url=url        self.port=port        self.url_code=url_code    def get_user_data(self,data_type='用户信息',password='123456'):        '''        获取使用的数据        data_type='用户信息','实时数据',历史数据','清空实时数据','清空历史数据'        '''        url='{}:{}/_dash-update-component'.format(self.url,self.port)        headers={'Content-Type':'application/json'}        data={"output":"joinquant_trader_table.data@{}".format(self.url_code),            "outputs":{"id":"joinquant_trader_table","property":"data@{}".format(self.url_code)},            "inputs":[{"id":"joinquant_trader_password","property":"value","value":password},                    {"id":"joinquant_trader_data_type","property":"value","value":data_type},                    {"id":"joinquant_trader_text","property":"value","value":"\n               {'状态': 'held', '订单添加时间': 'datetime.datetime(2024, 4, 23, 9, 30)', '买卖': 'False', '下单数量': '9400', '已经成交': '9400', '股票代码': '001.XSHE', '订单ID': '1732208241', '平均成交价格': '10.5', '持仓成本': '10.59', '多空': 'long', '交易费用': '128.31'}\n                "},                    {"id":"joinquant_trader_run","property":"value","value":"运行"},                    {"id":"joinquant_trader_down_data","property":"value","value":"不下载数据"}],                    "changedPropIds":["joinquant_trader_run.value"],"parsedChangedPropsIds":["joinquant_trader_run.value"]}        res=requests.post(url=url,data=json.dumps(data),headers=headers)        text=res.json()        df=pd.DataFrame(text['response']['joinquant_trader_table']['data'])        return df    def send_order(self,result,password):        '''        发送交易数据        '''        url='{}:{}/_dash-update-component'.format(self.url,self.port)        headers={'Content-Type':'application/json'}        data={"output":"joinquant_trader_table.data@{}".format(self.url_code),            "outputs":{"id":"joinquant_trader_table","property":"data@{}".format(self.url_code)},            "inputs":[{"id":"joinquant_trader_password","property":"value","value":password},                    {"id":"joinquant_trader_data_type","property":"value","value":'实时数据'},                    {"id":"joinquant_trader_text","property":"value","value":result},                    {"id":"joinquant_trader_run","property":"value","value":"运行"},                    {"id":"joinquant_trader_down_data","property":"value","value":"不下载数据"}],                    "changedPropIds":["joinquant_trader_run.value"],"parsedChangedPropsIds":["joinquant_trader_run.value"]}        res=requests.post(url=url,data=json.dumps(data),headers=headers)        text=res.json()        df=pd.DataFrame(text['response']['joinquant_trader_table']['data'])        return df#继承类xg_data=joinquant_trader(url=url,port=port,url_code=url_code)def send_order(result):    '''    发送函数    status: 状态, 一个OrderStatus值    add_time: 订单添加时间, [datetime.datetime]对象    is_buy: bool值, 买还是卖,对于期货:    开多/平空 -> 买    开空/平多 -> 卖    amount: 下单数量, 不管是买还是卖, 都是正数    filled: 已经成交的股票数量, 正数    security: 股票代码    order_id: 订单ID    price: 平均成交价格, 已经成交的股票的平均成交价格(一个订单可能分多次成交)    avg_cost: 卖出时表示下卖单前的此股票的持仓成本, 用来计算此次卖出的收益. 买入时表示此次买入的均价(等同于price).    side: 多/空,'long'/'short'    action: 开/平, 'open'/'close'    commission交易费用(佣金、税费等)    '''    data={}    data['状态']=str(result.status)    data['订单添加时间']=str(result.add_time)    data['买卖']=str(result.is_buy)    data['下单数量']=str(result.amount)    data['已经成交']=str(result.filled)    data['股票代码']=str(result.security)    data['订单ID']=str(result.order_id)    data['平均成交价格']=str(result.price)    data['持仓成本']=str(result.avg_cost)    data['多空']=str(result.side)    data['交易费用']=str(result.commission)    result=str(data)    for password in password_list:        try:            xg_data.send_order(result,password)            print('{} 授权码信号发送完成***************'.format(password))        except Exception as e:            print(e)            print('{} 授权码信号发送失败***************'.format(password))    return datadef xg_order(func):    '''    继承order对象 数据交易函数    '''    def wrapper(*args, **kwargs):        result = func(*args, **kwargs)        if result == None:            return        send_order(result)        return result    return wrapperdef xg_order_target(func):    '''    继承order_target对象 百分比    '''    def wrapper(*args, **kwargs):        result = func(*args, **kwargs)        if result == None:            return                send_order(result)        return result    return wrapper    def xg_order_value(func):    '''    继承order_value对象 数量    '''    def wrapper(*args, **kwargs):        result = func(*args, **kwargs)        if result == None:            return                send_order(result)        return result    return wrapperdef xg_order_target_value(func):    '''    继承order_target_value对象 数量    '''    def wrapper(*args, **kwargs):        result = func(*args, **kwargs)        if result == None:            return                send_order(result)        return result    return wrapperorder = xg_order(order)order_target = xg_order_target(order_target)order_value = xg_order_value(order_value)order_target_value = xg_order_target_value(order_target_value)def initialize(context):    set_option('use_real_price', True)    log.set_level('system', 'error')    set_option('avoid_future_data', True)    # 一进二    run_daily(get_stock_list, '9:01')    run_daily(buy, '09:26')    run_daily(sell_heavy_turnover, time='10:00', reference_security='000300.XSHG')    run_daily(sell, time='11:25', reference_security='000300.XSHG')    run_daily(sell, time='14:50', reference_security='000300.XSHG')# 选股def get_stock_list(context):     # 文本日期    date = context.previous_date    date_2,date_1,date = get_trade_days( end_date=date, count=3)    # 初始列表    initial_list = prepare_stock_list(date)    # 昨日涨停    hl0_list = get_hl_stock(initial_list, date)    # 前日曾涨停    hl1_list = get_ever_hl_stock(initial_list, date_1)    # 前前日曾涨停    hl2_list = get_ever_hl_stock(initial_list, date_2)        # 合并 hl1_list 和 hl2_list 为一个集合,用于快速查找需要剔除的元素      elements_to_remove = set(hl1_list + hl2_list)      # 使用列表推导式来剔除 hl_list 中存在于 elements_to_remove 集合中的元素      g.gap_up = [stock for stock in hl0_list if stock not in elements_to_remove]     # 昨日涨停,但前天没有涨停的    g.gap_down = [s for s in hl0_list if s not in hl1_list]         # 昨日曾涨停    h1_list = get_ever_hl_stock2(initial_list, date)    # 上上个交易日涨停过滤    elements_to_remove = get_hl_stock(initial_list, date_1)        # 过滤上上个交易日涨停、曾涨停    g.reversal = [stock for stock in h1_list if stock not in elements_to_remove]    # 交易def buy(context):    qualified_stocks = []     gk_stocks=[]    dk_stocks=[]    rzq_stocks=[]    current_data = get_current_data()    date_now = context.current_dt.strftime("%Y-%m-%d")    mid_time1 = ' 09:15:00'    end_times1 =  ' 09:26:00'    start = date_now + mid_time1    end = date_now + end_times1    # 高开    for s in g.gap_up:        # 条件一:均价,金额,市值,换手率        prev_day_data = attribute_history(s, 1, '1d', fields=['close', 'volume', 'money'], skip_paused=True)        avg_price_increase_value = prev_day_data['money'][0] / prev_day_data['volume'][0] / prev_day_data['close'][0] * 1.1 - 1        if avg_price_increase_value < 0.07 or prev_day_data['money'][0] < 5.5e8 or prev_day_data['money'][0] > 20e8 :            continue        # market_cap 总市值(亿元) > 70亿 流通市值(亿元) < 520亿        turnover_ratio_data=get_valuation(s, start_date=context.previous_date, end_date=context.previous_date, fields=['turnover_ratio', 'market_cap','circulating_market_cap'])        if turnover_ratio_data.empty or turnover_ratio_data['market_cap'][0] < 70  or turnover_ratio_data['circulating_market_cap'][0] > 520 :            continue                # 条件二:左压        if rise_low_volume(s, context):            continue                # 条件三:高开,开比        auction_data = get_call_auction(s, start_date=date_now, end_date=date_now, fields=['time','volume', 'current'])        #log.info(auction_data)        if auction_data.empty or auction_data['volume'][0] / prev_day_data['volume'][-1] < 0.03:            continue        current_ratio = auction_data['current'][0] / (current_data[s].high_limit/1.1)        if current_ratio<=1 or current_ratio>=1.06:            continue        # 如果股票满足所有条件,则添加到列表中          gk_stocks.append(s)        qualified_stocks.append(s)        # 低开        # 基础信息    date = transform_date(context.previous_date, 'str')    current_data = get_current_data()        if g.gap_down:        stock_list = g.gap_down        # 计算相对位置        rpd = get_relative_position_df(stock_list, date, 60)        rpd = rpd[rpd['rp'] <= 0.5]        stock_list = list(rpd.index)        # 低开        df =  get_price(stock_list, end_date=date, frequency='daily', fields=['close'], count=1, panel=False, fill_paused=False, skip_paused=True).set_index('code') if len(stock_list) != 0 else pd.DataFrame()        df['open_pct'] = [current_data[s].day_open/df.loc[s, 'close'] for s in stock_list]        df = df[(0.955 <= df['open_pct']) & (df['open_pct'] <= 0.97)] #低开越多风险越大,选择3个多点即可        stock_list = list(df.index)        # send_message(','.join(stock_list))        # print(df)        for s in stock_list:            prev_day_data = attribute_history(s, 1, '1d', fields=['close', 'volume', 'money'], skip_paused=True)            if prev_day_data['money'][0] >= 1e8  :                dk_stocks.append(s)                qualified_stocks.append(s)            # 弱转强    for s in g.reversal:        # 过滤前面三天涨幅超过28%的票        price_data = attribute_history(s, 4, '1d', fields=['close'], skip_paused=True)        if len(price_data) < 4:            continue        increase_ratio = (price_data['close'][-1] - price_data['close'][0]) / price_data['close'][0]        if increase_ratio > 0.28:            continue                # 过滤前一日收盘价小于开盘价5%以上的票        prev_day_data = attribute_history(s, 1, '1d', fields=['open', 'close'], skip_paused=True)        if len(prev_day_data) < 1:            continue        open_close_ratio = (prev_day_data['close'][0] - prev_day_data['open'][0]) / prev_day_data['open'][0]        if open_close_ratio < -0.05:            continue                prev_day_data = attribute_history(s, 1, '1d', fields=['close', 'volume','money'], skip_paused=True)        avg_price_increase_value = prev_day_data['money'][0] / prev_day_data['volume'][0] / prev_day_data['close'][0]  - 1        if avg_price_increase_value < -0.04 or prev_day_data['money'][0] < 3e8 or prev_day_data['money'][0] > 19e8:            continue        turnover_ratio_data = get_valuation(s, start_date=context.previous_date, end_date=context.previous_date, fields=['turnover_ratio','market_cap','circulating_market_cap'])        if turnover_ratio_data.empty or turnover_ratio_data['market_cap'][0] < 70  or turnover_ratio_data['circulating_market_cap'][0] > 520 :            continue        if rise_low_volume(s, context):            continue        auction_data = get_call_auction(s, start_date=date_now, end_date=date_now, fields=['time','volume', 'current'])                if auction_data.empty or auction_data['volume'][0] / prev_day_data['volume'][-1] < 0.03:            continue        current_ratio = auction_data['current'][0] / (current_data[s].high_limit/1.1)        if current_ratio <= 0.98 or current_ratio >= 1.09:            continue        rzq_stocks.append(s)        qualified_stocks.append(s)            if len(qualified_stocks)>0:        print('———————————————————————————————————')        send_message('今日选股:'+','.join(qualified_stocks))        print('一进二:'+','.join(gk_stocks))        print('首板低开:'+','.join(dk_stocks))        print('弱转强:'+','.join(rzq_stocks))        print('今日选股:'+','.join(qualified_stocks))        print('———————————————————————————————————')    else:        send_message('今日无目标个股')        print('今日无目标个股')                  if len(qualified_stocks)!=0  and context.portfolio.available_cash/context.portfolio.total_value>0.3:        value = context.portfolio.available_cash / len(qualified_stocks)        for s in qualified_stocks:            # 下单            #由于关闭了错误日志,不加这一句,不足一手买入失败也会打印买入,造成日志不准确            if context.portfolio.available_cash/current_data[s].last_price>100:                 order_value(s, value, MarketOrderStyle(current_data[s].day_open))                print('买入' + s)                print('———————————————————————————————————')# 处理日期相关函数def transform_date(date, date_type):    if type(date) == str:        str_date = date        dt_date = dt.datetime.strptime(date, '%Y-%m-%d')        d_date = dt_date.date()    elif type(date) == dt.datetime:        str_date = date.strftime('%Y-%m-%d')        dt_date = date        d_date = dt_date.date()    elif type(date) == dt.date:        str_date = date.strftime('%Y-%m-%d')        dt_date = dt.datetime.strptime(str_date, '%Y-%m-%d')        d_date = date    dct = {'str':str_date, 'dt':dt_date, 'd':d_date}    return dct[date_type]def get_shifted_date(date, days, days_type='T'):    #获取上一个自然日    d_date = transform_date(date, 'd')    yesterday = d_date + dt.timedelta(-1)    #移动days个自然日    if days_type == 'N':        shifted_date = yesterday + dt.timedelta(days+1)    #移动days个交易日    if days_type == 'T':        all_trade_days = [i.strftime('%Y-%m-%d') for i in list(get_all_trade_days())]        #如果上一个自然日是交易日,根据其在交易日列表中的index计算平移后的交易日                if str(yesterday) in all_trade_days:            shifted_date = all_trade_days[all_trade_days.index(str(yesterday)) + days + 1]        #否则,从上一个自然日向前数,先找到最近一个交易日,再开始平移        else:            for i in range(100):                last_trade_date = yesterday - dt.timedelta(i)                if str(last_trade_date) in all_trade_days:                    shifted_date = all_trade_days[all_trade_days.index(str(last_trade_date)) + days + 1]                    break    return str(shifted_date)# 过滤函数def filter_new_stock(initial_list, date, days=50):    d_date = transform_date(date, 'd')    return [stock for stock in initial_list if d_date - get_security_info(stock).start_date > dt.timedelta(days=days)]def filter_st_paused_stock(initial_list):    current_data = get_current_data()    # 使用列表推导式结合any()函数,筛选出符合条件的股票    return [stock for stock in initial_list             if not any([                current_data[stock].is_st,          # 排除ST股                current_data[stock].paused,         # 排除停牌股                '退' in current_data[stock].name    # 排除名称中含'退'字的股票,避免退市股            ])]def filter_kcbj_stock(initial_list):    return [stock for stock in initial_list if stock[:2] in (('60','00','30'))]def filter_st_stock(initial_list, date):    str_date = transform_date(date, 'str')    if get_shifted_date(str_date, 0, 'N') != get_shifted_date(str_date, 0, 'T'):        str_date = get_shifted_date(str_date, -1, 'T')    df = get_extras('is_st', initial_list, start_date=str_date, end_date=str_date, df=True)    df = df.T    df.columns = ['is_st']    df = df[df['is_st'] == False]    filter_list = list(df.index)    return filter_listdef filter_paused_stock(initial_list, date):    df = get_price(initial_list, end_date=date, frequency='daily', fields=['paused'], count=1, panel=False, fill_paused=True)    df = df[df['paused'] == 0]    paused_list = list(df.code)    return paused_list# 一字def filter_extreme_limit_stock(context, stock_list, date):    tmp = []    for stock in stock_list:        df = get_price(stock, end_date=date, frequency='daily', fields=['low','high_limit'], count=1, panel=False)        if df.iloc[0,0] < df.iloc[0,1]:            tmp.append(stock)    return tmp# 每日初始股票池def prepare_stock_list(date):     initial_list = get_all_securities('stock', date).index.tolist()    initial_list = filter_kcbj_stock(initial_list)    initial_list = filter_new_stock(initial_list, date)    # initial_list = filter_st_stock(initial_list, date)    # initial_list = filter_paused_stock(initial_list, date)    initial_list = filter_st_paused_stock(initial_list)    return initial_listdef rise_low_volume(s, context):   # 上涨时,未放量 rising on low volume    hist = attribute_history(s, 106, '1d', fields=['high','volume'], skip_paused=True,df=False)    high_prices = hist['high'][:102]    prev_high = high_prices[-1]    zyts_0 = next((i-1 for i, high in enumerate(high_prices[-3::-1], 2) if high >= prev_high), 100)    zyts = zyts_0 + 5    if  hist['volume'][-1] <= max(hist['volume'][-zyts:-1]) * 0.9:        return True    return False# 筛选出某一日涨停的股票def get_hl_stock(initial_list, date):    df = get_price(initial_list, end_date=date, frequency='daily', fields=['close','high_limit'], count=1, panel=False, fill_paused=False, skip_paused=False)    df = df.dropna() #去除停牌    df = df[df['close'] == df['high_limit']]    hl_list = list(df.code)    return hl_list    # 筛选曾涨停def get_ever_hl_stock(initial_list, date):    df = get_price(initial_list, end_date=date, frequency='daily', fields=['high','high_limit'], count=1, panel=False, fill_paused=False, skip_paused=False)    df = df.dropna() #去除停牌    df = df[df['high'] == df['high_limit']]    hl_list = list(df.code)    return hl_list# 筛选曾涨停def get_ever_hl_stock2(initial_list, date):    df = get_price(initial_list, end_date=date, frequency='daily', fields=['close','high','high_limit'], count=1, panel=False, fill_paused=False, skip_paused=False)    df = df.dropna() #去除停牌    cd1 = df['high'] == df['high_limit']     cd2 = df['close']!= df['high_limit']    df = df[cd1 & cd2]    hl_list = list(df.code)    return hl_list# 计算涨停数def get_hl_count_df(hl_list, date, watch_days):    # 获取watch_days的数据    df = get_price(hl_list, end_date=date, frequency='daily', fields=['close','high_limit','low'], count=watch_days, panel=False, fill_paused=False, skip_paused=False)    df.index = df.code    #计算涨停与一字涨停数,一字涨停定义为最低价等于涨停价    hl_count_list = []    extreme_hl_count_list = []    for stock in hl_list:        df_sub = df.loc[stock]        hl_days = df_sub[df_sub.close==df_sub.high_limit].high_limit.count()        extreme_hl_days = df_sub[df_sub.low==df_sub.high_limit].high_limit.count()        hl_count_list.append(hl_days)        extreme_hl_count_list.append(extreme_hl_days)    #创建df记录    df = pd.DataFrame(index=hl_list, data={'count':hl_count_list, 'extreme_count':extreme_hl_count_list})    return df# 计算连板数def get_continue_count_df(hl_list, date, watch_days):    df = pd.DataFrame()    for d in range(2, watch_days+1):        HLC = get_hl_count_df(hl_list, date, d)        CHLC = HLC[HLC['count'] == d]        df = df.append(CHLC)    stock_list = list(set(df.index))    ccd = pd.DataFrame()    for s in stock_list:        tmp = df.loc[[s]]        if len(tmp) > 1:            M = tmp['count'].max()            tmp = tmp[tmp['count'] == M]        ccd = ccd.append(tmp)    if len(ccd) != 0:        ccd = ccd.sort_values(by='count', ascending=False)        return ccd# 计算昨涨幅def get_index_increase_ratio(index_code, context):    # 获取指数昨天和前天的收盘价    close_prices = attribute_history(index_code, 2, '1d', fields=['close'], skip_paused=True)    if len(close_prices) < 2:        return 0  # 如果数据不足,返回0    day_before_yesterday_close = close_prices['close'][0]    yesterday_close = close_prices['close'][1]        # 计算涨幅    increase_ratio = (yesterday_close - day_before_yesterday_close) / day_before_yesterday_close    return increase_ratio#上午有利润就跑def sell(context):    # 基础信息    date = transform_date(context.previous_date, 'str')    current_data = get_current_data()            # 根据时间执行不同的卖出策略    if str(context.current_dt)[-8:] == '11:25:00' :        for s in list(context.portfolio.positions):            if ((context.portfolio.positions[s].closeable_amount != 0) and (current_data[s].last_price < current_data[s].high_limit) and (current_data[s].last_price > 1*context.portfolio.positions[s].avg_cost)):#avg_cost当前持仓成本                order_target_value(s, 0)                print( '止盈卖出', [s,get_security_info(s, date).display_name])                print('———————————————————————————————————')        if str(context.current_dt)[-8:] == '14:50:00':        for s in list(context.portfolio.positions):            close_data2 = attribute_history(s, 4, '1d', ['close'])            M4=close_data2['close'].mean()            MA5=(M4*4+current_data[s].last_price)/5            if ((context.portfolio.positions[s].closeable_amount != 0) and (current_data[s].last_price < current_data[s].high_limit) and (current_data[s].last_price > 1*context.portfolio.positions[s].avg_cost)):#avg_cost当前持仓成本                order_target_value(s, 0)                print( '止盈卖出', [s,get_security_info(s, date).display_name])                print('———————————————————————————————————')            elif ((context.portfolio.positions[s].closeable_amount != 0) and (current_data[s].last_price < MA5)):                #closeable_amount可卖出的仓位                order_target_value(s, 0)                print( '止损卖出', [s,get_security_info(s, date).display_name])                print('———————————————————————————————————')                                  # 首版低开策略代码                def filter_new_stock2(initial_list, date, days=250):    d_date = transform_date(date, 'd')    return [stock for stock in initial_list if d_date - get_security_info(stock).start_date > dt.timedelta(days=days)]        # 每日初始股票池def prepare_stock_list2(date):     initial_list = get_all_securities('stock', date).index.tolist()    initial_list = filter_kcbj_stock(initial_list)    initial_list = filter_new_stock2(initial_list, date)    initial_list = filter_st_stock(initial_list, date)    initial_list = filter_paused_stock(initial_list, date)    return initial_list        # 计算股票处于一段时间内相对位置def get_relative_position_df(stock_list, date, watch_days):    if len(stock_list) != 0:        df = get_price(stock_list, end_date=date, fields=['high', 'low', 'close'], count=watch_days, fill_paused=False, skip_paused=False, panel=False).dropna()        close = df.groupby('code').apply(lambda df: df.iloc[-1,-1])        high = df.groupby('code').apply(lambda df: df['high'].max())        low = df.groupby('code').apply(lambda df: df['low'].min())        result = pd.DataFrame()        result['rp'] = (close-low) / (high-low)        return result    else:        return pd.DataFrame(columns=['rp'])        # 计算股票最高位处于一段时间内相对位置        def get_relative_position_df2(stock_list, date, watch_days):    if len(stock_list) != 0:        df = get_price(stock_list, end_date=date, fields=['high', 'low', 'close'], count=watch_days, fill_paused=False, skip_paused=False, panel=False).dropna()        yestoday_high = df.groupby('code').apply(lambda df: df.iloc[-1,-3])        high = df.groupby('code').apply(lambda df: df['high'].max())        low = df.groupby('code').apply(lambda df: df['low'].min())        result = pd.DataFrame()        result['rp'] = (yestoday_high-low) / (high-low)        return result    else:        return pd.DataFrame(columns=['rp'])                def sell_heavy_turnover(context):    date = transform_date(context.previous_date, 'str')    current_data = get_current_data()        # 计算相对位置    rpd = get_relative_position_df2(list(context.portfolio.positions), date, 60)    rpd = rpd[rpd['rp'] >= 0.85]    stock_list = list(rpd.index)        for s in stock_list:        df = get_price(s, end_date=date, fields=['high', 'low', 'close', 'open', 'volume', 'high_limit'], count=2, fill_paused=False, skip_paused=False, panel=False)        pullback_ratio = (df['close'][-1] - df['high'][-1]) / df['high'][-1]        vol_ratio = df['volume'][-1] / df['volume'][-2]        close_pos = (df['close'][-1] - min(df['high'][-1], df['low'][-1])) / abs(df['high'][-1] - df['low'][-1])                # 如果处于高位,成交量放大,回调位置低于黄金分割点,当天在跌, 则卖出        if ((context.portfolio.positions[s].closeable_amount != 0) and (vol_ratio >= 0.5) and (close_pos <= 0.65) and (current_data[s].last_price < df['close'][-1])):            order_target_value(s, 0)            print( '高位放量卖出', [s,get_security_info(s, date).display_name])            print('———————————————————————————————————')

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xg_quant

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值