zhitou_trade/trade_logic.py

629 lines
31 KiB
Python
Raw Normal View History

2025-05-22 16:47:45 +08:00
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time : 2020/7/19 20:00
# @Author : Merlin
# @File : trade_logic.py
# @Software: PyCharm
from sqlalchemy import create_engine
import datetime
from tools import *
import re
import pandas as pd
import time
#找到当前路径
import os
2025-05-26 09:19:39 +08:00
from pathlib import Path
root_path = Path(__file__).parent
2025-05-22 16:47:45 +08:00
#交易主函数
class Trade:
'''
实现既定交易需求
'''
# 初始化 获取用户券商信息
def __init__(self, user, op,order_id):
self.log = Logger(f'{root_path}/logs','trade_logic')
self.user = str(user)
self.op = op
self.order_id = order_id
quanshang_df = download_data_from_db(f'select * from registration where username = "{user}"','auth_center')
securities = quanshang_df["securities"].tolist()[0]
broker = download_data_from_db(f'select name from support_securities where id = "{securities}"','auth_center')
self.broker = broker['name'].tolist()[0]
if self.broker == '其它':
broker = download_data_from_db(f'select comment from security_comment where phone = "{user}"','auth_center')
self.broker = broker['comment'].tolist()[0]
#获取交易列表
def get_trade_df(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())
ip = get_host_ip()
tradelist_df = pd.read_sql(
f'select * from trade_instruction where ID_Order = "{self.order_id}" and Account_Name = "{self.user}" and Intranet_IP="{ip}"',
engine_user_center)
return tradelist_df
#操作函数
def trade_by_op(self):
if self.op =='login':
self.login()
elif self.op == 'cancel':
self.cancel_all_undeal_order()
elif self.op == 'according_to_trade_instructions':
self.according_to_trade_instructions()
elif self.op == 'immediate_order':
self.immediate_order()
elif self.op == 'update_price':
self.update_price()
elif self.op == 'save_all':
self.save_all()
elif self.op =='save_balance_position':
self.save_balance_position()
elif self.op == 'save_trades_check':
self.save_trades_check()
elif self.op == 'reset_mac_ip':
self.reset_mac_ip()
elif self.op == 'etf_buy':
self.etf_buy()
elif self.op == 'save_order':
self.save_order()
elif self.op == 'save_deliver_order':
self.save_deliver_order()
else:
self.log.error('请输入正确的操作指令')
def reset_mac_ip(self):
try:
init_redis('82.156.3.152', 6379, 0,'1508181008')
time1 = time.time()
#重置ip
reset_wlan()
#重置mac
set_mac = SetMac()
# set_mac.get_macinfos()
set_mac.run()
time.sleep(10)
print('cost', time.time() - time1)
time.sleep(10)
except:
exit()
#匹配券商
def get_broker(self):
print(self.broker)
if self.broker == '华泰证券':
from autobasic import huatai_clienttrader
user = huatai_clienttrader.HTClientTrader(self.user)
elif self.broker == '中信建投':
from autobasic import zxjt_clienttrader
user = zxjt_clienttrader.ZXJTClientTrader(self.user)
elif self.broker == '中信证券(浙江)':
from autobasic import zxzq_clienttrader
user = zxzq_clienttrader.ZXZQClientTrader(self.user)
elif self.broker == '恒泰证券':
from autobasic import hengtai_clienttrader
user = hengtai_clienttrader.HENGTAIClientTrader(self.user)
elif self.broker == '金元证券':
from autobasic import jy_clienttrader
user = jy_clienttrader.JYClienttrader(self.user)
elif self.broker == '长城证券':
from autobasic import cc_clienttrader
user = cc_clienttrader.CCClientTrader(self.user)
elif self.broker == '广发证券' or self.broker == '广发':
from autobasic import gf_clienttrader
user = gf_clienttrader.GFClientTrader(self.user)
elif self.broker == '光大证券' or self.broker == '光大':
from autobasic import gd_clienttrader
user = gd_clienttrader.GDClientTrader(self.user)
elif self.broker == '国信证券' or self.broker == '国信':
from autobasic import gx_clienttrader
user = gx_clienttrader.GXClientTrader(self.user)
elif self.broker == '申万宏源' or self.broker == '申万宏源(原宏源)':
from autobasic import hy_clienttrader
user = hy_clienttrader.HYClientTrader(self.user)
elif self.broker == '申万宏源(原申万)' :
from autobasic import sw_clienttrader
user = sw_clienttrader.SWClientTrader(self.user)
elif self.broker == '平安证券' or self.broker == '平安':
from autobasic import pa_clienttrader
user = pa_clienttrader.PAClientTrader(self.user)
elif self.broker == '信达' or self.broker == '信达证券':
from autobasic import xd_clienttrader
user = xd_clienttrader.XDClientTrader(self.user)
elif self.broker == '招商证券' or self.broker == '招商':
from autobasic import zs_clienttrader
user = zs_clienttrader.ZSClientTrader(self.user)
elif self.broker == '海通证券':
from autobasic import haitong_clienttrader
user = haitong_clienttrader.HaiTongClientTrader(self.user)
elif self.broker == '银河证券':
from autobasic import yh_clienttrader
user = yh_clienttrader.YHClientTrader(self.user)
elif self.broker == '财富桥':
from autobasic import mts
user = mts
elif self.broker == '国融' or self.broker == '国融证券':
from autobasic import gr_clienttrader
user = gr_clienttrader.GuoRongClientTrader(self.user)
elif self.broker == '中山' or self.broker == '中山证券':
from autobasic import zhongshan_clienttrader
user = zhongshan_clienttrader.ZSZQClientTrader(self.user)
elif self.broker == '兴业' or self.broker == '兴业证券':
from autobasic import xy_clienttrader
print('1')
user = xy_clienttrader.XingYeClientTrader(self.user)
print('2')
elif self.broker == '东吴' or self.broker == '东吴证券':
from autobasic import dw_clienttrader
user = dw_clienttrader.DongWuClientTrader(self.user)
elif self.broker == '安信' or self.broker == '安信证券':
from autobasic import anxin_clienttrader
user = anxin_clienttrader.AXClientTrader(self.user)
elif self.broker == '开源' or self.broker == '开源证券':
from autobasic import ky_clienttrader
user = ky_clienttrader.KYClientTrader(self.user)
elif self.broker == '华福' or self.broker == '华福证券':
from autobasic import hf_clienttrader
user = hf_clienttrader.HuaFuClientTrader(self.user)
elif self.broker == '华龙' or self.broker == '华龙证券':
from autobasic import hualong_clienttrader
user = hualong_clienttrader.HLClientTrader(self.user)
elif self.broker == '德邦' or self.broker == '德邦证券':
from autobasic import db_clienttrader
user = db_clienttrader.DeBangClientTrader(self.user)
elif self.broker == '国金' or self.broker == '国金证券':
from autobasic import guojin_clienttrader
user = guojin_clienttrader.GJClientTrader(self.user)
elif self.broker == '国盛' or self.broker == '国盛证券':
from autobasic import guosheng_clienttrader
user = guosheng_clienttrader.GuoShengClientTrader(self.user)
else:
self.log.error('暂不支持该券商')
return user
#登陆函数
def login(self):
user_main = self.get_broker()
user_main.login()
#执行立即成交交易
def immediate_order(self):
print(self.user)
users_df = self.get_trade_df()
if users_df.empty:
self.log.info(self.user+ 'No transaction this time!')
else:
user_main = self.get_broker()
user_main.login()
operate_list = list(set(users_df['Operate'].tolist()))
operate_list = sorted(operate_list)
for operate in operate_list:
asset_type_list = list(set(users_df['Asset_Type'].tolist()))
trade_df = users_df[users_df['Operate'] == operate]
if operate == -1:
operate_name = 'sell'
elif operate == 1:
operate_name = 'buy'
for asset_type in asset_type_list:
trade_df1 = trade_df[trade_df['Asset_Type'] == asset_type]
trade_list = list(trade_df1['Ticker'])
if len(trade_list) == 0:
self.log.info('Not need to '+ operate_name+ asset_type+ 'this time!')
else:
self.log.info('Today'+operate_name+ asset_type+ ''+ str(trade_list))
for index,rows in trade_df1.iterrows():
price_level = 5
tick = rows['Ticker']
print(tick)
if len(str(tick)) == 8:
tick_code = tick[2:]
elif len(str(tick)) == 6:
tick_code = tick
if asset_type == 'Ticker':
round_num = 2
elif asset_type == 'Fund':
round_num = 3
if operate_name=='sell':
try:
price = round(
get_price(tick, level=price_level, op='buy') , round_num)
print(price)
while price==0:
price_level = price_level-1
if price_level ==0:
self.log.warn('卖出停板股票')
price = round(
get_price(tick,price_level,0), round_num)
break
else:
price = round(
get_price(tick, level=price_level, op='sell'), round_num)
except Exception as e:
self.log.error(f'卖出失败:{e}')
continue
elif operate_name=='buy':
print('111111')
try:
price = round(
get_price(tick, level=price_level, op='sell') , round_num)
print(price)
while price==0:
price_level = price_level-1
if price_level ==0:
self.log.warn('买入停板股票')
price = round(
get_price(tick,price_level,0), round_num)
break
else:
price = round(
get_price(tick, level=price_level, op='sell'), round_num)
except Exception as e :
print('444444',e)
continue
amount = int(rows['Number_transactions'])
self.log.info('The stocks to '+ operate_name+ ''+ tick+ ' '+ ' price:'+ str(price)+' amount:'+ str(amount))
if operate_name == 'buy':
user_main.buy(tick_code, price, amount)
elif operate_name == 'sell':
user_main.sell(tick_code, price, amount)
user_main.exit()
#一键撤单
def cancel_all_undeal_order(self):
self.log.info(self.user)
user_main = self.get_broker()
users_df = self.get_trade_df()
if users_df.empty:
print('用户今日无交易,不需要获取')
else:
user_main.login()
canceldf = user_main.get_unsettled_trades()
if len(canceldf)==0:
print('该用户挂单股票已全部成交')
user_main.exit()
elif canceldf.empty:
print('该用户挂单股票已全部成交')
user_main.exit()
else:
cancellist = canceldf['证券代码'].apply(tranTicker).tolist()
tradelist = users_df['Ticker'].tolist()
customer_operation = [i for i in cancellist if i not in tradelist]
if len(customer_operation) == 0:
user_main.cancel_entrust()
else:
cancellist = list(set(cancellist).intersection(set(tradelist)))
print('撤单股票:', cancellist)
try:
for tick in cancellist:
tick = tick[2:]
user_main.get_cancel_entrust(tick)
except :
user_main.cancel_entrust()
user_main.exit()
# 开盘前买卖
def according_to_trade_instructions(self):
self.log.info(self.user)
users_df = self.get_trade_df()
if users_df.empty:
self.log.info(self.user+ 'No transaction this time!')
else:
user_main = self.get_broker()
user_main.login()
operate_list = list(set(users_df['Operate'].tolist()))
for operate in operate_list:
asset_type_list = list(set(users_df['Asset_Type'].tolist()))
trade_df = users_df[users_df['Operate'] == operate]
if operate == -1:
operate_name = 'sell'
elif operate == 1:
operate_name = 'buy'
for asset_type in asset_type_list:
price_level = 3
trade_df1 = trade_df[trade_df['Asset_Type'] == asset_type]
trade_list = list(trade_df1['Ticker'])
if len(trade_list) == 0:
self.log.info('Not need to '+ operate_name+ asset_type+ 'this time!')
else:
self.log.info('Today'+ operate_name+ asset_type+ ''+ str(trade_list))
for tick in trade_list:
if len(str(tick)) == 8:
tick_code = tick[2:]
elif len(str(tick)) == 6:
tick_code = tick
if asset_type == 'Ticker':
round_num = 2
elif asset_type == 'Fund':
round_num = 3
price =float(( trade_df[trade_df['Ticker'] == tick])['Price'].values)
amount = int((trade_df[trade_df['Ticker'] == tick])['Number_transactions'].values)
self.log.info('The stocks to '+ operate_name+ ''+ tick+ ' '+ ' price:'+ price+ ' amount:'+
amount)
if operate_name == 'buy':
user_main.buy(tick_code, price, amount)
elif operate_name == 'sell':
user_main.sell(tick_code, price, amount)
user_main.exit()
#更新挂单价格
def update_price(self):
print(self.user)
users_df = self.get_trade_df()
if users_df.empty:
self.log.info(self.user+ 'No transaction this time!')
else:
user_main = self.get_broker()
user_main.login()
canceldf = user_main.get_unsettled_trades()
if len(canceldf) == 0:
self.log.info('All stocks dealt!')
user_main.exit()
else:
cancellist = canceldf['证券代码'].apply(tranTicker).tolist()
tradelist = users_df['Ticker'].tolist()
error_cancellist = [i for i in cancellist if i not in tradelist]
cancellist = list(set(cancellist).intersection(set(tradelist)))
self.log.info('Cancelist'+ cancellist)
try:
for tick in cancellist:
tick = tick[2:]
user_main.get_cancel_entrust(tick)
cancel_type='One_by_one'
except:
user_main.cancel_entrust()
cancel_type = 'all'
for tick in cancellist:
ticker_df = users_df[users_df['Ticker'] == tick]
asset_type = (ticker_df[ticker_df['Ticker']==tick])['Asset_Type'].tolist()[0]
tick_name = str((ticker_df[ticker_df['Ticker'] == tick])['Ticker_Name'].values)
if len(str(tick)) == 8:
tick_code = tick[2:]
elif len(str(tick)) == 6:
tick_code = tick
operate = str(((ticker_df[ticker_df['Ticker'] == tick])['Ticker_Name'].values)[0])
if operate == -1:
operate_name = 'sell'
elif operate == 1:
operate_name = 'buy'
price_level = 3
if asset_type == 'Ticker':
round_num = 2
elif asset_type == 'Fund':
round_num = 3
if operate_name == 'sell':
price = round(
self.get_price(tick, level=price_level, op='buy'), round_num)
elif operate_name == 'buy':
price = round(
self.get_price(tick, level=price_level, op='sell'), round_num)
amount = int((ticker_df[ticker_df['Ticker'] == tick])['Number_transactions'].values)
print('The stocks to ', operate_name, '', tick, ' ', tick_name, ' price:', price, ' amount:',
amount)
if operate_name == 'buy':
user_main.buy(tick_code, price, amount)
elif operate_name == 'sell':
user_main.sell(tick_code, price, amount)
if cancel_type == 'One_by_one':
user_main.exit()
elif cancel_type == 'all':
print(self.user,'需要重挂',error_cancellist)
user_main.exit()
def save_all(self):
today = str(datetime.date.today())
engine_auto_update_web_strategy = create_engine(
'mysql+pymysql://ainvest:JRLeiYD423!@rm-2zewagytttzk6f24xno.mysql.rds.aliyuncs.com:3306/auto_update_web_strategy',
encoding="utf-8", echo=False)
engine_ai_strategy_update_iddb = create_engine(
'mysql+pymysql://cn_ainvest_db:cn_ainvest_sd3a1@rm-2zewagytttzk6f24xno.mysql.rds.aliyuncs.com:3306/ai_strategy_update_iddb')
self.log.info('--------------------------------------'+self.user+ '--------------------------------------')
user_main = self.get_broker()
try:
user_main.login()
except Exception as e:
self.log.error(self.broker+' '+ self.user+'登陆失败!!!!!!!!')
self.log.error(sys.exc_info())
time.sleep(5)
# 存资金
balance = user_main.get_balance()
if balance['Total_account'].tolist()[0] == 0:
self.log.error('总资金为0请核查')
else:
print('资金', balance)
balance['As_Of_Date'] = today
balance['Account_Name'] = self.user
pd.read_sql(f'delete from account_ticker where As_Of_Date="{today}" and Account_Name = "{self.user}"',engine_ai_strategy_update_iddb,chunksize=100)
balance.to_sql('account_ticker', engine_ai_strategy_update_iddb, if_exists='append', index=False)
time.sleep(1)
# 存持仓
position = user_main.get_position()
if position.empty:
self.log.info('无持仓')
else:
position['Account_Name'] = self.user
position['As_Of_Date'] = today
position['Ticker'] = position['Ticker'].apply(tranTicker)
print('持仓', position)
pd.read_sql(f'delete from position_from_broker where As_Of_Date="{today}" and Account_Name = "{self.user}"',engine_ai_strategy_update_iddb,chunksize=100)
position.to_sql('position_from_broker', engine_ai_strategy_update_iddb, if_exists='append', index=False)
time.sleep(1)
trades = user_main.get_today_trades()
if trades.empty:
self.log.info('无成交')
else:
print('成交', trades)
trades['Ticker'] = trades['Ticker'].apply(tranTicker)
pd.read_sql(f'delete from daily_transaction_record_detail where As_Of_Date="{today}" and Account_Name = "{self.user}"',engine_auto_update_web_strategy,chunksize=100)
trades.to_sql('daily_transaction_record_detail', engine_auto_update_web_strategy,
if_exists='append',
index=False, chunksize=100)
user_main.exit()
def save_trades_check(self):
engine_auto_update_web_strategy = create_engine(
'mysql+pymysql://ainvest:JRLeiYD423!@rm-2zewagytttzk6f24xno.mysql.rds.aliyuncs.com:3306/auto_update_web_strategy',
encoding="utf-8", echo=False)
print('--------------------------------------',self.user, '--------------------------------------')
user_main = self.get_broker()
try:
user_main.login()
except Exception as e:
self.log.error(self.broker, ' ', self.user, '登陆失败!!!!!!!!')
self.log.error(sys.exc_info())
trades = user_main.get_today_trades()
if trades.empty:
self.log.info('无成交')
else:
print('成交', trades)
trades['Ticker'] = trades['Ticker'].apply(tranTicker)
trades_instruction = download_data_from_db(f'select * from user_center.trade_instruction_retail where Trade_Date >="{datetime.date.today()}" and Account_Number = "{self.user}"','user_center')
insDf = pd.DataFrame(trades_instruction.groupby(['Ticker','Open_Or_Close'])['Shares'].sum()).reset_index()
tradesdf = trades.copy(deep=True)
tradesdf['Open_Or_Close'] = tradesdf['Operate'].apply(lambda x:1 if '' in x else -1)
tradesdf['Trade_Shares'] = tradesdf['Open_Or_Close']*tradesdf['Number_transactions']
trddf = pd.DataFrame(tradesdf.groupby(['Ticker','Open_Or_Close'])['Trade_Shares'].sum()).reset_index()
check_df = pd.merge(insDf,trddf,how='outer',on=['Ticker','Open_Or_Close']).fillna(0)
check_df['diff'] = check_df['Shares']-check_df['Trade_Shares']
# print(check_df)
pd.read_sql(f'delete from daily_transaction_record_check where As_Of_Date="{datetime.date.today()}" and Account_Name = "{self.user}"',engine_auto_update_web_strategy,chunksize=100)
if check_df[check_df['diff']!=0].empty:
pass
else:
self.log.info(self.user+'交易错误')
send_email('交易错误',self.user)
trades.to_sql('daily_transaction_record_check', engine_auto_update_web_strategy,
if_exists='append',
index=False, chunksize=100)
user_main.exit()
def save_balance_position(self):
today = str(datetime.date.today())
engine_auto_update_web_strategy = create_engine(
'mysql+pymysql://ainvest:JRLeiYD423!@rm-2zewagytttzk6f24xno.mysql.rds.aliyuncs.com:3306/auto_update_web_strategy',
encoding="utf-8", echo=False)
engine_ai_strategy_update_iddb = create_engine(
'mysql+pymysql://cn_ainvest_db:cn_ainvest_sd3a1@rm-2zewagytttzk6f24xno.mysql.rds.aliyuncs.com:3306/ai_strategy_update_iddb')
self.log.info('--------------------------------------'+self.user+ '--------------------------------------')
user_main = self.get_broker()
try:
user_main.login()
except Exception as e:
self.log.error(self.broker+' '+ self.user+'登陆失败!!!!!!!!')
self.log.error(sys.exc_info())
time.sleep(1)
# 存资金
balance = user_main.get_balance()
if balance['Total_account'].tolist()[0] == 0:
self.log.error('总资金为0请核查')
else:
print('资金', balance)
balance['As_Of_Date'] = today
balance['Account_Name'] = self.user
pd.read_sql(f'delete from account_ticker where As_Of_Date="{today}" and Account_Name = "{self.user}"',engine_ai_strategy_update_iddb,chunksize=100)
balance.to_sql('account_ticker', engine_ai_strategy_update_iddb, if_exists='append', index=False)
time.sleep(1)
# 存持仓
position = user_main.get_position()
if position.empty:
self.log.info('无持仓')
else:
position['Account_Name'] = self.user
position['As_Of_Date'] = today
position['Ticker'] = position['Ticker'].apply(tranTicker)
print('持仓', position)
pd.read_sql(f'delete from position_from_broker where As_Of_Date="{today}" and Account_Name = "{self.user}"',engine_ai_strategy_update_iddb,chunksize=100)
position.to_sql('position_from_broker', engine_ai_strategy_update_iddb, if_exists='append', index=False)
user_main.exit()
def etf_buy(self):
users_df = self.get_trade_df()
if users_df.empty:
self.log.info(self.user+ 'No transaction this time!')
user_main = self.get_broker()
try:
user_main.login()
except Exception as e:
self.log.error(self.broker, ' ', self.user, '登陆失败!!!!!!!!')
self.log.error(sys.exc_info())
for index,row in users_df.iterrows():
user_main.etf_buy(row['Ticker'][2:], row['Number_transactions'])
user_main.exit()
def save_order(self):
today = str(datetime.date.today())
engine_auto_update_web_strategy = create_engine(
'mysql+pymysql://ainvest:JRLeiYD423!@rm-2zewagytttzk6f24xno.mysql.rds.aliyuncs.com:3306/auto_update_web_strategy',
encoding="utf-8", echo=False)
engine_ai_strategy_update_iddb = create_engine(
'mysql+pymysql://cn_ainvest_db:cn_ainvest_sd3a1@rm-2zewagytttzk6f24xno.mysql.rds.aliyuncs.com:3306/ai_strategy_update_iddb')
self.log.info('--------------------------------------' + self.user + '--------------------------------------')
user_main = self.get_broker()
try:
user_main.login()
except Exception as e:
self.log.error(self.broker + ' ' + self.user + '登陆失败!!!!!!!!')
self.log.error(sys.exc_info())
time.sleep(1)
trades = user_main.get_order()
if trades.empty:
self.log.info('无成交')
else:
print('成交', trades)
trades['Ticker'] = trades['Ticker'].apply(tranTicker)
pd.read_sql(
f'delete from daily_transaction_record_order where As_Of_Date="{today}" and Account_Name = "{self.user}"',
engine_auto_update_web_strategy, chunksize=100)
trades.to_sql('daily_transaction_record_order', engine_auto_update_web_strategy,
if_exists='append',
index=False, chunksize=100)
user_main.exit()
def save_deliver_order(self):
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')
self.log.info('--------------------------------------' + self.user + '--------------------------------------')
user_main = self.get_broker()
user_main.login()
time.sleep(2)
deliver_order = user_main.get_deliver_order()
if deliver_order.empty:
self.log.info('无交割单')
else:
deliver_order['Account_Name'] = self.user
deliver_order['证券代码'] = deliver_order['证券代码'].apply(tranTicker)
print('持仓', deliver_order)
deliver_order_rename = deliver_order.rename(columns={'成交日期':'Trade_Date','成交时间':'Trade_Time','证券代码':'Ticker','证券名称':'Ticker_Name','操作':'Operate',
'成交数量':'Number_transactions','成交编号':'Trade_Number','成交均价':'Average_Price','成交金额':'Trade_Amount',
'余额':'Balance','股票余额':'Stock_Balance','发生金额':'Amount_Incurred','手续费':'Net_Commission',
'印花税':'Stamp_Duty','其他杂费':'Other_Miscellaneous_Expenses','本次金额':'Current_Amount','合同编号':'Contract number',
'市场名称':'Market_Name','股东帐户':'Shareholder_Account','经手费':'Brokerage','证管费':'Securities_Management_Fees',
'过户费':'Transfer_Fee','交易市场':'Trade_Market'})
deliver_order_rename.to_sql('deliver_order', auto_update_web_strategy, if_exists='append', index=False)
user_main.exit()