分享

量化交易Python数据分析

 禁忌石 2022-03-01
# N日择时策略+ATRdef Nbreakstrategy(self,data, N1, N2, n_win, n_loss): # N1天内最高价 global start data['N1_high'] = data.High.rolling(window=N1).max() data['N1_high'] = data.N1_high.shift(1) max_val = data.Close.expanding().max() data['N1_high'].fillna(value=max_val, inplace=True) # N2天内最低价 data['N2_low'] = data.Low.rolling(window=N2).min() data['N2_low'] = data.N2_low.shift(1) min_val = data.Close.expanding().min() data['N2_low'].fillna(value=min_val, inplace=True) # ATR止盈止损判断 buy_price = 0 for k_index, today in data.iterrows(): tick = round(today.Close * 0.01, 2) # 买入 if (today.Close - tick) > today.N1_high: print('N day buy: {} {}'.format(k_index,today.Close)) buy_price = today.Close data.loc[k_index, 'signal'] = 1 # 止损,收盘价少于买入价,卖出 elif (buy_price != 0) and (buy_price > today.Close + tick) and ((buy_price - today.Close - tick) > n_loss * today.atr14): #print('stop loss: {} {} {}'.format(k_index, today.Close, buy_price)) data.loc[k_index, 'signal'] = 0 buy_price = 0 # 止盈:收盘价多于买入价,卖出 elif (buy_price != 0) and (buy_price < today.Close - tick) and ((today.Close - buy_price + tick) > n_win * today.atr14): #print('stop win: {} {} {}'.format(k_index, today.Close, buy_price)) data.loc[k_index, 'signal'] = 0 buy_price = 0 elif today.Close + tick < today.N2_low: #print('N day sell: {} {}'.format(k_index, today.Close)) data.loc[k_index, 'signal'] = 0 buy_price = 0 else: pass # 买入 / 卖出信号list data['signal'].fillna(method='ffill', inplace = True) data['signal'] = data.signal.shift(1) data['signal'].fillna(method='bfill', inplace=True) for k_index, today in data.iterrows(): # 买入/卖出 执行 if today.signal == 1 and self.hold_state == 0: # 买入 start = data.index.get_loc(k_index) # 区间开始日期 self.hold_state = -1 self.stock_num = int(self.init_money / today.Close) # 资金转化为股票 # 仓位管理 self.send_order(code=self.stock_code, amount=int(self.init_money * 0.01 / today.atr14), price=today.Close, order_type='buy') self.init_money = 0 self.graph_trade.annotate('买入',xy=(k_index,data.Close.asof(k_index)), xytext=(k_index,data.Close.asof(k_index)+2), arrowprops=dict(facecolor='r',shrink=0.1), horizontalalignment='left',verticalalignment='top') elif today.signal == 0 and self.hold_state == -1: # 卖出 end = data.index.get_loc(k_index) # 手续费:印花税1‰,手续费5元 profit = self.stock_num * today.Close fee = profit * 0.0001 - 5 self.init_money = round((profit - fee),1) # 股票转化为资金 self.hold_state = 0 self.market_value = 0 # 仓位管理 self.send_order(code=self.stock_code, amount=self.hold_available(code = '600410.SS'), price=today.Close, order_type='sell') if data.Close[end] < data.Close[start]: # 赔钱,绿色 self.graph_trade.fill_between(data.index[start:end],0, data.Close[start:end],color='green',alpha=0.8) else: # 赚钱 红色 self.graph_trade.fill_between(data.index[start:end], 0, data.Close[start:end], color='red', alpha=0.8) self.graph_trade.annotate('卖出',xy=(k_index,data.Close.asof(k_index)), xytext=(k_index+datetime.timedelta(days=5), data.Close.asof(k_index)+2), arrowprops=dict(facecolor='g',shrink=0.1), horizontalalignment='left',verticalalignment='top') latest_val = self.latest_assets(today.Close) data.loc[k_index, 'total_position'] = latest_val if self.hold_state == -1: # 持股状态 self.market_value = int(self.stock_num * today.Close) data.loc[k_index, 'total'] = self.market_value else: # 空仓 data.loc[k_index, 'total'] = self.init_money print('total value is {}'.format(data['total'][-1])) self.resultanalysis(data) return data['total'][-1] # 每次返回复制代码

2. 蒙特卡洛优化算法优化策略输入参数

# 使用蒙特卡洛方法挑选出最优的N1,N2,止盈,止损点# 25,5,2.3,0.7def montcarlo(self,data, n):    n1_min, n1_max = 10, 30    n2_min, n2_max = 5, 15    win_min, win_max = 1.5, 3    loss_min, loss_max = 0.5, 1.2    ma_ls = []    profit_ls = []    # 每次随机生成一组N1,N2,止盈,止损倍数,循环N日择时策略并把每次执行策略的最终资产存入数组    # 最终得到n次执行后,得到最大资产的一组随机数,作为最优策略的输入参数    for i in range(0, n+1):        n1 = int(random.uniform(n1_min,n1_max))        n2 = int(random.uniform(n2_min, n2_max))        win = round(random.uniform(win_min, win_max),1)        loss = round(random.uniform(loss_min, loss_max),1)        ma_ls.append([n1,n2,win,loss])        # 策略代码        trade = QuantAnalysis()        profit_ls.append(trade.Nbreakstrategy(data, n1, n2, win, loss))    profit_max = max(profit_ls)    ma_max = ma_ls[profit_ls.index(profit_max)]    print('maximize the profit is %s and correspond parametes are %s ' % (profit_max, ma_max))    return ma_ls复制代码

3. 基于ATR的仓位管理

# 仓位管理self.send_order(code=self.stock_code, amount=int(self.init_money * 0.01 / today.atr14),price=today.Close, order_type='buy')self.send_order(code=self.stock_code, amount=self.hold_available(code = '600410.SS'), price=today.Close, order_type='sell') 复制代码

4. 滑点收盘价的1%

在每一次买入卖出,止盈止损的过程中加入滑点值,让结果没那么'完美’,更符合实际的情况。复制代码

5. 印花税 1‰,手续费5元

在卖出时将印花税,手续费加入profit = self.stock_num * today.Closefee = profit * 0.0001 - 5复制代码

6. 结果生成图像:

a. 买卖区间图    b. 基准收益/策略收益对比图    c. 总资产图(无策略的总资产+N日择时策略下的总资产+仓位管理的总资产+最大总资产)        无仓位管理,无手续费,经过蒙特卡洛筛选出最优N日择时策略后的执行结果图复制代码
文章图片1
增加仓位管理,增加手续费后的结果图,可以对比看出仓位管理的优势,总资产比不实施仓位管理要高了很多复制代码
文章图片2
从图中可以看出当买入点较高时,股票开始下跌,策略能够及时止损,本次策略使用的止损点为0.7,卖出时能够较好的获利,止盈点为2.3。        采用量化分析的方式,可以对一只股票的交易历史有一个很好的分析,通过模拟策略来进行买卖,检验自己策略的好坏,但是有个疑问,怎么样能够通过策略来决定当下要是否要买这支股票呢?复制代码

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多