//+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CProcessor::OnFXIResponse(Response *resp) { SLTPOrderRequest req = { 0 }; if (resp->status == OrderSLExecuted || resp->status == OrderTPExecuted) if (ExtProcessor.m_orderRequests.Dequeue(resp->requestId, &req)) { CharString str; str.Printf(FALSE, "FXI response on SL-TP order %d, price=%g", req.orderId, resp->price); ExtServer->LogsOut(CmdOK, PROGRAM_TITLE, str.ToArray()); // модифицировать ордер - активировать его TradeRecord order = { 0 }; if (ExtServer->OrdersGet(req.orderId, &order)) { UserInfo user = {0}; user.login = ExtProcessor.m_manager; COPY_STR(user.name, "Virtual Dealer"); COPY_STR(user.ip, "VirtualDealer"); order.close_price = resp->price; str.Printf(FALSE, "FXI response order detail: login=%d, volume=%d", order.login, order.volume); ExtServer->LogsOut(CmdOK, PROGRAM_TITLE, str.ToArray()); UserInfo us; if (GetUserInfo(order.login, &us)) { #pragma pack(push,1) TradeTransInfo tti; memset(&tti, 0, sizeof(tti)); tti.cmd = order.cmd; strcpy(tti.symbol, order.symbol); tti.volume = order.volume; tti.price = resp->price; tti.type = TT_ORDER_MK_CLOSE; tti.order = order.order; if (ExtServer->OrdersClose(&tti, &us) == FALSE) ExtServer->LogsOut(CmdOK, PROGRAM_TITLE, "OrdersClose failed"); else ExtServer->LogsOut(CmdOK, PROGRAM_TITLE, "OrdersClose OK"); #pragma pack(pop) } else ExtServer->LogsOut(CmdOK, PROGRAM_TITLE, "GetUserInfo failed"); } return TRUE; } return FALSE; }
//+------------------------------------------------------------------+ //| Позиция открылась (закрылась) - уведомить FXI | //+------------------------------------------------------------------+ void CProcessor::OnTradeHistoryRecord(TradeRecord *trade) { CharString str; PendingRequest req = { 0 }; if (extPendingRequestQueue.FindRequest(trade->login, trade->cmd, trade->symbol, trade->volume, trade->open_price, &req)) { str.Printf(FALSE, "type=NOTIFY;requestId=%d;order=%d;", req.requestId, trade->order); m_sender->SendTo(&str, m_sendHost, m_sendPort); return; } str.Printf(FALSE, "Request for order=%d not found", trade->order); ExtServer->LogsOut(CmdOK, PROGRAM_TITLE, str.ToArray()); str.Printf(FALSE, "Detail: login=%d, cmd=%d, symbol=%s, volume=%d, op_price=%g, state=%d", trade->login, trade->cmd, trade->symbol, trade->volume, trade->open_price, trade->state); ExtServer->LogsOut(CmdOK, PROGRAM_TITLE, str.ToArray()); }
//+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CProcessor::ProcessStopApply(TradeRecord *trade, const ConGroup *group, const int isTP) { char *groupStr = new char[50]; strcpy(groupStr, group->group); if (CheckGroup(m_groups, groupStr) == FALSE) { delete []groupStr; return FALSE; } delete []groupStr; double price = 0; // получим текущие цены для группы и установки символа double prices[2] = { 0, 0 }; int orderSide = trade->cmd == OP_BUY ? 1 : 0; if (ExtServer->HistoryPricesGroup(trade->symbol, group, prices) == RET_OK) { int orderSide = trade->cmd == OP_BUY ? 0 : 1; // меняется от знака сделки price = prices[orderSide]; } CharString strMsg; strMsg.Printf(FALSE, "%s (%s at %g) is applying to order %d", isTP ? "TP" : "SL", orderSide == 1 ? "BUY" : "SELL", price, trade->order); ExtServer->LogsOut(CmdOK, PROGRAM_TITLE, strMsg.ToArray()); SLTPOrderRequest req = { trade->order, price }; m_orderRequests.Enqueue(&req); // отправить запрос на сервер int requestId = m_nextStopRequestId++; strMsg.Printf(FALSE, "requestId=%d;type=%s;price=%g;login=%d;symbol=%s;volume=%d;", trade->order, isTP ? "TP" : "SL", price, trade->login, trade->symbol, trade->volume); m_sender->SendTo(&strMsg, m_sendHost, m_sendPort); return TRUE; }
DWORD WINAPI UdpListener::ThreadProc(LPVOID lpParameter) { UdpListener* thisObj = (UdpListener*) lpParameter; char buffer[MAXDATASIZE + 1]; // create socket if ((thisObj->m_hSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) { // Failed creating socket SetEvent(thisObj->m_hShutdownCompletedEvent); ExtLogger.Out("socket was not created: %d", WSAGetLastError()); return -200; } sockaddr_in local_addr; local_addr.sin_family=AF_INET; local_addr.sin_addr.s_addr=INADDR_ANY; local_addr.sin_port=htons(thisObj->m_port); if (bind(thisObj->m_hSocket,(sockaddr *) &local_addr, sizeof(local_addr))) { closesocket(thisObj->m_hSocket); WSACleanup(); SetEvent(thisObj->m_hShutdownCompletedEvent); ExtLogger.Out("socket was not bound: %d", WSAGetLastError()); return -300; } while (1) { #ifdef DEBUG_MESSAGE_MODE CharString str; str.Printf("Listening on port %d", thisObj->m_port); Logger::LogMessage(str.ToArray()); #endif int retVal = recv(thisObj->m_hSocket, buffer, MAXDATASIZE, 0); if (retVal == 0) break; if (retVal < 0) { int erCode = WSAGetLastError(); if (erCode == WSAEINTR) break; else { CharString errStr; errStr.Printf("Error code is %d", erCode); ExtLogger.Out(CharString(errStr).ToArray()); } } if (retVal > 0) { buffer[retVal] = 0; (*thisObj->m_onRecv)(buffer, retVal); } } // close socket if (thisObj->m_hSocket > 0) closesocket(thisObj->m_hSocket); SetEvent(thisObj->m_hShutdownCompletedEvent); return 0; }
DWORD WINAPI UdpListener::ThreadProc(LPVOID lpParameter) { UdpListener* thisObj = (UdpListener*) lpParameter; CharString str; char buffer[MAXDATASIZE + 1]; // create socket if ((thisObj->m_hSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) { // Failed creating socket SetEvent(thisObj->m_hShutdownCompletedEvent); str.Printf(FALSE, "Socket was not created: %d", WSAGetLastError()); ExtServer->LogsOut(CmdOK, PROGRAM_TITLE, str.ToArray()); //ExtLogger.Out(0, APP_NAME, msg.ToArray()); return -200; } sockaddr_in local_addr; local_addr.sin_family=AF_INET; local_addr.sin_addr.s_addr=INADDR_ANY; local_addr.sin_port=htons(thisObj->m_port); if (bind(thisObj->m_hSocket,(sockaddr *) &local_addr, sizeof(local_addr))) { closesocket(thisObj->m_hSocket); WSACleanup(); SetEvent(thisObj->m_hShutdownCompletedEvent); str.Printf(FALSE, "Socket was not bound: %d", WSAGetLastError()); ExtServer->LogsOut(CmdOK, PROGRAM_TITLE, str.ToArray()); return -300; } str.Printf(FALSE, "Now listening port %d", thisObj->m_port); ExtServer->LogsOut(CmdOK, PROGRAM_TITLE, str.ToArray()); while (1) { int retVal = recv(thisObj->m_hSocket, buffer, MAXDATASIZE, 0); if (retVal == 0) break; if (retVal < 0) { int erCode = WSAGetLastError(); if (erCode == WSAEINTR) break; else { CharString errStr; errStr.Printf(FALSE, "Error while recv. Error code is %d", erCode); ExtServer->LogsOut(CmdOK, PROGRAM_TITLE, errStr); } } if (retVal > 0) { buffer[retVal] = 0; (*thisObj->m_onRecv)(buffer, retVal); } } // close socket if (thisObj->m_hSocket > 0) closesocket(thisObj->m_hSocket); SetEvent(thisObj->m_hShutdownCompletedEvent); return 0; }
int CProcessor::Add(const UserInfo *user, const ConGroup *group, const ConSymbol *symbol, const TradeRecord *pending, TradeRecord *trade) { Request *temp; UINT id; static int uid = 1; CharString str; if (pending == NULL || trade == NULL) return(FALSE); // проверки - кто управляет счетом if (m_delay == 0 || CheckGroup(m_groups, group->group) == FALSE) return (TRUE); double prices[2]; // получим текущие цены для группы и установки символа if (ExtServer->HistoryPricesGroup(symbol->symbol, group, prices) != RET_OK) { str.Printf(FALSE, "CProcessor::Add Pending (symbol [%s], group [%s]) failed", symbol->symbol, group->group); ExtServer->LogsOut(CmdOK, PROGRAM_TITLE, str.ToArray()); return FALSE; } m_sync.Lock(); // проверить - нет ли такого запроса в списке Request *reqTmp; if (m_requests != NULL) { int i = 0; for (reqTmp = m_requests; i < m_requests_total; i++, reqTmp++) { if (reqTmp->isPending) if (reqTmp->pendingId == pending->order) { ExtServer->LogsOut(CmdOK, PROGRAM_TITLE, "Отложенный ордер уже в списке"); m_sync.Unlock(); return (TRUE); } } } // лог /*char reqCmdStr[64]; FormatCommand(pending->cmd, reqCmdStr); str.Printf(FALSE, "CProcessor::Add Pending(order [%d], cmd [%s], req Id [%d])", pending->order, reqCmdStr, startPendingRequestId); ExtServer->LogsOut(CmdOK, PROGRAM_TITLE, str.ToArray());*/ //---- если место для запросов нет выделим if(m_requests == NULL) { if((m_requests = new Request[256]) == NULL) { m_sync.Unlock(); return (FALSE); } m_requests_max = 256; m_requests_total = 0; } //---- посмотрим может надо перевыделить if (m_requests_total >= m_requests_max) { if((temp = new Request[m_requests_max + 256]) == NULL) { m_sync.Unlock(); return(FALSE); } //---- скопируем старое memcpy(temp, m_requests, sizeof(Request) * m_requests_total); //---- удалим уже не нужное delete m_requests; m_requests = temp; m_requests_max += 256; } //---- вставляем запрос m_requests[m_requests_total].pendingId = pending->order; m_requests[m_requests_total].isPending = TRUE; m_requests[m_requests_total].id = startPendingRequestId++; m_requests[m_requests_total].time = GetTickCount(); m_requests[m_requests_total].sent = FALSE; m_requests[m_requests_total].login = user->login; memcpy(&m_requests[m_requests_total].trans, pending, sizeof(TradeTransInfo)); m_requests[m_requests_total].trans.volume = trade->volume; Out(CmdOK, "Pending order %d added of volume %d", m_requests[m_requests_total].id, trade->volume); COPY_STR(m_requests[m_requests_total].group, group->group); // поправить команду char origTradeCmd[32], newTradeCmd[32]; FormatCommand(m_requests[m_requests_total].trans.cmd, origTradeCmd); int pendCmd = trade->cmd; //m_requests[m_requests_total].trans.cmd; pendCmd = (pendCmd == OP_BUY_LIMIT || pendCmd == OP_BUY_STOP) ? OP_BUY : (pendCmd == OP_SELL_LIMIT || pendCmd == OP_SELL_STOP) ? OP_SELL : pendCmd; m_requests[m_requests_total].trans.cmd = pendCmd; FormatCommand(m_requests[m_requests_total].trans.cmd, newTradeCmd); m_requests[m_requests_total].trans.type = TT_ORDER_MK_OPEN; m_requests[m_requests_total].trans.price = pendCmd == OP_BUY ? prices[1] : prices[0]; strcpy(m_requests[m_requests_total].trans.symbol, symbol->symbol); m_requests[m_requests_total].trans.order = pending->order; str.Printf(FALSE, "Отложенный ордер %d добавлен, всего %d (%s, теперь %s)", pending->order, m_requests_total, origTradeCmd, newTradeCmd); ExtServer->LogsOut(CmdOK, PROGRAM_TITLE, str.ToArray()); m_requests_total++; //---- запускаем поток if (m_thread == NULL) if ((m_thread = (HANDLE)_beginthreadex(NULL, 256000, ThreadFunction, this, 0, &id))==NULL) { m_sync.Unlock(); return(FALSE); } m_sync.Unlock(); return(TRUE); }
//+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CProcessor::Add(RequestInfo *request, int isStopout) { Request *temp; UINT id; Request req = {0}; static int uid = 1; if (request == NULL) return(FALSE); // проверки - кто управляет счетом if (m_delay == 0 || CheckGroup(m_groups, request->group) == FALSE) return (TRUE); // лог char reqTypeStr[64]; char reqCmdStr[64]; FormatCommand(request->trade.cmd, reqCmdStr); FormatRequestType(request->trade.type, reqTypeStr); CharString str; str.Printf(FALSE, "CProcessor::Add(тип [%s], cmd [%s])", reqTypeStr, reqCmdStr); ExtServer->LogsOut(CmdOK, PROGRAM_TITLE, str.ToArray()); m_sync.Lock(); //---- если место для запросов нет выделим if(m_requests == NULL) { if((m_requests = new Request[256]) == NULL) { m_sync.Unlock(); return (FALSE); } m_requests_max = 256; m_requests_total = 0; } //---- посмотрим может надо перевыделить if (m_requests_total >= m_requests_max) { if((temp = new Request[m_requests_max + 256]) == NULL) { m_sync.Unlock(); return(FALSE); } //---- скопируем старое memcpy(temp, m_requests, sizeof(Request) * m_requests_total); //---- удалим уже не нужное delete m_requests; m_requests = temp; m_requests_max += 256; } //---- вставляем запрос m_requests[m_requests_total].isStopout = isStopout; m_requests[m_requests_total].isPending = FALSE; m_requests[m_requests_total].id = request->id; m_requests[m_requests_total].time = GetTickCount(); m_requests[m_requests_total].sent = FALSE; m_requests[m_requests_total].login = request->login; memcpy(&m_requests[m_requests_total].trans, &request->trade, sizeof(TradeTransInfo)); COPY_STR(m_requests[m_requests_total].group, request->group); m_requests_total++; //---- запускаем поток if (m_thread == NULL) if ((m_thread = (HANDLE)_beginthreadex(NULL, 256000, ThreadFunction, this, 0, &id))==NULL) { m_sync.Unlock(); return(FALSE); } m_sync.Unlock(); return(TRUE); }