mirror of
https://github.com/vdemydiuk/mtapi.git
synced 2026-08-18 05:08:11 +00:00
Issue #82: Refactored MQL5 expert to use json in function OrderSend
This commit is contained in:
+3
-1
@@ -1,4 +1,6 @@
|
|||||||
namespace MtApi
|
// ReSharper disable InconsistentNaming
|
||||||
|
|
||||||
|
namespace MtApi
|
||||||
{
|
{
|
||||||
public enum ENUM_TERMINAL_INFO_STRING
|
public enum ENUM_TERMINAL_INFO_STRING
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
// ReSharper disable InconsistentNaming
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace MtApi5
|
namespace MtApi5
|
||||||
{
|
{
|
||||||
@@ -22,6 +23,8 @@ namespace MtApi5
|
|||||||
public ulong Position { get; set; } // Position ticket
|
public ulong Position { get; set; } // Position ticket
|
||||||
public ulong PositionBy { get; set; } // The ticket of an opposite position
|
public ulong PositionBy { get; set; } // The ticket of an opposite position
|
||||||
|
|
||||||
|
public int MtExpiration => Mt5TimeConverter.ConvertToMtTime(Expiration);
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return $"{Symbol}|{Volume}|{Price}|{Volume}|{Action}";
|
return $"{Symbol}|{Volume}|{Price}|{Volume}|{Action}";
|
||||||
|
|||||||
+25
-10
@@ -1,4 +1,6 @@
|
|||||||
namespace MtApi5
|
// ReSharper disable InconsistentNaming
|
||||||
|
|
||||||
|
namespace MtApi5
|
||||||
{
|
{
|
||||||
public class MqlTradeResult
|
public class MqlTradeResult
|
||||||
{
|
{
|
||||||
@@ -15,15 +17,28 @@
|
|||||||
Request_id = request_id;
|
Request_id = request_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint Retcode { get; private set; } // Operation return code
|
internal MqlTradeResult(MqlTradeResult o)
|
||||||
public ulong Deal { get; private set; } // Deal ticket, if it is performed
|
{
|
||||||
public ulong Order { get; private set; } // Order ticket, if it is placed
|
Retcode = o.Retcode;
|
||||||
public double Volume { get; private set; } // Deal volume, confirmed by broker
|
Deal = o.Deal;
|
||||||
public double Price { get; private set; } // Deal price, confirmed by broker
|
Order = o.Order;
|
||||||
public double Bid { get; private set; } // Current Bid price
|
Volume = o.Volume;
|
||||||
public double Ask { get; private set; } // Current Ask price
|
Price = o.Price;
|
||||||
public string Comment { get; private set; } // Broker comment to operation (by default it is filled by the operation description)
|
Bid = o.Bid;
|
||||||
public uint Request_id { get; private set; } // Request ID set by the terminal during the dispatch
|
Ask = o.Ask;
|
||||||
|
Comment = o.Comment;
|
||||||
|
Request_id = o.Request_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint Retcode { get; } // Operation return code
|
||||||
|
public ulong Deal { get; } // Deal ticket, if it is performed
|
||||||
|
public ulong Order { get; } // Order ticket, if it is placed
|
||||||
|
public double Volume { get; } // Deal volume, confirmed by broker
|
||||||
|
public double Price { get; } // Deal price, confirmed by broker
|
||||||
|
public double Bid { get; } // Current Bid price
|
||||||
|
public double Ask { get; } // Current Ask price
|
||||||
|
public string Comment { get; } // Broker comment to operation (by default it is filled by the operation description)
|
||||||
|
public uint Request_id { get; } // Request ID set by the terminal during the dispatch
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
|
|||||||
+3
-1
@@ -1,4 +1,6 @@
|
|||||||
namespace MtApi5
|
// ReSharper disable InconsistentNaming
|
||||||
|
|
||||||
|
namespace MtApi5
|
||||||
{
|
{
|
||||||
|
|
||||||
// Chart Constants:
|
// Chart Constants:
|
||||||
|
|||||||
@@ -73,6 +73,7 @@
|
|||||||
<Compile Include="Requests\RequestType.cs" />
|
<Compile Include="Requests\RequestType.cs" />
|
||||||
<Compile Include="Responses\CopyTicksResponse.cs" />
|
<Compile Include="Responses\CopyTicksResponse.cs" />
|
||||||
<Compile Include="Responses\ICustomResponse.cs" />
|
<Compile Include="Responses\ICustomResponse.cs" />
|
||||||
|
<Compile Include="Responses\OrderSendResponse.cs" />
|
||||||
<Compile Include="Responses\ResponseBase.cs" />
|
<Compile Include="Responses\ResponseBase.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
+16
-8
@@ -1,9 +1,9 @@
|
|||||||
using System;
|
// ReSharper disable InconsistentNaming
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using MTApiService;
|
using MTApiService;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using System.ServiceModel;
|
using System.ServiceModel;
|
||||||
using MtApi5.Requests;
|
using MtApi5.Requests;
|
||||||
using MtApi5.Responses;
|
using MtApi5.Responses;
|
||||||
@@ -12,7 +12,6 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace MtApi5
|
namespace MtApi5
|
||||||
{
|
{
|
||||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
|
||||||
public class MtApi5Client
|
public class MtApi5Client
|
||||||
{
|
{
|
||||||
#region MT Constants
|
#region MT Constants
|
||||||
@@ -117,13 +116,22 @@ namespace MtApi5
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var commandParameters = request.ToArrayList();
|
var response = SendRequest<OrderSendResponse>(new OrderSendRequest
|
||||||
|
{
|
||||||
|
TradeRequest = request
|
||||||
|
});
|
||||||
|
|
||||||
var strResult = SendCommand<string>(Mt5CommandType.OrderSend, commandParameters);
|
result = response?.Value?.TradeResult;
|
||||||
|
return response?.Value != null && response.Value.RetVal;
|
||||||
|
|
||||||
Log.Debug($"OrderSend: strResult = {strResult}");
|
|
||||||
|
|
||||||
return strResult.ParseResult(ParamSeparator, out result);
|
//var commandParameters = request.ToArrayList();
|
||||||
|
|
||||||
|
//var strResult = SendCommand<string>(Mt5CommandType.OrderSend, commandParameters);
|
||||||
|
|
||||||
|
//Log.Debug($"OrderSend: strResult = {strResult}");
|
||||||
|
|
||||||
|
//return strResult.ParseResult(ParamSeparator, out result);
|
||||||
}
|
}
|
||||||
|
|
||||||
///<summary>
|
///<summary>
|
||||||
@@ -2398,7 +2406,7 @@ namespace MtApi5
|
|||||||
}
|
}
|
||||||
|
|
||||||
var responseValue = response.GetValue();
|
var responseValue = response.GetValue();
|
||||||
return responseValue != null ? (T)responseValue : default(T);
|
return (T) responseValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private T SendRequest<T>(RequestBase request) where T : ResponseBase, new()
|
private T SendRequest<T>(RequestBase request) where T : ResponseBase, new()
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
namespace MtApi5.Responses
|
// ReSharper disable InconsistentNaming
|
||||||
|
namespace MtApi5.Responses
|
||||||
{
|
{
|
||||||
internal class ICustomResponse: ResponseBase
|
internal class ICustomResponse: ResponseBase
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
namespace MtApi5.Responses
|
||||||
|
{
|
||||||
|
internal class OrderSendResult
|
||||||
|
{
|
||||||
|
public bool RetVal { get; set; }
|
||||||
|
public MqlTradeResult TradeResult { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class OrderSendResponse: ResponseBase
|
||||||
|
{
|
||||||
|
public OrderSendResult Value { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -269,15 +269,14 @@ namespace MtApi5TestClient
|
|||||||
private async void ExecuteOrderSend(object o)
|
private async void ExecuteOrderSend(object o)
|
||||||
{
|
{
|
||||||
var request = TradeRequest.GetMqlTradeRequest();
|
var request = TradeRequest.GetMqlTradeRequest();
|
||||||
|
MqlTradeResult result = null;
|
||||||
var retVal = await Execute(() =>
|
var retVal = await Execute(() =>
|
||||||
{
|
{
|
||||||
MqlTradeResult result;
|
|
||||||
var ok = _mtApiClient.OrderSend(request, out result);
|
var ok = _mtApiClient.OrderSend(request, out result);
|
||||||
return ok ? result : null;
|
return ok;
|
||||||
});
|
});
|
||||||
|
|
||||||
var message = retVal != null ? $"OrderSend successed. {MqlTradeResultToString(retVal)}" : "OrderSend failed.";
|
var message = retVal ? $"OrderSend excute successed. {MqlTradeResultToString(result)}" : $"OrderSend execute failed. {MqlTradeResultToString(result)}";
|
||||||
AddLog(message);
|
AddLog(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
+123
-3
@@ -39,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__
|
||||||
|
|
||||||
input int Port = 8228;
|
input int Port = 8228;
|
||||||
|
|
||||||
@@ -5562,7 +5562,7 @@ string OnRequest(string json)
|
|||||||
|
|
||||||
if(jv == NULL)
|
if(jv == NULL)
|
||||||
{
|
{
|
||||||
PrintFormat("OnRequest [ERROR]: %d - %s", (string)parser.getErrorCode(), parser.getErrorMessage());
|
PrintFormat("%s [ERROR]: %d - %s", __FUNCTION__, (string)parser.getErrorCode(), parser.getErrorMessage());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -5579,8 +5579,11 @@ string OnRequest(string json)
|
|||||||
case 2: //iCustom
|
case 2: //iCustom
|
||||||
response = ExecuteRequest_iCustom(jo);
|
response = ExecuteRequest_iCustom(jo);
|
||||||
break;
|
break;
|
||||||
|
case 3: //OrderSend
|
||||||
|
response = ExecuteRequest_OrderSend(jo);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
PrintFormat("OnRequest [WARNING]: Unknown request type %d", requestType);
|
PrintFormat("%s [WARNING]: Unknown request type %d", __FUNCTION__, requestType);
|
||||||
response = CreateErrorResponse(-1, "Unknown request type");
|
response = CreateErrorResponse(-1, "Unknown request type");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -5770,4 +5773,121 @@ int iCustomT(string symbol, ENUM_TIMEFRAMES timeframe, string name, T &p[], int
|
|||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PRINT_MSG_AND_RETURN_VALUE(msg,value) PrintFormat("%s: %s",__FUNCTION__,msg);return value
|
||||||
|
#define CHECK_JSON_VALUE(jo, name_value, return_fail_result) if (jo.getValue(name_value) == NULL) { PRINT_MSG_AND_RETURN_VALUE(StringFormat("failed to get %s from JSON!", name_value), return_fail_result); }
|
||||||
|
|
||||||
|
bool JsonToMqlTradeRequest(JSONObject *jo, MqlTradeRequest& request)
|
||||||
|
{
|
||||||
|
//Action
|
||||||
|
CHECK_JSON_VALUE(jo, "Action", false);
|
||||||
|
request.action = (ENUM_TRADE_REQUEST_ACTIONS) jo.getInt("Action");
|
||||||
|
|
||||||
|
//Magic
|
||||||
|
CHECK_JSON_VALUE(jo, "Magic", false);
|
||||||
|
request.magic = jo.getLong("Magic");
|
||||||
|
|
||||||
|
//Order
|
||||||
|
CHECK_JSON_VALUE(jo, "Order", false);
|
||||||
|
request.order = jo.getLong("Magic");
|
||||||
|
|
||||||
|
//Symbol
|
||||||
|
CHECK_JSON_VALUE(jo, "Symbol", false);
|
||||||
|
StringInit(request.symbol, 100, 0);
|
||||||
|
request.symbol = jo.getString("Symbol");
|
||||||
|
|
||||||
|
//Volume
|
||||||
|
CHECK_JSON_VALUE(jo, "Volume", false);
|
||||||
|
request.volume = jo.getDouble("Volume");
|
||||||
|
|
||||||
|
//Price
|
||||||
|
CHECK_JSON_VALUE(jo, "Price", false);
|
||||||
|
request.price = jo.getDouble("Price");
|
||||||
|
|
||||||
|
//Stoplimit
|
||||||
|
CHECK_JSON_VALUE(jo, "Stoplimit", false);
|
||||||
|
request.stoplimit = jo.getDouble("Stoplimit");
|
||||||
|
|
||||||
|
//Sl
|
||||||
|
CHECK_JSON_VALUE(jo, "Sl", false);
|
||||||
|
request.sl = jo.getDouble("Sl");
|
||||||
|
|
||||||
|
//Tp
|
||||||
|
CHECK_JSON_VALUE(jo, "Tp", false);
|
||||||
|
request.tp = jo.getDouble("Tp");
|
||||||
|
|
||||||
|
//Deviation
|
||||||
|
CHECK_JSON_VALUE(jo, "Deviation", false);
|
||||||
|
request.deviation = jo.getLong("Deviation");
|
||||||
|
|
||||||
|
//Type
|
||||||
|
CHECK_JSON_VALUE(jo, "Type", false);
|
||||||
|
request.type = (ENUM_ORDER_TYPE)jo.getInt("Type");
|
||||||
|
|
||||||
|
//Type_filling
|
||||||
|
CHECK_JSON_VALUE(jo, "Type_filling", false);
|
||||||
|
request.type_filling = (ENUM_ORDER_TYPE_FILLING)jo.getInt("Type_filling");
|
||||||
|
|
||||||
|
//Type_time
|
||||||
|
CHECK_JSON_VALUE(jo, "Type_time", false);
|
||||||
|
request.type_time = (ENUM_ORDER_TYPE_TIME)jo.getInt("Type_time");
|
||||||
|
|
||||||
|
//Expiration
|
||||||
|
CHECK_JSON_VALUE(jo, "Expiration", false);
|
||||||
|
request.expiration = (datetime)jo.getInt("MtExpiration");
|
||||||
|
|
||||||
|
//Comment
|
||||||
|
CHECK_JSON_VALUE(jo, "Comment", false);
|
||||||
|
StringInit(request.comment, 1000, 0);
|
||||||
|
request.comment = jo.getString("Comment");
|
||||||
|
|
||||||
|
//Position
|
||||||
|
CHECK_JSON_VALUE(jo, "Position", false);
|
||||||
|
request.position = jo.getLong("Position");
|
||||||
|
|
||||||
|
//PositionBy
|
||||||
|
CHECK_JSON_VALUE(jo, "PositionBy", false);
|
||||||
|
request.position_by = jo.getLong("PositionBy");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject* MqlTradeResultToJson(MqlTradeResult& result)
|
||||||
|
{
|
||||||
|
JSONObject* jo = new JSONObject();
|
||||||
|
|
||||||
|
jo.put("Retcode", new JSONNumber(result.retcode));
|
||||||
|
jo.put("Deal", new JSONNumber(result.deal));
|
||||||
|
jo.put("Order", new JSONNumber(result.order));
|
||||||
|
jo.put("Volume", new JSONNumber(result.volume));
|
||||||
|
jo.put("Price", new JSONNumber(result.price));
|
||||||
|
jo.put("Bid", new JSONNumber(result.bid));
|
||||||
|
jo.put("Ask", new JSONNumber(result.ask));
|
||||||
|
jo.put("Comment", new JSONString(result.comment));
|
||||||
|
jo.put("Request_id", new JSONNumber(result.request_id));
|
||||||
|
|
||||||
|
return jo;
|
||||||
|
}
|
||||||
|
|
||||||
|
string ExecuteRequest_OrderSend(JSONObject *jo)
|
||||||
|
{
|
||||||
|
CHECK_JSON_VALUE(jo, "TradeRequest", CreateErrorResponse(-1, "Undefinded mandatory parameter TradeRequest"));
|
||||||
|
JSONObject* trade_request_jo = jo.getObject("TradeRequest");
|
||||||
|
|
||||||
|
MqlTradeRequest trade_request = {0};
|
||||||
|
JsonToMqlTradeRequest(trade_request_jo, trade_request);
|
||||||
|
|
||||||
|
MqlTradeResult trade_result = {0};
|
||||||
|
bool ok = OrderSend(trade_request, trade_result);
|
||||||
|
|
||||||
|
JSONObject* result_value_jo = new JSONObject();
|
||||||
|
result_value_jo.put("RetVal", new JSONBool(ok));
|
||||||
|
result_value_jo.put("TradeResult", MqlTradeResultToJson(trade_result));
|
||||||
|
|
||||||
|
#ifdef __DEBUG_LOG__
|
||||||
|
PrintFormat("%s: return value = %s", __FUNCTION__, ok ? "true" : "false");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return CreateSuccessResponse("Value", result_value_jo);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user