#include "FutuApiManager.h"
|
|
FutuApiManager::FutuApiManager()
|
{
|
m_pQotApi = FTAPI::CreateQotApi();
|
m_pQotApi->RegisterQotSpi(this);
|
m_pQotApi->RegisterConnSpi(this);
|
m_bQotInitSuc = false;
|
|
m_pTrdApi = FTAPI::CreateTrdApi();
|
m_pTrdApi->RegisterTrdSpi(this);
|
m_pTrdApi->RegisterConnSpi(this);
|
m_bTrdInitSuc = false;
|
|
m_pSem = new Semaphore(0);
|
}
|
|
FutuApiManager::~FutuApiManager()
|
{
|
UnInitQot();
|
UnInitTrd();
|
delete m_pSem;
|
}
|
|
bool FutuApiManager::InitQot(const char* szIP, uint16_t nPort)
|
{
|
if (!m_bQotInitSuc && m_pQotApi != nullptr)
|
{
|
m_pQotApi->InitConnect(szIP, nPort, false);
|
m_pSem->wait();
|
}
|
cout << "InitQot, suc = " << m_bQotInitSuc << endl;
|
return m_bQotInitSuc;
|
}
|
|
void FutuApiManager::UnInitQot()
|
{
|
if (m_pQotApi != nullptr)
|
{
|
m_pQotApi->UnregisterQotSpi();
|
m_pQotApi->UnregisterConnSpi();
|
FTAPI::ReleaseQotApi(m_pQotApi);
|
m_pQotApi = nullptr;
|
m_bQotInitSuc = false;
|
}
|
}
|
|
bool FutuApiManager::InitTrd(const char* szIP, uint16_t nPort, const char* szPwdMD5, Trd_Common::SecurityFirm enFirm)
|
{
|
if (!m_bTrdInitSuc && m_pTrdApi != nullptr)
|
{
|
m_mapRealAccID.clear();
|
m_mapSimAccID.clear();
|
m_setAllAccID.clear();
|
|
m_pTrdApi->InitConnect(szIP, nPort, false);
|
m_pSem->wait();
|
if (m_bTrdInitSuc)
|
{
|
//ÏȽâËø½»Ò×(Ä£Äâ½»Òײ»ÐèÒª½âËø)
|
Unlock(szPwdMD5, enFirm);
|
//ÀÈ¡½»Ò×ÕË»§£¬²¢ÇÒ¶©ÔĽ»Ò×ÕË»§µÄÍÆËÍ
|
GetAccListAndSubTradePush();
|
}
|
}
|
cout << "InitTrd, suc = " << m_bTrdInitSuc << endl;
|
return m_bTrdInitSuc;
|
}
|
|
void FutuApiManager::UnInitTrd()
|
{
|
if (m_pTrdApi != nullptr)
|
{
|
m_pTrdApi->UnregisterTrdSpi();
|
m_pTrdApi->UnregisterConnSpi();
|
FTAPI::ReleaseTrdApi(m_pTrdApi);
|
m_pTrdApi = nullptr;
|
m_bTrdInitSuc = false;
|
}
|
|
m_mapRealAccID.clear();
|
m_mapSimAccID.clear();
|
m_setAllAccID.clear();
|
}
|
|
void FutuApiManager::Unlock(const char* szPwdMD5, Trd_Common::SecurityFirm enFirm)
|
{
|
if (m_pTrdApi != nullptr && szPwdMD5 != nullptr && strlen(szPwdMD5) != 0)
|
{
|
Trd_UnlockTrade::Request pbUnlockTrade;
|
Trd_UnlockTrade::C2S* pUnlockTradeC2S = pbUnlockTrade.mutable_c2s();
|
pUnlockTradeC2S->set_unlock(true);
|
pUnlockTradeC2S->set_pwdmd5(szPwdMD5);
|
pUnlockTradeC2S->set_securityfirm(enFirm);
|
WaitReply(m_pTrdApi->UnlockTrade(pbUnlockTrade));
|
}
|
}
|
|
void FutuApiManager::GetAccListAndSubTradePush()
|
{
|
if (m_pTrdApi != nullptr)
|
{
|
Trd_GetAccList::Request pbGetAccList;
|
Trd_GetAccList::C2S* pGetAccListC2S = pbGetAccList.mutable_c2s();
|
pGetAccListC2S->set_userid(0);
|
WaitReply(m_pTrdApi->GetAccList(pbGetAccList));
|
|
if (!m_setAllAccID.empty())
|
{
|
Trd_SubAccPush::Request pbSubAccPush;
|
Trd_SubAccPush::C2S* pSubAccC2S = pbSubAccPush.mutable_c2s();
|
for (auto iter = m_setAllAccID.begin(); iter != m_setAllAccID.end(); ++iter)
|
{
|
pSubAccC2S->add_accidlist(*iter);
|
}
|
WaitReply(m_pTrdApi->SubAccPush(pbSubAccPush));
|
}
|
}
|
}
|
|
void FutuApiManager::OnInitConnect(FTAPI_Conn* pConn, Futu::i64_t nErrCode, const char* strDesc)
|
{
|
if (pConn != nullptr)
|
{
|
if (pConn == m_pQotApi)
|
{
|
m_bQotInitSuc = (nErrCode == 0);
|
}
|
else if (pConn == m_pTrdApi)
|
{
|
m_bTrdInitSuc = (nErrCode == 0);
|
}
|
PostReply();
|
}
|
}
|
|
void FutuApiManager::OnReply_GetAccList(Futu::u32_t nSerialNo, const Trd_GetAccList::Response& stRsp)
|
{
|
if (stRsp.rettype() == Common::RetType_Succeed)
|
{
|
const Trd_GetAccList::S2C& pbS2C = stRsp.s2c();
|
i32_t nAccCount = pbS2C.acclist_size();
|
for (int32_t i = 0; i < nAccCount; ++i)
|
{
|
const Trd_Common::TrdAcc& pbTrdAcc = pbS2C.acclist(i);
|
//ÒµÎñÕ˺Å
|
uint64_t nAccID = pbTrdAcc.accid();
|
//½»Ò×»·¾³
|
Trd_Common::TrdEnv enTrdEnv = (Trd_Common::TrdEnv)pbTrdAcc.trdenv();
|
//ÒµÎñÕË»§Ö§³ÖµÄ½»Ò×Êг¡È¨ÏÞ£¬¼´´ËÕË»§Äܽ»Ò×ÄÇЩÊг¡, ¿ÉÓµÓжà¸ö½»Ò×Êг¡È¨ÏÞ£¬Ä¿Ç°½öµ¥¸ö
|
Trd_Common::TrdMarket enTrdMarket = (Trd_Common::TrdMarket)pbTrdAcc.trdmarketauthlist(0);
|
|
//ÊÕ¼¯½»Ò×·¶Àý±ØÒªÐÅÏ¢
|
m_setAllAccID.insert(nAccID);
|
vector<uint64_t>& vAccID = (enTrdEnv == Trd_Common::TrdEnv_Real) ? m_mapRealAccID[enTrdMarket] : m_mapSimAccID[enTrdMarket];
|
vAccID.push_back(nAccID);
|
}
|
}
|
else
|
{
|
PrintUTF8(stRsp.retmsg());
|
}
|
PostReply();
|
}
|
|
void FutuApiManager::OnReply_UnlockTrade(Futu::u32_t nSerialNo, const Trd_UnlockTrade::Response& stRsp)
|
{
|
if (stRsp.rettype() != Common::RetType_Succeed)
|
{
|
PrintUTF8(stRsp.retmsg());
|
}
|
PostReply();
|
}
|
|
void FutuApiManager::OnReply_SubAccPush(Futu::u32_t nSerialNo, const Trd_SubAccPush::Response& stRsp)
|
{
|
if (stRsp.rettype() != Common::RetType_Succeed)
|
{
|
PrintUTF8(stRsp.retmsg());
|
}
|
PostReply();
|
}
|
|
void FutuApiManager::WaitReply(int32_t nSerilNo)
|
{
|
//½Ó¿Ú·µ»ØµÄnSerilNoÓë»Øµ÷º¯ÊýOnReply_XXXµÚÒ»¸ö²ÎÊý¶ÔÓ¦
|
//ÓÃÓÚ¶ÔÓ¦ÇëÇóºÍ»Ø°ü£¬±¾·¶ÀýÒÔͬ²½½Ó¿ÚµÄÐÎʽµ÷Óã¬Ã¿´ÎÖ»·¢ËÍÒ»¸öÇëÇóËùÒÔÐèÒª¼Ç¼¡¢¶Ô±È¸Ã×Ö¶Î
|
if (nSerilNo != 0)
|
{
|
m_pSem->wait();
|
}
|
}
|
|
void FutuApiManager::PostReply()
|
{
|
m_pSem->post();
|
}
|
|
uint64_t FutuApiManager::GetFirstAccID(Trd_Common::TrdMarket enTrdMarket, Trd_Common::TrdEnv enTrdEnv)
|
{
|
uint64_t nAccID = 0;
|
vector<uint64_t>& vAccID = (enTrdEnv == Trd_Common::TrdEnv_Real) ? m_mapRealAccID[enTrdMarket] : m_mapSimAccID[enTrdMarket];
|
if (!vAccID.empty())
|
{
|
nAccID = vAccID[0];
|
}
|
return nAccID;
|
}
|