写在前面:
1. 本文中提到的“股票策略校验工具”的具体使用操作请查看该博文;
2. 文中知识内容来自书籍《同花顺炒股软件从入门到精通》
3. 本系列文章是用来学习技法,文中所得内容都仅仅只是作为演示功能使用
目录
所谓“三杆通底”是指股价跌到低位后,又接连出现三条下降的大阴线,且一根接一根地通到底部。“三杆通底”形态出现后的反弹力度一般较大,是短线获利的难得机会。因为该形态的三条大阴线,消耗了空头的有生力量,多头会趁机抢筹,推动股价上扬,掀起一轮反弹行情,在第三条大阴线的收盘价附近买入,后市一般都会获利。

出现“三杆通底”的形态后,股票投资者需遵循以下操作原则。
1)“三杆通底”形态可在底部行情和下降行情的途中出现。在底部行情中出现时,可放心买入,因为此时能基本确认股价已跌到了底部,买进后,凤霞较小,获利较为可靠。
2)“三杆通底”形态在下降行情途中出现时,需要谨慎对待,缺乏短线经验的投资者,最好避免参与,以防不测。
那么如何区分是底部行情的“三杆通底”形态,还是下降行情中的“三杆通底”形态呢?较为可靠的判断依据有两条:一是以股价下跌的深度作为判断的依据。股价上升到高位后,回档整理不久,下跌幅度较小,这时出现的连续三条大阴线,多属下跌途中的“三杆通底”形态,操作时就得慎重。反之,股价下跌的幅度已经很大,此时出现连续三条下降的大阴线,多为见底特征,可放心买入。二是依据30日移动平均线的走势情况进行判断。当30日均线由高位转势下行,在没有出现与5日均线金叉的情况下,如果出现了三条大阴线,就属于下降途中的“三杆通底”图线。反之,30日均线在低位与5日均线实现了金叉后出现的三条大阴线,就属于底部行情的“三杆通底”形态,此时就可放心买入。
3)“三杆通底”形态中的三条阴线,均要求为大阴线,每条阴线的跌幅不应小于3%,三条阴线的总跌幅不应少于10%,跌幅越大,有效性越高。第三条大阴线如果是三条阴线中最长的一条阴线的话,那么后市见底的可能性就会更大一些,反弹的力度也相应提高。
4)“三杆通底”形态形成后,在个别情况下,会出现继续下跌的走势。这种情况,多半出现在下降行情途中,或者三条阴线的总跌幅没达到10%以上,属于“瘪球落地”形态,缺乏反弹动力,股价只好继续下跌,寻求支撑。如果已按这一形态买进股票的投资者,第二天不涨反跌时,应迅速止损,以免越套越深,难以自拔。
- def excute_strategy(base_data,data_dir):
- '''
- 买入口诀 - 三杆通底,反弹在即
- 解析:
- 1. 接连出现三条下降的大阴线
- 2. 每条阴线的跌幅大于等于3%
- 3. 三条阴线的总跌幅不应少于10%
- 自定义:
- 1. 大阴线 =》实体大于昨收的4%
- 2. 买入点 =》三阴线后一个交易日收盘价
- 3. 胜 =》 买入后第三日收盘价涨跌幅,正为胜
- 只计算最近两年的数据
- :param base_data:股票代码与股票简称 键值对
- :param data_dir:股票日数据文件所在目录
- :return:
- '''
- import pandas as pd
- import numpy as np
- import talib,os
- from datetime import datetime
- from dateutil.relativedelta import relativedelta
-
- def res_pre_two_year_first_day():
- pre_year_day = (datetime.now() - relativedelta(years=2)).strftime('%Y-%m-%d')
- return pre_year_day
- caculate_start_date_str = res_pre_two_year_first_day()
-
- dailydata_file_list = os.listdir(data_dir)
-
- total_count = 0
- total_win = 0
- check_count = 0
- list_list = []
- detail_map = {}
- for item in dailydata_file_list:
- item_arr = item.split('.')
- ticker = item_arr[0]
- secName = base_data[ticker]
- file_path = data_dir + item
- df = pd.read_csv(file_path,encoding='utf-8')
- # 删除停牌的数据
- df = df.loc[df['openPrice'] > 0].copy()
- df['o_date'] = df['tradeDate']
- df['o_date'] = pd.to_datetime(df['o_date'])
- df = df.loc[df['o_date'] >= caculate_start_date_str].copy()
- # 保存未复权收盘价数据
- df['close'] = df['closePrice']
- # 计算前复权数据
- df['openPrice'] = df['openPrice'] * df['accumAdjFactor']
- df['closePrice'] = df['closePrice'] * df['accumAdjFactor']
- df['highestPrice'] = df['highestPrice'] * df['accumAdjFactor']
- df['lowestPrice'] = df['lowestPrice'] * df['accumAdjFactor']
-
- if len(df)<=0:
- continue
-
- # 开始计算
- df.reset_index(inplace=True)
- df['i_row'] = [i for i in range(len(df))]
- df['body_length'] = abs(df['closePrice']-df['openPrice'])
- df['big_body'] = 0
- df.loc[(df['closePrice']
'openPrice']) & (df['body_length']/df['closePrice'].shift(1)>0.04),'big_body'] = 1 - df['close_chg'] = ((df['closePrice'] - df['closePrice'].shift(1))/df['closePrice'].shift(1))*100
- df['three_yeah'] = 0
- df.loc[(df['big_body']==1) & (df['big_body'].shift(-1)==1) & (df['big_body'].shift(-2)==1) & (df['close_chg']<=-3) & (df['close_chg'].shift(-1)<=3) & (df['close_chg'].shift(-2)<=3),'three_yeah'] = 1
- df['target_yeah'] = 0
- df.loc[(df['three_yeah']==1) & ((df['close_chg']+df['close_chg'].shift(-1)+df['close_chg'].shift(-2))<=10),'target_yeah'] = 1
-
- df['three_chg'] = round(((df['close'].shift(-3) - df['close']) / df['close']) * 100, 4)
- df['three_after_close'] = df['close'].shift(-3)
-
- df_target = df.loc[df['target_yeah']==1].copy()
-
- node_count = 0
- node_win = 0
- duration_list = []
- table_list = []
- i_row_list = df_target['i_row'].values.tolist()
- for i,row0 in enumerate(i_row_list):
- row = row0 + 3
- if row >= len(df):
- continue
- date_str = df.iloc[row]['tradeDate']
- cur_close = df.iloc[row]['close']
- three_after_close = df.iloc[row]['three_after_close']
- three_chg = df.iloc[row]['three_chg']
-
- table_list.append([
- i,date_str,cur_close,three_after_close,three_chg
- ])
- duration_list.append([row-3,row+3])
- node_count += 1
- if three_chg>0:
- node_win +=1
- pass
-
- list_list.append({
- 'ticker':ticker,
- 'secName':secName,
- 'count':node_count,
- 'win':0 if node_count<=0 else round((node_win/node_count)*100,2)
- })
- detail_map[ticker] = {
- 'table_list': table_list,
- 'duration_list': duration_list
- }
-
- total_count += node_count
- total_win += node_win
- check_count += 1
- pass
- df = pd.DataFrame(list_list)
-
- results_data = {
- 'check_count':check_count,
- 'total_count':total_count,
- 'total_win':0 if total_count<=0 else round((total_win/total_count)*100,2),
- 'start_date_str':caculate_start_date_str,
- 'df':df,
- 'detail_map':detail_map
- }
- return results_data

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