├── .idea ├── cainiao_shizhan.iml ├── encodings.xml ├── inspectionProfiles │ └── Project_Default.xml ├── misc.xml ├── modules.xml ├── shelf │ ├── Uncommitted_changes_before_Update_at_2021_12_28,_11_24_下午_[Default_Changelist] │ │ └── shelved.patch │ └── Uncommitted_changes_before_Update_at_2021_12_28__11_24___Default_Changelist_.xml ├── vcs.xml └── workspace.xml ├── README.md ├── __init__.py ├── __pycache__ ├── dingding.cpython-36.pyc ├── dingding.cpython-37.pyc ├── handleconfig.cpython-36.pyc ├── handleconfig.cpython-37.pyc ├── stock.cpython-36.pyc ├── stock.cpython-37.pyc └── trading.cpython-37.pyc ├── config.ini ├── dingding.py ├── handleconfig.py ├── main.py ├── requirements.txt ├── stock.py ├── stock_ding_remaind.py └── trading.py /.idea/cainiao_shizhan.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <<<<<<< HEAD 6 | 7 | ======= 8 | 9 | >>>>>>> origin/master 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 30 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/shelf/Uncommitted_changes_before_Update_at_2021_12_28,_11_24_下午_[Default_Changelist]/shelved.patch: -------------------------------------------------------------------------------- 1 | Index: .idea/workspace.xml 2 | IDEA additional info: 3 | Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP 4 | <+>\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 81 | 82 | 83 | 84 | 85 | 86 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 120 | 121 | 122 | 142 | 143 | 144 | 164 | 165 | 166 | 186 | 187 | 188 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 1556431530936 226 | 249 | 250 | 251 | 252 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 283 | 284 | 293 | 295 | 296 | 297 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/z991/StockWaring/d92d5ef7cbf86916f870e52337c4c0cc3dc6e81e/__init__.py -------------------------------------------------------------------------------- /__pycache__/dingding.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/z991/StockWaring/d92d5ef7cbf86916f870e52337c4c0cc3dc6e81e/__pycache__/dingding.cpython-36.pyc -------------------------------------------------------------------------------- /__pycache__/dingding.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/z991/StockWaring/d92d5ef7cbf86916f870e52337c4c0cc3dc6e81e/__pycache__/dingding.cpython-37.pyc -------------------------------------------------------------------------------- /__pycache__/handleconfig.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/z991/StockWaring/d92d5ef7cbf86916f870e52337c4c0cc3dc6e81e/__pycache__/handleconfig.cpython-36.pyc -------------------------------------------------------------------------------- /__pycache__/handleconfig.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/z991/StockWaring/d92d5ef7cbf86916f870e52337c4c0cc3dc6e81e/__pycache__/handleconfig.cpython-37.pyc -------------------------------------------------------------------------------- /__pycache__/stock.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/z991/StockWaring/d92d5ef7cbf86916f870e52337c4c0cc3dc6e81e/__pycache__/stock.cpython-36.pyc -------------------------------------------------------------------------------- /__pycache__/stock.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/z991/StockWaring/d92d5ef7cbf86916f870e52337c4c0cc3dc6e81e/__pycache__/stock.cpython-37.pyc -------------------------------------------------------------------------------- /__pycache__/trading.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/z991/StockWaring/d92d5ef7cbf86916f870e52337c4c0cc3dc6e81e/__pycache__/trading.cpython-37.pyc -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | --------------------------------------------------------------------------------