├── __init__.py ├── __pycache__ ├── stock.cpython-36.pyc ├── stock.cpython-37.pyc ├── dingding.cpython-36.pyc ├── dingding.cpython-37.pyc ├── trading.cpython-37.pyc ├── handleconfig.cpython-36.pyc └── handleconfig.cpython-37.pyc ├── .idea ├── encodings.xml ├── vcs.xml ├── modules.xml ├── misc.xml ├── cainiao_shizhan.iml ├── shelf │ ├── Uncommitted_changes_before_Update_at_2021_12_28__11_24___Default_Changelist_.xml │ └── Uncommitted_changes_before_Update_at_2021_12_28,_11_24_下午_[Default_Changelist] │ │ └── shelved.patch ├── inspectionProfiles │ └── Project_Default.xml └── workspace.xml ├── dingding.py ├── requirements.txt ├── config.ini ├── README.md ├── handleconfig.py ├── trading.py ├── stock.py ├── main.py └── stock_ding_remaind.py /__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /__pycache__/stock.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/z991/StockWaring/HEAD/__pycache__/stock.cpython-36.pyc -------------------------------------------------------------------------------- /__pycache__/stock.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/z991/StockWaring/HEAD/__pycache__/stock.cpython-37.pyc -------------------------------------------------------------------------------- /__pycache__/dingding.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/z991/StockWaring/HEAD/__pycache__/dingding.cpython-36.pyc -------------------------------------------------------------------------------- /__pycache__/dingding.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/z991/StockWaring/HEAD/__pycache__/dingding.cpython-37.pyc -------------------------------------------------------------------------------- /__pycache__/trading.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/z991/StockWaring/HEAD/__pycache__/trading.cpython-37.pyc -------------------------------------------------------------------------------- /__pycache__/handleconfig.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/z991/StockWaring/HEAD/__pycache__/handleconfig.cpython-36.pyc -------------------------------------------------------------------------------- /__pycache__/handleconfig.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/z991/StockWaring/HEAD/__pycache__/handleconfig.cpython-37.pyc -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /dingding.py: -------------------------------------------------------------------------------- 1 | from dingtalkchatbot.chatbot import DingtalkChatbot 2 | 3 | 4 | class Ding: 5 | 6 | def __init__(self): 7 | self.webhook = "你自己钉钉机器人的webhook" 8 | 9 | def send_text(self, message): 10 | dingding = DingtalkChatbot(self.webhook) 11 | dingding.send_text(msg=message) 12 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | beautifulsoup4==4.7.1 2 | bs4==0.0.1 3 | certifi==2019.3.9 4 | chardet==3.0.4 5 | DingtalkChatbot==1.3.0 6 | idna==2.8 7 | lxml==4.3.3 8 | numpy==1.16.3 9 | pandas==0.24.2 10 | python-dateutil==2.8.0 11 | pytz==2019.1 12 | requests==2.21.0 13 | simplejson==3.16.0 14 | six==1.12.0 15 | soupsieve==1.9.1 16 | tushare==1.2.34 17 | urllib3==1.24.2 18 | -------------------------------------------------------------------------------- /config.ini: -------------------------------------------------------------------------------- 1 | [stock_config] 2 | # 手动控制任务是否启动(优先级最高)ON、OFF、AUTO 3 | task_status=ON 4 | 5 | stock_list = [{"name":"招商银行", "stock_num": "sh600036", "high": 62, "low":62, "stop": 0}, 6 | {"name":"宁德时代", "stock_num": "sz300750", "high": 638, "low":500, "stop": 0}, 7 | {"name":"京东方A", "stock_num": "sz000725", "high": 5, "low":4, "stop": 0}, 8 | {"name":"春晖智控", "stock_num": "sz300943", "high": 46, "low":37, "stop": 0}] 9 | 10 | 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### 股票实时提醒功能 2 | 3 | #### 1.功能 4 | 5 | ``` 6 | 根据config.ini的section来读取对应的股票配置信息,通过调取新浪财经的股票接口获取改股票的实时价格,通过钉钉机器人发送对应的提醒信息。这块增加了股票交易日的判断,如果是非交易日不进行任何提醒。 7 | ``` 8 | 9 | #### 2.代码结构 10 | 11 | ``` 12 | 项目入口文件是main.py文件。 13 | trading.py是股票交易日判断模块 14 | dingding.py钉钉机器人发送信息模块,可以更改其webhook配置。 15 | stock.py是获取某只股票的实时信息模块 16 | handleconfig.py读取config.ini配置文件信息模块 17 | ``` 18 | 19 | #### 3.项目运行 20 | 21 | ``` 22 | pip install -r requirements.txt 23 | python main.py 24 | ``` 25 | 26 | -------------------------------------------------------------------------------- /.idea/cainiao_shizhan.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <<<<<<< HEAD 6 | 7 | ======= 8 | 9 | >>>>>>> origin/master 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/shelf/Uncommitted_changes_before_Update_at_2021_12_28__11_24___Default_Changelist_.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /handleconfig.py: -------------------------------------------------------------------------------- 1 | import configparser 2 | import json 3 | 4 | 5 | class ConfigStock: 6 | """ 7 | 获取股票配置信息 8 | """ 9 | def __init__(self): 10 | self.conf_main = configparser.ConfigParser() 11 | self.conf = self.conf_main.read("config.ini") 12 | 13 | def get_stock_json(self): 14 | """ 15 | 获取要监控的股票信息 16 | :return: 17 | """ 18 | stock_json = self.conf_main.get('stock_config', 'stock_list') 19 | return json.loads(stock_json) 20 | 21 | def manual_control(self): 22 | """ 23 | 判断是否开始监控或者停止监控 24 | :return: 25 | """ 26 | task_status = self.conf_main.get('stock_config', 'task_status') 27 | return task_status 28 | 29 | -------------------------------------------------------------------------------- /trading.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | 4 | class Trading: 5 | 6 | def is_start(self, config): 7 | """ 8 | 判断是否为股票交易日(周一到周五,9:30-11:30 13:00-15:00) 9 | :return: 10 | """ 11 | now = datetime.datetime.now() 12 | hour = now.hour 13 | min = now.minute 14 | week = now.weekday() 15 | 16 | # 是否运行代码 17 | result = 1 18 | # 优先从配置文件中获取,是否为交易日 19 | is_start = config.manual_control() 20 | 21 | if is_start == "ON": 22 | return 1 23 | if is_start == "OFF": 24 | return 0 25 | 26 | if week not in range(1, 6): 27 | result = 0 28 | if (hour == 9 or hour == 11) and min in range(0, 30): 29 | result = 0 30 | if hour in range(0, 9) or hour in range(15, 24) or hour == 0: 31 | result = 0 32 | 33 | if (week not in range(1, 6)) and ((hour == 9 or hour == 11) and min in (0, 31)): 34 | result = 0 35 | if hour in range(0, 9) or hour in range(15, 24) or hour == 0: 36 | result = 0 37 | return result 38 | -------------------------------------------------------------------------------- /stock.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | import requests 4 | 5 | 6 | class Stock: 7 | 8 | def __init__(self, stock_num): 9 | self.stock_num = stock_num 10 | 11 | def get_current(self): 12 | """ 13 | 获取实时股票信息 14 | :return: 15 | """ 16 | url = "http://hq.sinajs.cn/list={}".format(self.stock_num) 17 | stock_info = requests.get(url).text 18 | try: 19 | current_price = stock_info.split(',')[3] 20 | current_stock = stock_info.split(',')[0].split('="')[-1] 21 | except Exception as e: 22 | current_price = '0' 23 | current_stock = '股票代码错误' + str(e) 24 | current_price = float(current_price) 25 | return current_stock, current_price 26 | 27 | def get_rec_60(self): 28 | yes_date = datetime.datetime.now() - datetime.timedelta(days=1) 29 | before_60 = yes_date - datetime.timedelta(days=59) 30 | now_data_str = datetime.datetime.strftime(yes_date, "%Y%m%d") 31 | before_60_str = datetime.datetime.strftime(before_60, "%Y%m%d") 32 | url = f"https://q.stock.sohu.com/hisHq?code=cn_{self.stock_num[2:]}&start={before_60_str}&end={now_data_str}" 33 | res = requests.get(url=url) 34 | return res.json() 35 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | from handleconfig import ConfigStock 4 | from dingding import Ding 5 | from stock import Stock 6 | from trading import Trading 7 | 8 | 9 | def send_waring(stock_num, high, low): 10 | """ 11 | 发送报警信息 12 | :param config文件中股票的配置名称: 13 | :return: 14 | """ 15 | # 浮点数 16 | high = float(high) 17 | low = float(low) 18 | stock = Stock(stock_num) 19 | current_stock, current_price = stock.get_current() 20 | message = None 21 | if '股票代码错误' in current_stock: 22 | message = '股票 {} ,请输入正确股票代码!'.format(current_stock) 23 | 24 | elif current_price > high: 25 | message = '股票 {} ,现价为{},大于卖出阀值{},可以卖出'.format(current_stock, current_price, high) 26 | 27 | elif current_price < low: 28 | message = '股票 {} ,现价为{},小于买入阀值{},可以买入'.format(current_stock, current_price, low) 29 | return message 30 | 31 | 32 | if __name__ == '__main__': 33 | # 配置类实例化 34 | config = ConfigStock() 35 | # 钉钉类实例化 36 | ding = Ding() 37 | # 交易日判断类实例化 38 | condition = Trading() 39 | # 判断是否交易日,1为交易日 40 | task_status = condition.is_start(config) 41 | 42 | if task_status == 1: 43 | # 获取需要监控的股票列表信息(包括股票编码、买入阈值、卖出阈值) 44 | stock_list = config.get_stock_json() 45 | for stock in stock_list: 46 | # 获取某个股票的信息 47 | stock_num = stock['stock_num'] 48 | high = stock['high'] 49 | low = stock['low'] 50 | # 判断是否为非监控股票 51 | stop = stock['stop'] 52 | 53 | if str(stop) == '1': 54 | continue 55 | # 判断是否有买入或者卖出的消息提醒 56 | message = send_waring(stock_num, high, low) 57 | if message: 58 | # 如果有的话就发送钉钉消息 59 | ding.send_text(message) 60 | # time.sleep(2) 61 | 62 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 30 | -------------------------------------------------------------------------------- /stock_ding_remaind.py: -------------------------------------------------------------------------------- 1 | import requests 2 | from dingtalkchatbot.chatbot import DingtalkChatbot 3 | import configparser 4 | import datetime 5 | import time 6 | 7 | conf = configparser.ConfigParser() 8 | 9 | 10 | class Ding: 11 | 12 | def __init__(self, webhook): 13 | self.webhook = webhook 14 | 15 | def send(self, message): 16 | xiaoding = DingtalkChatbot(self.webhook) 17 | res = xiaoding.send_text(msg=message, is_at_all=True) 18 | print("res====", res) 19 | 20 | 21 | class Stock: 22 | 23 | def __init__(self, stock_num): 24 | self.stock_num = stock_num 25 | 26 | def get_current(self): 27 | """ 28 | 获取股票信息 29 | :return: 30 | """ 31 | url = "http://hq.sinajs.cn/list={}".format(self.stock_num) 32 | stock_info = requests.get(url).text 33 | print('stock_info===', stock_info) 34 | try: 35 | current_price = stock_info.split(',')[3] 36 | current_stock = stock_info.split(',')[0].split('="')[-1] 37 | except Exception as e: 38 | current_price = '0' 39 | current_stock = '股票代码错误' + str(e) 40 | return current_stock, current_price 41 | 42 | 43 | class Warning: 44 | 45 | def __init__(self): 46 | self.conf = conf.read("config.ini") 47 | self.hight = conf.get('stock', 'high') 48 | self.low = conf.get('stock', 'low') 49 | self.stock_num = conf.get('stock', 'stock_num') 50 | self.webhook=conf.get('dingding', 'webhook') 51 | 52 | def condion(self): 53 | """ 54 | 判断是否为股票交易时间 55 | :return: 56 | """ 57 | now = datetime.datetime.now() 58 | hour = now.hour 59 | min = now.minute 60 | week = now.weekday() 61 | 62 | result = 1 63 | 64 | if (week not in range(1, 6)) or ((hour == 9 or hour == 11) and min in (0, 31)) or ( 65 | hour in range(0, 9) or hour in range(15, 24)): 66 | result = 0 67 | 68 | return result 69 | 70 | def sen_waring(self): 71 | """ 72 | 发送提醒信息 73 | :return: 74 | """ 75 | stock = Stock(self.stock_num) 76 | current_stock, current_price = stock.get_current() 77 | ding = Ding(self.webhook) 78 | 79 | if '股票代码错误' in current_stock: 80 | ding.send(message='股票 {} ,请输入正确股票代码!'.format(current_stock)) 81 | 82 | elif current_price > self.hight: 83 | ding.send(message='股票 {} ,现价为{},大于卖出阀值{},可以卖出'.format(current_stock, current_price, self.hight)) 84 | 85 | elif current_price < self.low: 86 | ding.send(message='股票 {} ,现价为{},小于买入阀值{},可以买入'.format(current_stock, current_price, self.low)) 87 | 88 | 89 | if __name__ == '__main__': 90 | while True: 91 | waring = Warning() 92 | if waring.condion() == 0: 93 | time.sleep(2) 94 | waring.sen_waring() 95 | else: 96 | continue 97 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 27 | 28 | 29 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 58 | 59 | 60 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n 1556431530936\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n 5 | Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP 6 | <+>UTF-8 7 | =================================================================== 8 | diff --git a/.idea/workspace.xml b/.idea/workspace.xml 9 | --- a/.idea/workspace.xml (revision 335ae341b9be8be67ee9ae441e45cfce926e994b) 10 | +++ b/.idea/workspace.xml (date 1640705016832) 11 | @@ -1,20 +1,14 @@ 12 | 13 | 14 | 15 | - 16 | - 17 | - 18 | - 19 | - 20 | + 21 | 22 | - 23 | - 24 | 25 | 26 | 27 | 28 | 29 | - 30 | + 31 | 32 | 36 | 37 | 40 | 41 | 42 | @@ -105,7 +100,7 @@ 43 | 44 | 45 | 46 | - 47 | + 48 | 49 | 64 | - 65 | + 66 | 67 | 82 | - 83 | + 84 | 85 | 100 | - 101 | + 102 | 103 | 127 | @@ -255,6 +250,10 @@ 128 | 129 | 130 | 131 | + 132 | + 133 | + 134 | + 135 | 136 | 137 | 138 | @@ -293,22 +292,139 @@ 139 | 140 | 174 | + 179 | 181 | + 182 | + 183 | + 184 | + 185 | + file://$PROJECT_DIR$/main.py 186 | + 33 187 | + 189 | + 190 | + file://$PROJECT_DIR$/trading.py 191 | + 10 192 | + 194 | + 195 | + file://$PROJECT_DIR$/trading.py 196 | + 18 197 | + 199 | + 200 | + file://$PROJECT_DIR$/handleconfig.py 201 | + 25 202 | + 204 | + 205 | + file://$PROJECT_DIR$/handleconfig.py 206 | + 17 207 | + 209 | + 210 | + file://$PROJECT_DIR$/handleconfig.py 211 | + 18 212 | + 214 | + 215 | + file://$PROJECT_DIR$/main.py 216 | + 39 217 | + 219 | + 220 | + file://$PROJECT_DIR$/main.py 221 | + 43 222 | + 224 | + 225 | + file://$PROJECT_DIR$/main.py 226 | + 44 227 | + 229 | + 230 | + file://$PROJECT_DIR$/main.py 231 | + 55 232 | + 234 | + 235 | + file://$PROJECT_DIR$/main.py 236 | + 19 237 | + 239 | + 240 | + file://$PROJECT_DIR$/stock.py 241 | + 15 242 | + 244 | + 245 | + file://$PROJECT_DIR$/stock.py 246 | + 18 247 | + 249 | + 250 | + file://$PROJECT_DIR$/stock.py 251 | + 19 252 | + 254 | + 255 | + file://$PROJECT_DIR$/stock.py 256 | + 8 257 | + 259 | + 260 | + file://$PROJECT_DIR$/main.py 261 | + 17 262 | + 264 | + 265 | + 266 | + 267 | 268 | - 269 | + 270 | 271 | + 272 | 273 | 274 | - 275 | 276 | + 277 | 278 | 279 | 280 | --------------------------------------------------------------------------------