An example of using JQ as index monitoring

Keywords: Python Excel Mac

Turn from ( https://www.joinquant.com/view/community/detail/8a21c68016d0d1601ccf2b9d376c0131)

Receive the needs of a friend, do a simple indicator monitoring, that is, when the average and K-line of multiple cycles meet a certain situation, send a signal. In fact, a lot of chart operation software can also do this kind of early warning, but the problem is that the efficiency of multiple varieties of monitoring is very low, and it is easy to crash. At the same time, the sending means of monitoring information is not flexible, such as it is not convenient to send to QQ or wechat group. So I thought that I could do this through python.
The main program is as follows:

Mon = Monitor()
Mon.addRule(RuleResonanceUp())

with open("flist.txt",'r') as f:
    flist = f.readlines()
    for line in flist:
        print("Processing "+line)
        bd = BarData(line.strip('\n'))
        Mon.Run(bd)

Initialize a Monitor monitor, and put the rule class ruleresonceup to be monitored into the Monitor
All kinds of codes are put in a flist.txt file, which is read out and initialized by BarData class to obtain multi cycle transaction data as the data context to be processed by the monitor.
Then run the monitor, the monitor will set the rules into the context data one by one to judge, and send a message notification if the conditions are met.

Other codes:

from jqdatasdk import *
import talib    #It's the most popular library for index calculation.
import matplotlib.pyplot as plt     #It's used for illustration. It's for debugging. It's basically not used after debugging.
from matplotlib.pylab import date2num     #It's used for making diagrams. After adjustment, it's almost useless.
import mpl_finance as mpf         #Used for illustration.
import matplotlib.ticker as ticker      #To change the abscissa of a diagram
import pandas as pd       
import pandas.io.excel       #For output files
import datetime
import numpy as np

class BarData(object):       #To obtain the actual data of varieties
    def __init__(self, stockCode, enddate=None):
        self.stockCode = stockCode
        self.endDate = enddate
        self.get_560Bars()
        self.apply_indicators()

    def get_560Bars(self):      #This system uses weekly daily line hours and 5 minutes
        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)

    def apply_indicators(self):   #This system uses a Mac D of 2060 and classical parameters
        def apply_ma60(df):
            df["MA60"] = talib.MA(df["close"], timeperiod=60)
        def apply_ma20(df):
            df["MA20"] = talib.MA(df["close"], timeperiod=20)
        def apply_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)
        def apply_hist_signals(df):
            """

            :type df: Dataframe
            """
            #Add all historical signals in the original data frame, one column for each signal
            #The values to be supported are: c-ma60, ma60Slope, c-ma20, macdGold, macdDead, macdGoldsoon, macdDeadsoon, DEASlope.
            df['c_minus_ma60'] = df['close'] - df["MA60"]   #It is used to judge whether it is above ma60.

            df['ma60Slope'] = None
            for i in range(1,len(df)):
                df.loc[i,'ma60Slope'] = df["MA60"][i] - df["MA60"][i-1]
             #To judge the slope of ma60

            df['c_minus_ma20'] =  df['close'] - df["MA20"]   #Used to judge whether it is above ma20

            df["macdGold"] = False                          # macd gold fork
            df["macdDead"] = False
            for i in range(len(df)):
                if (df["DIFF"][i] - df["DEA"][i]) > 0 :
                    df.loc[i,"macdGold"] = True
                if (df["DIFF"][i] - df["DEA"][i]) < 0 :
                    df.loc[i,"macdDead"] = True

            df["macdGoldsoon"] = None                       # macd is going to have a golden fork
            df["macdDeadsoon"] = None
            for i in range(len(df)-2) :
                if df["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"] = True

                if df["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"] = True


            df['DEASlope'] = None
            for i in range(1, len(df)):
                df.loc[i, 'DEASlope'] = df["DEA"][i] - df["DEA"][i - 1]

            df["KDir"] = 0
            for i in range(1,len(df)):                  # Judging the direction of K-line, if the high point rises and the low point rises, the high point and the low point fall, it will be empty, and the outsourcing will be maintained.
                if (df["high"][i] > df["high"][i-1]) and (df["low"][i] > df["low"][i-1]):
                    df.loc[i,"KDir"] = 1
                elif df["high"][i] < df["high"][i-1] and df["low"][i] < df["low"][i-1]:
                    df.loc[i,"KDir"] = -1
                else :
                    df.loc[i,"KDir"] = df["KDir"][i-1]

        for dft in [self.df5m, self.df60m, self.df1d, self.df1w]:
            apply_ma60(dft)
            apply_ma20(dft)
            apply_macd(dft)
            apply_hist_signals(dft)

class Rule(object):    #Basic class of early warning rule
    def __init__(self):
        self.name = "RuleBase"

    def ApplyRule(self, bd):
        pass

    def Msg(self):    #Messages to be sent when rules happen
        return "Non Rule Implemented."

class RuleResonanceUp(Rule):            #The rule of multi head resonance, all cycles are multi time reminder
    def __init__(self):
        self.name = "RuleResonaceUp"
    def ApplyRule(self, bd):
        if bd.df1w["KDir"].tolist()[-1] > 0 and bd.df1d.KDir.tolist()[-1] > 0 and bd.df1d.DEASlope.tolist()[-1] > 0 and bd.df60m.KDir.tolist()[-1] > 0 \
            and bd.df60m.DEASlope.tolist()[-1] > 0 and bd.df5m.ma60Slope.tolist()[-1] > 0 and bd.df5m.DEASlope.tolist()[-1] > 0 \
            and bd.df5m.KDir.tolist()[-1] >0:
            return True
        else:
            return False

    def Msg(self):
        return "week K,day K,day DEA,day K,hour DEA,hour K,5mDEA,5mMA60,5mK,Multi resonance."


class Monitor(object):
    def __init__(self):
        self.Rules = []
    def addRule(self,r):
        self.Rules += [r]

    def Run(self,bd):      #Execute the rules and print the reminders when the rules are met. Here, you can change it to ichat or pyqq, and you can realize wechat and qq notifications.
        for r in self.Rules:
            if r.ApplyRule(bd):
                print(datetime.datetime.now()," "+get_security_info(bd.stockCode).display_name+': '+r.Msg())
    pass

The above is a simple rule framework to monitor the situation of multi species average using jqdata.

Posted by kikki on Fri, 01 Nov 2019 21:40:13 -0700