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

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

二、策略的核心逻辑与关键要素
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. 基准价更新机制
卖出成功后,最新成交价成为新的基准价,下一次上涨需基于新基准价重新计算涨幅。这形成了“卖出→基准价上移→再上涨再卖出”的阶梯式止盈路径。

网格卖出策略的本质是将价格波动转化为可控的收益流。它通过动态基准价和固定涨幅阈值,构建了一个“上涨即卖出”的自动止盈系统。其核心思路可概括为:
- 分散风险:分批卖出,避免一次性决策失误。
- 顺应波动:利用市场固有的上下波动赚取差价,而非预测方向。
- 机械执行:完全自动化,排除情绪干扰,确保交易纪律。
- 循环反馈:每次交易后更新基准价,使网格自适应市场,形成正反馈循环。
该策略是量化交易中经典的网格交易法的组成部分,适合风险偏好适中、追求稳定收益的投资者,尤其适用于震荡市中的指数基金或高流动性个股。通过合理设置参数并与网格买入策略协同,可在控制风险的前提下,长期从市场波动中获利。
下面是策略框架运行的流程图方便理解

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

源代码方便大家去理解策略思路,只参考学习,不做交易参考
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()))