• 策略验证_指标买点分析技法_运用boll布林线指标选择买点


    写在前面:
    1. 本文中提到的“股票策略校验工具”的具体使用操作请查看该博文
    2. 文中知识内容来自书籍《同花顺炒股软件从入门到精通》
    3. 本系列文章是用来学习技法,文中所得内容都仅仅只是作为演示功能使用

    目录

    解说

    策略代码

    结果


    解说

            布林线(BOLL)是金融市场常用的技术指标之一,属于价格路径指标。它利用统计原理,求出股价的标准差及其信赖区间,从而确定股价的波动范围及未来走势,利用波带显示股价的风险、安全的高低价位,因此也称之为布林带。

            运用布林线指标选择买点的依据如下:

            1)当股价穿越最外面的支撑线时,表示买点出现。

            2)当股价沿着压力线(支撑线)上升,虽然股价并未穿越,但若回头突破支撑线(压力线)即是买点。

            3)股价由下向上穿越下轨线(LOWER)时,可视为买进信号。

            4)股价突破上轨,回探时仍在上轨线附近,表示后市上涨的机会增大,是加仓买进的信号。

            5)波带如果开始收紧,表示股价将会发生变化,此时可结合多个技术参数进行分析,做出正确的判断。

    策略代码

    书籍中提交的买入点与网上查询到的有些出入,本文只考虑以下三种情况:

     

    1. def excute_strategy(base_data,data_dir):
    2. '''
    3. 指标买点分析技法 - 运用boll布林线指标选择买点
    4. 解析:
    5. 选择买点依据:
    6. 1. 当股价穿越最外面的支撑线时,表示买点出现
    7. 2. 当股价沿着压力线(支撑线)上升,虽然股价并未穿越,但若回头突破支撑线(压力线)即是买点。
    8. 3. 股价由下向上穿越下轨线(LOWER)时,可视为买进信号
    9. 4. 股价突破上轨,回探时仍在上轨线附近,表示后市上涨的机会增大,是加仓买进的信号。
    10. 5. 波带如果开始收紧,表示股价将会发生变化,此时可结合多个技术参数进行分析,做出正确的判断
    11. PS: UPER 压力线;LOWER支撑线
    12. 自定义:
    13. 1. 靠近、附近 =》 数值差额小于0.5%
    14. 2. 买入时点 =》 走势确定后下一交易日
    15. 3. 胜 =》 买入后第三个交易日收盘价上升,为胜
    16. 只计算最近两年的数据
    17. :param base_data:股票代码与股票简称 键值对
    18. :param data_dir:股票日数据文件所在目录
    19. :return:
    20. '''
    21. import pandas as pd
    22. import numpy as np
    23. import talib,os
    24. from datetime import datetime
    25. from dateutil.relativedelta import relativedelta
    26. from tools import stock_factor_caculate
    27. def res_pre_two_year_first_day():
    28. pre_year_day = (datetime.now() - relativedelta(years=2)).strftime('%Y-%m-%d')
    29. return pre_year_day
    30. caculate_start_date_str = res_pre_two_year_first_day()
    31. dailydata_file_list = os.listdir(data_dir)
    32. total_count = 0
    33. total_win = 0
    34. check_count = 0
    35. list_list = []
    36. detail_map = {}
    37. factor_list = ['BOLL']
    38. ma_list = []
    39. for item in dailydata_file_list:
    40. item_arr = item.split('.')
    41. ticker = item_arr[0]
    42. secName = base_data[ticker]
    43. file_path = data_dir + item
    44. df = pd.read_csv(file_path,encoding='utf-8')
    45. # 删除停牌的数据
    46. df = df.loc[df['openPrice'] > 0].copy()
    47. df['o_date'] = df['tradeDate']
    48. df['o_date'] = pd.to_datetime(df['o_date'])
    49. df = df.loc[df['o_date'] >= caculate_start_date_str].copy()
    50. # 保存未复权收盘价数据
    51. df['close'] = df['closePrice']
    52. # 计算前复权数据
    53. df['openPrice'] = df['openPrice'] * df['accumAdjFactor']
    54. df['closePrice'] = df['closePrice'] * df['accumAdjFactor']
    55. df['highestPrice'] = df['highestPrice'] * df['accumAdjFactor']
    56. df['lowestPrice'] = df['lowestPrice'] * df['accumAdjFactor']
    57. if len(df)<=0:
    58. continue
    59. # 开始计算
    60. for item in factor_list:
    61. df = stock_factor_caculate.caculate_factor(df,item)
    62. for item in ma_list:
    63. df = stock_factor_caculate.caculate_factor(df,item)
    64. df.reset_index(inplace=True)
    65. df['i_row'] = [i for i in range(len(df))]
    66. df['three_chg'] = round(((df['close'].shift(-3) - df['close']) / df['close']) * 100, 4)
    67. df['three_after_close'] = df['close'].shift(-3)
    68. # upper mid lower
    69. # 股价上穿上轨的点
    70. df['up_close_up'] = 0
    71. df.loc[(df['closePrice'].shift(1)'upper'].shift(1)) & (df['closePrice']>=df['upper']),'up_close_up'] = 1
    72. df['up_close_down'] = 0
    73. df.loc[(df['closePrice'].shift(1)>df['upper'].shift(1)) & (df['closePrice']<=df['upper']),'up_close_down'] = 1
    74. up_point_rows_list = df.loc[(df['up_close_up']==1) | (df['up_close_down']==1)]['i_row'].values.tolist()
    75. df['distance_upper'] = df['closePrice']-df['upper']
    76. df['near_upper'] = 0
    77. df.loc[(df['distance_upper']>0) & (df['distance_upper']/df['upper']<=0.005),'near_upper'] = 1
    78. df['ext_0'] = df['near_upper'] - df['near_upper'].shift(1)
    79. df['ext_1'] = df['near_upper'] - df['near_upper'].shift(-1)
    80. start_i_row_list = df.loc[df['ext_0']==1]['i_row'].values.tolist()
    81. end_i_row_list = df.loc[df['ext_1']==1]['i_row'].values.tolist()
    82. nearest_upper_list = []
    83. if start_i_row_list and end_i_row_list:
    84. if start_i_row_list[0]>end_i_row_list[0]:
    85. end_i_row_list = end_i_row_list[1:]
    86. if start_i_row_list[-1]>end_i_row_list[-1]:
    87. start_i_row_list = start_i_row_list[:-1]
    88. near_upper_list = []
    89. for i,item in enumerate(start_i_row_list):
    90. start_node = item
    91. end_node = end_i_row_list[i]
    92. enter_yeah = True
    93. for i00 in up_point_rows_list:
    94. if i00>=start_node and i00 <=end_node:
    95. enter_yeah = False
    96. break
    97. if enter_yeah:
    98. near_upper_list.append([start_node,end_node])
    99. pass
    100. for item in near_upper_list:
    101. min_val = None
    102. min_i = None
    103. for i in range(item[0],item[1]+1):
    104. if min_val is None or min_val > df.iloc[i]['distance_upper']:
    105. min_val = df.iloc[i]['distance_upper']
    106. min_i = i
    107. pass
    108. if min_i:
    109. nearest_upper_list.append(min_i)
    110. # 股价上穿下轨的点
    111. df['lower_close_up'] = 0
    112. df.loc[(df['closePrice'].shift(1)'lower'].shift(1)) & (df['closePrice']>=df['lower']),'lower_close_up'] = 1
    113. df['lower_close_down'] = 0
    114. df.loc[(df['closePrice'].shift(1)>df['lower'].shift(1)) & (df['closePrice']<=df['lower']),'lower_close_down'] = 1
    115. target_one_list = df.loc[df['lower_close_up']==1]['i_row'].values.tolist()
    116. lower_point_rows_list = df.loc[(df['lower_close_up']==1) | (df['lower_close_down']==1)]['i_row'].values.tolist()
    117. df['distance_lower'] = df['closePrice']-df['lower']
    118. df['near_lower'] = 0
    119. df.loc[(df['distance_lower']>0) & (df['distance_lower']/df['lower']<=0.005),'near_lower'] = 1
    120. df['ext_2'] = df['near_lower'] - df['near_lower'].shift(1)
    121. df['ext_3'] = df['near_lower'] - df['near_lower'].shift(-1)
    122. start_i_row_list0 = df.loc[df['ext_2'] == 1]['i_row'].values.tolist()
    123. end_i_row_list0 = df.loc[df['ext_3'] == 1]['i_row'].values.tolist()
    124. nearest_lower_list = []
    125. if start_i_row_list0 and end_i_row_list0:
    126. if start_i_row_list0[0] > end_i_row_list0[0]:
    127. end_i_row_list0 = end_i_row_list0[1:]
    128. if start_i_row_list0[-1] > end_i_row_list0[-1]:
    129. start_i_row_list0 = start_i_row_list0[:-1]
    130. near_lower_list = []
    131. for i, item in enumerate(start_i_row_list0):
    132. start_node = item
    133. end_node = end_i_row_list0[i]
    134. enter_yeah = True
    135. for i00 in lower_point_rows_list:
    136. if i00 >= start_node and i00 <= end_node:
    137. enter_yeah = False
    138. break
    139. if enter_yeah:
    140. near_lower_list.append([start_node, end_node])
    141. pass
    142. for item in near_lower_list:
    143. min_val = None
    144. min_i = None
    145. for i in range(item[0], item[1] + 1):
    146. if min_val is None or min_val > df.iloc[i]['distance_lower']:
    147. min_val = df.iloc[i]['distance_lower']
    148. min_i = i
    149. pass
    150. if min_i:
    151. nearest_lower_list.append(min_i)
    152. i_row_list = nearest_upper_list + target_one_list + nearest_lower_list
    153. # 临时 start
    154. # df.to_csv('D:/temp006/'+ticker + '.csv',encoding='utf-8')
    155. # 临时 end
    156. node_count = 0
    157. node_win = 0
    158. duration_list = []
    159. table_list = []
    160. for i,row0 in enumerate(i_row_list):
    161. row = row0 + 1
    162. if row >= len(df):
    163. continue
    164. date_str = df.iloc[row]['tradeDate']
    165. cur_close = df.iloc[row]['close']
    166. three_after_close = df.iloc[row]['three_after_close']
    167. three_chg = df.iloc[row]['three_chg']
    168. table_list.append([
    169. i,date_str,cur_close,three_after_close,three_chg
    170. ])
    171. duration_list.append([row-2,row+3])
    172. node_count += 1
    173. if three_chg<0:
    174. node_win +=1
    175. pass
    176. list_list.append({
    177. 'ticker':ticker,
    178. 'secName':secName,
    179. 'count':node_count,
    180. 'win':0 if node_count<=0 else round((node_win/node_count)*100,2)
    181. })
    182. detail_map[ticker] = {
    183. 'table_list': table_list,
    184. 'duration_list': duration_list
    185. }
    186. total_count += node_count
    187. total_win += node_win
    188. check_count += 1
    189. pass
    190. df = pd.DataFrame(list_list)
    191. results_data = {
    192. 'check_count':check_count,
    193. 'total_count':total_count,
    194. 'total_win':0 if total_count<=0 else round((total_win/total_count)*100,2),
    195. 'start_date_str':caculate_start_date_str,
    196. 'df':df,
    197. 'detail_map':detail_map,
    198. 'factor_list':factor_list,
    199. 'ma_list':ma_list
    200. }
    201. return results_data

    结果

     

    本文校验的数据是随机抽取的81个股票

  • 相关阅读:
    JavaScript 63 JavaScript 对象 63.2 JavaScript 对象属性
    一个程序员的水平能差到什么程度?
    09_SpingBoot 集成Dubbo
    MySQL入门
    Java实现ATM架构设计
    UNIX环境高级编程_文件IO_文件描述符
    Halcon Geometry-Measurement-or-Calculation相关算子(一)
    PyQt5可视化编程-菜单和工具栏
    ICG-PEG-NHS,吲哚菁绿-聚乙二醇-活性酯,ICG-PEG2000-NHS
    使用python读取csv文件中的数据
  • 原文地址:https://blog.csdn.net/m0_37967652/article/details/127967881