接到一個(gè)朋友的需要悍赢,做一個(gè)簡單的指標(biāo)監(jiān)控,就是當(dāng)多個(gè)周期的均線和K線滿足某種情況的時(shí)候發(fā)出信號。其實(shí)這種預(yù)警很多圖表操盤軟件也可以做啊奄,但是問題是多個(gè)品種監(jiān)控的時(shí)候效率非常低纬朝,還容易死機(jī)收叶,同時(shí)監(jiān)控信息的發(fā)出手段不靈活,例如不方便發(fā)到QQ或者微信群里面共苛。于是想到可以通過python來做這個(gè)事情判没。
主程序如下:
Mon = Monitor()Mon.addRule(RuleResonanceUp())withopen("flist.txt",'r')asf:? ? flist = f.readlines()forlineinflist:? ? ? ? print("Processing "+line)? ? ? ? bd = BarData(line.strip('\n'))? ? ? ? Mon.Run(bd)
初始化一個(gè)Monitor監(jiān)控器,并給這個(gè)監(jiān)控器里面放入所需要監(jiān)控的規(guī)則類RuleResonanceUp
所有品種的代碼放在一個(gè)flist.txt文件中隅茎,讀出來以后由BarData這個(gè)類進(jìn)行初始化澄峰,獲得多周期的交易數(shù)據(jù),作為監(jiān)控器要處理的數(shù)據(jù)上下文辟犀。
然后運(yùn)行監(jiān)控器俏竞,監(jiān)控器會(huì)逐一將規(guī)則套入上下文數(shù)據(jù)中進(jìn)行判斷,滿足條件的就發(fā)出消息通知堂竟。
其他的代碼:
fromjqdatasdkimport*importtalib#用來做指標(biāo)計(jì)算魂毁,算是最流行的庫了吧importmatplotlib.pyplotasplt#用來做圖示,這個(gè)是調(diào)試用的出嘹,調(diào)好后基本就不用了frommatplotlib.pylabimportdate2num#用來做圖示的席楚,調(diào)試用,調(diào)好后就基本不用了importmpl_financeasmpf#用來圖示的税稼。importmatplotlib.tickerasticker#用來改圖示的橫坐標(biāo)importpandasaspdimportpandas.io.excel#用來輸出文件用的importdatetimeimportnumpyasnpclassBarData(object):#用來獲取品種的實(shí)際數(shù)據(jù)def__init__(self, stockCode, enddate=None):self.stockCode = stockCode? ? ? ? self.endDate = enddate? ? ? ? self.get_560Bars()? ? ? ? self.apply_indicators()defget_560Bars(self):#這個(gè)系統(tǒng)用到周線日線小時(shí)和5分鐘self.df1w = get_bars(self.stockCode,100, unit='1w', fields=['date','open','high','low','close'], include_now=True,? ? ? ? ? ? ? ? ? ? ? end_dt = self.endDate)? ? ? ? self.df1d = get_bars(self.stockCode,100, unit='1d', fields=['date','open','high','low','close'], include_now=True,? ? ? ? ? ? ? ? ? ? ? end_dt = self.endDate)? ? ? ? self.df60m = get_bars(self.stockCode,100, unit='60m', fields=['date','open','high','low','close'], include_now=True,? ? ? ? ? ? ? ? ? ? ? ? end_dt=self.endDate)? ? ? ? self.df5m = get_bars(self.stockCode,100, unit='5m', fields=['date','open','high','low','close'], include_now=True,? ? ? ? ? ? ? ? ? ? ? ? end_dt=self.endDate)defapply_indicators(self):#這個(gè)系統(tǒng)用到20? 60? 和經(jīng)典參數(shù)的macddefapply_ma60(df):df["MA60"] = talib.MA(df["close"], timeperiod=60)defapply_ma20(df):df["MA20"] = talib.MA(df["close"], timeperiod=20)defapply_macd(df):#close = [float(x) for x in df['close']]df["DIFF"], df['DEA'], df['MACDhist'] = talib.MACD(df['close'], fastperiod=12, slowperiod=26, signalperiod=9)defapply_hist_signals(df):"""
? ? ? ? ? ? :type df: Dataframe
? ? ? ? ? ? """#在原來的dataframe里面加入所有歷史的信號烦秩,每個(gè)信號加一列#需要支持的值是: c-ma60, ma60Slope, c-ma20, macdGold, macdDead, macdGoldsoon, macdDeadsoon, DEASlopedf['c_minus_ma60'] = df['close'] - df["MA60"]#用來判斷是否在ma60之上df['ma60Slope'] =Noneforiinrange(1,len(df)):? ? ? ? ? ? ? ? df.loc[i,'ma60Slope'] = df["MA60"][i] - df["MA60"][i-1]#用來判斷ma60的斜率df['c_minus_ma20'] =? df['close'] - df["MA20"]#用來判斷是否在ma20之上df["macdGold"] =False# macd 金叉死叉df["macdDead"] =Falseforiinrange(len(df)):if(df["DIFF"][i] - df["DEA"][i]) >0:? ? ? ? ? ? ? ? ? ? df.loc[i,"macdGold"] =Trueif(df["DIFF"][i] - df["DEA"][i]) <0:? ? ? ? ? ? ? ? ? ? df.loc[i,"macdDead"] =Truedf["macdGoldsoon"] =None# macd 將要金叉死叉df["macdDeadsoon"] =Noneforiinrange(len(df)-2) :ifdf["DEA"][i+1] > df["DIFF"][i+1]:if(df["DEA"][i+1] - df["DIFF"][i+1])-((df["DEA"][i]-df["DIFF"][i]) - (df["DEA"][i+1]-df["DIFF"][i+1])) <0:? ? ? ? ? ? ? ? ? ? ? ? df.loc[i+2,"macdGoldsoon"] =Trueifdf["DIFF"][i +1] > df["DEA"][i +1]:if(df["DIFF"][i +1] - df["DEA"][i +1]) - (? ? ? ? ? ? ? ? ? ? ? ? ? ? (df["DIFF"][i] - df["DEA"][i]) - (df["DIFF"][i +1] - df["DEA"][i +1])) <0:? ? ? ? ? ? ? ? ? ? ? ? df.loc[i+2,"macdDeadsoon"] =Truedf['DEASlope'] =Noneforiinrange(1, len(df)):? ? ? ? ? ? ? ? df.loc[i,'DEASlope'] = df["DEA"][i] - df["DEA"][i -1]? ? ? ? ? ? df["KDir"] =0foriinrange(1,len(df)):# K線方向判斷刁赦,如果高點(diǎn)抬高 低點(diǎn)抬高就多,高點(diǎn)低點(diǎn)降低就空闻镶,內(nèi)包外包就保持if(df["high"][i] > df["high"][i-1])and(df["low"][i] > df["low"][i-1]):? ? ? ? ? ? ? ? ? ? df.loc[i,"KDir"] =1elifdf["high"][i] < df["high"][i-1]anddf["low"][i] < df["low"][i-1]:? ? ? ? ? ? ? ? ? ? df.loc[i,"KDir"] =-1else:? ? ? ? ? ? ? ? ? ? df.loc[i,"KDir"] = df["KDir"][i-1]fordftin[self.df5m, self.df60m, self.df1d, self.df1w]:? ? ? ? ? ? apply_ma60(dft)? ? ? ? ? ? apply_ma20(dft)? ? ? ? ? ? apply_macd(dft)? ? ? ? ? ? apply_hist_signals(dft)classRule(object):#預(yù)警規(guī)則的基類def__init__(self):self.name ="RuleBase"defApplyRule(self, bd):passdefMsg(self):#當(dāng)規(guī)則發(fā)生的時(shí)候甚脉,要發(fā)出來的消息return"Non Rule Implemented."classRuleResonanceUp(Rule):#多頭共振的規(guī)則,所有的周期都是多的時(shí)候提醒def__init__(self):self.name ="RuleResonaceUp"defApplyRule(self, bd):ifbd.df1w["KDir"].tolist()[-1] >0andbd.df1d.KDir.tolist()[-1] >0andbd.df1d.DEASlope.tolist()[-1] >0andbd.df60m.KDir.tolist()[-1] >0\andbd.df60m.DEASlope.tolist()[-1] >0andbd.df5m.ma60Slope.tolist()[-1] >0andbd.df5m.DEASlope.tolist()[-1] >0\andbd.df5m.KDir.tolist()[-1] >0:returnTrueelse:returnFalsedefMsg(self):return"周K铆农,日K牺氨,日DEA,日K墩剖,小時(shí)DEA猴凹,小時(shí)K,5mDEA岭皂、5mMA60郊霎、5mK,多方共振爷绘。"classMonitor(object):def__init__(self):self.Rules = []defaddRule(self,r):self.Rules += [r]defRun(self,bd):#執(zhí)行規(guī)則书劝,滿足規(guī)則的時(shí)候打印提醒信息,在這里土至,可以換成ichat或者pyqq啥的购对,就可以實(shí)現(xiàn)微信和qq的通知了。forrinself.Rules:ifr.ApplyRule(bd):? ? ? ? ? ? ? ? print(datetime.datetime.now()," "+get_security_info(bd.stockCode).display_name+': '+r.Msg())pass