阿仕18 发布于2020-04-03
回复 19
浏览 2675
41
在没有学习接触量化的概念前,喜欢用通达信的选股公式去选股,毕竟3000多支股票不可能每个都去一个一个看。自己也用通达信写了一些公式来选股,所谓的技术分析:“出水芙蓉”,“蜻蜓点水”,“创X日新高”,“强势股回调” ,"支撑线,阻力线“等等各种各样的形态,刚开始会因为其中的一次两次的好运赚到钱了,以为从此打开了财富的大门,可是随着时间的流逝,几轮牛熊后,账户里的钱不但没有增加,反而越来越少了。
实际上通达信上或者自己认为的赚钱的K线形态,在统计概率上看并不高,再加上手续费,税费,随着交易的次数越来越多,大概率就是亏钱的,除非刚刚好遇到牛市。我想很多刚进入股市的同学,在入坑K线形态分析后都会遇到这些困惑。
我抽取了一个K线形:(涨停后股价回调到起涨点买入)来进行策略分析,看这个K线形态是否能在A股市场里赚钱。
强势股回调K线形态策略:
买入条件1:股价在前7日内有涨停;
买入条件2:股价回调到之前涨停那天前的收盘价附近+-3%;
买入条件3:成交量回落到涨停前5天的平均成交量附近+-3%;
全部满足以上3个条件后,第二天开盘时股价无异动(涨幅在+-3个点内)则买入。
卖出情形1:止损----亏损超7%;
卖出情形2:走势破坏----买入4天后,收益在小于3%;
卖出情形3:走势破坏止盈-----受益大于3%,股价下穿5日均线。
**第一步:先把退市股,ST股,停牌股去掉。**
def paused_filter(security_list):
current_data = get_current_data() #通过get_current_data()获取当前单位时间(当天/当前分钟)的涨跌停价, 是否停牌,当天的开盘价等
security_list = [stock for stock in security_list if not current_data[stock].paused]#将没有停牌的股票代码储存在一个列表中
return security_list #返回储存代码的列表
过滤退市股票
def delisted_filter(security_list):
current_data = get_current_data()
security_list = [stock for stock in security_list if not '退' in current_data[stock].name]#如果股票名称中没有“退”则储存在列表中
return security_list #返回储存代码的列表
过滤ST股票
def st_filter(security_list):
current_data = get_current_data()
security_list = [stock for stock in security_list if not current_data[stock].is_st]#通过`is_st`判断是否为ST股或*ST
return security_list #返回储存代码的列表
****第二步:编辑选股函数:select_stocks****
筛选出符合策略条件的股票 # 返回:{stock:high_limit}
def select_stocks(security_list,period):
period_add=period+5 #计算涨停前5天人成交量均值
volume_mean5=0
stockspool=[]
stocksztdate=[] #涨停日期
zt_count=0
zt_date=0
for stock in security_list:
zt_bool=0 #涨停的标签
zt_price=0 #涨停价格记录
df_highandh_limit=attribute_history(stock,period_add,'1d',['high','low','high_limit','close','pre_close','volume'])
j=0
zt_date=0
for i in range(len(df_highandh_limit)-5):
j=i+5
volume_mean5=df_highandh_limit['volume'][i:i+4].sum()/5 #计算涨停前5天人成交量均值
increase_volume=df_highandh_limit['volume'][j]/(volume_mean5+1) #成交量放量 volume_mean5+1为去除日志的除数为0人警告
growrate=df_highandh_limit['close'][j]/df_highandh_limit['pre_close'][j] #涨幅
if df_highandh_limit['high'][j]==df_highandh_limit['high_limit'][j] and growrate>1.08 and increase_volume>3: #涨停且涨幅大于%8且成交放量2倍
zt_bool=1 #符合条件的涨停的标签=1
zt_date=j #记录涨停是哪一天
zt_price=df_highandh_limit['high_limit'][j] #涨停价格记录
break
#比较涨停前一天的价格偏离值
devition_price=abs(df_highandh_limit['close'][-1]-df_highandh_limit['pre_close'][zt_date])/df_highandh_limit['pre_close'][zt_date]
#振幅
zf=(df_highandh_limit['high'][-1]-df_highandh_limit['low'][-1])/df_highandh_limit['pre_close'][-1]-1
#涨跌幅
zdf=df_highandh_limit['close'][-1]/df_highandh_limit['pre_close'][-1]-1
#涨停后3天收盘价最大值
zdg=df_highandh_limit['close'][zt_date+1:zt_date+3].max()
#判断符合条件1且#比涨停前一天的价格偏离值小于0.03回到起涨点 振幅小于0.05 涨跌幅大于-0.03 涨停后3天价格有超过涨停价格
if zt_bool==1 and devition_price< 0.03 and zf< 0.05 and zdf>-0.03 and zdg>zt_price :
zt_count=zt_count+1
stockspool.append(stock)
rq=df_highandh_limit.index.to_frame(index=False) #选出日期
stocksztdate.append(rq.iloc[zt_date,0])
print('选出的自选股数为:'+str(zt_count))
print(stockspool)
dc={'涨停股票':stockspool,'涨停日期':stocksztdate}
return stockspool #返回储存代码的列表
**第三步:对符合策略的股票评分,排序(符合策略的股票过多,用另一些条件因子股票缩小范围)**
自选股评分
def stockspool_mark(security_list):
raise_clist=[]
raise_hlist=[]
raise_llist=[]
score=0
score_list=[]
for stock in security_list:
df=attribute_history(stock,30,'1d',['close','high','low'])
raise_C=(df['close'][-1]/df['close'][0]-1)*100 #股价当前涨跌幅
if raise_C< 0:
score_1=0
elif raise_C>=0 and raise_C< 10:
score_1=1*0.5
elif raise_C>=10 and raise_C< 30:
score_1=5*0.5
elif raise_C>=30 and raise_C< 40:
score_1=3*0.5
else:
score_1=0
raise_clist.append(raise_C)
raise_h=(df['high'].max()/df['close'][0]-1)*100 #股价最低价涨跌幅
if raise_h< 20:
score_2=0
elif raise_h>=20 and raise_h< 30:
score_2=2*0.25
elif raise_h>=30 and raise_h< 40:
score_2=4*0.25
elif raise_h>=40 and raise_h< 50:
score_2=2*0.25
else:
score_2=0
raise_hlist.append(raise_h)
raise_l=(df['low'].min()/df['close'][0]-1)*100 #股价最高价涨跌幅
if raise_l< -30:
score_3=0
elif raise_l>=-30 and raise_l< -20:
score_3=1*0.25
elif raise_l>=-20 and raise_l< -10:
score_3=2*0.25
else:
score_3=3*0.25
raise_llist.append(raise_l)
score=score_1+score_2+score_3
score_list.append(score)
dc={'涨停股票':security_list,'当前涨幅':raise_clist,'最高涨幅':raise_hlist,'最低涨幅':raise_llist,'股票得分':score_list}
df_a=DataFrame(dc)
print(df_a)
df_b=df_a[df_a['股票得分']>=1.5].sort_values(by='股票得分',ascending=False)
print("评分大于1.5分的股票:")
print(df_b)
g.buystocks=df_b['涨停股票'].tolist()
**第四步:筛选出股票后,第二天买入股票**
买入函数
def buy_stocks(context):
#可买的自选股数大于等于1只 #持股数未到最大值少于4
if len(g.buystocks)>0 and g.unit< 4:
#可买股票个数,总持仓量少于4,自选股票池可买标的少于可持仓数
buy_today_num=min(len(g.buystocks),(g.max_unit-g.unit))
if buy_today_num>0:
for i in range(buy_today_num):
security = g.buystocks[i]
# 获取标的的最新价
current_price = attribute_history(security, 1, '1m', ['close'], df=False)['close'][0]
pre_c = attribute_history(security, 1, '1d', ['pre_close'], df=False)['pre_close'][0]
#计算开盘涨跌幅
current_raise=current_price/pre_c-1
#判断是否已经买过此股
if(security not in context.portfolio.positions):
#开盘涨跌幅在-0.03到0.03之间
if (-0.03< current_raise and current_raise< 0.03) :
cash = context.portfolio.available_cash/(g.max_unit-g.unit)
order_value(security,cash)
#写入交易信息
g.trade_date.append(context.current_dt)
g.trade_buy.append(security)
g.trade_sell.append('na')
g.trade_price.append(current_price)
g.trade_profit.append('na')
log.info('开仓买入:'+security+' 买入价格:'+str(current_price))
**第五步:监测股票是否达到卖出的条件,如果是卖出**
卖出函数 包含止损 止盈
def sell_stocks(context):
for stock in context.portfolio.positions:
#持有股票的天数
hold_day=len(get_price(stock, start_date=context.portfolio.positions[stock].init_time, end_date=context.current_dt))
profit=context.portfolio.positions[stock].price/context.portfolio.positions[stock].avg_cost-1
sell_price=context.portfolio.positions[stock].price
if hold_day< 4:
if(profit< -g.cut_loss_pct):
order_target(stock,0)
if context.portfolio.positions[stock].total_amount == 0:
g.trade_date.append(context.current_dt)
g.trade_buy.append('na')
g.trade_sell.append(stock)
g.trade_price.append(sell_price)
g.trade_profit.append(profit)
log.info('股票 %s 已经亏损至百分之7止损' % stock)
elif hold_day==4:
if(profit< 0.03):
order_target(stock,0)
if context.portfolio.positions[stock].total_amount == 0:
g.trade_date.append(context.current_dt)
g.trade_buy.append('na')
g.trade_sell.append(stock)
g.trade_price.append(sell_price)
g.trade_profit.append(profit)
log.info('股票 %s 已经4个交易日涨幅小于百分之3,卖出' % stock)
else:
close_data = attribute_history(stock,5,'1d',['close'])
ma5=close_data['close'][-5:].mean() #5日均线
if context.portfolio.positions[stock].price< ma5:
order_target(stock,0)
if context.portfolio.positions[stock].total_amount == 0:
g.trade_date.append(context.current_dt)
g.trade_buy.append('na')
g.trade_sell.append(stock)
g.trade_price.append(sell_price)
g.trade_profit.append(profit)
log.info('股票 %s 股价低于5日均价,卖出' % stock)
以上就是一个含选股的简单策略,代码的运行效率不高,但是简单易懂,仅供对刚开始接触量化的初学者参考。千万别想着一个简单的策略就能躺着赚钱,那是不可能的,跑了一段时间的回测后才发现:找到能稳定赚钱的策略难如登天。量化路上道阻且长,以此共勉。
评论
失败案例很多,成功案例没见过。
登天很难,还是登天根本不可能?
2020-04-04
大家都能想到的量价关系赚钱效应一般
2020-04-04
成功策略聚宽很多的,你希望能年化多少?20%很多免费的,更高的也有,免费的可能就没有了。
2020-04-04
@freemars 收益越高,回撤越大。收益与风险成正比,我自己写个几十行代码的策略,7年十几倍收益,但我自己都不会用的
2020-04-14
@freemars 就喜欢听到这种年收益20% 很多免费的。
2020-10-10
@freemars 求从2011年开始每年跑赢hs300年化20%以上的免费策略
2020-10-11
@yangss7770
这个算不算有未来函数呢?基金池是预先设置的。我自己实盘跑了一年,带银华锐进的能做到年化20%以上。
https://www.joinquant.com/view/community/detail/177edab03367da01e96210469dd5290d
我发的策略基本上都可以做到。你可以试试。
2020-10-11
@yangss7770 好人做到底,再给你一个。 https://www.joinquant.com/view/community/detail/1edca153a30a134063675c5318b183d3。 大神的帖子你试试,基本上都可以。
2020-10-11
指标有滞后性,所以看技术指标有些不准。
2020-11-13
@freemars 看了看大神在策略商城的实盘,短期基本跑不过指数,拟合太多了吧
2020-11-21
框架搭的非常好,可结合具体个股涨跌实例修改,通过实例,慢慢找出规律。
2024-11-11