前面文章讲了前复权,RPS基础数据的生成,有了这些基础数据,我们就可以和通达信一样使用公式系统来选股,分析板块等。python中模拟用通达信的风格书写公式,大致上只有部分符号有点差异,稍微改动一下就可以在python中跑通了。MA10:=MA(C,10);MA20:=MA(C,20);MA200:=MA(C,200);JXDT10:=EVERY(MA20>=REF(MA20,1),7);{20日线一直上升}JXDT11:=EVERY(MA10>=REF(MA10,1),7);{10日线一直上升}JXDT12:=COUNT(MA20>=REF(MA20,1),7)>5;{至少有6天20日线上升}JXDT1:=JXDT10 OR (JXDT11 AND JXDT12);JXDT2:=EVERY(MA10>=MA20,5);{10日线在20日线上}SRXXD:=BARSSINCEN(C<MA(C,10),10);{首次十日线下距离今天的天数}SRXXL:=REF(L,SRXXD);{首次十日线下的最低价}JXDT3:=IF(ISVALID(SRXXD),EVERY(C>=SRXXL*0.985,SRXXD+1),1);{不跌破首次十日线低点}JXDT4:=COUNT(MA(C,200)>REF(MA(C,200),1),30)>=20 OR COUNT(C>MA(C,200),30)>=20;{200日线向上或站上200日线}JXDT5:=RANGE(C/REF(C,20),1.19,1.60);{20日涨幅大于20%}JXDT:JXDT1 AND JXDT2 AND JXDT3 AND JXDT4 AND JXDT5;
def DTPL(df_code: pd.DataFrame, start_date="", end_date=""): """ 均线多头排列公式 :param df_code: 股票前复权日K线 :param start_date: 起始日期 :param end_date: 截至日期 :return: """ start_date = df_code.index[0] if start_date == "" else start_date end_date = df_code.index[-1] if end_date == "" else end_date df = df_code.loc[start_date:end_date] C = df["close"] L = df["low"] MA10 = MA(C, 10) MA20 = MA(C, 20) MA200 = MA(C, 200) JXDT10 = EVERY(MA20 >= REF(MA20, 1), 7) # {20日线一直上升} JXDT11 = EVERY(MA10 >= REF(MA10, 1), 7) # {10日线一直上升} JXDT12 = COUNT(MA20 >= REF(MA20, 1), 7) > 5 # {至少有6天20日线上升} JXDT1 = JXDT10 | (JXDT11 & JXDT12) JXDT2 = EVERY(MA10 >= MA20, 5) # {10日线在20日线上} # {首次十日线下距离今天的天数} SRXXD = BARSSINCEN(C < MA(C, 10), 10) # {不跌破首次十日线低点} tmp_df = pd.DataFrame({"close": C, "low": L, "srxxd": SRXXD}) new_tmp_df = tmp_df.reset_index() new_tmp_df["cond"] = new_tmp_df.apply( lambda row: ( True if (pd.isna(row["srxxd"]) or row["srxxd"] == 0) else new_tmp_df.loc[row.name - row["srxxd"] + 1 : row.name, "close"].min() >= new_tmp_df.loc[row.name - row["srxxd"], "low"] * 0.985 ), axis=1, ) tmp_df["cond"] = new_tmp_df["cond"].values JXDT3 = tmp_df["cond"] JXDT4 = (COUNT(MA(C, 200) > REF(MA(C, 200), 1), 30) >= 20) | (COUNT(C > MA(C, 200), 30) >= 20) # {200日线向上或站上200日线} JXDT5 = RANGE(C / REF(C, 20), 1.19, 1.60) # {20日涨幅大于20%} return JXDT1 & JXDT2 & JXDT3 & JXDT4 & JXDT5
python中的数据是基于pandas的Series和DataFrame的,得益于pandas的向量运算,以上公式可见只是一些符号改动,通达信赋值:=在python中就是=,通达信中逻辑运算符AND,OR在python中&,|,,通达信中一些基础函数,如REF,MA,COUNT等在python中定义也很简单,分析类的函数可以调用talib的实现。例如:REF函数,MA函数(使用talib库实现)def REF(series, n): """ 引用n周期前的数据 """ return series.shift(periods=n) def MA(value, day): """ 返回当前周期的简单移动平均值。传入可以是列表或序列类型。传出是当前周期的简单移动平均具体值。 :rtype: float """ import talib result = talib.SMA(value, day) return result
熟练pandas中Series和DataFrame的操作就能解决绝大部分问题。