695 lines
24 KiB
Python
695 lines
24 KiB
Python
|
# -*- coding: utf-8 -*-
|
||
|
"""
|
||
|
Created on Fri Aug 5 15:29:12 2022
|
||
|
|
||
|
@author: MINGL
|
||
|
"""
|
||
|
import numpy as np
|
||
|
import pandas as pd
|
||
|
import pyautogui
|
||
|
import pywinauto
|
||
|
from pywinauto import clipboard
|
||
|
from pywinauto import keyboard
|
||
|
from skimage import io
|
||
|
import time
|
||
|
import io as mio
|
||
|
import pytesseract
|
||
|
import warnings
|
||
|
import datetime
|
||
|
from config import ssid,password
|
||
|
from tools import *
|
||
|
|
||
|
warnings.filterwarnings('ignore')
|
||
|
scripts_path = os.path.dirname(os.path.realpath(__file__))
|
||
|
root_path = scripts_path[:scripts_path.find(project_name)+len(project_name)]
|
||
|
|
||
|
path = r'C:\trade_software\双子星金融终端独立交易-中国银河证券\xiadan.exe'
|
||
|
engine = create_engine(
|
||
|
'mysql+pymysql://cn_ainvest_db:cn_ainvest_sd3a1@rm-2zewagytttzk6f24xno.mysql.rds.aliyuncs.com:3306/',
|
||
|
encoding="utf-8", echo=False)
|
||
|
|
||
|
class YHClientTrader:
|
||
|
"""
|
||
|
基于同花顺委托下单程序的"平安证券客户端"自动交易程序
|
||
|
"""
|
||
|
|
||
|
def __init__(self, account_name, exe_path=path):
|
||
|
self.path = exe_path
|
||
|
self.account_name = account_name
|
||
|
self.log = Logger(f'{root_path}/logs',self.account_name)
|
||
|
# 用户券商信息
|
||
|
sql = f"select * from ainvest_usercount where username='{account_name}'"
|
||
|
df_count = download_data_from_db(sql, 'ai_strategy_update_iddb')
|
||
|
self.securities_name = str(df_count['securities_username'].tolist()[0])
|
||
|
self.securities_password = str(df_count['securities_password'].tolist()[0])
|
||
|
self.communication_password = str(df_count['communication_password'].tolist()[0])
|
||
|
|
||
|
def exit(self):
|
||
|
'''
|
||
|
结束进程
|
||
|
|
||
|
Returns
|
||
|
-------
|
||
|
None.
|
||
|
|
||
|
'''
|
||
|
self._app.kill()
|
||
|
def _close_prompt_windows(self):
|
||
|
time.sleep(0.1)
|
||
|
for window in self._app.windows(class_name="#32770"):
|
||
|
if window.window_text() != '网上股票交易系统*':
|
||
|
window.close()
|
||
|
time.sleep(0.1)
|
||
|
def login(self):
|
||
|
'''
|
||
|
启动软件并登录
|
||
|
|
||
|
Returns
|
||
|
-------
|
||
|
None.
|
||
|
|
||
|
'''
|
||
|
#软件启动判断,若有进行中进程,先关闭再重启
|
||
|
try:
|
||
|
self._app = pywinauto.Application().connect(
|
||
|
path=self.path, timeout=1
|
||
|
)
|
||
|
self.exit()
|
||
|
self.log.warn('There are running programs, and there are processes in retreat')
|
||
|
except Exception:
|
||
|
pass
|
||
|
|
||
|
#启动软件进程,输入账号密码
|
||
|
self.log.info('Start login')
|
||
|
|
||
|
# 重置mac并尝试连接WiFi
|
||
|
set_mac = SetMac()
|
||
|
set_mac.run()
|
||
|
connect_wifi(ssid, password)
|
||
|
|
||
|
# 获取动态IP
|
||
|
new_mac = set_mac.get_macinfos()
|
||
|
broker = '银河证券'
|
||
|
proxy_ip,proxy_port = get_proxy_ip(broker,new_mac,self.account_name)
|
||
|
|
||
|
# 设置全局代理
|
||
|
set_proxy(proxy_ip, proxy_port)
|
||
|
self.log.info('全局代理设置成功')
|
||
|
|
||
|
|
||
|
self._app = pywinauto.Application().start(self.path)
|
||
|
while True:
|
||
|
try:
|
||
|
self._app.window(title_re='用户登录.*').wait("ready")
|
||
|
break
|
||
|
except RuntimeError:
|
||
|
pass
|
||
|
self._app.window(title_re='用户登录.*').window(control_id=0x3E9, class_name='Edit').type_keys(self.securities_name)
|
||
|
time.sleep(0.1)
|
||
|
self._app.window(title_re='用户登录.*').window(control_id=0x3F4, class_name='Edit').type_keys(self.securities_password)
|
||
|
time.sleep(0.1)
|
||
|
|
||
|
# 验证码登录
|
||
|
while True:
|
||
|
#获取id_code
|
||
|
id_code = self.verify_code(0x5DB)
|
||
|
time.sleep(0.2)
|
||
|
self._app.top_window().Edit3.type_keys('{BACKSPACE}' * 6)
|
||
|
time.sleep(0.2)
|
||
|
self._app.top_window().Edit3.type_keys(id_code)
|
||
|
time.sleep(0.2)
|
||
|
pywinauto.keyboard.send_keys("{ENTER}")
|
||
|
time.sleep(0.5)
|
||
|
try:
|
||
|
self._app.top_window().set_focus()
|
||
|
result_idcode = self._app.top_window().window(control_id=0x3EC, class_name='Static').window_text()
|
||
|
self.log.softInfo(result_idcode)
|
||
|
if '验证码错误' in result_idcode:
|
||
|
self.log.warn('Verification code error')
|
||
|
self._app.top_window().window(control_id=0x2, class_name="Button").click()
|
||
|
time.sleep(0.5)
|
||
|
else:
|
||
|
break
|
||
|
except Exception:
|
||
|
break
|
||
|
|
||
|
# time.sleep(2)
|
||
|
# while True:
|
||
|
# try:
|
||
|
# self._app.window(title_re='网上股票交易系统.*').wait("ready")
|
||
|
# break
|
||
|
# except RuntimeError:
|
||
|
# pass
|
||
|
tryrun(self._app.window(title_re='网上股票交易系统.*').wait("ready"))
|
||
|
#关闭弹窗
|
||
|
# for i in range(3):
|
||
|
# self._turn_off_advertising()
|
||
|
self._close_prompt_windows()
|
||
|
#设置主窗口及菜单窗口
|
||
|
self.main_wnd = self._app.window(title='网上股票交易系统5.0')
|
||
|
self.left_wnd = self.main_wnd.window(class_name='SysTreeView32', control_id=0x81)
|
||
|
|
||
|
def _turn_off_advertising(self):
|
||
|
'''
|
||
|
关闭弹窗
|
||
|
|
||
|
Returns
|
||
|
-------
|
||
|
None.
|
||
|
|
||
|
'''
|
||
|
try:
|
||
|
self._app.top_window().set_focus()
|
||
|
time.sleep(0.5)
|
||
|
pywinauto.keyboard.send_keys("{ESC}")
|
||
|
pywinauto.keyboard.send_keys("{ENTER}")
|
||
|
pywinauto.keyboard.send_keys("{ESC}")
|
||
|
except Exception as e:
|
||
|
pass
|
||
|
|
||
|
def verify_code(self,control_id):
|
||
|
'''
|
||
|
获取登录验证码
|
||
|
|
||
|
Returns
|
||
|
-------
|
||
|
id_code : TYPE
|
||
|
DESCRIPTION.
|
||
|
|
||
|
'''
|
||
|
time.sleep(0.5)
|
||
|
self._app.top_window().Static.click()
|
||
|
time.sleep(0.2)
|
||
|
self._app.top_window().window(control_id=control_id, class_name='Static').capture_as_image().save(
|
||
|
f'{root_path}/imgs/temp.png')
|
||
|
time.sleep(0.2)
|
||
|
im = io.imread(f'{root_path}/imgs/temp.png')
|
||
|
id_code = pytesseract.image_to_string(im, lang='eng',
|
||
|
config='--psm 6 --oem 3 -c tessedit_char_whitelist=0123456789').strip()
|
||
|
id_code = id_code.replace(' ', '')
|
||
|
return id_code
|
||
|
|
||
|
def buy(self, stock_no, price, num):
|
||
|
'''
|
||
|
买入股票
|
||
|
|
||
|
Parameters
|
||
|
----------
|
||
|
stock_no : TYPE
|
||
|
DESCRIPTION.
|
||
|
price : TYPE
|
||
|
DESCRIPTION.
|
||
|
num : TYPE
|
||
|
DESCRIPTION.
|
||
|
|
||
|
Returns
|
||
|
-------
|
||
|
None.
|
||
|
|
||
|
'''
|
||
|
self.left_wnd.select(['买入[F1]'])
|
||
|
self.__trade(stock_no, price, num)
|
||
|
|
||
|
def sell(self, stock_no, price, num):
|
||
|
'''
|
||
|
卖出股票
|
||
|
|
||
|
Parameters
|
||
|
----------
|
||
|
stock_no : TYPE
|
||
|
DESCRIPTION.
|
||
|
price : TYPE
|
||
|
DESCRIPTION.
|
||
|
num : TYPE
|
||
|
DESCRIPTION.
|
||
|
|
||
|
Returns
|
||
|
-------
|
||
|
None.
|
||
|
|
||
|
'''
|
||
|
self.left_wnd.select(['卖出[F2]'])
|
||
|
self.__trade(stock_no, price, num)
|
||
|
|
||
|
def get_cancel_entrust(self, ticker):
|
||
|
'''
|
||
|
按股票撤单
|
||
|
|
||
|
Parameters
|
||
|
----------
|
||
|
ticker : TYPE
|
||
|
DESCRIPTION.
|
||
|
|
||
|
Returns
|
||
|
-------
|
||
|
None.
|
||
|
|
||
|
'''
|
||
|
self.left_wnd.select(['撤单[F3]'])
|
||
|
|
||
|
time.sleep(1)
|
||
|
# 删除框内ticker
|
||
|
self.main_wnd.window(control_id=0xD14, class_name='Edit').click()
|
||
|
for i in range(7):
|
||
|
pywinauto.keyboard.send_keys("{DELETE}")
|
||
|
|
||
|
# 输入ticker
|
||
|
self.main_wnd.window(control_id=0xD14, class_name='Edit').type_keys(ticker)
|
||
|
time.sleep(0.2)
|
||
|
# 选中ticker
|
||
|
pywinauto.keyboard.send_keys("{ENTER}")
|
||
|
time.sleep(0.1)
|
||
|
# 点击撤单
|
||
|
self.main_wnd.window(control_id=0x44B, class_name='Button').click()
|
||
|
time.sleep(0.1)
|
||
|
# 确认撤单
|
||
|
pywinauto.keyboard.send_keys("{ENTER}")
|
||
|
time.sleep(0.2)
|
||
|
|
||
|
#获取弹窗信息
|
||
|
result = self._app.top_window().window(control_id=0x3EC, class_name='Static').window_text()
|
||
|
self.log.info(result)
|
||
|
pywinauto.keyboard.send_keys("{ENTER}")
|
||
|
time.sleep(0.2)
|
||
|
pywinauto.keyboard.send_keys("{ESC}")
|
||
|
|
||
|
def cancel_entrust(self):
|
||
|
'''
|
||
|
全撤
|
||
|
|
||
|
Returns
|
||
|
-------
|
||
|
None.
|
||
|
|
||
|
'''
|
||
|
# # 进入撤单页面
|
||
|
self.left_wnd.select(['撤单[F3]'])
|
||
|
|
||
|
time.sleep(1)
|
||
|
# 一键全撤
|
||
|
self.main_wnd.window(control_id=0x7531, class_name='Button').click()
|
||
|
self._app.top_window().set_focus()
|
||
|
self.main_wnd.window(control_id=0x44B, class_name='Button').click()
|
||
|
time.sleep(1)
|
||
|
pywinauto.keyboard.send_keys("{ENTER}")
|
||
|
time.sleep(0.5)
|
||
|
pywinauto.keyboard.send_keys("{ENTER}")
|
||
|
|
||
|
def get_unsettled_trades(self):
|
||
|
'''
|
||
|
获取未成交单
|
||
|
|
||
|
Returns
|
||
|
-------
|
||
|
one_df : TYPE
|
||
|
DESCRIPTION.
|
||
|
|
||
|
'''
|
||
|
self.left_wnd.select(['撤单[F3]'])
|
||
|
|
||
|
self._copy_data()
|
||
|
one_df =self._data_to_df()
|
||
|
if len(one_df) == 0:
|
||
|
pass
|
||
|
else:
|
||
|
one_df['证券代码'] = one_df['证券代码'].apply(lambda x: tranTicker(x.strip('=').strip('"')))
|
||
|
return one_df
|
||
|
def _output_data(self):
|
||
|
self._app.top_window().set_focus()
|
||
|
time.sleep(1)
|
||
|
pywinauto.keyboard.send_keys('^S')
|
||
|
time.sleep(1)
|
||
|
self._app.top_window().set_focus()
|
||
|
time.sleep(1)
|
||
|
self._app.top_window().set_focus()
|
||
|
|
||
|
time.sleep(2)
|
||
|
self._app.window(title_re='另存为').window(control_id=0x480, class_name='Edit', found_index=0).type_keys(
|
||
|
str(datetime.date.today()).replace("-", "") + self.account_name)
|
||
|
self._app.window(title_re='另存为').window(control_id=0x1, class_name='Button', found_index=0).click()
|
||
|
try:
|
||
|
self._app['确认另存为'].window(control_id=0x0, class_name='#32770').click()
|
||
|
except:
|
||
|
pass
|
||
|
filenme = f'C:\\Users\\Administrator\\Documents\\{str(datetime.date.today()).replace("-", "")}{self.account_name}.xls'
|
||
|
# 读文件
|
||
|
df = pd.read_csv(filenme, encoding='gbk', sep='\t', engine='python', error_bad_lines=False)
|
||
|
os.remove(filenme)
|
||
|
return df
|
||
|
def get_balance(self):
|
||
|
'''
|
||
|
获取资金情况
|
||
|
|
||
|
Returns
|
||
|
-------
|
||
|
record : TYPE
|
||
|
DESCRIPTION.
|
||
|
|
||
|
'''
|
||
|
self.left_wnd.select(['查询[F4]','资金股票'])
|
||
|
self.main_wnd.window(control_id=0x51C, class_name='CVirtualGridCtrl').click()
|
||
|
time.sleep(1)
|
||
|
result = self._output_data()
|
||
|
|
||
|
result = result[['总市值', '可用金额', '总资产']]
|
||
|
result['Position_amount'] = float(result['总市值'].values[0])
|
||
|
result['Cash'] = float(result['可用金额'].values[0])
|
||
|
result['Total_account'] = float(result['总资产'].values[0])
|
||
|
df_every_money = pd.DataFrame(result, index=[0])
|
||
|
del df_every_money['总市值']
|
||
|
del df_every_money['可用金额']
|
||
|
del df_every_money['总资产']
|
||
|
df_every_money['Account_Name'] = self.account_name
|
||
|
import datetime
|
||
|
df_every_money['As_Of_Date'] = datetime.date.today()
|
||
|
return df_every_money
|
||
|
|
||
|
def get_position(self):
|
||
|
'''
|
||
|
获取持仓情况
|
||
|
|
||
|
Returns
|
||
|
-------
|
||
|
df_position : TYPE
|
||
|
DESCRIPTION.
|
||
|
|
||
|
'''
|
||
|
self.left_wnd.select(['查询[F4]', '资金全景'])
|
||
|
self.left_wnd.select(['查询[F4]','资金股票'])
|
||
|
# 复制表格数据
|
||
|
time.sleep(5)
|
||
|
self.main_wnd.window(control_id=0xC8, class_name="AfxWnd42s",found_index = 0).click()
|
||
|
self._app.top_window().set_focus()
|
||
|
time.sleep(1)
|
||
|
df_position = self._output_data()
|
||
|
|
||
|
# print(df_position)
|
||
|
# 处理self.df_position格式
|
||
|
del (df_position['交易市场'])
|
||
|
del (df_position['股东代码'])
|
||
|
del (df_position['当前持仓'])
|
||
|
del (df_position['股份余额'])
|
||
|
del (df_position['Unnamed: 17'])
|
||
|
del (df_position['证券中文全称'])
|
||
|
del (df_position['币种'])
|
||
|
df_position["冻结数量"] = df_position['买入冻结'] + df_position['卖出冻结']
|
||
|
df_position.rename(columns={"证券代码": "Ticker",
|
||
|
"证券名称": "Ticker_name",
|
||
|
"股份实时余额": "Number_transactions",
|
||
|
"可用余额": "cash",
|
||
|
"冻结数量": "frozen_quantity",
|
||
|
"参考成本价": "cost_price",
|
||
|
"参考市价": "market_price",
|
||
|
"参考市值": "market_value",
|
||
|
"参考盈亏": "profit_and_loss",
|
||
|
"盈亏比例(%)": "profit_loss_ratio",
|
||
|
}, inplace=True)
|
||
|
del (df_position['买入冻结'])
|
||
|
del (df_position['卖出冻结'])
|
||
|
df_position['Ticker'] = df_position['Ticker'].apply(lambda x: tranTicker(x))
|
||
|
# print(df_position)
|
||
|
return df_position
|
||
|
|
||
|
def get_order(self):
|
||
|
'''
|
||
|
获取委托情况
|
||
|
|
||
|
Returns
|
||
|
-------
|
||
|
TYPE
|
||
|
DESCRIPTION.
|
||
|
|
||
|
'''
|
||
|
self.left_wnd.select(['查询[F4]','当日委托'])
|
||
|
self._copy_data()
|
||
|
|
||
|
return self._data_to_df()
|
||
|
|
||
|
def get_today_trades(self):
|
||
|
'''
|
||
|
获取当日成交
|
||
|
|
||
|
Returns
|
||
|
-------
|
||
|
TYPE
|
||
|
DESCRIPTION.
|
||
|
|
||
|
'''
|
||
|
self.left_wnd.select(['查询[F4]','当日成交'])
|
||
|
time.sleep(1)
|
||
|
self.main_wnd.window(control_id=0x417, class_name="CVirtualGridCtrl").click()
|
||
|
df = self._output_data()
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
if len(df) == 0:
|
||
|
print('无当日成交---------------------')
|
||
|
return []
|
||
|
# return False
|
||
|
else:
|
||
|
# 通过展示所有字段,摘取所需字段
|
||
|
df = df[['成交时间', '证券代码', '证券名称', '操作', '成交数量', '成交均价']]
|
||
|
df['Account_Name'] = self.account_name
|
||
|
df['As_Of_Date'] = datetime.date.today()
|
||
|
df.rename(columns={'成交时间': 'Trade_time', '证券代码': 'Ticker', '证券名称': 'Ticker_name',
|
||
|
'操作': 'Operate',
|
||
|
'成交数量': 'Number_transactions',
|
||
|
'成交均价': 'Average_price'}, inplace=True)
|
||
|
df['Operate'] = df['Operate'].apply(lambda x: '卖' if '卖' in x else '买')
|
||
|
|
||
|
df['Ticker'] = df['Ticker'].apply(lambda x: tranTicker(str(x).replace('="', '').replace('"', '')))
|
||
|
return df
|
||
|
def cash_in_out(self):
|
||
|
engine = create_engine(
|
||
|
'mysql+pymysql://cn_ainvest_db:cn_ainvest_sd3a1@rm-2zewagytttzk6f24xno.mysql.rds.aliyuncs.com:3306/',
|
||
|
encoding="utf-8", echo=False)
|
||
|
self.left_wnd.select(['银证转账', '流 水 账'])
|
||
|
today = datetime.date.today()
|
||
|
# today = datetime.date(2025,1,27)
|
||
|
trade_date_list = pd.read_sql(fr'select As_Of_Date from ai_strategy.trade_days where As_Of_Date < "{today}"',engine)['As_Of_Date'].to_list()
|
||
|
if today + datetime.timedelta(days=-1) in trade_date_list:
|
||
|
pass
|
||
|
else:
|
||
|
date = trade_date_list[-1:][0]+datetime.timedelta(days=1)
|
||
|
print(date)
|
||
|
time.sleep(1)
|
||
|
pyautogui.click(567, 279)
|
||
|
pyautogui.write(str(date.year))
|
||
|
pyautogui.click(594, 278)
|
||
|
pyautogui.write(str(date.month))
|
||
|
pyautogui.click(610, 279)
|
||
|
pyautogui.write(str(date.day))
|
||
|
self.main_wnd.window(control_id=0x3EE, class_name="Button").click()
|
||
|
|
||
|
time.sleep(1)
|
||
|
self.main_wnd.window(control_id=0x417, class_name="CVirtualGridCtrl").click()
|
||
|
# self.main_wnd.window(control_id=0xC8, class_name="AfxWnd140s",found_index = 0).click()
|
||
|
df = self._output_data()
|
||
|
if len(df) == 0:
|
||
|
self.log.info('--------------------------------------无存取款--------------------------------------')
|
||
|
return pd.DataFrame()
|
||
|
else:
|
||
|
df_new = df[['日期','发生金额','操作','备注']]
|
||
|
df_new = df_new[(df_new['发生金额'] !=0)&(df_new['备注'] =='交易成功')]
|
||
|
print(df_new)
|
||
|
df_new.columns = df_new.columns.str.strip()
|
||
|
|
||
|
df_new_rename = df_new.rename(columns = {'发生金额':'Deposit_Withdraw','日期':'As_Of_Date'})[['As_Of_Date','Deposit_Withdraw']]
|
||
|
df_new_rename['Account_name'] = self.account_name
|
||
|
return df_new_rename
|
||
|
def __trade(self, stock_no, price, amount):
|
||
|
'''
|
||
|
交易输入函数
|
||
|
|
||
|
Parameters
|
||
|
----------
|
||
|
stock_no : TYPE
|
||
|
DESCRIPTION.
|
||
|
price : TYPE
|
||
|
DESCRIPTION.
|
||
|
amount : TYPE
|
||
|
DESCRIPTION.
|
||
|
|
||
|
Returns
|
||
|
-------
|
||
|
None.
|
||
|
|
||
|
'''
|
||
|
time.sleep(0.2)
|
||
|
|
||
|
# 设置股票代码
|
||
|
self.main_wnd.window(control_id=0x408, class_name="Edit").click()
|
||
|
self.main_wnd.window(control_id=0x408, class_name="Edit").set_text(str(stock_no))
|
||
|
time.sleep(0.5)
|
||
|
|
||
|
# 设置价格
|
||
|
self.main_wnd.window(control_id=0x409, class_name="Edit").set_text(str(price))
|
||
|
time.sleep(0.5)
|
||
|
|
||
|
# 设置股数目
|
||
|
self.main_wnd.window(control_id=0x40A, class_name="Edit").set_text(str(amount))
|
||
|
time.sleep(0.5)
|
||
|
|
||
|
# 点击卖出or买入
|
||
|
self.main_wnd.window(control_id=0x3EE, class_name="Button").click()
|
||
|
time.sleep(1)
|
||
|
|
||
|
#获取弹窗返回的信息
|
||
|
self._app.top_window().set_focus()
|
||
|
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._app.top_window().window(control_id=0x7, class_name='Button').click()
|
||
|
# 保留两位小数截断
|
||
|
price = str(price)[:-1]
|
||
|
# 重新设置价格
|
||
|
self.main_wnd.window(control_id=0x409, class_name="Edit").set_text(str(price))
|
||
|
time.sleep(0.5)
|
||
|
# 点击卖出or买入
|
||
|
self.main_wnd.window(control_id=0x3EE, class_name="Button").click()
|
||
|
time.sleep(1)
|
||
|
self._app.top_window().set_focus()
|
||
|
one_text = self._app.top_window().window(control_id=0x410, class_name='Static').window_text()
|
||
|
else:
|
||
|
# 摘取合同信息
|
||
|
self.log.info(one_text.replace('/n',' '))
|
||
|
time.sleep(0.2)
|
||
|
|
||
|
# 确认买入
|
||
|
pywinauto.keyboard.send_keys("{ENTER}")
|
||
|
time.sleep(0.5)
|
||
|
|
||
|
# 摘取合同信息2
|
||
|
one_text2 = self._app.top_window().window(control_id=0x3EC, class_name='Static').window_text()
|
||
|
self.log.info(one_text2.replace('/n', ' '))
|
||
|
|
||
|
# 确认合同
|
||
|
pywinauto.keyboard.send_keys("{ENTER}")
|
||
|
time.sleep(0.5)
|
||
|
|
||
|
def _copy_data(self):
|
||
|
'''
|
||
|
拷贝数据函数
|
||
|
|
||
|
Returns
|
||
|
-------
|
||
|
None.
|
||
|
|
||
|
'''
|
||
|
while True:
|
||
|
keyboard.send_keys('^C')
|
||
|
# 获取验证码
|
||
|
id_code = self.verify_code(0x965)
|
||
|
time.sleep(0.2)
|
||
|
self._app.top_window().Edit3.type_keys('{BACKSPACE}' * 6)
|
||
|
time.sleep(0.2)
|
||
|
self._app.top_window().Edit3.type_keys(id_code)
|
||
|
time.sleep(0.2)
|
||
|
pywinauto.keyboard.send_keys("{ENTER}")
|
||
|
time.sleep(0.5)
|
||
|
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)
|
||
|
if '验证码错误' in result_idcode:
|
||
|
self.log.warn('Verification code error')
|
||
|
self._app.top_window().window(control_id=0x2, class_name="Button").click()
|
||
|
time.sleep(0.5)
|
||
|
else:
|
||
|
break
|
||
|
except Exception:
|
||
|
break
|
||
|
|
||
|
def _data_to_df(self):
|
||
|
'''
|
||
|
剪切板转dataframe
|
||
|
|
||
|
Returns
|
||
|
-------
|
||
|
TYPE
|
||
|
DESCRIPTION.
|
||
|
|
||
|
'''
|
||
|
data_table = clipboard.GetData()
|
||
|
df_table = pd.read_csv(mio.StringIO(data_table), delimiter='\t', na_filter=False)
|
||
|
table_dict = df_table.to_dict('records')
|
||
|
if len(table_dict) == 0:
|
||
|
return pd.DataFrame()
|
||
|
else:
|
||
|
data = []
|
||
|
for i in table_dict:
|
||
|
data.append(pd.DataFrame.from_dict(i, orient='index').T)
|
||
|
return pd.concat(data, ignore_index=True)
|
||
|
|
||
|
def subscribe_stock(self):
|
||
|
# 申购新股
|
||
|
self.left_wnd.select(['申购', '一键打新'])
|
||
|
time.sleep(0.5)
|
||
|
# self.main_wnd.window(class_name='#32770', control_id=0xE901).window(control_id=0x44A,
|
||
|
# class_name='Button').click()
|
||
|
time.sleep(1)
|
||
|
self.main_wnd.window(class_name='#32770', control_id=0xE901).window(control_id=0x3EE,
|
||
|
class_name='Button').click()
|
||
|
|
||
|
one_text = self._app.window(class_name='#32770', control_id=0x0).window(control_id=0x410,
|
||
|
class_name='Static').window_text()
|
||
|
print(one_text)
|
||
|
self._app.window(class_name='#32770', control_id=0x0).window(control_id=0x6, class_name='Button').click()
|
||
|
one_text = self._app.window(class_name='#32770', control_id=0x0).window(control_id=0x3EC,
|
||
|
class_name='Static').window_text()
|
||
|
print(one_text)
|
||
|
self._app.window(class_name='#32770', control_id=0x0).window(control_id=0x2, class_name='Button').click()
|
||
|
time.sleep(1)
|
||
|
# 申购新债
|
||
|
self.left_wnd.select(['申购', '可转债及可交换债申购'])
|
||
|
self.main_wnd.window(control_id=0x418, class_name="CVirtualGridCtrl").click()
|
||
|
ticker_list = self._output_data()
|
||
|
print(ticker_list)
|
||
|
if ticker_list.empty:
|
||
|
print('无新债')
|
||
|
pass
|
||
|
else:
|
||
|
ticker_list['证券代码'] = ticker_list['证券代码'].apply(lambda x: x.replace('="', ''))
|
||
|
ticker_list['证券代码'] = ticker_list['证券代码'].apply(lambda x: x.replace('"', ''))
|
||
|
ticker_list_new = ticker_list['证券代码'].to_list()
|
||
|
for ticker in ticker_list_new:
|
||
|
# 设置股票代码
|
||
|
self.main_wnd.window(control_id=0x408, class_name="Edit").click()
|
||
|
self.main_wnd.window(control_id=0x408, class_name="Edit").set_text(str(ticker))
|
||
|
time.sleep(0.5)
|
||
|
# 设置股数目
|
||
|
self.main_wnd.window(control_id=0x3FA, class_name="Static").click()
|
||
|
time.sleep(0.5)
|
||
|
# 点击申购
|
||
|
self.main_wnd.window(control_id=0x3EE, class_name="Button").click()
|
||
|
time.sleep(1)
|
||
|
one_text = self._app.window(class_name='#32770', control_id=0x0).window(control_id=0x3EC,
|
||
|
class_name='Static').window_text()
|
||
|
print(one_text)
|
||
|
self._app.window(class_name='#32770', control_id=0x0).window(control_id=0x2,
|
||
|
class_name='Button').click()
|
||
|
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
|
||
|
account_name = str('15975655656')
|
||
|
a = YHClientTrader(account_name)
|
||
|
a.login()
|
||
|
# a.subscribe_stock()
|
||
|
# 买入
|
||
|
# a.buy('600000', '7','100')
|
||
|
|
||
|
# 卖出
|
||
|
# a.sell('600835', '12.45','900')
|
||
|
# 获取资金情况
|
||
|
# print(a.get_balance())
|
||
|
# 获取当日实际持仓
|
||
|
# print(a.get_position())
|
||
|
|
||
|
# 获取当日成交
|
||
|
# print(a.get_today_trades())
|
||
|
# print(a.cash_in_out())
|