zhitou_trade/autobasic/hy_clienttrader.py
2025-05-22 16:47:45 +08:00

887 lines
32 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@Time : 2020-03-26 16:17
@Author : Zdanjuan
@Site :
@File : hy_clienttrader.py
@Software: PyCharm
"""
import pywinauto
from pywinauto import clipboard
from pywinauto import keyboard
import pandas as pd
from skimage import io
import time
import io as mio
import win32api
import re
import requests
from PIL import Image
import win32com.client
import getpass
import pytesseract
import warnings
import pyautogui
import datetime
from sqlalchemy import create_engine
from tools import *
from connect_wifi import connect_wifi
from iptest import get_proxy_ip,set_global_proxy,get_ip_data
warnings.filterwarnings('ignore')
pc_name111 = getpass.getuser() #返回用户名
shell = win32com.client.Dispatch("WScript.Shell") #使用启动独立的进程
shortcut = shell.CreateShortCut(f"C:\\Users\\{pc_name111}\\Desktop\\申万宏源同花顺专业版.lnk")
path1 = shortcut.Targetpath
path = path1
scripts_path = os.path.dirname(os.path.realpath(__file__))
root_path = scripts_path[:scripts_path.find(project_name)+len(project_name)]
class HYClientTrader:
"""
基于同花顺委托下单程序的"宏源客户端"自动交易程序
"""
def __init__(self, account_name, exe_path=path):
self.log = Logger(f'{root_path}/logs',self.account_name)
self.path = exe_path
self.BALANCE_CONTROL_ID_GROUP = {
# "资金余额": 0x3F4,
"可用金额": 0x3f8,
# "可取金额": 0x3f9,
"股票市值": 0x3f6,
"总资产": 0x3f7,
}
self.trade_control_id_group = {
's1': 0x3FD, 's2': 0x3FE, 's3': 0x3FF, 's4': 0x409, 's5': 0x408,
'b1': 0x3FA, 'b2': 0x401, 'b3': 0x402, 'b4': 0x40B, 'b5': 0x40C,
}
self.BALANCE_MENU_PATH = ["查询[F4]", "资金股票"]
self.today = datetime.datetime.today().strftime('%Y-%m-%d')
self.account_name = account_name
self.table_df = []
# self.is_bond = is_bond # 0:股票 1债券
self.is_buy = 1
self.verify_code_wrong = 0
self.position = {'当日成交':(106,348),'中心':(333,333)}
# 获取债券列表
engine_iddb = create_engine(
'mysql+pymysql://cn_ainvest_db:cn_ainvest_sd3a1@rm-2zewagytttzk6f24xno.mysql.rds.aliyuncs.com:3306/iddb')
df_bond = pd.read_sql(f'select * from conbond_basic_info', engine_iddb)
self.df_list = df_bond.drop_duplicates('Bond_Ticker')['Bond_Ticker'].values.tolist()
# 用户券商信息
sql = f"select * from ainvest_usercount where username='{account_name}'"
df_count = self.download_data_from_db(sql, 'ai_strategy_update_iddb')
self.securities_name = str(list(df_count['securities_username'])[0])
self.securities_password = str(list(df_count['securities_password'])[0])
self.communication_password = str(list(df_count['communication_password'])[0])
# 转换股票代码
def tranTicker(self, x):
x = str(x)
if len(x) == 8:
pass
else:
if len(x) == 6:
if x.startswith('6'):
x = 'SH' + x
else:
x = 'SZ' + x
else:
num = 6 - len(x)
x = 'SZ' + num * '0' + x
return x
# 从数据库获取数据
def download_data_from_db(self, sql, schema_name):
"""
create connection with DB
阿里云数据库连接
:param sql: 查询语句
:param schema_name: 数据库名称
:return: 查询结果数据
"""
cnx = create_engine(
'mysql+pymysql://cn_ainvest_db:cn_ainvest_sd3a1@rm-2zewagytttzk6f24xno.'
'mysql.rds.aliyuncs.com:3306/%s?charset=utf8' %
schema_name, encoding="utf-8", echo=False)
df = pd.read_sql(sql, con=cnx)
return df
def get_open_price(self, tick):
str_ticker = tick.lower()
price_all = requests.get('http://hq.sinajs.cn/list=' + str_ticker).text
price_ticker = str(re.findall(r'var hq_str_(.*?);', price_all))
# 开盘价
open_price = float(price_ticker.split(',')[1])
# 昨日收盘价
price_pre_close = float(price_ticker.split(',')[2])
# 实时股价
price_real_time = float(price_ticker.split(',')[3])
return open_price
def exit(self):
self._app.kill()
def login(self):
try:
self._app = pywinauto.Application().connect(
path=self.path, timeout=1
)
# print('连接成功')
a.exit()
except Exception:
pass
# wait login window ready
# while True:
# try:
# self._app.top_window().Edit1.wait("ready")
# break
# except RuntimeError:
# pass
broker = '申万宏源'
start_time = time.time()
reset_proxy_to_default() # 初始化proxy信息
# 重置mac
set_mac = SetMac()
set_mac.run()
if not connect_wifi('ZTE_A5DB9D', '1234567890'): # 'Redmi K40','123456789'
self.log.error("无法建立网络连接,请检查配置")
else:
self.log.info("网络已就绪")
get_ip_times = 0
writer = ExcelDataWriter() # 初始化ip_records 表格
used_ip = writer.get_unavailable_ips(broker, account_name)
while get_ip_times < 3:
try:
item = get_ip_data() # 获取动态IP
if item['ip'] in used_ip:
get_ip_times += 1
else:
self.log.info(f'代理IP已经获取{item}')
break
except Exception as e:
self.log.error(f'获取IP失败请检查网络连接{e}')
time.sleep(5)
# raise ConnectionError(f"获取IP失败请检查网络连接。错误详情: {e}")
# 设置全局代理
proxy_ip = item['ip']
proxy_port = item['port']
set_global_proxy(proxy_ip, proxy_port, enable=True)
# exit_ip = get_proxy_ip(proxy_ip,proxy_port)
time_with_change_proxy = time.time() - start_time
self.log.info('全局代理设置成功')
insert_data = {'as_of_date': datetime.datetime.fromtimestamp(start_time).strftime('%Y-%m-%d %H:%M:%S.%f'),
'broker': broker,
'account': account_name,
'proxy_ip': proxy_ip,
'proxy_port': proxy_port,
'ip_location': item['prov'] + ':' + item['city'],
# 'exit_ip': exit_ip,
'ip_cross_check_result': '一致',
'ip_switch_time': time_with_change_proxy,
# 'ip_expire_time':item['expire']
'ip_survival_time': '3min'
}
# 写入数据表
writer = ExcelDataWriter() # 初始化ip_records 表格
writer.write_data(insert_data)
self._app = pywinauto.Application().start(self.path)
time.sleep(0.1)
self._app.top_window().Edit1.type_keys(self.securities_name)
time.sleep(0.1)
self._app.top_window().Edit2.type_keys(self.securities_password)
time.sleep(0.1)
# while True:
time.sleep(1)
self._app.top_window().set_focus()
self._app.top_window().Edit1.wait("ready")
# 输入验证码
id_code = self.verify_code()
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()
if '验证码错误' in result_idcode:
self._app.top_window().window(control_id=0x2, class_name="Button").click()
time.sleep(0.5)
# 重新获取id_code
id_code = self.verify_code()
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)
except Exception as e:
pass
time.sleep(2)
self.main_wnd = self._app.window(title='网上股票交易系统5.0')
# self.main_wnd = self._app.top_window()
# 关闭广告
try:
self._app.top_window().set_focus()
time.sleep(0.5)
pywinauto.keyboard.send_keys("{ENTER}")
time.sleep(0.2)
pywinauto.keyboard.send_keys("{ENTER}")
except Exception as e:
pass
time.sleep(0.5)
# 转换股票代码
def tranTicker(self, x):
x = str(x)
if len(x) == 8:
pass
else:
if len(x) == 6:
if x.startswith('6'):
x = 'SH' + x
else:
x = 'SZ' + x
else:
num = 6 - len(x)
x = 'SZ' + num * '0' + x
return x
# 窗口最小化
def minimize(self):
self.main_wnd.minimize()
# 获取验证码
def verify_code(self):
time.sleep(1)
self._app.top_window().Static.click()
time.sleep(0.2)
self._app.top_window().window(control_id=0x5DB, class_name='Static').capture_as_image().save(
r'temp.png')
time.sleep(0.2)
im = io.imread(r'temp.png')
id_code = pytesseract.image_to_string(im, lang='eng',
config='--psm 6 --oem 3 -c tessedit_char_whitelist=0123456789').strip()
# id_code = pytesseract.image_to_string(Image.open('temp.png'))
id_code = id_code.replace(' ', '')
return id_code
# 复制数据时获取验证码
def get_copy_date_verify_code(self):
time.sleep(1)
self._app.top_window().Static.click()
time.sleep(0.2)
self._app.top_window().window(control_id=0x965, class_name='Static').capture_as_image().save(
r'copy.png')
time.sleep(0.2)
im = io.imread(r'copy.png')
id_code = pytesseract.image_to_string(im, lang='eng',
config='--psm 6 --oem 3 -c tessedit_char_whitelist=0123456789').strip()
# id_code = pytesseract.image_to_string(Image.open('temp.png'))
id_code = id_code.replace(' ', '')
return id_code
# 买
def buy(self, stock_no, price, num):
time.sleep(0.5)
# 点击买入
pyautogui.press('f1')
time.sleep(0.2)
pyautogui.press('f1')
self.__trade(stock_no, price, num)
def __trade(self, stock_no, price, amount):
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(2)
# # 无法判断市场类型
# try:
# self._app.top_window().set_focus()
# result_a = self._app.top_window().window(control_id=0xBBA, class_name='Static').window_text()
# result_b = self._app.top_window().window(control_id=0x7AF, class_name='Button').window_text()
# result_c = self._app.top_window().window(control_id=0x7CD, class_name='Button').window_text()
# if '该证券代码在多个市场存在,客户端无法判' in result_a:
# if ticker_name in result_b:
# self._app.top_window().window(control_id=0x7AF, class_name="Button").click()
# time.sleep(0.5)
# elif ticker_name in result_c:
# self._app.top_window().window(control_id=0x7CD, class_name="Button").click()
# time.sleep(0.5)
# except Exception as e:
# pass
if price in ['b1','b2','b3','b4','b5','s1','s2','s3','s4','s5']:
price = float(self.main_wnd.window(control_id=self.trade_control_id_group[price], class_name="Static").window_text())
# 设置价格
self.main_wnd.window(control_id=0x409, class_name="Edit").set_text(str(price))
time.sleep(0.5)
# # 判断股票还是债券(1债券)
# if self.is_bond == 1:
# # 买
# unit = self.main_wnd.window(control_id=0x579, class_name="Static").window_text()
# if unit[-2] == '股':
# amount = int(int(amount) / 10)
# # 卖
# if self.is_buy == 0:
# sell_num = int(self.main_wnd.window(control_id=0x40E, class_name="Static").window_text())
# if sell_num < int(amount):
# amount = int(int(amount) / 10)
# print('卖出数量已减少10倍')
# 设置股数目
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)
# 小数后只能填2位情况
self._app.top_window().set_focus()
result_1 = self._app.top_window().window(control_id=0x410, class_name='Static').window_text()
if result_1 == '委托价格的小数部分应为 2 位,是否继续?':
# 点击“否”
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()
result_1 = self._app.top_window().window(control_id=0x410, class_name='Static').window_text()
else:
# 摘取合同信息
self.__parse_contract(result_1)
time.sleep(0.2)
# # 摘取合同信息
# self._app.top_window().set_focus()
# result_1 = self._app.top_window().window(control_id=0x410, class_name='Static').window_text()
# self.__parse_contract(result_1)
# time.sleep(0.2)
# 确认买入
pywinauto.keyboard.send_keys("{ENTER}")
time.sleep(0.5)
# 摘取合同信息2
result_2 = self._app.top_window().window(control_id=0x3EC, class_name='Static').window_text()
print(result_2)
# 确认合同
pywinauto.keyboard.send_keys("{ENTER}")
time.sleep(0.5)
# 卖
def sell(self, stock_no, price, num):
time.sleep(0.5)
# 点击卖出
# pywinauto.keyboard.send_keys("{F2}")
pyautogui.press('f2')
time.sleep(0.5)
pyautogui.press('f2')
self.is_buy = 0
self.__trade(stock_no, price, num)
# 撤单
def get_cancel_entrust(self, ticker):
# # 进入撤单页面
# # self._app.top_window().set_focus()
# time.sleep(0.5)
# pyautogui.press('f1')
# time.sleep(0.5)
# pyautogui.press('f3')
pyautogui.press('f5')
time.sleep(1)
# 删除框内ticker
self.main_wnd.window(control_id=0x3421A0, class_name='Edit').click()
for i in range(7):
pywinauto.keyboard.send_keys("{DELETE}")
# 输入ticker
self.main_wnd.window(control_id=0x3421A0, 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()
# print(result)
pywinauto.keyboard.send_keys("{ENTER}")
time.sleep(0.2)
pywinauto.keyboard.send_keys("{ESC}")
time.sleep(1)
# 撤单
def cancel_entrust(self):
# # 进入撤单页面
# # self._app.top_window().set_focus()
# time.sleep(0.5)
# pyautogui.press('f1')
# time.sleep(0.5)
# pyautogui.press('f3')
pyautogui.press('f5')
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=0x6, class_name='Button').click()
# time.sleep(1)
# 确认买入
pywinauto.keyboard.send_keys("{ENTER}")
time.sleep(0.5)
# 获取未成交单
def get_unsettled_trades(self):
time.sleep(0.5)
pyautogui.press('f1')
time.sleep(0.5)
pyautogui.press('f3')
time.sleep(0.5)
# 刷新页面
pyautogui.press('f5')
time.sleep(0.2)
pyautogui.press('f5')
time.sleep(0.2)
# 复制表格数据
self._copy_data()
if self.verify_code_wrong == 1: # 验证码错误时将self.verify_code_wrong置1
self.get_today_trades()
self.verify_code_wrong = 0 # 验证码正确时将self.verify_code_wrong置0
self._data_to_df()
self.df_unsettled = self.df
return self.df_unsettled
# 获取当日实际持仓
def get_position(self):
"""获取资金情况"""
pyautogui.press('f1')
time.sleep(0.5)
pyautogui.press('f4')
time.sleep(0.5)
# 刷新页面
pyautogui.press('f5')
time.sleep(0.2)
pyautogui.press('f5')
time.sleep(0.2)
# 复制表格数据
self._copy_data()
if self.verify_code_wrong == 1: # 验证码错误时将self.verify_code_wrong置1
self.get_today_trades()
self.verify_code_wrong = 0 # 验证码正确时将self.verify_code_wrong置0
self._data_to_df()
self.df_position = self.df
# 处理self.df_position格式
del (self.df_position['交易市场'])
del (self.df_position['股东代码'])
del (self.df_position['成本金额'])
del (self.df_position['买入冻结'])
del (self.df_position['卖出冻结'])
del (self.df_position['在途卖出'])
del (self.df_position['在途买入'])
del (self.df_position['Unnamed: 18'])
del (self.df_position['股份余额'])
del (self.df_position['币种'])
self.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)
return self.df_position
# 获取资金情况
def get_balance(self):
"""获取资金情况"""
pyautogui.press('f1')
time.sleep(0.5)
pyautogui.press('f4')
time.sleep(0.5)
# 刷新页面
pyautogui.press('f5')
time.sleep(0.2)
pyautogui.press('f5')
time.sleep(0.2)
result = {}
for key, control_id in self.BALANCE_CONTROL_ID_GROUP.items():
result[key] = float(self.main_wnd.window(control_id=control_id, class_name="Static").window_text())
return result
# 获取左边窗口
def _get_left_handle(self):
while True:
try:
self.left_handle = self.main_wnd.window(control_id=0x81, class_name='SysTreeView32')
self.left_handle.wait('ready', 2) # sometime can't find handle ready, must retry
break
except Exception as ex:
print(ex)
pass
# 复制数据
def _copy_data(self):
# 复制表格数据
keyboard.send_keys('^C')
# 获取验证码
id_code = self.get_copy_date_verify_code()
time.sleep(0.2)
self._app.top_window().Edit.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(1)
# 若验证码错误
try:
result_id = self._app.top_window().window(control_id=0x966, class_name='Static').window_text()
if '验证码错误' in result_id:
self._app.top_window().window(control_id=0x2, class_name='Button').click()
self.verify_code_wrong = 1
else:
self.verify_code_wrong = 0
except Exception as e:
self.verify_code_wrong = 0
pass
# 复制的数据转为DataFrame
def _data_to_df(self):
# 数据转为Dateframe
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:
self.df = []
return
else:
data = []
for i in table_dict:
data.append(pd.DataFrame.from_dict(i, orient='index').T)
self.df = pd.concat(data, ignore_index=True)
# 获取委托单
def get_order(self):
# 点击当日委托
path = ['查询[F4]', '当日委托']
self._get_left_handle() # 获取self.left_handle
self.left_handle.get_item(path, exact=False).click_input(button=u'left', double=False, wheel_dist=0,
pressed=u'')
# x, y = win32api.GetCursorPos()
# pywinauto.mouse.click(button='left', coords=(x, y + 100))
# 刷新页面
pyautogui.press('f5')
time.sleep(0.2)
pyautogui.press('f5')
time.sleep(0.2)
self._copy_data()
if self.verify_code_wrong == 1: # 验证码错误时将self.verify_code_wrong置1
self.get_order()
self.verify_code_wrong = 0 # 验证码正确时将self.verify_code_wrong置0
self._data_to_df()
# print(self.df)
return self.df
# 获取当日成交
def get_today_trades(self):
"""
返回: self.table_df:汇总前表格
self.df: 汇总后表格
"""
time.sleep(1)
# 点击当日成交
path = ['查询[F4]', '当日成交']
self._get_left_handle() # 获取self.left_handle
self.left_handle.get_item(path, exact=False).click_input(button=u'left', double=True, wheel_dist=0,
pressed=u'')
# x_1, y_1 = win32api.GetCursorPos()
# pywinauto.mouse.click(button='left', coords=(x_1, y_1 + 50))
# x_2, y_2 = win32api.GetCursorPos()
# pywinauto.mouse.click(button='left', coords=(x_2, y_2 + 25))
# 关闭广告
try:
self._app.top_window().set_focus()
time.sleep(0.5)
pywinauto.keyboard.send_keys("{ESC}")
time.sleep(0.5)
# pywinauto.keyboard.send_keys("{ENTER}")
except Exception as e:
pass
# 刷新页面
pyautogui.press('f5')
time.sleep(0.2)
pyautogui.press('f5')
time.sleep(0.2)
# 数据转为DataFrame
self._copy_data()
if self.verify_code_wrong == 1: # 验证码错误时将self.verify_code_wrong置1
self.get_today_trades()
self.verify_code_wrong = 0 # 验证码正确时将self.verify_code_wrong置0
self._data_to_df()
if len(self.df) == 0:
return
self.table_df = self.df # 获取汇总前self.table_df
# 窗口最大化
try:
self.main_wnd.maximize()
except Exception as e:
pass
time.sleep(0.5)
# 数据汇总
pyautogui.click(self.position['中心'])
time.sleep(0.1)
# 右键
pyautogui.rightClick() # 右键
time.sleep(0.2)
# 点击常见汇总
pyautogui.press('down')
time.sleep(0.2)
pyautogui.press('down')
time.sleep(0.2)
pyautogui.press('enter')
time.sleep(0.2)
# 点击代码+操作
pyautogui.press('down')
time.sleep(0.2)
pyautogui.press('enter')
time.sleep(0.2)
self._copy_data()
if self.verify_code_wrong == 1: # 验证码错误时将self.verify_code_wrong置1
self.get_today_trades()
self.verify_code_wrong = 0 # 验证码正确时将self.verify_code_wrong置0
self._data_to_df() # 获取self.df
return self.df
# 交易记录入库(一)
def save_trades_sql(self):
As_Of_Date = datetime.datetime.today().strftime('%Y-%m-%d')
self.get_today_trades()
if len(self.df) == 0:
print('无当日成交---------------------')
# return False
else:
# 通过展示所有字段,摘取所需字段
need_info_df = self.df[['证券代码', '证券名称', '买卖标志', '成交数量', '成交价格']]
need_info_df['Account_name'] = self.account_name
need_info_df['As_Of_Date'] = As_Of_Date
need_info_df['买卖标志'] = need_info_df['买卖标志'].apply(
lambda x: '' if x == '卖出' else x)
need_info_df['买卖标志'] = need_info_df['买卖标志'].apply(
lambda x: '' if x == '证券卖出' else x)
need_info_df['买卖标志'] = need_info_df['买卖标志'].apply(
lambda x: '' if x == '证券买入' else x)
need_info_df['买卖标志'] = need_info_df['买卖标志'].apply(
lambda x: '' if x == '买入' else x)
need_info_df.rename(columns={"证券代码": "Ticker",
"证券名称": "Ticker_name",
"买卖标志": "Operate",
"成交数量": "Number_transactions",
"成交价格": "Average_price",
}, inplace=True)
need_info_df['Ticker'] = need_info_df['Ticker'].map(
lambda x: 'SH' + str("%06d" % int(x)) if str("%06d" % int(x))[0] == '6' or str("%06d" % int(x))[
0] == '5' else 'SZ' + str("%06d" % int(x)))
# 去掉债券前面的SH/SZ
need_info_df['Ticker'] = need_info_df['Ticker'].apply(
lambda x: x.strip('SH').strip('SZ') if x.strip('SH').strip('SZ') in self.df_list else x)
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)
# print(need_info_df)
# 入库
try:
return need_info_df
# engine_auto_update_web_strategy = create_engine('mysql+pymysql://cn_ainvest_db:cn_ainvest_sd3a1@rm-2zewagytttzk6f24xno.mysql.rds.aliyuncs.com:3306/auto_update_web_strategy', encoding="utf-8", echo=False)
# need_info_df.to_sql('daily_transaction_record',engine_auto_update_web_strategy,if_exists='append',index=False,chunksize=1000)
print(self.account_name,"入库成功!")
except Exception as e:
# print(e)
print(self.account_name,"入库失败!!!!!!!!!!!!!!!!!!!!!!!!!!")
# 交易记录存表(二)
def save_trade_table(self):
# 获取当日成交
As_Of_Date = datetime.datetime.today().strftime('%Y%m%d')
As_Of_Date = As_Of_Date[-4:]
# df = self.get_today_trades()
if len(self.df) == 0:
return
else:
# 填写备注
df_trade = self._get_df_trade()
# pc_name111 = getpass.getuser() # 返回用户名
# df_trade = pd.read_excel(f'C:\\Users\\{pc_name111}\\Desktop\\{self.today}_股票交易列表.xls')
df_trade['用户名'] = df_trade['用户名'].map(lambda x:str(x))
df_user = df_trade[df_trade['用户名'].isin([self.account_name])]
df_user = df_user.drop_duplicates('股票代码')
df_user['股票代码'] = df_user['股票代码'].map(lambda x: x.strip('SH').strip('SZ'))
self.df['证券代码'] = self.df['证券代码'].map(lambda x: str(x))
strategy_ticker_list = df_user['股票代码'].tolist()
self.df['备注'] = '客户操作'
self.df.loc[self.df['证券代码'].isin(strategy_ticker_list), '备注'] = '策略选股'
# 填写成交时间
df_time = self.table_df.drop_duplicates('证券代码')
time_ticker_list = df_time['证券代码'].tolist()
self.df['证券代码'] = self.df['证券代码'].map(lambda x:int(x))
for i in time_ticker_list:
df_ticker_one = self.table_df[self.table_df['证券代码'].isin([i])]
time = max(df_ticker_one['成交时间'])
self.df.loc[self.df['证券代码'].isin([i]), '成交时间'] = time
# 存储入表
return self.df
# self.df.to_excel(f'C:\\Users\\{pc_name111}\\Desktop\\{self.account_name}_{As_Of_Date}.xls')
# self.df.to_excel(f'C:\\Users\\{pc_name111}\\Desktop\\{As_Of_Date}_交易记录\\{self.account_name}_{As_Of_Date}.xls')
print('存表成功')
# 读取交易指令表
def _get_df_trade(self):
engine_user_center = create_engine(
'mysql+pymysql://cn_ainvest_db:cn_ainvest_sd3a1@rm-2zewagytttzk6f24xno.mysql.rds.aliyuncs.com:3306/user_center',
encoding="utf-8", echo=False)
today = str(datetime.date.today())
df_trade = pd.read_sql(f'select * from trade_instruction where As_Of_Date = "{today}"', engine_user_center)
return df_trade
# 解析合同
@staticmethod
def __parse_contract(result):
""" 解析买入卖出的结果 """
# 股东帐号A217477596
# 证券代码600000
# 买入价格3.330
# 买入数量100
result_list = result.split('\n')
for i in result_list[:-1]:
print(i,end=', ')
if __name__ == '__main__':
account_name = str('18242094506')
is_bond = 0
# user = str('802102044749')
user = '1910004175'
password = str('210419')
a = HYClientTrader(account_name)
a.login()
# # 最小化
# a.minimize()
# # 买入
# a.buy('600000', '3.333','100')
# # 卖出
# a.sell('600835', '14.45','900')
# # 撤单
# a.cancel_entrust()
# # 获取未成交单
# print(a.get_unsettled_trades())
# # 获取当日实际持仓
# print(a.get_position())
# # 获取资金情况
# print(a.balance())
# 获取委托单
# print(a.get_order())
# # 获取当日成交
# a.get_today_trades()
# print(a.df)
# # 交易记录入库
# a.save_trades_sql()
# # 交易记录存表
# a.save_trade_table()