import time
from tcorepyapi.tcoreapi_mq import *
import pandas as pd
#登入
TCoreAPI= TCoreZMQ(quote_port="51630",trade_port="51600")
#TCoreAPI= TCoreZMQ(quote_port="51864",trade_port="51834")
#TCoreAPI= TCoreZMQ(quote_port="51424",trade_port="51394")
#查询指定合约信息
print("查询指定合约：",TCoreAPI.QueryInstrumentInfo("TC.O.SSE.510050.202108.C.3.6"))

#查询指定类型合约列表
#参数1：
    #期货：Future
    #期权：Options
    #证券：Stock
#参数2：指定日期的合约列表，如果不带或带入空参数，返回最新的合约列表，否则返回指定日期的合约列表
symbollist=TCoreAPI.QueryAllInstrumentInfo("Options")
#print("查询合约：\n",symbollist)
#解析期权合约列表
if symbollist['Success']=="OK":
    for opt in symbollist['Instruments']['Node']:
        #SSE交易所的期权
        if opt['ENG']=='SSE(O)':
            for optlist in opt['Node']:
                #标的50etf的期权
                if optlist['ENG_M']=='50ETF':
                    for optlist2 in optlist['Node']:
                        #202108月份合约
                        if optlist2['ENG']=='202108':
                            for syblist in optlist2['Node']:
                                for symb in syblist['Contracts']:
                                    print(symb)
#解除订阅
#TCoreAPI.UnsubQuote("TC.F.CFFEX.IF.202106")
#订阅实时行情
TCoreAPI.SubQuote("TC.O.SSE.510050.202108.C.3.2")
#解除订阅
#TCoreAPI.UnsubGreeks("TC.F.U_SSE.510050.202106")
#订阅实时Greeks行情
#TCoreAPI.SubGreeks("TC.F.U_SSE.510050.202106")

#获取历史数据
    #1：合约代码，
    #2：数据周期:
        ##标准行情历史数据
        # tick: "TICKS", 
        # 分K: "1K",
        # 日K: "DK"，
        ##DOGS为包含Greeks、标的期货、标的合约的历史数据
        # DOGS秒："DOGSS", 
        # DOGS分K："DOGSK"
    #3: 历史数据开始时间,
    #4: 历史数据结束时间
#his=TCoreAPI.SubHistory("TC.F.U_SSE.510050.202106", "DOGSK", "2021050100", "2021052107")
his=TCoreAPI.SubHistory("TC.O.SSE.510050.202108.C.3.6", "1K", "2021062300", "2021062307")
print("历史数据：\n",his)

#查询已登入资金账户
accountInfo = TCoreAPI.QryAccount()
#查询当日委托回报
reportData = TCoreAPI.QryReport()
if reportData:
    print("当日委托回报：\n",pd.DataFrame(reportData))
else:
    print("今日没有委托记录")
#查询当日成交回报
fillReportData = TCoreAPI.QryFillReport()
if fillReportData:
    print("当日成交回报：\n",pd.DataFrame(fillReportData))
else:
    print("今日没有成交记录")
#查询持仓监控
PositionTracker=TCoreAPI.QryPositionTracker()
if PositionTracker:
    print("持仓监控信息：\n",PositionTracker)
else:
    print("没有持仓监控信息")
strAccountMask =""
if accountInfo != None:
    arrInfo = accountInfo["Accounts"]
    if len(arrInfo) != 0:
        for acc in arrInfo:
            print("当前已登入资金账户\n",pd.DataFrame.from_dict(acc,orient='index').T)
        #获取账户列表中的第一个账户
        strAccountMask = arrInfo[0]["AccountMask"]
        #查询资金
        margin=TCoreAPI.QryMargin(strAccountMask)
        print("资金信息：\n",pd.DataFrame(margin["Margins"]))
        #查询持仓
        pos = TCoreAPI.QryPosition(strAccountMask)
        print("持仓信息：\n",pd.DataFrame(pos))

def mdupdatethread():
    flag=True
    while True:
        #行情更新
        quoteupdate= TCoreAPI.mdupdate()
        if quoteupdate:
            if quoteupdate['DataType']=='REALTIME':
                print("实时行情: \n",pd.DataFrame.from_dict(quoteupdate['Quote'],orient='index').T)  #这里只是展示用，实际应用建议不要使用dataframe转换实时数据，会影响运行效率
                if strAccountMask !="" and flag:
                    #新增一笔委托
                    orders_obj = {
                                    "Symbol":quoteupdate['Quote']['Symbol'],
                                    "BrokerID":arrInfo[0]['BrokerID'],
                                    "Account":arrInfo[0]['Account'],
                                    "Price":"0.0001",#quoteupdate['Quote']['LowPrice'],
                                    "TimeInForce":"1",
                                    "Side":"1",
                                    "OrderType":"2",
                                    "OrderQty":"1",
                                    "PositionEffect":"4",
                                    "SelfTradePrevention":"3"
                                    #"ChasePrice":"1T|5|3|M"
                                }
                    ordid = TCoreAPI.NewOrder(orders_obj)
                    if ordid!=None:
                        while True:
                            if TCoreAPI.getorderinfo(ordid):
                                print("新增委托",TCoreAPI.getorderinfo(ordid)['ReportID'])#,TCoreAPI.QryReport()[-1]['ReportID'])
                                break

                    #改单
                    time.sleep(1)
                    print(TCoreAPI.getorderinfo(ordid)['ExecType'])
                    reporders_obj={
                        "ReportID":TCoreAPI.getorderinfo(ordid)['ReportID'],#TCoreAPI.QryReport()[-1]['ReportID'],
                        "ReplaceExecType":"0",
                        "Price":quoteupdate['Quote']['TradingPrice']
                        }
                    #在可改单的委托单状态下发送改单指令（注意：模拟交易和外盘允许改单，内盘建议使用先删单单然后发送新委托方式改单）
                    if TCoreAPI.getorderinfo(ordid)['ExecType'] in ["0","1","4","6"]:
                        reorder=TCoreAPI.ReplaceOrder(reporders_obj)
                        print("修改委托单：\n",reorder,TCoreAPI.QryReport()[-1]['ReportID'])
                    #取消委托单
                    time.sleep(1)
                    cancalorders_obj = {
                                "ReportID":TCoreAPI.getorderinfo(ordid)['ReportID'],#TCoreAPI.QryReport()[-1]['ReportID'],
                                }
                    #在可删单的委托单状态下发送删单指令      
                    if TCoreAPI.getorderinfo(ordid)['ExecType'] in ["0","1","4","6"]:
                        cancal_order = TCoreAPI.CancelOrder(cancalorders_obj )
                        print("删单:",cancal_order)
                    #建组合
                    orders_obj = {
                                "Symbol":"TC.O.SSE.510050.202106.C.3.6&TC.O.SSE.510050.202106.C.3.7",
                                "BrokerID":arrInfo[0]['BrokerID'],
                                "Account":arrInfo[0]['Account'],
                                "CombDirection":"1",
                                "Side":"1",
                                "CombinationType":"1",
                                "Volume":"1"
                                }
                    TCoreAPI.OptComb(orders_obj)
                    #查询新建组合的委托回报
                    TCoreAPI.QryOptCombOrder(strAccountMask,"")
                    flag=False
            elif  quoteupdate['DataType']=="GREEKS":
                print("实时GREEKS: \n",pd.DataFrame.from_dict(quoteupdate['Quote'],orient='index').T)

def tdupdatethread():
    while True:
        #交易更新
        tradeupdate= TCoreAPI.tdupdate()
        if tradeupdate:
            if tradeupdate['DataType']=='ACCOUNTS':
                print("账户列表更新: \n",tradeupdate['Accounts'])
                arrInfo = tradeupdate['Accounts']
                if len(arrInfo) != 0:
                    strAccountMask = arrInfo[0]["AccountMask"]
            elif tradeupdate['DataType'] == "EXECUTIONREPORT":
                print("实时委托回报: \n",pd.DataFrame.from_dict(tradeupdate["Report"],orient='index').T)
            elif tradeupdate['DataType'] == "FILLEDREPORT":
                print("实时成交: \n",pd.DataFrame.from_dict(tradeupdate["Report"],orient='index').T)
            elif tradeupdate['DataType'] == "POSITIONTRACKER":
                #查询持仓监控
                PositionTracker=TCoreAPI.QryPositionTracker()
                print("持仓监控信息更新\n",PositionTracker)

thr1=threading.Thread(target=mdupdatethread)
thr2=threading.Thread(target=tdupdatethread)
thr2.start()
thr1.start()

