This commit is contained in:
maxinxin 2025-06-20 13:35:41 +08:00
parent c1325e1396
commit 0010be1b6b
7 changed files with 90 additions and 142 deletions

Binary file not shown.

Binary file not shown.

1
asd.py
View File

@ -1 +0,0 @@
import requests

Binary file not shown.

View File

@ -24,7 +24,7 @@ path = os.path.join(root_path,'broker_xiadan','东吴证券金融终端独立下
global engine
engine = create_engine(
'mysql+pymysql://cn_ainvest_db:cn_ainvest_sd3a1@rm-2zewagytttzk6f24xno.mysql.rds.aliyuncs.com:3306/',
encoding="utf-8", echo=False)
echo=False)
@ -37,7 +37,13 @@ class DongWuClientTrader:
self.path = exe_path
self.account_name = account_name
self.log = Logger(f'{root_path}/logs',self.account_name)
# 确保logs目录存在
logs_dir = root_path / 'logs'
logs_dir.mkdir(exist_ok=True)
# 初始化日志系统
self._setup_logging()
# 用户券商信息
sql = f"select * from ainvest_usercount where username='{account_name}'"
@ -46,6 +52,42 @@ class DongWuClientTrader:
self.securities_password = str(df_count['securities_password'].tolist()[0])
self.communication_password = str(df_count['communication_password'].tolist()[0])
def _setup_logging(self):
"""设置日志系统"""
import logging
import os
# 获取当前模块的logger
self.logger = logging.getLogger(__name__)
# 为当前账户添加文件处理器记录到logs目录
logs_file = os.path.join(root_path, 'logs', f'{self.account_name}.log')
# 检查是否已经有针对这个账户的处理器,避免重复添加
account_handler_exists = False
for handler in self.logger.handlers:
if hasattr(handler, 'baseFilename') and handler.baseFilename == os.path.abspath(logs_file):
account_handler_exists = True
break
if not account_handler_exists:
formatter = logging.Formatter('[%(asctime)s] [%(levelname)s] %(message)s', '%Y-%m-%d %H:%M:%S')
file_handler = logging.FileHandler(logs_file, encoding='utf-8')
file_handler.setFormatter(formatter)
file_handler.setLevel(logging.DEBUG)
self.logger.addHandler(file_handler)
# 如果根logger没有处理器单独运行时添加控制台处理器
root_logger = logging.getLogger()
if not root_logger.handlers:
console_handler = logging.StreamHandler()
console_handler.setFormatter(logging.Formatter('[%(asctime)s] [%(levelname)s] %(message)s', '%Y-%m-%d %H:%M:%S'))
console_handler.setLevel(logging.INFO)
self.logger.addHandler(console_handler)
# 设置logger级别
self.logger.setLevel(logging.DEBUG)
def exit(self):
'''
结束进程
@ -74,12 +116,12 @@ class DongWuClientTrader:
path=self.path, timeout=1
)
self.exit()
self.log.warn('There are running programs, and there are processes in retreat')
self.logger.warning('There are running programs, and there are processes in retreat')
except Exception:
pass
#启动软件进程,输入账号密码
self.log.info('Start login')
self.logger.info('Start login')
start_time = time.time()
# 重置mac
@ -96,12 +138,12 @@ class DongWuClientTrader:
item = get_ip_data() #获取动态IP
if item['ip'] in used_ip:
get_ip_times += 1
self.log.warn(f'代理IP重复重新获取IP')
self.logger.warning(f'代理IP重复重新获取IP')
else:
self.log.info(f'代理IP已经获取{item}')
self.logger.info(f'代理IP已经获取{item}')
break
except Exception as e:
self.log.error(f'获取IP失败请检查网络连接{e}')
self.logger.error(f'获取IP失败请检查网络连接{e}')
time.sleep(5)
# raise ConnectionError(f"获取IP失败请检查网络连接。错误详情: {e}")
@ -113,7 +155,7 @@ class DongWuClientTrader:
# exit_ip = get_proxy_ip(proxy_ip,proxy_port)
time_with_change_proxy = time.time()-start_time
self.log.info('全局代理设置成功')
self.logger.info('全局代理设置成功')
insert_data= {'as_of_date':datetime.datetime.fromtimestamp(start_time).strftime('%Y-%m-%d %H:%M:%S.%f'),
'broker':broker,
@ -328,7 +370,7 @@ class DongWuClientTrader:
one_text = self._app.window(control_id=0x0, class_name='#32770').window(control_id=0x410,
class_name='Static').window_text()
# 摘取合同信息
self.log.info(one_text.replace('/n', ' '))
self.logger.info(one_text.replace('/n', ' '))
time.sleep(0.2)
# 确认申购委托
self._app.window(control_id=0x0, class_name="#32770", found_index=0).window(control_id=0x6,
@ -337,7 +379,7 @@ class DongWuClientTrader:
# self._app.top_window().set_focus()
one_text = self._app.window(control_id=0x0, class_name='#32770').window(control_id=0x3EC,
class_name='Static').window_text()
self.log.info(one_text.replace('/n', ' '))
self.logger.info(one_text.replace('/n', ' '))
time.sleep(0.2)
self._app.window(control_id=0x0, class_name="#32770", found_index=0).window(control_id=0x2,
class_name='Button').click()
@ -379,7 +421,7 @@ class DongWuClientTrader:
#获取弹窗信息
result = self._app.top_window().window(control_id=0x3EC, class_name='Static').window_text()
self.log.info(result)
self.logger.info(result)
pywinauto.keyboard.send_keys("{ENTER}")
time.sleep(0.2)
pywinauto.keyboard.send_keys("{ESC}")
@ -470,7 +512,7 @@ class DongWuClientTrader:
self._copy_data()
df_position = self._data_to_df()
if len(df_position) == 0:
self.log.info('--------------------------------------无当日持仓--------------------------------------')
self.logger.info('--------------------------------------无当日持仓--------------------------------------')
return pd.DataFrame()
df_position['证券代码'] = df_position['证券代码'].apply(lambda x: tranTicker(str(x).replace('="', '').replace('"', '')))
df_position = df_position[['证券代码','证券名称','股票余额','可用余额','冻结数量','成本价','市价','市值','盈亏','盈亏比例(%)']]
@ -508,7 +550,7 @@ class DongWuClientTrader:
self._copy_data()
df = self._data_to_df()
if len(df) == 0:
self.log.info('--------------------------------------无当日委托--------------------------------------')
self.logger.info('--------------------------------------无当日委托--------------------------------------')
return pd.DataFrame()
else:
df = df[['委托时间', '证券代码', '证券名称', '操作', '委托价格', '委托数量', '成交数量', '成交均价', '股票成交金额']]
@ -544,7 +586,7 @@ class DongWuClientTrader:
self._copy_data()
df = self._data_to_df()
if len(df) == 0:
self.log.info('--------------------------------------无当日成交--------------------------------------')
self.logger.info('--------------------------------------无当日成交--------------------------------------')
return pd.DataFrame()
else:
df = df[['成交时间','证券代码','证券名称','操作','成交数量','成交均价']]
@ -603,8 +645,8 @@ class DongWuClientTrader:
# one_text = self._app.top_window().window(control_id=0x410, class_name='Static').window_text()
if '委托价格的小数部分应该为2位' in one_text:
# 点击“否”
self.log.warn(one_text.replace('/n',' '))
# 点击"否"
self.logger.warning(one_text.replace('/n',' '))
self._app.top_window().window(control_id=0x7, class_name='Button').click()
# 保留两位小数截断
price = str(price)[:-1]
@ -618,7 +660,7 @@ class DongWuClientTrader:
one_text = self._app.top_window().window(control_id=0x410, class_name='Static').window_text()
else:
# 摘取合同信息
self.log.info(one_text.replace('/n',' '))
self.logger.info(one_text.replace('/n',' '))
time.sleep(0.2)
# 确认买入
@ -634,7 +676,7 @@ class DongWuClientTrader:
class_name='Static').window_text()
# self._app.top_window().set_focus()
# one_text2 = self._app.top_window().window(control_id=0x3EC, class_name='Static').window_text()
self.log.info(one_text2.replace('/n', ' '))
self.logger.info(one_text2.replace('/n', ' '))
time.sleep(0.5)
# 确认合同
# self._app.top_window().set_focus()
@ -668,9 +710,9 @@ class DongWuClientTrader:
try:
self._app.top_window().set_focus()
result_idcode = self._app.top_window().window(control_id=0x966, class_name='Static').window_text()
self.log.softInfo(result_idcode)
self.logger.info(result_idcode)
if '验证码错误' in result_idcode:
self.log.warn('Verification code error')
self.logger.warning('Verification code error')
self._app.top_window().window(control_id=0x2, class_name="Button").click()
time.sleep(0.5)
else:

View File

@ -1,107 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
定时执行 init_proxy.py 脚本
每整十分钟执行一次001020304050
"""
import time
import datetime
import subprocess
import sys
import os
import logging
from pathlib import Path
# 设置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('scheduler_init_proxy.log', encoding='utf-8'),
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
def execute_init_proxy():
"""执行 init_proxy.py 脚本"""
try:
script_path = Path(__file__).parent / "init_proxy.py"
if not script_path.exists():
logger.error(f"脚本文件不存在: {script_path}")
return False
# 使用当前 Python 解释器执行脚本 - 兼容老版本Python
result = subprocess.run(
[sys.executable, str(script_path)],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True
)
if result.returncode == 0:
logger.info("init_proxy.py 执行成功")
if result.stdout and result.stdout.strip():
logger.info(f"输出: {result.stdout.strip()}")
else:
logger.error(f"init_proxy.py 执行失败,返回码: {result.returncode}")
if result.stderr and result.stderr.strip():
logger.error(f"错误信息: {result.stderr.strip()}")
return result.returncode == 0
except Exception as e:
logger.error(f"执行 init_proxy.py 时发生异常: {e}")
return False
def wait_for_next_execution():
"""等待到下一个整十分钟"""
now = datetime.datetime.now()
current_minute = now.minute
# 计算下一个整十分钟
next_minute = ((current_minute // 10) + 1) * 10
# 处理小时进位
if next_minute >= 60:
next_minute = 0
next_execution = now.replace(minute=0, second=0, microsecond=0) + datetime.timedelta(hours=1)
else:
next_execution = now.replace(minute=next_minute, second=0, microsecond=0)
wait_seconds = (next_execution - now).total_seconds()
logger.info(f"当前时间: {now.strftime('%Y-%m-%d %H:%M:%S')}")
logger.info(f"下次执行时间: {next_execution.strftime('%Y-%m-%d %H:%M:%S')}")
logger.info(f"等待 {wait_seconds:.0f}")
return wait_seconds
def main():
"""主函数"""
logger.info("代理重置定时器启动")
logger.info("脚本将在每整十分钟执行一次 init_proxy.py")
# 首次执行
logger.info("执行首次代理重置...")
execute_init_proxy()
# 定时循环
while True:
try:
wait_seconds = wait_for_next_execution()
time.sleep(wait_seconds)
logger.info("开始执行定时任务...")
execute_init_proxy()
except KeyboardInterrupt:
logger.info("接收到中断信号,程序退出")
break
except Exception as e:
logger.error(f"定时器运行异常: {e}")
# 发生异常时等待60秒后继续
time.sleep(60)
if __name__ == "__main__":
main()

View File

@ -633,46 +633,60 @@ class Logger():
"""
def __init__(self, path, name, Flevel=logging.DEBUG):
self.time = time.strftime("%Y-%m-%d")
self.fileName = path + '/' + name + ".log"
self.logger = logging.getLogger(self.fileName)
self.logger.setLevel(Flevel)
if not self.logger.handlers:
fmt = logging.Formatter('[%(asctime)s] [%(levelname)s] %(message)s', '%Y-%m-%d %H:%M:%S')
fh = logging.FileHandler(self.fileName, encoding='utf-8')
fh.setFormatter(fmt)
fh.setLevel(Flevel)
self.logger.addHandler(fh)
import os
# 确保日志目录存在
os.makedirs(path, exist_ok=True)
self.time = time.strftime("%Y-%m-%d")
self.fileName = os.path.join(path, name + ".log")
# 为每个实例创建唯一的logger名称避免重复
logger_name = f"{name}_{id(self)}"
self.logger = logging.getLogger(logger_name)
self.logger.setLevel(Flevel)
# 清除已有的处理器,避免重复
self.logger.handlers.clear()
# 设置格式
fmt = logging.Formatter('[%(asctime)s] [%(levelname)s] %(message)s', '%Y-%m-%d %H:%M:%S')
# 文件处理器
fh = logging.FileHandler(self.fileName, encoding='utf-8')
fh.setFormatter(fmt)
fh.setLevel(Flevel)
self.logger.addHandler(fh)
# 控制台处理器
ch = logging.StreamHandler()
ch.setFormatter(fmt)
ch.setLevel(logging.INFO)
self.logger.addHandler(ch)
@output
def debug(self, message):
"""
This is debug
"""
self.logger.debug(message)
@output
def info(self, message):
"""
This is info
"""
self.logger.info(message)
@output
def warn(self, message):
"""
This is warn
"""
self.logger.warn(message)
self.logger.warning(message)
@output
def error(self, message):
"""
This is error
"""
self.logger.error(message)
@output
def critical(self, message):
"""
This is critical