Issue #136: Updated structures MqlTick, MqlBook with new field volume_real. Remove redundant code from MtApiService.

This commit is contained in:
vdemydiuk
2019-03-18 17:31:54 +02:00
parent d1387148df
commit 44fab4dae1
15 changed files with 81 additions and 228 deletions
-47
View File
@@ -31,22 +31,6 @@ public struct CMqlRates
int spread; // Spread int spread; // Spread
__int64 real_volume; // Trade volume __int64 real_volume; // Trade volume
}; };
public struct CMqlTick
{
__int64 time; // Time of the last prices update
double bid; // Current Bid price
double ask; // Current Ask price
double last; // Price of the last deal (Last)
unsigned __int64 volume; // Volume for the current Last price
};
public struct CMqlBookInfo
{
int type; // Order type from ENUM_BOOK_TYPE enumeration
double price; // Price
__int64 volume; // Volume
};
#pragma pack(pop) #pragma pack(pop)
void convertSystemString(wchar_t* dest, String^ src) void convertSystemString(wchar_t* dest, String^ src)
@@ -224,37 +208,6 @@ _DLLAPI int _stdcall sendMqlRatesArrayResponse(int expertHandle, CMqlRates value
}, err, 0); }, err, 0);
} }
_DLLAPI int _stdcall sendMqlTickResponse(int expertHandle, CMqlTick* response, wchar_t* err)
{
return Execute<int>([&expertHandle, response]() {
MtMqlTick^ mtResponse = gcnew MtMqlTick();
mtResponse->time = response->time;
mtResponse->bid = response->bid;
mtResponse->ask = response->ask;
mtResponse->last = response->last;
mtResponse->volume = response->volume;
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlTick(mtResponse));
return 1;
}, err, 0);
}
_DLLAPI int _stdcall sendMqlBookInfoArrayResponse(int expertHandle, CMqlBookInfo values[], int size, wchar_t* err)
{
return Execute<int>([&expertHandle, values, &size]() {
array<MtMqlBookInfo^>^ list = gcnew array<MtMqlBookInfo^>(size);
for (int i = 0; i < size; i++)
{
MtMqlBookInfo^ info = gcnew MtMqlBookInfo();
info->type = values[i].type;
info->price = values[i].price;
info->volume = values[i].volume;
list[i] = info;
}
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlBookInfoArray(list));
return 1;
}, err, 0);
}
//----------- get values ------------------------------- //----------- get values -------------------------------
_DLLAPI int _stdcall getCommandType(int expertHandle, int* res, wchar_t* err) _DLLAPI int _stdcall getCommandType(int expertHandle, int* res, wchar_t* err)
-2
View File
@@ -72,9 +72,7 @@
<Compile Include="MtClient.cs" /> <Compile Include="MtClient.cs" />
<Compile Include="MtCommandTask.cs" /> <Compile Include="MtCommandTask.cs" />
<Compile Include="MtEvent.cs" /> <Compile Include="MtEvent.cs" />
<Compile Include="MtMqlBookInfo.cs" />
<Compile Include="MtMqlRates.cs" /> <Compile Include="MtMqlRates.cs" />
<Compile Include="MtMqlTick.cs" />
<Compile Include="MtMqlTradeRequest.cs" /> <Compile Include="MtMqlTradeRequest.cs" />
<Compile Include="MtRegistryManager.cs" /> <Compile Include="MtRegistryManager.cs" />
<Compile Include="MtConnectionProfile.cs" /> <Compile Include="MtConnectionProfile.cs" />
-17
View File
@@ -1,17 +0,0 @@
using System.Runtime.Serialization;
namespace MTApiService
{
[DataContract]
public class MtMqlBookInfo
{
[DataMember]
public int type { get; set; }
[DataMember]
public double price { get; set; }
[DataMember]
public long volume { get; set; }
}
}
-23
View File
@@ -1,23 +0,0 @@
using System.Runtime.Serialization;
namespace MTApiService
{
[DataContract]
public class MtMqlTick
{
[DataMember]
public long time { get; set; } // Time of the last prices update
[DataMember]
public double bid { get; set; } // Current Bid price
[DataMember]
public double ask { get; set; } // Current Ask price
[DataMember]
public double last { get; set; } // Price of the last deal (Last)
[DataMember]
public ulong volume { get; set; } // Volume for the current Last price
}
}
+2 -42
View File
@@ -17,9 +17,8 @@ namespace MTApiService
typeof(MtResponseString), typeof(MtResponseBool), typeof(MtResponseString), typeof(MtResponseBool),
typeof(MtResponseLong), typeof(MtResponseULong), typeof(MtResponseLong), typeof(MtResponseULong),
typeof(MtResponseDoubleArray), typeof(MtResponseIntArray), typeof(MtResponseDoubleArray), typeof(MtResponseIntArray),
typeof(MtResponseLongArray), typeof(MtResponseMqlTick), typeof(MtResponseLongArray),
typeof(MtResponseArrayList), typeof(MtResponseMqlRatesArray), typeof(MtResponseArrayList), typeof(MtResponseMqlRatesArray)};
typeof(MtResponseMqlBookInfoArray)};
} }
public abstract object GetValue(); public abstract object GetValue();
@@ -255,43 +254,4 @@ namespace MTApiService
return Value.ToString(); return Value.ToString();
} }
} }
[DataContract]
public class MtResponseMqlTick : MtResponse
{
public MtResponseMqlTick(MtMqlTick value)
{
Value = value;
}
[DataMember]
public MtMqlTick Value { get; private set; }
public override object GetValue() { return Value; }
public override string ToString()
{
return Value.ToString();
}
}
[DataContract]
public class MtResponseMqlBookInfoArray : MtResponse
{
public MtResponseMqlBookInfoArray(MtMqlBookInfo[] value)
{
Value = value;
}
[DataMember]
public MtMqlBookInfo[] Value { get; private set; }
public override object GetValue() { return Value; }
public override string ToString()
{
return Value.ToString();
}
}
} }
+2 -2
View File
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.30.0")] [assembly: AssemblyVersion("1.0.31.0")]
[assembly: AssemblyFileVersion("1.0.30.0")] [assembly: AssemblyFileVersion("1.0.31.0")]
+1
View File
@@ -16,6 +16,7 @@ namespace MtApi5
public ENUM_BOOK_TYPE type { get; set; } // Order type from ENUM_BOOK_TYPE enumeration public ENUM_BOOK_TYPE type { get; set; } // Order type from ENUM_BOOK_TYPE enumeration
public double price { get; set; } // Price public double price { get; set; } // Price
public long volume { get; set; } // Volume public long volume { get; set; } // Volume
public double volume_real { get; set; } // Volume for the current Last price with greater accuracy
public override string ToString() public override string ToString()
{ {
+2 -1
View File
@@ -23,7 +23,8 @@ namespace MtApi5
public double bid { get; set; } // Current Bid price public double bid { get; set; } // Current Bid price
public double ask { get; set; } // Current Ask price public double ask { get; set; } // Current Ask price
public double last { get; set; } // Price of the last deal (Last) public double last { get; set; } // Price of the last deal (Last)
public ulong volume { get; set; } // Volume for the current Last price public ulong volume { get; set; } // Volume for the current Last price
public double volume_real { get; set; } // Volume for the current Last price with greater accuracy
public DateTime time => Mt5TimeConverter.ConvertFromMtTime(MtTime); public DateTime time => Mt5TimeConverter.ConvertFromMtTime(MtTime);
} }
+1
View File
@@ -98,6 +98,7 @@
<Compile Include="Requests\Response.cs" /> <Compile Include="Requests\Response.cs" />
<Compile Include="Requests\SymbolInfoStringRequest.cs" /> <Compile Include="Requests\SymbolInfoStringRequest.cs" />
<Compile Include="Requests\SymbolInfoStringResult.cs" /> <Compile Include="Requests\SymbolInfoStringResult.cs" />
<Compile Include="Requests\SymbolInfoTickRequest.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\MTApiService\MTApiService.csproj"> <ProjectReference Include="..\MTApiService\MTApiService.csproj">
+16 -8
View File
@@ -1476,19 +1476,27 @@ namespace MtApi5
///<param name="tick"> Link to the structure of the MqlTick type, to which the current prices and time of the last price update will be placed.</param> ///<param name="tick"> Link to the structure of the MqlTick type, to which the current prices and time of the last price update will be placed.</param>
public bool SymbolInfoTick(string symbol, out MqlTick tick) public bool SymbolInfoTick(string symbol, out MqlTick tick)
{ {
var commandParameters = new ArrayList { symbol }; tick = SendRequest<MqlTick>(new SymbolInfoTickRequest
var retVal = SendCommand<MtMqlTick>(Mt5CommandType.SymbolInfoTick, commandParameters);
tick = null;
if (retVal != null)
{ {
tick = new MqlTick { MtTime = retVal.time, ask = retVal.ask, bid = retVal.bid, last = retVal.last, volume = retVal.volume }; SymbolName = symbol
} });
return tick != null; return tick != null;
} }
///<summary>
///The function returns current prices of a specified symbol in a variable of the MqlTick type.
///</summary>
///<param name="symbol">Symbol name.</param>
public MqlTick SymbolInfoTick(string symbol)
{
var tick = SendRequest<MqlTick>(new SymbolInfoTickRequest
{
SymbolName = symbol
});
return tick;
}
///<summary> ///<summary>
///Allows receiving time of beginning and end of the specified quoting sessions for a specified symbol and weekday. ///Allows receiving time of beginning and end of the specified quoting sessions for a specified symbol and weekday.
+2 -1
View File
@@ -15,6 +15,7 @@ namespace MtApi5.Requests
SymbolInfoString = 8, SymbolInfoString = 8,
ChartTimePriceToXY = 9, ChartTimePriceToXY = 9,
ChartXYToTimePrice = 10, ChartXYToTimePrice = 10,
PositionClose = 11 PositionClose = 11,
SymbolInfoTick = 12
} }
} }
+14
View File
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MtApi5.Requests
{
internal class SymbolInfoTickRequest : RequestBase
{
public override RequestType RequestType => RequestType.SymbolInfoTick;
public string SymbolName { get; set; }
}
}
+2 -1
View File
@@ -1030,6 +1030,7 @@ namespace MtApi5TestClient
AddLog($"SymbolInfoTick(EURUSD) tick.ask = {result.ask}"); AddLog($"SymbolInfoTick(EURUSD) tick.ask = {result.ask}");
AddLog($"SymbolInfoTick(EURUSD) tick.last = {result.last}"); AddLog($"SymbolInfoTick(EURUSD) tick.last = {result.last}");
AddLog($"SymbolInfoTick(EURUSD) tick.volume = {result.volume}"); AddLog($"SymbolInfoTick(EURUSD) tick.volume = {result.volume}");
AddLog($"SymbolInfoTick(EURUSD) tick.volume_real = {result.volume_real}");
} }
private async void ExecuteSymbolInfoSessionQuote(object o) private async void ExecuteSymbolInfoSessionQuote(object o)
@@ -1100,7 +1101,7 @@ namespace MtApi5TestClient
for (var i = 0; i < result.Length; i++) for (var i = 0; i < result.Length; i++)
{ {
AddLog($"MarketBookGet: [{i}] - {result[i].price} | {result[i].volume} | {result[i].type}"); AddLog($"MarketBookGet: [{i}] - {result[i].price} | {result[i].volume} | {result[i].type} | {result[i].volume_real}");
} }
} }
BIN
View File
Binary file not shown.
+39 -84
View File
@@ -1,7 +1,7 @@
#property copyright "Vyacheslav Demidyuk" #property copyright "Vyacheslav Demidyuk"
#property link "" #property link ""
#property version "1.7" #property version "1.6"
#property description "MtApi (MT5) connection expert" #property description "MtApi (MT5) connection expert"
#include <json.mqh> #include <json.mqh>
@@ -25,8 +25,6 @@
bool sendULongResponse(int expertHandle, ulong response, string& err); bool sendULongResponse(int expertHandle, ulong response, string& err);
bool sendLongArrayResponse(int expertHandle, long& values[], int size, string& err); bool sendLongArrayResponse(int expertHandle, long& values[], int size, string& err);
bool sendMqlRatesArrayResponse(int expertHandle, MqlRates& values[], int size, string& err); bool sendMqlRatesArrayResponse(int expertHandle, MqlRates& values[], int size, string& err);
bool sendMqlTickResponse(int expertHandle, MqlTick& response, string& err);
bool sendMqlBookInfoArrayResponse(int expertHandle, MqlBookInfo& values[], int size, string& err);
bool sendErrorResponse(int expertHandle, int code, string message, string& err); bool sendErrorResponse(int expertHandle, int code, string message, string& err);
bool sendEvent(int expertHandle, int eventType, string payload, string& err); bool sendEvent(int expertHandle, int eventType, string payload, string& err);
@@ -41,7 +39,7 @@
bool getBooleanValue(int expertHandle, int paramIndex, bool& res, string& err); bool getBooleanValue(int expertHandle, int paramIndex, bool& res, string& err);
#import #import
//#define __DEBUG_LOG__ #define __DEBUG_LOG__
enum LockTickType enum LockTickType
{ {
@@ -532,9 +530,8 @@ int executeCommand()
case 56: //SymbolInfoString case 56: //SymbolInfoString
Execute_SymbolInfoString(); Execute_SymbolInfoString();
break; break;
case 57: //SymbolInfoTick // case 57: //SymbolInfoTick
Execute_SymbolInfoTick(); // break;
break;
case 58: //SymbolInfoSessionQuote case 58: //SymbolInfoSessionQuote
Execute_SymbolInfoSessionQuote(); Execute_SymbolInfoSessionQuote();
break; break;
@@ -3150,37 +3147,6 @@ void Execute_SymbolInfoString()
} }
} }
void Execute_SymbolInfoTick()
{
string symbol;
StringInit(symbol, 100, 0);
if (!getStringValue(ExpertHandle, 0, symbol, _error))
{
PrintParamError("SymbolInfoTick", "symbol", _error);
sendErrorResponse(ExpertHandle, -1, _error, _response_error);
return;
}
MqlTick tick={0};
bool ok = SymbolInfoTick(symbol, tick);
if (ok)
{
if (!sendMqlTickResponse(ExpertHandle, tick, _response_error))
{
PrintResponseError("SymbolInfoTick", _response_error);
}
}
else
{
if (!sendVoidResponse(ExpertHandle, _response_error))
{
PrintResponseError("SymbolInfoTick", _response_error);
}
}
}
void Execute_SymbolInfoSessionQuote() void Execute_SymbolInfoSessionQuote()
{ {
string symbol; string symbol;
@@ -3433,87 +3399,52 @@ void Execute_PositionSelectByTicket()
void Execute_ObjectCreate() void Execute_ObjectCreate()
{ {
int nParameter = 0;
long chartId; long chartId;
string name; string name;
int type; int type;
int nwin; int nwin;
int time1; int time;
double price1; double price;
int arrTime[29];
double arrPrice[29];
StringInit(name, 200, 0); StringInit(name, 200, 0);
if (!getIntValue(ExpertHandle, 0, nParameter, _error)) if (!getLongValue(ExpertHandle, 0, chartId, _error))
{
PrintParamError("ObjectCreate", "nParameter", _error);
sendErrorResponse(ExpertHandle, -1, _error, _response_error);
return;
}
if (!getLongValue(ExpertHandle, 1, chartId, _error))
{ {
PrintParamError("ObjectCreate", "chartId", _error); PrintParamError("ObjectCreate", "chartId", _error);
sendErrorResponse(ExpertHandle, -1, _error, _response_error); sendErrorResponse(ExpertHandle, -1, _error, _response_error);
return; return;
} }
if (!getStringValue(ExpertHandle, 2, name, _error)) if (!getStringValue(ExpertHandle, 1, name, _error))
{ {
PrintParamError("ObjectCreate", "name", _error); PrintParamError("ObjectCreate", "name", _error);
sendErrorResponse(ExpertHandle, -1, _error, _response_error); sendErrorResponse(ExpertHandle, -1, _error, _response_error);
return; return;
} }
if (!getIntValue(ExpertHandle, 3, type, _error)) if (!getIntValue(ExpertHandle, 2, type, _error))
{ {
PrintParamError("ObjectCreate", "type", _error); PrintParamError("ObjectCreate", "type", _error);
sendErrorResponse(ExpertHandle, -1, _error, _response_error); sendErrorResponse(ExpertHandle, -1, _error, _response_error);
return; return;
} }
if (!getIntValue(ExpertHandle, 4, nwin, _error)) if (!getIntValue(ExpertHandle, 3, nwin, _error))
{ {
PrintParamError("ObjectCreate", "nwin", _error); PrintParamError("ObjectCreate", "nwin", _error);
sendErrorResponse(ExpertHandle, -1, _error, _response_error); sendErrorResponse(ExpertHandle, -1, _error, _response_error);
return; return;
} }
if (!getIntValue(ExpertHandle, 5, time1, _error)) if (!getIntValue(ExpertHandle, 4, time, _error))
{ {
PrintParamError("ObjectCreate", "time1", _error); PrintParamError("ObjectCreate", "time", _error);
sendErrorResponse(ExpertHandle, -1, _error, _response_error); sendErrorResponse(ExpertHandle, -1, _error, _response_error);
return; return;
} }
if (!getDoubleValue(ExpertHandle, 6, price1, _error)) if (!getDoubleValue(ExpertHandle, 5, price, _error))
{ {
PrintParamError("ObjectCreate", "price1", _error); PrintParamError("ObjectCreate", "price", _error);
sendErrorResponse(ExpertHandle, -1, _error, _response_error); sendErrorResponse(ExpertHandle, -1, _error, _response_error);
return; return;
} }
ArrayInitialize(arrTime, 0); if (!sendBooleanResponse(ExpertHandle, ObjectCreate(chartId, name, (ENUM_OBJECT)type, nwin, (datetime)time, price), _response_error))
ArrayInitialize(arrPrice, 0);
for(int i = 0; i * 2 + 6 < nParameter; i++)
{
if (!getIntValue(ExpertHandle, i * 2 + 7, arrTime[i], _error))
{
PrintParamError("ObjectCreate", "time" + IntegerToString(i * 2 + 7), _error);
sendErrorResponse(ExpertHandle, -1, _error, _response_error);
return;
}
else if (!getDoubleValue(ExpertHandle, i * 2 + 8, arrPrice[i], _error))
{
PrintParamError("ObjectCreate", "price" + IntegerToString(i * 2 + 8), _error);
sendErrorResponse(ExpertHandle, -1, _error, _response_error);
return;
}
}
if (!sendBooleanResponse(ExpertHandle
,ObjectCreate(chartId, name, (ENUM_OBJECT)type, nwin, (datetime)time1, price1
,(datetime)arrTime[0], arrPrice[0],(datetime)arrTime[1], arrPrice[1],(datetime)arrTime[2], arrPrice[2],(datetime)arrTime[3], arrPrice[3],(datetime)arrTime[4], arrPrice[4],(datetime)arrTime[5], arrPrice[5]
,(datetime)arrTime[6], arrPrice[6],(datetime)arrTime[7], arrPrice[7],(datetime)arrTime[8], arrPrice[8],(datetime)arrTime[9], arrPrice[9],(datetime)arrTime[10], arrPrice[10],(datetime)arrTime[11], arrPrice[11]
,(datetime)arrTime[12], arrPrice[12],(datetime)arrTime[13], arrPrice[13],(datetime)arrTime[14], arrPrice[14],(datetime)arrTime[15], arrPrice[15],(datetime)arrTime[16], arrPrice[16],(datetime)arrTime[17], arrPrice[17]
,(datetime)arrTime[18], arrPrice[18],(datetime)arrTime[19], arrPrice[19],(datetime)arrTime[20], arrPrice[20],(datetime)arrTime[21], arrPrice[21],(datetime)arrTime[22], arrPrice[22],(datetime)arrTime[23], arrPrice[23]
,(datetime)arrTime[24], arrPrice[24],(datetime)arrTime[25], arrPrice[25],(datetime)arrTime[26], arrPrice[26],(datetime)arrTime[27], arrPrice[27],(datetime)arrTime[28], arrPrice[28])
, _response_error))
{ {
PrintResponseError("ObjectCreate", _response_error); PrintResponseError("ObjectCreate", _response_error);
} }
@@ -6830,6 +6761,9 @@ string OnRequest(string json)
case 11: //PositionClose case 11: //PositionClose
response = ExecuteRequest_PositionClose(jo); response = ExecuteRequest_PositionClose(jo);
break; break;
case 12: //SymbolInfoTick
response = ExecuteRequest_SymbolInfoTick(jo);
break;
default: default:
PrintFormat("%s [WARNING]: Unknown request type %d", __FUNCTION__, requestType); PrintFormat("%s [WARNING]: Unknown request type %d", __FUNCTION__, requestType);
response = CreateErrorResponse(-1, "Unknown request type"); response = CreateErrorResponse(-1, "Unknown request type");
@@ -7118,6 +7052,7 @@ JSONObject* MqlBookInfoToJson(MqlBookInfo& info)
jo.put("type", new JSONNumber((int)info.type)); jo.put("type", new JSONNumber((int)info.type));
jo.put("price", new JSONNumber(info.price)); jo.put("price", new JSONNumber(info.price));
jo.put("volume", new JSONNumber(info.volume)); jo.put("volume", new JSONNumber(info.volume));
jo.put("volume_real", new JSONNumber(info.volume_real));
return jo; return jo;
} }
@@ -7341,6 +7276,25 @@ string ExecuteRequest_PositionClose(JSONObject *jo)
return CreateSuccessResponse("Value", result_value_jo); return CreateSuccessResponse("Value", result_value_jo);
} }
string ExecuteRequest_SymbolInfoTick(JSONObject *jo)
{
CHECK_JSON_VALUE(jo, "SymbolName", CreateErrorResponse(-1, "Undefinded mandatory parameter SymbolName"));
string symbol_name = jo.getString("SymbolName");
#ifdef __DEBUG_LOG__
PrintFormat("%s: symbol_name = %s", __FUNCTION__, symbol_name);
#endif
MqlTick tick={0};
bool ok = SymbolInfoTick(symbol_name, tick);
#ifdef __DEBUG_LOG__
PrintFormat("%s: ok = %s", __FUNCTION__, BoolToString(ok));
#endif
return CreateSuccessResponse("Value", MqlTickToJson(tick));
}
//------------ Events ------------------------------------------------------- //------------ Events -------------------------------------------------------
enum MtEventTypes enum MtEventTypes
@@ -7572,6 +7526,7 @@ JSONObject* MqlTickToJson(MqlTick& tick)
jo.put("ask", new JSONNumber(tick.ask)); jo.put("ask", new JSONNumber(tick.ask));
jo.put("last", new JSONNumber(tick.last)); jo.put("last", new JSONNumber(tick.last));
jo.put("volume", new JSONNumber(tick.volume)); jo.put("volume", new JSONNumber(tick.volume));
jo.put("volume_real", new JSONNumber(tick.volume_real));
return jo; return jo;
} }