迅投QMT社区 门户 查看主题

算法研究--日内拐点卖出算法原理研究

发布者: 落花忆流年 | 发布时间: 2026-5-19 17:35| 查看数: 45| 评论数: 1|帖子模式

前天介绍了完整的拐点交易算法的分析,今天详细的介绍一下里面的子模块,挂点卖出,先看简单的原理图,这个是固定的,更改起点会变成连续动态的分析算法研究--日内拐点交易算法原理研究

通过基准价与涨幅比例计算涨幅阈值价p1,当最新价突破p1后,以突破后的最高价p2与回调比例计算回调阈值价p3,当最新价突破p3后,如果P3>P1则以(价格策略—价格偏移*最小价差)挂单卖出

2b6405350714a454dd37e3d7e2e70282.png

最高价说明:当涨幅比例阈值p1满足后,开始记录最高价p2,此时的最高价p2会根据行情的更新而随时变化,p2取到的是从p1满足起开始到当前时间内的最高价

一、原理:捕捉“冲高回落”的动能衰竭点

该算法的核心原理是:识别一个上涨趋势在经历“加速赶顶”后的“动能衰竭”信号,并以此作为卖点。它认为,一个健康的上涨趋势转为危险的下跌趋势,通常会经历两个阶段:

加速上涨阶段:价格快速拉升,突破某个关键位置(P1),这证明多头力量达到顶峰。

高位回落阶段:价格在创出新高后,无法维持,开始显著回落。这个“回落”动作本身就是多头力量衰竭、空头开始反扑的直接证据。策略捕捉的正是这个“从最高点回落”的拐点。

二、核心交易思路:一个带有“门控”的两阶段确认模型

这个算法的思路非常严谨,可以概括为一个 “门控式”的两阶段确认模型。

第一阶段:上涨趋势的“入场券”——突破P1,作用:P1是基准价上方的一个“门槛”。价格必须向上突破这个门槛,才被纳入监控范围。思路:这起到了一个趋势强度过滤器的作用。如果价格连P1都无法突破,说明上涨动能不足,不值得启动“高位回落”监控。这避免了在横盘震荡行情中频繁产生无效信号。

第二阶段:动能衰竭的“确认键”——跌破P3

作用:一旦价格突破P1,策略便开始寻找这个上涨波段中的最高点(P2),并计算出从P2回落的“警戒线”P3。当价格从高点回落到P3以下时,触发卖出。思路:这个阶段是本策略的精髓。它不预测顶部,而是等待顶部出现(P2)并从顶部显著回落(跌破P3)后才行动,是一种典型的“右侧交易”思维。它牺牲了顶部的一小部分利润,来换取趋势可能反转的更高确定性。

最关键的约束条件:P3 > P1

代码体现:if p_3>p_1:思路:这是整个策略逻辑中最精妙、最关键的一环。它要求“回调警戒线P3”必须高于“上涨启动线P1”。这保证了触发卖出时,股价仍然高于最初确认上涨趋势的位置。

深层含义:如果 P3 <= P1,意味着股价从高点P2回落的幅度过大,不仅吃掉了所有涨幅,还跌回了“上涨趋势确认线”下方。这种情况虽然也是亏损,但它可能属于“假突破”或趋势的彻底反转,与策略定义的“冲高回落的动能衰竭”模式不符。策略主动放弃处理这种情况,以保持其信号的纯粹性。

三、设计理念:有取舍的模式

这个算法的设计体现了清晰的取舍:它要赚什么钱? 它旨在捕捉一个已确认的上升趋势中,最后一段加速上涨后,趋势发生温和反转的那一段利润。它要放弃什么行情?放弃窄幅震荡:价格无法突破P1,永不触发。

放弃深度V型反转:股价突破P1后快速拉升,然后掉头向下,直接跌破P1(此时 P3 <= P1)。这种行情它不参与,也因此避开了追高买入后立刻被套在山顶的风险。放弃预测最高点:它在最高点(P2)出现并回落之后才行动,属于确认易,而非预测易。

策略内部计算的核心变量

637a5945a6c1cad07d46316facfa021d.png

2d0ad1a35580eac68c72e5661386d870.png

f175721ee7c4d2435758c1cf199a24b9.png

不懂的问我就可以,加我备注入群可以加入量化群

76f56801095acc837a56f5d6282672df.jpg

量化开户需要找我就可以,专业量化技术支持服务

6f43de12faf05315e60ae8c1947f477a.png

代码的研究学习参考不做交易参考

def run_sell_trade(c):
    '''
    卖出拐点运行函数
    "上涨比例":,
    "回调比例":,
    '''
    path=c.text['记录文件路径']
    up_ratio=c.text['上涨比例']
    down_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:
                    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]
                        #最大值
                        max_value=max(lastClose_list)
                        #p1值
                        p_1=base_price*(1+up_ratio/100)
                        p_1=round(p_1,3)
                        #目前涨跌幅
                        last_zdf=((last_price-base_price)/base_price)*100
                        last_zdf=round(last_zdf,2)
                        #最高点涨跌幅
                        last_max_zdf=((max_value-base_price)/base_price)*100
                        last_max_zdf=round(last_max_zdf,2)
                        #p2最大价
                        p_2=max_value
                        p_2=round(p_2,3)
                        #回调比例计算p3
                        p_3=p_2*(1-down_ratio/100)
                        p_3=round(p_3,3)
                        #目前回调比例
                        last_ht_ratio=((last_price-p_2)/p_2)*100
                        last_ht_ratio=round(last_ht_ratio,2)
                        #最新价大于P1,开始监控
                        if last_price>=p_1:
                            #回调没有跌破p1
                            if p_3>p_1:
                                #最新价跌破回调值
                                if last_price<=p_3:
                                    print('触发拐点卖出,时间:{},股票:{},名称:{},基准价:{},p1值:{},p2值:{},p3:值{},最新价:{},目前涨跌幅:{},最高涨跌幅:{},目前回调比例:{} '.format(str(datetime.now())[:-7:],
                                        stock,name,base_price,p_1,p_2,p_3,last_price,
                                        last_zdf,last_max_zdf,last_ht_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):
                                        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.sell_**==0:
                                            print(stock,'第一次循环运行卖出不记录********')
                                            a.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('没有触发拐点卖出,会调没有跌破P3,时间:{},股票:{},名称:{},基准价:{},p1值:{},p2值:{},p3:值{},最新价:{},目前涨跌幅:{},最高涨跌幅:{},目前回调比例:{} '.format(str(datetime.now())[:-7:],
                                        stock,name,base_price,p_1,p_2,p_3,last_price,
                                        last_zdf,last_max_zdf,last_ht_ratio))
                            else:
                                print('没有触发拐点卖出,P3小于P1,时间:{},股票:{},名称:{},基准价:{},p1值:{},p2值:{},p3:值{},最新价:{},目前涨跌幅:{},最高涨跌幅:{},目前回调比例:{} '.format(str(datetime.now())[:-7:],
                                    stock,name,base_price,p_1,p_2,p_3,last_price,
                                    last_zdf,last_max_zdf,last_ht_ratio))
                        else:
                            print('没有触发拐点卖出,最新加没有突破P1,时间:{},股票:{},名称:{},基准价:{},p1值:{},p2值:{},p3:值{},最新价:{},目前涨跌幅:{},最高涨跌幅:{},目前回调比例:{} '.format(str(datetime.now())[:-7:],
                                stock,name,base_price,p_1,p_2,p_3,last_price,
                                last_zdf,last_max_zdf,last_ht_ratio))
                    else:
                        print(str(datetime.now())[:-7],stock,'拐点卖出,拐点触发后的时间没有数据,拐点触发交易时间大于15:00')
                except Exception as e:
                    print(e,stock,'拐点卖出有问题*********')
        else:
            print('拐点买入没有自定义交易股票池*********')
    else:
        print('{}拐点卖出目前不是交易时间*********'.format(datetime.now()))

原理图

5c6eaab93f855d4dbe9cf78cd65bfef0.png

流程图

image.png

最新评论

落花忆流年发表于  昨天 17:45
不懂的问我就可以作者微信xg_quant
客服专线

400-080-8112

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