在jointquant利用macd在次新股实现自动交易
来源:互联网 发布:sql server入门到精通 编辑:程序博客网 时间:2024/06/02 08:48
1. macd金叉死叉,上次和这次的macd变号
https://www.joinquant.com/post/9289?tag=algorithm
'''策略描述: 选取行业龙头股、概念龙头股的交集,作为股池,每月更新一次止损描述: MACD金叉买入,死叉卖出版权所有: nil0 '''# 导入函数库import jqdataimport numpy as npimport pandas as pdfrom prettytable import PrettyTableimport mathimport datetimefrom jqlib.technical_analysis import * # 初始化函数,设定基准等等def initialize(context): # 设定沪深300作为基准 set_benchmark('000300.XSHG') # 开启动态复权模式(真实价格) set_option('use_real_price', True) # 输出内容到日志 log.info() log.info('>>>>>>>>>>>>>>>次新概念股策略 开始运行<<<<<<<<<<<<<<<<<') # 过滤掉order系列API产生的比error级别低的log # log.set_level('order', 'error') ### 股票相关设定 ### # 股票类每笔交易时的手续费是:买入时佣金万分之三,卖出时佣金万分之三加千分之一印花税, 每笔交易佣金最低扣5块钱 set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock') #初始化可选股票列表 g.wlist = set(['600000.XSHG','600016.XSHG','600036.XSHG','601166.XSHG','600015.XSHG','000001.XSHE','002142.XSHE','601169.XSHG','601398.XSHG']) g.buy_stocks = [] g.sell_stocks = [] #持仓记录 g.holds = pd.DataFrame([],columns=['amount','price','avgcost','pmax','plast','buydate','holddays','fbdays','wvdays','tfbdays','twvdays']) #index直接存股票代码 g.hold_rate = 0.0 #仓位百分比 g.hold_period = 60 #持仓天数 g.buy_count = 2 # 每次买入几只股票 g.gain_rate = 10.0 * 2.5 #目标获利比率 g.stop_loss_rate = -5.0 #止损比率 g.fb_rate = -6.18 # 从高点回落比率,大行情时期用-8.0比较好 g.hold_rate_min = 95.0 #最低仓位 g.total_values = 0.0 # 总值 = 现金 + 股票市值 ## 运行函数(reference_security为运行时间的参考标的;传入的标的只做种类区分,因此传入'000300.XSHG'或'510300.XSHG'是一样的) # 开盘前运行 run_daily(before_market_open, time='before_open', reference_security='000300.XSHG') # 开盘时运行 run_daily(market_open, time='open', reference_security='000300.XSHG') # 收盘后运行 run_daily(after_market_close, time='after_close', reference_security='000300.XSHG') ## 开盘前运行函数 def before_market_open(context): # 输出运行时间 #log.info('函数运行时间(before_market_open):'+str(context.current_dt.time())) date = context.current_dt.strftime('%Y-%m-%d') to_buy_stocks = set(get_concept_stocks('GN189')) g.buy_stocks = list(to_buy_stocks - set(g.holds.index.values)) #去掉已经持仓的 # 给微信发送消息(添加模拟交易,并绑定微信生效) if(len(g.buy_stocks)>0): msg = '今天可买股票:' for s in g.buy_stocks: msg = msg + show_stock(s) + " " else: msg = '今天没有可买股票,慢慢享受美好的一天吧~' send_message(msg) log.info(msg)def sell_stocks(context): for stock in g.holds.index: holddays = g.holds.loc[stock,'holddays'] # 计算回报率 roe = round(100 * (g.holds.loc[stock,'price'] /g.holds.loc[stock,'avgcost'] -1.0),2) # 计算回落率 fallback = round(100 * (g.holds.loc[stock,'price'] /g.holds.loc[stock,'pmax'] -1.0),2) # 计算梯度止损比例,如果收益小于这个止损比例,卖出 threshold = round(holddays/g.hold_period * g.gain_rate,2) fbwvdays = g.holds.loc[stock,'fbdays'] + g.holds.loc[stock,'wvdays'] # -------------------------止损判断条件-------------------- if(holddays>= g.hold_period) or (isMACDDead(context,stock)): log.info('已经持有%s %d天, ROE=%.2f%% FB=%.2f%% , 卖出...' %(show_stock(stock),holddays,roe,fallback)) order_target(stock, 0) else: log.info('%s 持股%d天, ROE=%.2f FB=%.2f , 继续持有...' %(show_stock(stock),holddays,roe,fallback)) ## 买入股票def buy_stocks(context): if(len(g.buy_stocks) < 1): #没有股票可买 return # 可用资金所占仓位比例 ar = round(100 * context.portfolio.subportfolios[0].available_cash / context.portfolio.subportfolios[0].total_value,0) if(ar > 100 - g.hold_rate_min): #不到最低仓位,买入 # 计算最多可买几只股票 #avr = round(100 / g.buy_count,0) #每只股票所占比例 #buy_count = int(math.ceil(ar / avr)) buy_count = g.buy_count - len(g.holds) if(buy_count < 1): return to_buy = g.buy_stocks if(buy_count > len(to_buy)): buy_count = len(to_buy) # 每只股票所用资金,只能基本平均 value = context.portfolio.subportfolios[0].available_cash / (g.buy_count - len(g.holds)) #for i in range(buy_count): i = 0 for stock in to_buy: #stock = to_buy[i] if(isMACDGold(context, stock)): cur_price = get_close_price(stock,1,'1m') if(cur_price != np.nan): # 通过当前价,四乘五入的计算要买的股票数。 amount = int(round(value / cur_price / 100) * 100) new_value = amount * cur_price order = order_value(stock, new_value) if(order != None): i += 1 log.info('成功买入%d股 %s !' %(order.filled,show_stock(stock))) else: log.info('买入%s失败...' %show_stock(stock)) if(i>= buy_count): break ## 开盘时运行函数def market_open(context): sell_stocks(context) update_holds(context,0) buy_stocks(context) ## 收盘后运行函数 def after_market_close(context): update_holds(context) log.info(show_holds(context)) log.info('========================>>无聊的一天结束<<============================')## 更新持仓数据def update_holds(context, days=1): cash = context.subportfolios[0].cash p_value = context.subportfolios[0].positions_value g.total_values = p_value + cash g.hold_rate = p_value * 100 / (cash + p_value) #更新当天成交的持仓数据 for stock in context.subportfolios[0].long_positions.keys(): pos = context.subportfolios[0].long_positions[stock] if(stock in g.holds.index): pmax = g.holds.loc[stock,'pmax'] plast = g.holds.loc[stock,'plast'] g.holds.loc[stock,'plast'] = g.holds.loc[stock,'price'] g.holds.loc[stock,'price'] = pos.price g.holds.loc[stock,'pmax'] = max(pmax,pos.price) if(pos.price <= pmax): if(pos.price < plast): g.holds.loc[stock,'fbdays'] = days + g.holds.loc[stock,'fbdays'] g.holds.loc[stock,'tfbdays'] = days + g.holds.loc[stock,'tfbdays'] else: g.holds.loc[stock,'wvdays'] = days + g.holds.loc[stock,'wvdays'] g.holds.loc[stock,'twvdays'] = days + g.holds.loc[stock,'twvdays'] else: g.holds.loc[stock,'fbdays'] = 0 g.holds.loc[stock,'wvdays'] = 0 g.holds.loc[stock,'holddays'] = days + g.holds.loc[stock,'holddays'] g.holds.loc[stock,'amount'] = pos.total_amount ocost = g.holds.loc[stock,'avgcost'] g.holds.loc[stock,'avgcost'] = pos.avg_cost #发生了分红配股 if(ocost > pos.avg_cost): g.holds.loc[stock,'pmax'] = round((pmax * pos.avg_cost/ocost),2) else: g.holds.loc[stock] = { 'amount':pos.total_amount, 'price':pos.price, 'avgcost':pos.avg_cost, 'pmax':pos.price, 'plast':pos.price, 'buydate':pos.init_time, 'holddays':1, 'fbdays':0, 'wvdays':0, 'tfbdays':0, 'twvdays':0 } #去掉已经卖掉的 hstocks = context.subportfolios[0].long_positions.keys() for stock in g.holds.index.values: if(stock not in hstocks): g.holds = g.holds.drop(stock) def show_holds(context): sub_str = '' table = PrettyTable([ "代码 名称", "持仓量", "成本价","上日价", "当前价","最高价","盈亏", "持仓比","仓龄"]) for stock in g.holds.index: stock_str = show_stock(stock) stock_raite = (g.holds.loc[stock,'amount'] * g.holds.loc[stock,'price']) / g.total_values * 100 table.add_row([ stock_str, g.holds.loc[stock,'amount'], g.holds.loc[stock,'avgcost'], g.holds.loc[stock,'plast'], g.holds.loc[stock,'price'], g.holds.loc[stock,'pmax'], "%.2f%%" % ((g.holds.loc[stock,'price'] - g.holds.loc[stock,'avgcost']) / g.holds.loc[stock,'avgcost'] * 100), "%.2f%%" % (stock_raite), "%d" %(g.holds.loc[stock,'holddays']) ] ) sub_str += '[仓号: %d] [总值:%d] [持股数:%d] [仓位:%.2f%%] \n' % (0, g.total_values, len(g.holds) , g.hold_rate) if len(g.holds) == 0: return '子仓详情:\n' + sub_str else: return '子仓详情:\n' + sub_str + str(table) def get_close_price(security, n, unit='1d'): ''' 获取前n个单位时间当时的收盘价 为防止取不到收盘价,试3遍 :param security: :param n: :param unit: '1d'/'1m' :return: float ''' cur_price = np.nan for i in range(3): cur_price = attribute_history(security, n, unit, 'close', True)['close'][0] if not math.isnan(cur_price): break return cur_price def show_stock(stock): ''' 获取股票代码的显示信息 :param stock: 股票代码,例如: '603822.SH' :return: str,例如:'603822 嘉澳环保' ''' return u"%s %s" % (stock[:6], get_security_info(stock).display_name)def isMACDGold(context,security): ''' 判断是否 MACD 金叉 return True or False ''' #当天和前一个交易日的日期 check_date = context.current_dt.strftime('%Y-%m-%d') previous_date = context.previous_date # 计算并输出 security 的 MACD 值 macd_dif, macd_dea, macd_macd = MACD(security,check_date=check_date, SHORT = 12, LONG = 26, MID = 9) previous_date_macd_dif, previous_date_macd_dea, previous_date_macd_macd = MACD(security,check_date=previous_date, SHORT = 12, LONG = 26, MID = 9) if previous_date_macd_macd[security] < 0 and macd_macd[security] > 0: return True else: return False def isMACDDead(context,security): ''' 判断是否 MACD 死叉 return True or False ''' #当天和前一个交易日的日期 check_date = context.current_dt.strftime('%Y-%m-%d') previous_date = context.previous_date # 计算并输出 security 的 MACD 值 macd_dif, macd_dea, macd_macd = MACD(security,check_date=check_date, SHORT = 12, LONG = 26, MID = 9) previous_date_macd_dif, previous_date_macd_dea, previous_date_macd_macd = MACD(security,check_date=previous_date, SHORT = 12, LONG = 26, MID = 9) if previous_date_macd_macd[security] > 0 and macd_macd[security] < 0: return True else: return False
阅读全文
0 0
- 在jointquant利用macd在次新股实现自动交易
- 利用MACD指标进阶使用技巧计算交易信号
- 在shell脚本中利用expect实现自动应答
- 在shell脚本中利用expect实现自动应答
- 在webstorm上利用babel实现自动编译es6文件
- python自动申购新股
- 尾盘次新股杀跌
- 利用DataView.ToTable 方法 (String) 在结果中查询,可以实现无限次循环
- 量化交易之羊驼算法在python中的实现
- MACD图在判断大的行情时太准了!
- 要在最经典的MACD指标上下功夫
- macd指标分析 交易代码 c++
- [交易策略]MACD金叉买死叉卖模型回测
- 【量亿数据-量化交易】MACD五日变值法
- 打造艺术品数字资产平台:他们利用区块链技术让养在“深闺”的艺术品实现良性的流通交易
- 打造艺术品数字资产平台:他们利用区块链技术让养在“深闺”的艺术品实现良性的流通交易
- 如何在APP内交易
- 利用Javascript 与 VBscript 在asp中实现图片自动切换
- C语言 用if goto求n!
- angularjs+ngCordova 手机录音
- 有趣的位运算
- 反向代理、Nginx
- 基于Linux命令行KVM虚拟机的安装配置与基本使用
- 在jointquant利用macd在次新股实现自动交易
- C++实现静态顺序表的增删查改
- JDT Compilation Error deploying Contract Management Ear File (文档 ID 2088882.1)
- LaTex(PART I)第一个LaTex程序
- selenium技术学习-浏览器操作
- 浅析ThreadPoolExecutor的执行过程
- 超级楼梯
- poj 1062 昂贵的聘礼
- Android 切换至surfaceView闪屏(黑屏)