change error handling to utilize MQL5 standard error handling

This commit is contained in:
Gunther Schulz
2020-03-02 22:11:32 +01:00
parent 7099ac1cac
commit cc0f9b7575
2 changed files with 243 additions and 169 deletions
+232 -158
View File
@@ -31,6 +31,7 @@
#include <Zmq/Zmq.mqh> #include <Zmq/Zmq.mqh>
#include <Json.mqh> #include <Json.mqh>
#include <EnumStringToInt.mqh> #include <EnumStringToInt.mqh>
#include <ControlErrors.mqh>
//#include <ChartObjects\ChartObject.mqh> //#include <ChartObjects\ChartObject.mqh>
//#include<Canvas\Canvas.mqh> //#include<Canvas\Canvas.mqh>
//#include <Graphics\Graphic.mqh> //#include <Graphics\Graphic.mqh>
@@ -70,14 +71,10 @@ struct SymbolSubscription {
string chartTf; string chartTf;
datetime lastBar; datetime lastBar;
}; };
SymbolSubscription symbolSubscriptions[]; SymbolSubscription symbolSubscriptions[];
//string chartSymbols[];
int symbolSubscriptionCount = 0; int symbolSubscriptionCount = 0;
//string chartSymbolSettings[][3];
// Variables for controlling indicators // Variables for controlling indicators
struct Indicator { struct Indicator {
long id; long id;
string indicatorId; string indicatorId;
@@ -87,12 +84,6 @@ struct Indicator {
}; };
Indicator indicators[]; Indicator indicators[];
int indicatorCount = 0; int indicatorCount = 0;
/*
double indicators[];
string indicatorIds[];
int indicatorParamCount[];
int indicatorBufferCount[];
*/
// Variables for controlling chart // Variables for controlling chart
struct ChartWindow { struct ChartWindow {
@@ -108,6 +99,7 @@ int chartWindowCount = 0;
int chartWindowTimerInterval = 100; int chartWindowTimerInterval = 100;
int chartWindowTimerCounter = 0; int chartWindowTimerCounter = 0;
ControlErrors mControl;
//string chartWindowObjects[]; //string chartWindowObjects[];
@@ -120,36 +112,27 @@ int chartWindowTimerCounter = 0;
bool BindSockets(){ bool BindSockets(){
bool result = false; bool result = false;
result = sysSocket.bind(StringFormat("tcp://%s:%d", HOST,SYS_PORT)); result = sysSocket.bind(StringFormat("tcp://%s:%d", HOST,SYS_PORT));
if (result == false) return result; if (result == false) { return result; } else {Print("Bound 'System' socket on port ", SYS_PORT);}
result = dataSocket.bind(StringFormat("tcp://%s:%d", HOST,DATA_PORT)); result = dataSocket.bind(StringFormat("tcp://%s:%d", HOST,DATA_PORT));
if (result == false) return result; if (result == false) { return result; } else {Print("Bound 'Data' socket on port ", DATA_PORT);}
result = liveSocket.bind(StringFormat("tcp://%s:%d", HOST,LIVE_PORT)); result = liveSocket.bind(StringFormat("tcp://%s:%d", HOST,LIVE_PORT));
if (result == false) return result; if (result == false) { return result; } else {Print("Bound 'Live' socket on port ", LIVE_PORT);}
result = streamSocket.bind(StringFormat("tcp://%s:%d", HOST,STR_PORT)); result = streamSocket.bind(StringFormat("tcp://%s:%d", HOST,STR_PORT));
if (result == false) return result; if (result == false) { return result; } else {Print("Bound 'Streaming' socket on port ", STR_PORT);}
result = indicatorDataSocket.bind(StringFormat("tcp://%s:%d", HOST,IND_DATA_PORT)); result = indicatorDataSocket.bind(StringFormat("tcp://%s:%d", HOST,IND_DATA_PORT));
if (result == false) return result; if (result == false) { return result; } else {Print("Bound 'Indicator Data' socket on port ", IND_DATA_PORT);}
result = chartLiveSocket.bind(StringFormat("tcp://%s:%d", HOST,CHART_LIVE_PORT)); result = chartLiveSocket.bind(StringFormat("tcp://%s:%d", HOST,CHART_LIVE_PORT));
if (result == false) { return result; } else {Print("Bound 'Chart Live' socket on port ", CHART_LIVE_PORT);} if (result == false) { return result; } else {Print("Bound 'Chart Live' socket on port ", CHART_LIVE_PORT);}
result = pubChartLiveSocket.bind(StringFormat("tcp://%s:%d", HOST,PUB_CHART_LIVE_PORT)); result = pubChartLiveSocket.bind(StringFormat("tcp://%s:%d", HOST,PUB_CHART_LIVE_PORT));
if (result == false) { return result; } else {Print("Bound 'PUB Chart Live' socket on port ", PUB_CHART_LIVE_PORT);} if (result == false) { return result; } else {Print("Bound 'PUB Chart Live' socket on port ", PUB_CHART_LIVE_PORT);}
Print("Bound 'System' socket on port ", SYS_PORT);
Print("Bound 'Data' socket on port ", DATA_PORT);
Print("Bound 'Live' socket on port ", LIVE_PORT);
Print("Bound 'Streaming' socket on port ", STR_PORT);
Print("Bound 'Indicator Data' socket on port ", IND_DATA_PORT);
sysSocket.setLinger(1000); sysSocket.setLinger(1000);
dataSocket.setLinger(1000); dataSocket.setLinger(1000);
liveSocket.setLinger(1000); liveSocket.setLinger(1000);
streamSocket.setLinger(1000); streamSocket.setLinger(1000);
indicatorDataSocket.setLinger(1000); indicatorDataSocket.setLinger(1000);
chartLiveSocket.setLinger(1000); chartLiveSocket.setLinger(1000);
//pubChartLiveSocket.setLinger(1000); pubChartLiveSocket.setLinger(1000);
// Number of messages to buffer in RAM. // Number of messages to buffer in RAM.
sysSocket.setSendHighWaterMark(1); sysSocket.setSendHighWaterMark(1);
@@ -158,7 +141,7 @@ bool BindSockets(){
streamSocket.setSendHighWaterMark(50); streamSocket.setSendHighWaterMark(50);
indicatorDataSocket.setSendHighWaterMark(5); indicatorDataSocket.setSendHighWaterMark(5);
chartLiveSocket.setReceiveHighWaterMark(1); // TODO confirm settings chartLiveSocket.setReceiveHighWaterMark(1); // TODO confirm settings
//pubChartLiveSocket.setReceiveHighWaterMark(1); pubChartLiveSocket.setReceiveHighWaterMark(1);
return result; return result;
} }
@@ -167,8 +150,15 @@ bool BindSockets(){
//| Expert initialization function | //| Expert initialization function |
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
int OnInit(){ int OnInit(){
/* Bindinig ZMQ ports on init */
// Settimg up error reporting
mControl.SetAlert(true);
//mControl.SetPrint(true);
mControl.SetSound(false);
mControl.SetWriteFlag(false);
//mControl.SetPlaySoundFile("news.wav");
/* Bindinig ZMQ ports on init */
// Skip reloading of the EA script when the reason to reload is a chart timeframe change // Skip reloading of the EA script when the reason to reload is a chart timeframe change
if (deInitReason != REASON_CHARTCHANGE){ if (deInitReason != REASON_CHARTCHANGE){
@@ -232,9 +222,6 @@ void OnDeinit(const int reason){
ResetSubscriptionsAndIndicators(); ResetSubscriptionsAndIndicators();
EventKillTimer(); EventKillTimer();
for(int i=0;i<ArraySize(chartWindows);i++){
ChartClose(chartWindows[i].id);
}
} }
} }
@@ -308,13 +295,16 @@ void StreamPriceData(){
MqlRates rates[1]; MqlRates rates[1];
int spread[1]; int spread[1];
//if(CopyBuffer(indicators[idx].indicatorHandle, i, fromDate, 1, values) < 0) {
// CheckError(__FUNCTION__, indicatorDataSocket);
//}
if( chartTF == "TICK"){ if( chartTF == "TICK"){
if(SymbolInfoTick(symbol,tick) !=true) { /*error processing */ }; if(SymbolInfoTick(symbol,tick) !=true) { /*mControl.Check();*/ }
thisBar=(datetime) tick.time_msc; thisBar=(datetime) tick.time_msc;
} }
else { else {
if(CopyRates(symbol,period,1,1,rates)!=1) { /*error processing */ }; if(CopyRates(symbol,period,1,1,rates)!=1) { /*mControl.Check();*/ }
if(CopySpread(symbol,period,1,1,spread)!=1) { /*error processing */ }; if(CopySpread(symbol,period,1,1,spread)!=1) { /*mControl.Check();*/; }
thisBar=(datetime)rates[0].time; thisBar=(datetime)rates[0].time;
} }
if(lastBar!=thisBar){ if(lastBar!=thisBar){
@@ -409,7 +399,7 @@ void OnTimer(){
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
void RequestHandler(ZmqMsg &request){ void RequestHandler(ZmqMsg &request){
CJAVal message; CJAVal incomingMessage;
ResetLastError(); ResetLastError();
// Get data from reguest // Get data from reguest
@@ -418,30 +408,43 @@ void RequestHandler(ZmqMsg &request){
if(debug) Print("Processing:"+msg); if(debug) Print("Processing:"+msg);
// Deserialize msg to CJAVal array // Deserialize msg to CJAVal array
/*
if(!message.Deserialize(msg)){ if(!message.Deserialize(msg)){
ActionDoneOrError(65537, __FUNCTION__); ActionDoneOrError(65537, __FUNCTION__);
Alert("Deserialization Error"); Alert("Deserialization Error");
ExpertRemove(); ExpertRemove();
} }
*/
if(!incomingMessage.Deserialize(msg)){
mControl.mSetUserError(65537, GetErrorID(65537));
CheckError(__FUNCTION__);
//ExpertRemove();
}
// Send response to System socket that request was received // Send response to System socket that request was received
// Some historical data requests can take a lot of time // Some historical data requests can take a lot of time
InformClientSocket(sysSocket, "OK"); InformClientSocket(sysSocket, "OK");
// Process action command // Process action command
string action = message["action"].ToStr(); string action = incomingMessage["action"].ToStr();
if(action=="CONFIG") ScriptConfiguration(message); if(action=="CONFIG") ScriptConfiguration(incomingMessage);
else if(action=="ACCOUNT") GetAccountInfo(); else if(action=="ACCOUNT") GetAccountInfo();
else if(action=="BALANCE") GetBalanceInfo(); else if(action=="BALANCE") GetBalanceInfo();
else if(action=="HISTORY") HistoryInfo(message); else if(action=="HISTORY") HistoryInfo(incomingMessage);
else if(action=="TRADE") TradingModule(message); else if(action=="TRADE") TradingModule(incomingMessage);
else if(action=="POSITIONS") GetPositions(message); else if(action=="POSITIONS") GetPositions(incomingMessage);
else if(action=="ORDERS") GetOrders(message); else if(action=="ORDERS") GetOrders(incomingMessage);
else if(action=="RESET") ResetSubscriptionsAndIndicators(); else if(action=="RESET") ResetSubscriptionsAndIndicators();
else if(action=="INDICATOR") IndicatorControl(message); else if(action=="INDICATOR") IndicatorControl(incomingMessage);
else if(action=="CHART") ChartControl(message); else if(action=="CHART") ChartControl(incomingMessage);
// Action command error processing // Action command error processing
else ActionDoneOrError(65538, __FUNCTION__); //else ActionDoneOrError(65538, __FUNCTION__);
else {
mControl.mSetUserError(65538, GetErrorID(65538));
CheckError(__FUNCTION__);
}
} }
@@ -452,7 +455,6 @@ void ScriptConfiguration(CJAVal &dataObject){
string symbol=dataObject["symbol"].ToStr(); string symbol=dataObject["symbol"].ToStr();
string chartTF=dataObject["chartTF"].ToStr(); string chartTF=dataObject["chartTF"].ToStr();
//string actionType=dataObject["actionType"].ToStr();
ArrayResize(symbolSubscriptions, symbolSubscriptionCount+1); ArrayResize(symbolSubscriptions, symbolSubscriptionCount+1);
symbolSubscriptions[symbolSubscriptionCount].symbol = symbol; symbolSubscriptions[symbolSubscriptionCount].symbol = symbol;
@@ -460,25 +462,16 @@ void ScriptConfiguration(CJAVal &dataObject){
// to initialze with value 0 skips the first price // to initialze with value 0 skips the first price
symbolSubscriptions[symbolSubscriptionCount].lastBar = 0; symbolSubscriptions[symbolSubscriptionCount].lastBar = 0;
symbolSubscriptionCount++; symbolSubscriptionCount++;
/* /*
string symbArr[1];
symbArr[0]= symbol;
if (!HasChartSymbol(symbol, chartTF)) {
ArrayInsert(chartSymbols,symbArr,0);
ArrayResize(chartSymbolSettings,symbolSubscriptionCount+1);
chartSymbolSettings[symbolSubscriptionCount][0]=symbol;
chartSymbolSettings[symbolSubscriptionCount][1]=chartTF;
// lastBar
chartSymbolSettings[symbolSubscriptionCount][2]=0; // to initialze with value 0 skips the first price
symbolSubscriptionCount++;
}
*/
if(SymbolInfoInteger(symbol, SYMBOL_EXIST)){ if(SymbolInfoInteger(symbol, SYMBOL_EXIST)){
ActionDoneOrError(ERR_SUCCESS, __FUNCTION__); ActionDoneOrError(ERR_SUCCESS, __FUNCTION__);
} }
else ActionDoneOrError(ERR_MARKET_UNKNOWN_SYMBOL, __FUNCTION__); else ActionDoneOrError(ERR_MARKET_UNKNOWN_SYMBOL, __FUNCTION__);
*/
mControl.mResetLastError();
SymbolInfoString(symbol, SYMBOL_DESCRIPTION);
if(!CheckError(__FUNCTION__)) ActionDoneOrError(ERR_SUCCESS, __FUNCTION__, "ERR_SUCCESS");
//if(!CheckError(__FUNCTION__, dataSocket)) ActionDoneOrError(ERR_SUCCESS, __FUNCTION__, dataSocket);
} }
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
@@ -508,9 +501,6 @@ void StartIndicator(CJAVal &dataObject){
indicatorCount++; indicatorCount++;
ArrayResize(indicators,indicatorCount); ArrayResize(indicators,indicatorCount);
//ArrayResize(indicatorIds,indicatorCount);
//ArrayResize(indicatorParamCount,indicatorCount);
//ArrayResize(indicatorBufferCount,indicatorCount);
int idx = indicatorCount-1; int idx = indicatorCount-1;
@@ -567,19 +557,31 @@ void StartIndicator(CJAVal &dataObject){
break; break;
} }
CJAVal message; CJAVal message;
message["id"] = (string) id; if(mControl.mGetLastError())
{
string desc = mControl.mGetDesc();
int lastError = mControl.mGetLastError();
mControl.Check();
string t=message.Serialize(); message["error"]=(bool) true;
if(debug) Print(t); message["lastError"]=(string) lastError;
InformClientSocket(indicatorDataSocket,t); message["description"]=desc;
message["function"]=(string) __FUNCTION__;
string t=message.Serialize();
if(debug) Print(t);
InformClientSocket(indicatorDataSocket,t);
}
else
{
message["error"]=(bool) false;
message["id"] = (string) id;
string t=message.Serialize();
if(debug) Print(t);
InformClientSocket(indicatorDataSocket,t);
}
// TODO more error handling
//if(SymbolInfoInteger(symbol, SYMBOL_EXIST)){
// ActionDoneOrError(ERR_SUCCESS, __FUNCTION__);
//}
//else ActionDoneOrError(ERR_MARKET_UNKNOWN_SYMBOL, __FUNCTION__);
} }
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
@@ -596,7 +598,7 @@ void GetIndicatorResult(CJAVal &dataObject) {
int idx = GetIndicatorIdxByIndicatorId(id); int idx = GetIndicatorIdxByIndicatorId(id);
double values[2]; double values[2];
ArrayResize(values, indicators[idx].indicatorBufferCount);
CJAVal results; CJAVal results;
// Cycle through all avaliable buffer positions // Cycle through all avaliable buffer positions
for(int i=0;i<indicators[idx].indicatorBufferCount;i++){ for(int i=0;i<indicators[idx].indicatorBufferCount;i++){
@@ -604,16 +606,29 @@ void GetIndicatorResult(CJAVal &dataObject) {
values[1] = 0.0; values[1] = 0.0;
results[i] = 0.0; results[i] = 0.0;
if(idx >= 0) { if(idx >= 0) {
if(CopyBuffer(indicators[idx].indicatorHandle, i, fromDate, 1, values) < 0) {/* Error handling */} if(CopyBuffer(indicators[idx].indicatorHandle, i, fromDate, 1, values) < 0) {
if(mControl.mGetLastError())
{
CJAVal message;
string desc = mControl.mGetDesc();
int lastError = mControl.mGetLastError();
mControl.Check();
message["error"]=(bool) true;
message["lastError"]=(string) lastError;
message["description"]=desc;
message["function"]=(string) __FUNCTION__;
string t=message.Serialize();
if(debug) Print(t);
InformClientSocket(indicatorDataSocket,t);
}
}
results[i] = DoubleToString(values[0]); results[i] = DoubleToString(values[0]);
} }
else {
// TODO error handling
}
} }
CJAVal message; CJAVal message;
message["error"]=(bool) false;
message["id"] = (string) id; message["id"] = (string) id;
message["data"].Set(results); message["data"].Set(results);
@@ -621,11 +636,6 @@ void GetIndicatorResult(CJAVal &dataObject) {
if(debug) Print(t); if(debug) Print(t);
InformClientSocket(indicatorDataSocket,t); InformClientSocket(indicatorDataSocket,t);
// TODO more error handling
//if(SymbolInfoInteger(symbol, SYMBOL_EXIST)){
// ActionDoneOrError(ERR_SUCCESS, __FUNCTION__);
//}
//else ActionDoneOrError(ERR_MARKET_UNKNOWN_SYMBOL, __FUNCTION__);
} }
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
@@ -655,9 +665,6 @@ void OpenChart(CJAVal &dataObject){
chartWindowCount++; chartWindowCount++;
ArrayResize(chartWindows,chartWindowCount); ArrayResize(chartWindows,chartWindowCount);
//ArrayResize(chartWindowIds,chartWindowCount);
//ArrayResize(chartWindowPeriods,chartWindowCount);
// ArrayResize(chartWindowObjects,chartWindowCount);
int idx = chartWindowCount-1; int idx = chartWindowCount-1;
@@ -665,7 +672,6 @@ void OpenChart(CJAVal &dataObject){
ENUM_TIMEFRAMES period = GetTimeframe(chartTF); ENUM_TIMEFRAMES period = GetTimeframe(chartTF);
chartWindows[idx].id = ChartOpen(symbol, period); chartWindows[idx].id = ChartOpen(symbol, period);
//chartWindowPeriods[idx] = period;
CJAVal message; CJAVal message;
message["chartId"] = (string) chartId; message["chartId"] = (string) chartId;
@@ -694,17 +700,18 @@ void AddIndicatorChartToChart(CJAVal &dataObject){
double chartIndicatorHandle = iCustom(ChartSymbol(ChartId),ChartPeriod(ChartId),"JsonAPIIndicator",chartIndicatorId,shortname,colorstyle,linetype,linestyle,linewidth); double chartIndicatorHandle = iCustom(ChartSymbol(ChartId),ChartPeriod(ChartId),"JsonAPIIndicator",chartIndicatorId,shortname,colorstyle,linetype,linestyle,linewidth);
ChartIndicatorAdd(ChartId, chartIndicatorSubWindow, chartIndicatorHandle); if(ChartIndicatorAdd(ChartId, chartIndicatorSubWindow, chartIndicatorHandle)){
chartWindows[idx].indicatorId = chartIndicatorId;
chartWindows[idx].indicatorHandle = chartIndicatorHandle;
}
if(!CheckError(__FUNCTION__)) {
CJAVal message;
message["chartId"] = (string) chartIdStr;
chartWindows[idx].indicatorId = chartIndicatorId; string t=message.Serialize();
chartWindows[idx].indicatorHandle = chartIndicatorHandle; if(debug) Print(t);
InformClientSocket(dataSocket,t);
CJAVal message; }
message["chartId"] = (string) chartIdStr;
string t=message.Serialize();
if(debug) Print(t);
InformClientSocket(dataSocket,t);
} }
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
@@ -943,19 +950,22 @@ void HistoryInfo(CJAVal &dataObject){
ulong toDateM = StringToTime(toDate); ulong toDateM = StringToTime(toDate);
tickCount=CopyTicksRange(symbol,tickArray,COPY_TICKS_ALL,1000*(ulong)fromDateM,1000*(ulong)toDateM); tickCount=CopyTicksRange(symbol,tickArray,COPY_TICKS_ALL,1000*(ulong)fromDateM,1000*(ulong)toDateM);
if(tickCount){ if(tickCount < 0) {
ActionDoneOrError(ERR_SUCCESS , __FUNCTION__); mControl.mSetUserError(65541, GetErrorID(65541));
} }
else ActionDoneOrError(65541 , __FUNCTION__); CheckError(__FUNCTION__);
Print("Preparing data of ", tickCount, " ticks for ", symbol); Print("Preparing data of ", tickCount, " ticks for ", symbol);
int file_handle=FileOpen(outputFile, FILE_WRITE | FILE_CSV); int file_handle=FileOpen(outputFile, FILE_WRITE | FILE_CSV);
if(file_handle!=INVALID_HANDLE){ if(file_handle!=INVALID_HANDLE){
msg["status"] = (string) "CONNECTED"; msg["status"] = (string) "CONNECTED";
msg["type"] = (string) "NORMAL"; msg["type"] = (string) "NORMAL";
msg["data"] = (string) StringFormat("Writing to: %s\\%s", TerminalInfoString(TERMINAL_DATA_PATH), outputFile); msg["data"] = (string) StringFormat("Writing to: %s\\%s", TerminalInfoString(TERMINAL_DATA_PATH), outputFile);
if(liveStream) InformClientSocket(liveSocket, msg.Serialize()); if(liveStream) InformClientSocket(liveSocket, msg.Serialize());
ActionDoneOrError(ERR_SUCCESS , __FUNCTION__); ActionDoneOrError(ERR_SUCCESS , __FUNCTION__, "ERR_SUCCESS");
//ActionDoneOrError(ERR_SUCCESS , __FUNCTION__, dataSocket);
// Inform client that file is avalable for writing
PrintFormat("%s file is available for writing",fileName); PrintFormat("%s file is available for writing",fileName);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH)); PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
//--- write the time and values of signals to the file //--- write the time and values of signals to the file
@@ -976,8 +986,11 @@ void HistoryInfo(CJAVal &dataObject){
} }
else{ else{
PrintFormat("Failed to open %s file, Error code = %d",fileName,GetLastError()); // File is not available for writing
ActionDoneOrError(65542 , __FUNCTION__); mControl.mSetUserError(65542, GetErrorID(65542));
CheckError(__FUNCTION__);
//PrintFormat("Failed to open %s file, Error code = %d",fileName,GetLastError());
//ActionDoneOrError(65542 , __FUNCTION__);
} }
connectedFlag=false; connectedFlag=false;
} }
@@ -1005,16 +1018,16 @@ void HistoryInfo(CJAVal &dataObject){
if(dataObject["toDate"].ToInt()!=NULL)Print("4) Date to:"+TimeToString(toDate)); if(dataObject["toDate"].ToInt()!=NULL)Print("4) Date to:"+TimeToString(toDate));
barCount=CopyRates(symbol,period,fromDate,toDate,r); barCount=CopyRates(symbol,period,fromDate,toDate,r);
if(CopySpread(symbol,period, fromDate, toDate, spread)!=1) { /*error processing */ } if(CopySpread(symbol,period, fromDate, toDate, spread)!=1) {
mControl.mSetUserError(65541, GetErrorID(65541));
if(barCount){ //CheckError(__FUNCTION__);
ActionDoneOrError(ERR_SUCCESS, __FUNCTION__);
} }
else ActionDoneOrError(65541, __FUNCTION__);
Print("Preparing tick data of ", barCount, " ticks for ", symbol); Print("Preparing tick data of ", barCount, " ticks for ", symbol);
int file_handle=FileOpen(outputFile, FILE_WRITE | FILE_CSV); int file_handle=FileOpen(outputFile, FILE_WRITE | FILE_CSV);
if(file_handle!=INVALID_HANDLE){ if(file_handle!=INVALID_HANDLE){
ActionDoneOrError(ERR_SUCCESS , __FUNCTION__, "ERR_SUCCESS");
//ActionDoneOrError(ERR_SUCCESS , __FUNCTION__, dataSocket);
PrintFormat("%s file is available for writing",outputFile); PrintFormat("%s file is available for writing",outputFile);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH)); PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
//--- write the time and values of signals to the file //--- write the time and values of signals to the file
@@ -1025,8 +1038,10 @@ void HistoryInfo(CJAVal &dataObject){
PrintFormat("Data is written, %s file is closed", outputFile); PrintFormat("Data is written, %s file is closed", outputFile);
} }
else{ else{
PrintFormat("Failed to open %s file, Error code = %d",outputFile,GetLastError()); //PrintFormat("Failed to open %s file, Error code = %d",outputFile,GetLastError());
ActionDoneOrError(65542 , __FUNCTION__); //ActionDoneOrError(65542 , __FUNCTION__);
mControl.mSetUserError(65542, GetErrorID(65542));
CheckError(__FUNCTION__);
} }
} }
@@ -1091,7 +1106,7 @@ void HistoryInfo(CJAVal &dataObject){
} }
barCount=CopyRates(symbol, period, fromDate, toDate, r); barCount=CopyRates(symbol, period, fromDate, toDate, r);
if(CopySpread(symbol,period, fromDate, toDate, spread)!=1) { /*error processing */ } if(CopySpread(symbol,period, fromDate, toDate, spread)!=1) { /*mControl.Check();*/ }
if(barCount){ if(barCount){
for(int i=0;i<barCount;i++){ for(int i=0;i<barCount;i++){
@@ -1145,7 +1160,11 @@ void HistoryInfo(CJAVal &dataObject){
InformClientSocket(dataSocket,t); InformClientSocket(dataSocket,t);
} }
// Error wrong action type // Error wrong action type
else ActionDoneOrError(65538, __FUNCTION__); //else ActionDoneOrError(65538, __FUNCTION__);
else {
mControl.mSetUserError(65538, GetErrorID(65538));
CheckError(__FUNCTION__);
}
} }
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
@@ -1161,7 +1180,8 @@ void GetPositions(CJAVal &dataObject){
if(!positionsTotal) data["positions"].Add(position); if(!positionsTotal) data["positions"].Add(position);
// Go through positions in a loop // Go through positions in a loop
for(int i=0;i<positionsTotal;i++){ for(int i=0;i<positionsTotal;i++){
ResetLastError(); //ResetLastError();
mControl.mResetLastError();
if(myposition.Select(PositionGetSymbol(i))){ if(myposition.Select(PositionGetSymbol(i))){
position["id"]=PositionGetInteger(POSITION_IDENTIFIER); position["id"]=PositionGetInteger(POSITION_IDENTIFIER);
@@ -1178,7 +1198,8 @@ void GetPositions(CJAVal &dataObject){
data["positions"].Add(position); data["positions"].Add(position);
} }
// Error handling // Error handling
else ActionDoneOrError(ERR_TRADE_POSITION_NOT_FOUND, __FUNCTION__); //else ActionDoneOrError(ERR_TRADE_POSITION_NOT_FOUND, __FUNCTION__);
CheckError(__FUNCTION__);
} }
string t=data.Serialize(); string t=data.Serialize();
@@ -1190,7 +1211,8 @@ void GetPositions(CJAVal &dataObject){
//| Fetch orders information | //| Fetch orders information |
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
void GetOrders(CJAVal &dataObject){ void GetOrders(CJAVal &dataObject){
ResetLastError(); //ResetLastError();
mControl.mResetLastError();
COrderInfo myorder; COrderInfo myorder;
CJAVal data, order; CJAVal data, order;
@@ -1217,7 +1239,8 @@ void GetOrders(CJAVal &dataObject){
data["orders"].Add(order); data["orders"].Add(order);
} }
// Error handling // Error handling
else ActionDoneOrError(ERR_TRADE_ORDER_NOT_FOUND, __FUNCTION__); //else ActionDoneOrError(ERR_TRADE_ORDER_NOT_FOUND, __FUNCTION__);
CheckError(__FUNCTION__);
} }
} }
@@ -1226,47 +1249,20 @@ void GetOrders(CJAVal &dataObject){
InformClientSocket(dataSocket,t); InformClientSocket(dataSocket,t);
} }
//+------------------------------------------------------------------+
//| Clear symbol subscriptions and indicators |
//+------------------------------------------------------------------+
void ResetSubscriptionsAndIndicators(){
ArrayFree(symbolSubscriptions);
//ArrayFree(chartSymbolSettings);
symbolSubscriptionCount=0;
bool error = false;
for(int i=0;i<indicatorCount;i++){
if(!IndicatorRelease(indicators[i].indicatorHandle)) error = true;
}
ArrayFree(indicators);
//ArrayFree(indicatorIds);
indicatorCount = 0;
for(int i=0;i<ArraySize(chartWindows);i++){
if(!IndicatorRelease(chartWindows[i].indicatorHandle)) error = true;
ChartClose(chartWindows[i].id);
}
if(ArraySize(symbolSubscriptions)!=0 || ArraySize(indicators)!=0 || ArraySize(chartWindows)!=0 || error){
// TODO Implement propery error codes and descriptions
ActionDoneOrError(GetLastError(), __FUNCTION__);
}
else ActionDoneOrError(ERR_SUCCESS, __FUNCTION__);
}
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
//| Trading module | //| Trading module |
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
void TradingModule(CJAVal &dataObject){ void TradingModule(CJAVal &dataObject){
ResetLastError(); //ResetLastError();
mControl.mResetLastError();
CTrade trade; CTrade trade;
string actionType = dataObject["actionType"].ToStr(); string actionType = dataObject["actionType"].ToStr();
string symbol=dataObject["symbol"].ToStr(); string symbol=dataObject["symbol"].ToStr();
// Check if symbol is the same // Check if symbol is the same
if(!(symbol==_Symbol)) ActionDoneOrError(ERR_MARKET_UNKNOWN_SYMBOL, __FUNCTION__); // if(!(symbol==_Symbol)) ActionDoneOrError(ERR_MARKET_UNKNOWN_SYMBOL, __FUNCTION__);
SymbolInfoString(symbol, SYMBOL_DESCRIPTION);
CheckError(__FUNCTION__);
int idNimber=dataObject["id"].ToInt(); int idNimber=dataObject["id"].ToInt();
double volume=dataObject["volume"].ToDbl(); double volume=dataObject["volume"].ToDbl();
@@ -1369,7 +1365,11 @@ void TradingModule(CJAVal &dataObject){
} }
} }
// Action type dosen't exist // Action type dosen't exist
else ActionDoneOrError(65538, __FUNCTION__); //else ActionDoneOrError(65538, __FUNCTION__);
else {
mControl.mSetUserError(65538, GetErrorID(65538));
CheckError(__FUNCTION__);
}
// This part of the code runs if order was not completed // This part of the code runs if order was not completed
OrderDoneOrError(true, __FUNCTION__, trade); OrderDoneOrError(true, __FUNCTION__, trade);
@@ -1478,10 +1478,45 @@ void OrderDoneOrError(bool error, string funcName, CTrade &trade){
InformClientSocket(dataSocket,t); InformClientSocket(dataSocket,t);
} }
//+------------------------------------------------------------------+
//| Error reporting |
//+------------------------------------------------------------------+
bool CheckError(string funcName) {
//string desc = "OK";
int lastError = ERR_SUCCESS;
if(mControl.mGetLastError())
{
string desc = mControl.mGetDesc();
lastError = mControl.mGetLastError();
if(debug) Print("Error handling source: ", funcName ," description: ", desc);
Print("Error handling source: ", funcName ," description: ", desc);
mControl.Check();
ActionDoneOrError(lastError, funcName, desc);
//ActionDoneOrError(lastError, __FUNCTION__, socket, desc)
}
if(lastError==0)
return false;
else
return true;
//Print("lasterror", lastError);
//return lastError;
/*
else
{
mControl.Check();
ActionDoneOrError(ERR_SUCCESS, callingFunction);
//ActionDoneOrError(lastError, __FUNCTION__, socket, desc);
}
*/
}
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
//| Action confirmation | //| Action confirmation |
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
void ActionDoneOrError(int lastError, string funcName){ void ActionDoneOrError(int lastError, string funcName, string desc){
CJAVal conf; CJAVal conf;
@@ -1489,12 +1524,16 @@ void ActionDoneOrError(int lastError, string funcName){
if(lastError==0) conf["error"]=(bool)false; if(lastError==0) conf["error"]=(bool)false;
conf["lastError"]=(string) lastError; conf["lastError"]=(string) lastError;
conf["description"]=GetErrorID(lastError); //conf["lastError"]=(int) lastError;
//conf["description"]=GetErrorID(lastError);
conf["description"]=(string) desc;
conf["function"]=(string) funcName; conf["function"]=(string) funcName;
string t=conf.Serialize(); string t=conf.Serialize();
if(debug) Print(t); if(debug) Print(t);
InformClientSocket(dataSocket,t); InformClientSocket(dataSocket,t);
//InformClientSocket(socket,t);
} }
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
@@ -1505,7 +1544,40 @@ void InformClientSocket(Socket &workingSocket,string replyMessage){
// non-blocking // non-blocking
workingSocket.send(replyMessage,true); workingSocket.send(replyMessage,true);
// TODO: Array out of range error // TODO: Array out of range error
ResetLastError(); //ResetLastError();
mControl.mResetLastError();
//mControl.Check();
}
//+------------------------------------------------------------------+
//| Clear symbol subscriptions and indicators |
//+------------------------------------------------------------------+
void ResetSubscriptionsAndIndicators(){
ArrayFree(symbolSubscriptions);
symbolSubscriptionCount=0;
bool error = false;
for(int i=0;i<indicatorCount;i++){
if(!IndicatorRelease(indicators[i].indicatorHandle)) error = true;
}
ArrayFree(indicators);
indicatorCount = 0;
for(int i=0;i<ArraySize(chartWindows);i++){
// TODO check if chart exists first: if(ChartGetInteger...
if(!IndicatorRelease(chartWindows[i].indicatorHandle)) error = true;
ChartClose(chartWindows[i].id);
}
ArrayFree(chartWindows);
if(ArraySize(symbolSubscriptions)!=0 || ArraySize(indicators)!=0 || ArraySize(chartWindows)!=0 || error){
// Only Alert. Fails too often, this happens when i.e. the backtrader script gets aborted unexpectedly
// mControl.Check();
// mControl.mSetUserError(65540, GetErrorID(65540));
//CheckError(__FUNCTION__);
}
ActionDoneOrError(ERR_SUCCESS, __FUNCTION__, "ERR_SUCCESS");
} }
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
@@ -1566,19 +1638,21 @@ string GetRetcodeID(int retcode){
string GetErrorID(int error){ string GetErrorID(int error){
switch(error){ switch(error){
/*
case 0: return("ERR_SUCCESS"); break; case 0: return("ERR_SUCCESS"); break;
case 4301: return("ERR_MARKET_UNKNOWN_SYMBOL"); break; case 4301: return("ERR_MARKET_UNKNOWN_SYMBOL"); break;
case 4303: return("ERR_MARKET_WRONG_PROPERTY"); break; case 4303: return("ERR_MARKET_WRONG_PROPERTY"); break;
case 4752: return("ERR_TRADE_DISABLED"); break; case 4752: return("ERR_TRADE_DISABLED"); break;
case 4753: return("ERR_TRADE_POSITION_NOT_FOUND"); break; case 4753: return("ERR_TRADE_POSITION_NOT_FOUND"); break;
case 4754: return("ERR_TRADE_ORDER_NOT_FOUND"); break; case 4754: return("ERR_TRADE_ORDER_NOT_FOUND"); break;
*/
// Custom errors // Custom errors
case 65537: return("ERR_DESERIALIZATION"); break; case 65537: return("ERR_DESERIALIZATION"); break;
case 65538: return("ERR_WRONG_ACTION"); break; case 65538: return("ERR_WRONG_ACTION"); break;
case 65539: return("ERR_WRONG_ACTION_TYPE"); break; case 65539: return("ERR_WRONG_ACTION_TYPE"); break;
//case 65540: return("ERR_CLEAR_SUBSCRIPTIONS_FAILED"); break; case 65540: return("ERR_CLEAR_SUBSCRIPTIONS_FAILED"); break;
case 65541: return("ERR_RETRIEVE_DATA_FAILED"); break; case 65541: return("ERR_RETRIEVE_DATA_FAILED"); break;
case 65542: return("ERR_CFILE_CREATION_FAILED"); break; case 65542: return("ERR_CVS_FILE_CREATION_FAILED"); break;
default: default:
Binary file not shown.