#!/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 from pathlib import Path root_path = Path(__file__).parent #交易主函数 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()