迅投QMT社区 门户 查看主题

算法研究--单边网格卖出原理

发布者: 落花忆流年 | 发布时间: 2026-5-11 16:38| 查看数: 25| 评论数: 0|帖子模式

在网格的配置中,参数可以单独开启买入,卖出网格,也可以买卖网格一起开启形成循环的买卖做T网格,这里采用单独开启买入网格,我一般不用网页做买入,我一般是检测持股卖出比较多 算法研究--网格算法单边网格买入原理研究

acf6c102f6d70188406e447e83a04220.png

一、算法定义与核心理念

网格卖出策略是一种基于价格波动的自动分批止盈方法,其核心思想是:当股价相对于某个基准价上涨达到预设幅度时,自动卖出固定数量(或固定金额、固定比例)的持仓,锁定利润,并将该次卖出价格作为新的基准价,形成动态上移的卖出网格。该策略通常与网格买入策略配合,构成完整的网格交易系统,通过捕捉市场价格的上下波动,反复赚取差价

下面是我绘制的大概原理情况,网格多数用来做检测持股卖出

ce57d6f4da9d541a4af4356c9205df21.png

二、策略的核心逻辑与关键要素

1. 基准价的动态设定

  • 初始基准价:若无历史交易记录,通常取昨日收盘价或开盘参考价(由 <span leaf="">get_base_price</span>函数获取)。
  • 运行期基准价:取该股票最后一次交易(买入或卖出)的成交价格,从交易日志中读取。这使得基准价始终跟随最新成交价,确保网格的连续性。
  • 基准价的作用:作为计算涨幅的参照点,决定了卖出触发的位置。

2. 触发条件

  • 监控对象:实时行情最新价(<span leaf="">last_price</span>)。
  • 涨幅计算<span leaf="">涨幅 = (最新价 - 基准价) / 基准价 × 100%</span>
  • 触发阈值:当涨幅 ≥ 预设的“上涨比例”(如1%)时,触发卖出。该阈值决定了网格的密度——阈值越小,网格越密,交易越频繁。

3. 卖出数量确定

根据交易模式(<span leaf="">trader_type</span>)计算应卖数量,但不得超过当前可用持仓:

  • 数量模式:每次固定卖出指定股数(如100股)。
  • 金额模式:每次卖出指定金额的股票,按最新价折算股数(<span leaf="">amount = 金额 / 价格</span>),并经过 <span leaf="">adjust_amount</span>调整至符合最小交易单位(如100股的整数倍)。
  • 百分比模式:按账户总资产的一定比例卖出,<span leaf="">amount = 总资产 × 百分比 / 价格</span>,同样调整至合规股数。

4. 执行与记录

  • 满足触发条件且可用持仓足够(≥10股)时,通过 <span leaf="">passorder</span>发出卖出委托。
  • 记录本次交易信息(股票代码、名称、类型、价格、时间等)到日志文件,供后续基准价更新使用。
  • 为防止首次运行时误记录历史数据,代码中通过标志 <span leaf="">a.gd_sell</span>控制第一次循环不写入日志。

5. 基准价更新机制

卖出成功后,最新成交价成为新的基准价,下一次上涨需基于新基准价重新计算涨幅。这形成了“卖出→基准价上移→再上涨再卖出”的阶梯式止盈路径。

ff1d747557f25f789fd21d9b2ffd1d96.png

网格卖出策略的本质是将价格波动转化为可控的收益流。它通过动态基准价和固定涨幅阈值,构建了一个“上涨即卖出”的自动止盈系统。其核心思路可概括为:

  • 分散风险:分批卖出,避免一次性决策失误。
  • 顺应波动:利用市场固有的上下波动赚取差价,而非预测方向。
  • 机械执行:完全自动化,排除情绪干扰,确保交易纪律。
  • 循环反馈:每次交易后更新基准价,使网格自适应市场,形成正反馈循环。

该策略是量化交易中经典的网格交易法的组成部分,适合风险偏好适中、追求稳定收益的投资者,尤其适用于震荡市中的指数基金或高流动性个股。通过合理设置参数并与网格买入策略协同,可在控制风险的前提下,长期从市场波动中获利。

下面是策略框架运行的流程图方便理解

c4031f2ece4e4281a84fd22712ac0dd4.png

不懂的问我就可以,加我备注入群可以加入专业的量化群,技术支持服务

量化福利

6f43de12faf05315e60ae8c1947f477a.png

源代码方便大家去理解策略思路,只参考学习,不做交易参考

def run_gd_trade_sell(c):
    '''
    网格卖出
    "网格卖出设置":"网格卖出设置*********",
    "是否开启网格卖出":"是",
    "上涨比例":1,
    '''
    path=c.text['记录文件路径']
    up_ratio=c.text['上涨比例']
    trader_type=c.text['交易模式']
    value=c.text['下单值']
    position=get_position(c,c.account,c.account_type)
    account=get_account(c,c.account,c.account_type)
    if position.shape[0]>0:
        position=position[position['持仓量']>=10]
        if position.shape[0]>0:
            hold_list=position['证券代码'].tolist()
            av_amount_dict=dict(zip(position['证券代码'],position['可用数量']))
        else:
            hold_list=[]
            av_amount_dict={}
    else:
        hold_list=[]
        av_amount_dict={}
    if check_is_trader_date_1(c):
        df=get_trader_stock(c)
        if df.shape[0]>0:
            for stock,name in zip(df['证券代码'],df['名称']):
                try:
                    print('***************************网格卖出{} {}************************************************************************************'.format(stock,name))
                    now_date=int(''.join(str(datetime.now())[:10].split('-')))
                    date_time=int(''.join(str(datetime.now()).split('.')[0][-8:].split(':')))
                    log=check_trader_log(c)
                    price=get_price(c,stock)
                    price=round(price,3)
                    if log.shape[0]>0:
                        log=log[['证券代码','名称',"类型",'交易模式',
                            '交易方向','交易值','交易价格','交易时间','交易日']]
                        log=log.sort_values(by='交易时间',ascending=True)
                        log['交易日']=log['交易日'].astype(int)
                        log=log[log['交易日']==now_date]
                    else:
                        log=pd.DataFrame()
                    #获取开始的基础价格
                    if log.shape[0]>0:
                        log_stock=log[log['证券代码']==stock]
                        if log_stock.shape[0]>0:
                            base_price=log_stock['交易价格'].tolist()[-1]
                            last_time=log_stock['交易时间'].tolist()[-1]
                            stats=True
                        else:
                            base_price=get_base_price(c,stock)
                            last_time=93000
                            stats=False
                    else:
                        base_price=get_base_price(c,stock)
                        last_time=93000
                        stats=False
                    if stats==True:
                        tick=get_stock_lx_tick(c,stock,date=str(now_date))
                        tick=tick[tick['time']>=last_time]
                    else:
                        tick=get_stock_lx_tick(c,stock,date=str(now_date))
                    if tick.shape[0]>0:
                        lastClose_list=tick['lastPrice'].tolist()
                        #最新值
                        last_price=lastClose_list[-1]
                        #目前的涨跌幅
                        last_zdf=((last_price-base_price)/base_price)*100
                        last_zdf=round(last_zdf,3)
                        #涨幅大于目前涨跌幅
                        if last_zdf>=up_ratio:
                            print('触发网格卖出{} 最新价{},基准价{},涨跌幅{}大于目标涨跌幅{}'.format(stock,last_price,base_price,last_zdf,up_ratio))
                            if trader_type=='数量':
                                amount=value
                            elif trader_type=='金额':
                                amount=value/price
                                amount=adjust_amount(stock,amount)
                            elif trader_type=='百分比':
                                total=account['总资产']
                                value=total*value
                                amount=value/price
                                amount=adjust_amount(stock,amount)
                            else:
                                amount=0
                            av_amount=av_amount_dict.get(stock,0)
                            if av_amount>=amount:
                                amount=amount
                            else:
                                amount=av_amount
                            if check_is_sell(c,c.account,c.account_type,stock=stock,amount=amount) and amount>=10:
                                maker='{},网格卖出,{},{},{},{}'.format(c.st_name,stock,'sell',amount,price)
                                passorder(c.sell_code, 1101,c.account, stock, c.sell_price_code, 0, amount, maker,1,maker,c)
                                trader_log=pd.DataFrame()
                                trader_log['证券代码']=[stock]
                                trader_log['名称']=[name]
                                trader_log['类型']=['网格卖出']
                                trader_log['交易模式']=[trader_type]
                                trader_log['交易方向']=['sell']
                                trader_log['交易值']=[value]
                                trader_log['交易价格']=[price]
                                trader_log['交易时间']=[int(date_time)]
                                trader_log['交易日']=[int(now_date)]
                                #第一次循环运行卖出不记录
                                if a.gd_sell==0:
                                    print(stock,'第一次循环运行卖出不记录********')
                                    a.gd_sell=1
                                else:
                                    log=pd.concat([log,trader_log],ignore_index=True)
                                    if log.shape[0]>0:
                                        log['证券代码']=log['证券代码'].apply(lambda x: '0'*(6-len(str(x)))+str(x))
                                    else:
                                        log=log
                                    log.to_excel(r'{}'.format(path))
                                    print(maker)
                            else:
                                print(stock,'卖出失败可能没有持股')
                        else:
                            print('没有触发网格卖出{} 最新价{},基准价{},涨跌幅{}小于目标涨跌幅{}'.format(stock,last_price,base_price,last_zdf,up_ratio))
                    else:
                        print(str(datetime.now())[:-7],stock,'网格卖出没有数据/拐点触发交易时间大于15:00')
                except Exception as e:
                    print(e,stock,'网格卖出有问题*******************')
        else:
            print('网格卖出没有自定义交易股票池*********')
    else:
        print('{}网格卖出目前不是交易时间*********'.format(datetime.now()))

最新评论

客服专线

400-080-8112

用思考的速度交易,用真诚的态度合作,我们是认真的!
  • 关注公众号
  • 添加微信客服
Copyright © 2001-2026 迅投QMT社区 版权所有 All Rights Reserved. 京ICP备2025122616号-3
关灯 快速发帖
扫一扫添加微信客服
QQ客服返回顶部
快速回复 返回顶部 返回列表