#include "pch.h" #include "PluginInstance.h" CPluginInstance::CPluginInstance() : m_enable(false) { } CPluginInstance::~CPluginInstance() { Stop(); } void CPluginInstance::Release() { delete this; } MTAPIRES CPluginInstance::Start(IMTServerAPI * server) { MTAPIRES ret = MT_RET_OK; if (!server) return MT_RET_ERR_PARAMS; m_api = server; if ((m_config = m_api->PluginCreate()) == nullptr) return MT_RET_ERR_MEM; ret = m_api->About(m_info); if (ret != MT_RET_OK) m_api->LoggerOut(MTLogOK, L"Server info failed [%d]", ret); if ((ret = m_api->PluginSubscribe(this)) != MT_RET_OK) { m_api->LoggerOut(MTLogAtt, L"Plugin subscribe failed [%d]", ret); return ret; } if (ret = m_api->OrderSubscribe(this) != MT_RET_OK) { m_api->LoggerOut(MTLogAtt, L"Order subscribe failed [%d]", ret); return ret; } if (ret = m_api->DealSubscribe(this) != MT_RET_OK) { m_api->LoggerOut(MTLogAtt, L"Deal subscribe failed [%d]", ret); return ret; } if ((ret = LoadParam()) != MT_RET_OK) { m_api->LoggerOut(MTLogAtt, L"Load param failed [%d]", ret); return ret; } return MT_RET_OK; } MTAPIRES CPluginInstance::Stop() { MTAPIRES ret = MT_RET_OK; if (m_api == nullptr) return MT_RET_OK; if (m_config != nullptr) { m_config->Release(); m_config = nullptr; } if ((ret = m_api->PluginUnsubscribe(this)) != MT_RET_OK && ret != MT_RET_ERR_NOTFOUND) m_api->LoggerOut(MTLogErr, L"failed to unsubscribe from plugin config updates [%s (%u)]", SMTFormat::FormatError(ret), ret); if ((ret = m_api->OrderUnsubscribe(this)) != MT_RET_OK && ret != MT_RET_ERR_NOTFOUND) m_api->LoggerOut(MTLogErr, L"failed to unsubscribe order [%s (%u)]", SMTFormat::FormatError(ret), ret); if ((ret = m_api->DealUnsubscribe(this)) != MT_RET_OK && ret != MT_RET_ERR_NOTFOUND) m_api->LoggerOut(MTLogErr, L"failed to unsubscribe deal [%s (%u)]", SMTFormat::FormatError(ret), ret); m_api = nullptr; m_enable = false; return MT_RET_OK; } void CPluginInstance::OnPluginUpdate(const IMTConPlugin * plugin) { LoadParam(); } void CPluginInstance::OnOrderAdd(const IMTOrder * order) { if (order == nullptr) return; std::lock_guard lk(m_lock); if (!m_enable) return; if (order->Login() != m_trader) return; m_api->LoggerOut(MTLogOK, L"OnOrderAdd, login: %l64d, ord: %l64d, pos: %l64d, state: %l64d, vol_init: %l64d, vol_cur: %l64d", order->Login(), order->Order(), order->PositionID(), order->State(), order->VolumeInitial(), order->VolumeCurrent()); } void CPluginInstance::OnOrderUpdate(const IMTOrder * order) { if (order == nullptr) return; std::lock_guard lk(m_lock); if (!m_enable) return; if (order->Login() != m_trader) return; m_api->LoggerOut(MTLogOK, L"OnOrderAdd, login: %l64d, ord: %l64d, pos: %l64d, state: %l64d, vol_init: %l64d, vol_cur: %l64d", order->Login(), order->Order(), order->PositionID(), order->State(), order->VolumeInitial(), order->VolumeCurrent()); } void CPluginInstance::OnOrderDelete(const IMTOrder * order) { if (order == nullptr) return; std::lock_guard lk(m_lock); if (!m_enable) return; if (order->Login() != m_trader) return; m_api->LoggerOut(MTLogOK, L"OnOrderDelete, login: %l64d, ord: %l64d, pos: %l64d, state: %d, vol_init: %l64d, vol_cur: %l64d", order->Login(), order->Order(), order->PositionID(), order->State(), order->VolumeInitial(), order->VolumeCurrent()); } void CPluginInstance::OnOrderClean(const UINT64 login) { std::lock_guard lk(m_lock); if (!m_enable) return; if (login != m_trader) return; m_api->LoggerOut(MTLogOK, L"OnOrderClean, Login: %d", login); } void CPluginInstance::OnDealAdd(const IMTDeal * deal) { if (deal == nullptr) return; std::lock_guard lk(m_lock); if (!m_enable) return; if (deal->Login() != m_trader) return; m_api->LoggerOut(MTLogOK, L"OnDealAdd, login: %l64d, deal: %l64d, ord: %l64d, pos: %l64d, vol: %l64d, volc: %l64d", deal->Login(), deal->Deal(), deal->Order(), deal->PositionID(), deal->Volume(), deal->VolumeClosed()); } void CPluginInstance::OnDealUpdate(const IMTDeal * deal) { if (deal == nullptr) return; std::lock_guard lk(m_lock); if (!m_enable) return; if (deal->Login() != m_trader) return; m_api->LoggerOut(MTLogOK, L"OnDealUpdate, login: %l64d, deal: %l64d, ord: %l64d, pos: %l64d, vol: %l64d, volc: %l64d", deal->Login(), deal->Deal(), deal->Order(), deal->PositionID(), deal->Volume(), deal->VolumeClosed()); } void CPluginInstance::OnDealDelete(const IMTDeal * deal) { if (deal == nullptr) return; std::lock_guard lk(m_lock); if (!m_enable) return; if (deal->Login() != m_trader) return; m_api->LoggerOut(MTLogOK, L"OnDealDelete, login: %l64d, deal: %l64d, ord: %l64d, pos: %l64d, vol: %l64d, volc: %l64d", deal->Login(), deal->Deal(), deal->Order(), deal->PositionID(), deal->Volume(), deal->VolumeClosed()); } void CPluginInstance::OnDealClean(const UINT64 login) { std::lock_guard lk(m_lock); if (!m_enable) return; if (login != m_trader) return; m_api->LoggerOut(MTLogOK, L"OndealClean, Login: %d", login); } void CPluginInstance::OnDealPerform(const IMTDeal * deal, IMTAccount * account, IMTPosition * position) { // position为nullptr时,说明该deal不是由交易本身触发 // account是deal完成后的用户状况 // position是交易完成后的持仓状况 // 对于deal是关闭一个持仓的情况,该position的volume会是0 if (position == nullptr || deal == nullptr || account == nullptr) return; std::lock_guard lk(m_lock); if (!m_enable) return; if (deal->Login() != m_trader) return; m_api->LoggerOut(MTLogOK, L"OnDealPerform, login: %l64d, deal: %l64d, ord: %l64d, pos: %l64d, vol: %l64d, volc: %l64d", deal->Login(), deal->Deal(), deal->Order(), deal->PositionID(), deal->Volume(), deal->VolumeClosed()); } MTAPIRES CPluginInstance::LoadParam() { MTAPIRES res = MT_RET_OK; IMTConParam* param = NULL; CMTStr128 tmp; if (!m_api || !m_config) return MT_RET_ERR_PARAMS; if ((res = m_api->PluginCurrent(m_config)) != MT_RET_OK) { m_api->LoggerOut(MTLogErr, L"failed to get current plugin configuration [%s (%u)]", SMTFormat::FormatError(res), res); return res; } if ((param = m_api->PluginParamCreate()) == NULL) { m_api->LoggerOut(MTLogErr, L"failed to create plugin parameter object"); return MT_RET_ERR_MEM; } ScopeGuard param_release([param]() { param->Release(); }); std::lock_guard lk(m_lock); if ((res = m_config->ParameterGet(L"Trader", param)) != MT_RET_OK || param->Type() != IMTConParam::TYPE_INT) { return(MT_RET_ERR_PARAMS); } m_trader = param->ValueInt(); if ((res = m_config->ParameterGet(L"Step", param)) != MT_RET_OK || param->Type() != IMTConParam::TYPE_INT) { return(MT_RET_ERR_PARAMS); } m_step = param->ValueInt(); if ((res = m_config->ParameterGet(L"Tolerance", param)) != MT_RET_OK || param->Type() != IMTConParam::TYPE_INT) { return(MT_RET_ERR_PARAMS); } m_tolerance = param->ValueInt(); if ((res = m_config->ParameterGet(L"Groups", param)) != MT_RET_OK || param->Type() != IMTConParam::TYPE_STRING) { return(MT_RET_ERR_PARAMS); } m_groups = param->ValueString(); if ((res = m_config->ParameterGet(L"Logins", param)) != MT_RET_OK || param->Type() != IMTConParam::TYPE_STRING) { return(MT_RET_ERR_PARAMS); } m_logins = param->ValueString(); m_enable = true; return MT_RET_OK; }