mirror of
https://github.com/vdemydiuk/mtapi.git
synced 2026-07-27 18:47:55 +00:00
Issue #93: Added event OnTradeTransaction. Udpated json.mqh to fix JSONNumber for correct serialization zero integer value".
This commit is contained in:
@@ -104,6 +104,14 @@ _DLLAPI int _stdcall updateQuote(int expertHandle, wchar_t* symbol, double bid,
|
||||
}, err, 0);
|
||||
}
|
||||
|
||||
_DLLAPI bool _stdcall sendEvent(int expertHandle, int eventType, wchar_t* payload, wchar_t* err)
|
||||
{
|
||||
return Execute<bool>([&expertHandle, &eventType, payload]() {
|
||||
MtAdapter::GetInstance()->SendEvent(expertHandle, eventType, gcnew String(payload));
|
||||
return true;
|
||||
}, err, false);
|
||||
}
|
||||
|
||||
_DLLAPI int _stdcall sendIntResponse(int expertHandle, int response, wchar_t* err)
|
||||
{
|
||||
return Execute<int>([&expertHandle, &response]() {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace MtApi5.Events
|
||||
{
|
||||
internal enum Mt5EventTypes
|
||||
{
|
||||
OnTradeTransaction = 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace MtApi5.Events
|
||||
{
|
||||
internal class OnTradeTransactionEvent
|
||||
{
|
||||
public MqlTradeTransaction Trans { get; set; }
|
||||
public MqlTradeRequest Request { get; set; }
|
||||
public MqlTradeResult Result { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
// ReSharper disable InconsistentNaming
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace MtApi5
|
||||
{
|
||||
@@ -18,16 +19,23 @@ namespace MtApi5
|
||||
public ENUM_ORDER_TYPE Type { get; set; } // Order type
|
||||
public ENUM_ORDER_TYPE_FILLING Type_filling { get; set; } // Order execution type
|
||||
public ENUM_ORDER_TYPE_TIME Type_time { get; set; } // Order expiration type
|
||||
public DateTime Expiration { get; set; } // Order expiration time (for the orders of ORDER_TIME_SPECIFIED type)
|
||||
|
||||
[JsonIgnore]
|
||||
public DateTime Expiration // Order expiration time (for the orders of ORDER_TIME_SPECIFIED type)
|
||||
{
|
||||
get { return Mt5TimeConverter.ConvertFromMtTime(MtExpiration); }
|
||||
set { MtExpiration = Mt5TimeConverter.ConvertToMtTime(value); }
|
||||
}
|
||||
|
||||
public string Comment { get; set; } // Order comment
|
||||
public ulong Position { get; set; } // Position ticket
|
||||
public ulong PositionBy { get; set; } // The ticket of an opposite position
|
||||
|
||||
public int MtExpiration => Mt5TimeConverter.ConvertToMtTime(Expiration);
|
||||
public int MtExpiration { get; private set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Symbol}|{Volume}|{Price}|{Volume}|{Action}";
|
||||
return $"Action={Action}; Magic={Magic}; Order={Order}; Symbol={Symbol}; Volume={Volume}; Price={Price}; Stoplimit={Stoplimit}; Sl={Sl}; Tp={Tp}; Deviation={Deviation}; Type={Type}; Type_filling={Type_filling}; Type_time={Type_time}; Expiration={Expiration}; Comment={Comment}; Position={Position}; PositionBy={PositionBy}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace MtApi5
|
||||
{
|
||||
public class MqlTradeTransaction
|
||||
{
|
||||
public ulong Deal { get; set; } // Deal ticket
|
||||
public ulong Order { get; set; } // Order ticket
|
||||
public string Symbol { get; set; } // Trade symbol name
|
||||
public ENUM_TRADE_TRANSACTION_TYPE Type { get; set; } // Trade transaction type
|
||||
public ENUM_ORDER_TYPE OrderType { get; set; } // Order type
|
||||
public ENUM_ORDER_STATE OrderState { get; set; } // Order state
|
||||
public ENUM_DEAL_TYPE DealType { get; set; } // Deal type
|
||||
public ENUM_ORDER_TYPE_TIME TimeType { get; set; } // Order type by action period
|
||||
|
||||
[JsonIgnore]
|
||||
public DateTime TimeExpiration // Order expiration time
|
||||
{
|
||||
get { return Mt5TimeConverter.ConvertFromMtTime(MtTimeExpiration); }
|
||||
set { MtTimeExpiration = Mt5TimeConverter.ConvertToMtTime(value); }
|
||||
}
|
||||
|
||||
public double Price { get; set; } // Price
|
||||
public double PriceTrigger { get; set; } // Stop limit order activation price
|
||||
public double PriceSl { get; set; } // Stop Loss level
|
||||
public double PriceTp { get; set; } // Take Profit level
|
||||
public double Volume { get; set; } // Volume in lots
|
||||
public ulong Position { get; set; } // Position ticket
|
||||
public ulong PositionBy { get; set; } // Ticket of an opposite position
|
||||
|
||||
public int MtTimeExpiration { get; private set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Deal={Deal}; Order={Order}; Symbol={Symbol}; Type={Type}; OrderType={OrderType}; OrderState={OrderState}; DealType={DealType}; TimeType={TimeType}; TimeExpiration={TimeExpiration}; Price={Price}; PriceTrigger{PriceTrigger}; PriceSl={PriceSl}; PriceTp={PriceTp}; Volume={Volume}; Position={Position}; PositionBy={PositionBy}";
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
-10
@@ -582,16 +582,16 @@ namespace MtApi5
|
||||
public enum ENUM_TRADE_TRANSACTION_TYPE
|
||||
{
|
||||
TRADE_TRANSACTION_ORDER_ADD = 0, //Adding a new open order
|
||||
TRADE_TRANSACTION_ORDER_UPDATE = 1, //Updating an open order
|
||||
TRADE_TRANSACTION_ORDER_DELETE = 2, //Removing an order from the list of the open ones
|
||||
TRADE_TRANSACTION_DEAL_ADD = 6, //Adding a deal to the history
|
||||
TRADE_TRANSACTION_DEAL_UPDATE = 7, //Updating a deal in the history
|
||||
TRADE_TRANSACTION_DEAL_DELETE = 8, //Deleting a deal from the history
|
||||
TRADE_TRANSACTION_HISTORY_ADD = 3, //Adding an order to the history as a result of execution or cancellation
|
||||
TRADE_TRANSACTION_HISTORY_UPDATE = 4, //Changing an order located in the orders history
|
||||
TRADE_TRANSACTION_HISTORY_DELETE = 5, //Deleting an order from the orders history
|
||||
TRADE_TRANSACTION_POSITION = 9, //Changing a position not related to a deal execution
|
||||
TRADE_TRANSACTION_REQUEST = 10 //Notification of the fact that a trade request has been processed by a server and processing result has been received
|
||||
TRADE_TRANSACTION_ORDER_UPDATE = 1, //Updating an open order. The updates include not only evident changes from the client terminal or a trade server sides but also changes of an order state when setting it (for example, transition from ORDER_STATE_STARTED to ORDER_STATE_PLACED or from ORDER_STATE_PLACED to ORDER_STATE_PARTIAL, etc.).
|
||||
TRADE_TRANSACTION_ORDER_DELETE = 2, //Removing an order from the list of the open ones. An order can be deleted from the open ones as a result of setting an appropriate request or execution (filling) and moving to the history.
|
||||
TRADE_TRANSACTION_DEAL_ADD = 6, //Adding a deal to the history. The action is performed as a result of an order execution or performing operations with an account balance.
|
||||
TRADE_TRANSACTION_DEAL_UPDATE = 7, //Updating a deal in the history. There may be cases when a previously executed deal is changed on a server. For example, a deal has been changed in an external trading system (exchange) where it was previously transferred by a broker.
|
||||
TRADE_TRANSACTION_DEAL_DELETE = 8, //Deleting a deal from the history. There may be cases when a previously executed deal is deleted from a server. For example, a deal has been deleted in an external trading system (exchange) where it was previously transferred by a broker.
|
||||
TRADE_TRANSACTION_HISTORY_ADD = 3, //Adding an order to the history as a result of execution or cancellation.
|
||||
TRADE_TRANSACTION_HISTORY_UPDATE = 4, //Changing an order located in the orders history. This type is provided for enhancing functionality on a trade server side.
|
||||
TRADE_TRANSACTION_HISTORY_DELETE = 5, //Deleting an order from the orders history. This type is provided for enhancing functionality on a trade server side.
|
||||
TRADE_TRANSACTION_POSITION = 9, //Changing a position not related to a deal execution. This type of transaction shows that a position has been changed on a trade server side. Position volume, open price, Stop Loss and Take Profit levels can be changed. Data on changes are submitted in MqlTradeTransaction structure via OnTradeTransaction handler. Position change (adding, changing or closing), as a result of a deal execution, does not lead to the occurrence of TRADE_TRANSACTION_POSITION transaction.
|
||||
TRADE_TRANSACTION_REQUEST = 10 //Notification of the fact that a trade request has been processed by a server and processing result has been received. Only type field (trade transaction type) must be analyzed for such transactions in MqlTradeTransaction structure. The second and third parameters of OnTradeTransaction (request and result) must be analyzed for additional data.
|
||||
}
|
||||
|
||||
#endregion //Trade Transaction Types
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
|
||||
namespace MtApi5
|
||||
{
|
||||
public class Mt5TradeTransactionEventArgs : EventArgs
|
||||
{
|
||||
public int ExpertHandle { get; set; }
|
||||
public MqlTradeTransaction Trans { get; set; } // trade transaction structure
|
||||
public MqlTradeRequest Request { get; set; } // request structure
|
||||
public MqlTradeResult Result { get; set; } // result structure
|
||||
}
|
||||
}
|
||||
@@ -48,11 +48,13 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CopyTicksFlag.cs" />
|
||||
<Compile Include="Events\OnTradeTransactionEvent.cs" />
|
||||
<Compile Include="MqlBookInfo.cs" />
|
||||
<Compile Include="MqlParam.cs" />
|
||||
<Compile Include="MqlRates.cs" />
|
||||
<Compile Include="MqlTick.cs" />
|
||||
<Compile Include="MqlTradeCheckResult.cs" />
|
||||
<Compile Include="MqlTradeTransaction.cs" />
|
||||
<Compile Include="Mt5TimeConverter.cs" />
|
||||
<Compile Include="Mt5Enums.cs" />
|
||||
<Compile Include="Mt5ConnectionEventArgs.cs" />
|
||||
@@ -60,11 +62,13 @@
|
||||
<Compile Include="MqlTradeRequest.cs" />
|
||||
<Compile Include="MqlTradeResult.cs" />
|
||||
<Compile Include="Mt5QuoteEventArgs.cs" />
|
||||
<Compile Include="Mt5TradeTransactionEventArgs.cs" />
|
||||
<Compile Include="MtApi5Client.cs" />
|
||||
<Compile Include="Mt5CommandType.cs" />
|
||||
<Compile Include="MtConverters.cs" />
|
||||
<Compile Include="ErrorCode.cs" />
|
||||
<Compile Include="ExecutionException.cs" />
|
||||
<Compile Include="Events\Mt5EventTypes.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Mt5Quote.cs" />
|
||||
<Compile Include="Requests\CopyTicksRequest.cs" />
|
||||
|
||||
@@ -8,6 +8,7 @@ using System.ServiceModel;
|
||||
using MtApi5.Requests;
|
||||
using Newtonsoft.Json;
|
||||
using System.Threading.Tasks;
|
||||
using MtApi5.Events;
|
||||
|
||||
namespace MtApi5
|
||||
{
|
||||
@@ -2385,6 +2386,7 @@ namespace MtApi5
|
||||
public event EventHandler<Mt5QuoteEventArgs> QuoteAdded;
|
||||
public event EventHandler<Mt5QuoteEventArgs> QuoteRemoved;
|
||||
public event EventHandler<Mt5ConnectionEventArgs> ConnectionStateChanged;
|
||||
public event EventHandler<Mt5TradeTransactionEventArgs> OnTradeTransaction;
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
@@ -2438,6 +2440,7 @@ namespace MtApi5
|
||||
_client.QuoteUpdated += _client_QuoteUpdated;
|
||||
_client.ServerDisconnected += _client_ServerDisconnected;
|
||||
_client.ServerFailed += _client_ServerFailed;
|
||||
_client.MtEventReceived += _client_MtEventReceived;
|
||||
message = string.IsNullOrEmpty(client.Host) ? $"Connected to localhost:{client.Port}" : $"Connected to { client.Host}:{client.Port}";
|
||||
}
|
||||
|
||||
@@ -2452,6 +2455,32 @@ namespace MtApi5
|
||||
}
|
||||
}
|
||||
|
||||
private void _client_MtEventReceived(MtEvent e)
|
||||
{
|
||||
var eventType = (Mt5EventTypes)e.EventType;
|
||||
|
||||
switch (eventType)
|
||||
{
|
||||
case Mt5EventTypes.OnTradeTransaction:
|
||||
ReceivedOnTradeTransaction(e.ExpertHandle, e.Payload);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
private void ReceivedOnTradeTransaction(int expertHandler, string payload)
|
||||
{
|
||||
var e = JsonConvert.DeserializeObject<OnTradeTransactionEvent>(payload);
|
||||
OnTradeTransaction?.Invoke(this, new Mt5TradeTransactionEventArgs
|
||||
{
|
||||
ExpertHandle = expertHandler,
|
||||
Trans = e.Trans,
|
||||
Request = e.Request,
|
||||
Result = e.Result
|
||||
});
|
||||
}
|
||||
|
||||
private void Connect(string host, int port)
|
||||
{
|
||||
var client = new MtClient(host, port);
|
||||
@@ -2482,6 +2511,7 @@ namespace MtApi5
|
||||
_client.QuoteUpdated -= _client_QuoteUpdated;
|
||||
_client.ServerDisconnected -= _client_ServerDisconnected;
|
||||
_client.ServerFailed -= _client_ServerFailed;
|
||||
_client.MtEventReceived -= _client_MtEventReceived;
|
||||
|
||||
if (!failed)
|
||||
{
|
||||
|
||||
@@ -174,6 +174,7 @@ namespace MtApi5TestClient
|
||||
_mtApiClient.QuoteAdded += mMtApiClient_QuoteAdded;
|
||||
_mtApiClient.QuoteRemoved += mMtApiClient_QuoteRemoved;
|
||||
_mtApiClient.QuoteUpdated += mMtApiClient_QuoteUpdated;
|
||||
_mtApiClient.OnTradeTransaction += mMtApiClient_OnTradeTransaction;
|
||||
|
||||
_quotesMap = new Dictionary<string, QuoteViewModel>();
|
||||
|
||||
@@ -554,14 +555,6 @@ namespace MtApi5TestClient
|
||||
|
||||
private async void ExecuteIndicatorCreate(object o)
|
||||
{
|
||||
//const string symbol = "EURUSD";
|
||||
//const ENUM_TIMEFRAMES timeframe = ENUM_TIMEFRAMES.PERIOD_H1;
|
||||
//const string name = @"Examples\c";
|
||||
//int[] parameters = { 0, 21, (int)ENUM_APPLIED_PRICE.PRICE_CLOSE };
|
||||
|
||||
//var retVal = await Execute(() => _mtApiClient.iCustom(symbol, timeframe, name, parameters));
|
||||
//AddLog($"Custom Moving Average: result - {retVal}");
|
||||
|
||||
var parameters = new List<MqlParam>
|
||||
{
|
||||
new MqlParam
|
||||
@@ -586,10 +579,10 @@ namespace MtApi5TestClient
|
||||
}
|
||||
};
|
||||
|
||||
const string symbol = "EURUSD";
|
||||
const ENUM_TIMEFRAMES timeframe = ENUM_TIMEFRAMES.PERIOD_H1;
|
||||
const ENUM_INDICATOR indicatorType = ENUM_INDICATOR.IND_MACD;
|
||||
var retVal = await Execute(() => _mtApiClient.IndicatorCreate(symbol, timeframe, indicatorType, parameters));
|
||||
var retVal = await Execute(() =>
|
||||
_mtApiClient.IndicatorCreate(TimeSeriesValues.SymbolValue,
|
||||
TimeSeriesValues.TimeFrame, TimeSeriesValues.IndicatorType, parameters));
|
||||
|
||||
TimeSeriesValues.IndicatorHandle = retVal;
|
||||
AddLog($"IndicatorCreate [IND_MA]: result - {retVal}");
|
||||
}
|
||||
@@ -1016,6 +1009,11 @@ namespace MtApi5TestClient
|
||||
}
|
||||
}
|
||||
|
||||
private void mMtApiClient_OnTradeTransaction(object sender, Mt5TradeTransactionEventArgs e)
|
||||
{
|
||||
AddLog($"OnTradeTransaction: ExpertHandle = {e.ExpertHandle}.{Environment.NewLine}Transaction = {e.Trans}.{Environment.NewLine}Request = {e.Request}.{Environment.NewLine}Result = {e.Result}.");
|
||||
}
|
||||
|
||||
private void AddQuote(Mt5Quote quote)
|
||||
{
|
||||
if (quote == null)
|
||||
|
||||
Binary file not shown.
+244
-124
@@ -29,6 +29,8 @@
|
||||
bool sendMqlBookInfoArrayResponse(int expertHandle, MqlBookInfo& values[], int size, string& err);
|
||||
bool sendErrorResponse(int expertHandle, int code, string message, string& err);
|
||||
|
||||
bool sendEvent(int expertHandle, int eventType, string payload, string& err);
|
||||
|
||||
bool getCommandType(int expertHandle, int& res, string& err);
|
||||
bool getIntValue(int expertHandle, int paramIndex, int& res, string& err);
|
||||
bool getUIntValue(int expertHandle, int paramIndex, uint& res, string& err);
|
||||
@@ -39,7 +41,7 @@
|
||||
bool getBooleanValue(int expertHandle, int paramIndex, bool& res, string& err);
|
||||
#import
|
||||
|
||||
//#define __DEBUG_LOG__
|
||||
#define __DEBUG_LOG__
|
||||
|
||||
input int Port = 8228;
|
||||
|
||||
@@ -76,6 +78,21 @@ void OnTick()
|
||||
if (IsTesting()) OnTimer();
|
||||
}
|
||||
|
||||
void OnTradeTransaction(
|
||||
const MqlTradeTransaction& trans, // trade transaction structure
|
||||
const MqlTradeRequest& request, // request structure
|
||||
const MqlTradeResult& result // result structure
|
||||
)
|
||||
{
|
||||
#ifdef __DEBUG_LOG__
|
||||
Print("%s:", __FUNCTION__);
|
||||
#endif
|
||||
|
||||
OnTradeTransactionEvent* transEvent = new OnTradeTransactionEvent(trans, request, result);
|
||||
SendMtEvent(ON_TRADE_TRANSACTION_EVENT, transEvent);
|
||||
delete transEvent;
|
||||
}
|
||||
|
||||
int preinit()
|
||||
{
|
||||
StringInit(_response_error,1000,0);
|
||||
@@ -5592,6 +5609,8 @@ bool OrderCloseAll()
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------ Requests -------------------------------------------------------
|
||||
|
||||
string OnRequest(string json)
|
||||
{
|
||||
string response = "";
|
||||
@@ -5680,17 +5699,6 @@ string CreateSuccessResponse(string responseName, JSONValue* responseBody)
|
||||
return result;
|
||||
}
|
||||
|
||||
JSONObject* Serialize(MqlTick& tick)
|
||||
{
|
||||
JSONObject *jo = new JSONObject();
|
||||
jo.put("MtTime", new JSONNumber(tick.time));
|
||||
jo.put("bid", new JSONNumber(tick.bid));
|
||||
jo.put("ask", new JSONNumber(tick.ask));
|
||||
jo.put("last", new JSONNumber(tick.last));
|
||||
jo.put("volume", new JSONNumber(tick.volume));
|
||||
return jo;
|
||||
}
|
||||
|
||||
string ExecuteRequest_CopyTicks(JSONObject *jo)
|
||||
{
|
||||
if (jo.getValue("SymbolName") == NULL)
|
||||
@@ -5715,7 +5723,7 @@ string ExecuteRequest_CopyTicks(JSONObject *jo)
|
||||
JSONArray* jaTicks = new JSONArray();
|
||||
for(int i = 0; i < received; i++)
|
||||
{
|
||||
jaTicks.put(i, Serialize(ticks[i]));
|
||||
jaTicks.put(i, MqlTickToJson(ticks[i]));
|
||||
}
|
||||
|
||||
return CreateSuccessResponse("Value", jaTicks);
|
||||
@@ -5829,107 +5837,15 @@ int iCustomT(string symbol, ENUM_TIMEFRAMES timeframe, string name, T &p[], int
|
||||
#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");
|
||||
|
||||
//MtExpiration
|
||||
CHECK_JSON_VALUE(jo, "MtExpiration", false);
|
||||
request.expiration = (datetime)jo.getInt("MtExpiration");
|
||||
|
||||
//Comment
|
||||
if (jo.getValue("Comment") != NULL)
|
||||
{
|
||||
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);
|
||||
bool converted = JsonToMqlTradeRequest(trade_request_jo, trade_request);
|
||||
if (converted == false)
|
||||
return CreateErrorResponse(-1, "Failed to parse parameter TradeRequest");
|
||||
|
||||
MqlTradeResult trade_result = {0};
|
||||
bool ok = OrderSend(trade_request, trade_result);
|
||||
@@ -5996,22 +5912,6 @@ string ExecuteRequest_PositionOpen(JSONObject *jo)
|
||||
return CreateSuccessResponse("Value", result_value_jo);
|
||||
}
|
||||
|
||||
JSONObject* MqlTradeCheckResultToJson(MqlTradeCheckResult& result)
|
||||
{
|
||||
JSONObject* jo = new JSONObject();
|
||||
|
||||
jo.put("Retcode", new JSONNumber(result.retcode));
|
||||
jo.put("Balance", new JSONNumber(result.balance));
|
||||
jo.put("Equity", new JSONNumber(result.equity));
|
||||
jo.put("Profit", new JSONNumber(result.profit));
|
||||
jo.put("Margin", new JSONNumber(result.margin));
|
||||
jo.put("Margin_free", new JSONNumber(result.margin_free));
|
||||
jo.put("Margin_level", new JSONNumber(result.margin_level));
|
||||
jo.put("Comment", new JSONString(result.comment));
|
||||
|
||||
return jo;
|
||||
}
|
||||
|
||||
string ExecuteRequest_OrderCheck(JSONObject *jo)
|
||||
{
|
||||
CHECK_JSON_VALUE(jo, "TradeRequest", CreateErrorResponse(-1, "Undefinded mandatory parameter TradeRequest"));
|
||||
@@ -6137,4 +6037,224 @@ string ExecuteRequest_IndicatorCreate(JSONObject *jo)
|
||||
#endif
|
||||
|
||||
return CreateSuccessResponse("Value", new JSONNumber(indicator_handle));
|
||||
}
|
||||
|
||||
//------------ Events -------------------------------------------------------
|
||||
|
||||
enum MtEventTypes
|
||||
{
|
||||
ON_TRADE_TRANSACTION_EVENT = 1
|
||||
};
|
||||
|
||||
class MtEvent
|
||||
{
|
||||
public:
|
||||
virtual JSONObject* CreateJson() = 0;
|
||||
};
|
||||
|
||||
class OnTradeTransactionEvent : public MtEvent
|
||||
{
|
||||
public:
|
||||
OnTradeTransactionEvent(const MqlTradeTransaction& trans, const MqlTradeRequest& request, const MqlTradeResult& result)
|
||||
{
|
||||
_trans = trans;
|
||||
_request = request;
|
||||
_result = result;
|
||||
}
|
||||
|
||||
virtual JSONObject* CreateJson()
|
||||
{
|
||||
JSONObject *jo = new JSONObject();
|
||||
jo.put("Trans", MqlTradeTransactionToJson(_trans));
|
||||
jo.put("Request", MqlTradeRequestToJson(_request));
|
||||
jo.put("Result", MqlTradeResultToJson(_result));
|
||||
return jo;
|
||||
}
|
||||
|
||||
private:
|
||||
MqlTradeTransaction _trans;
|
||||
MqlTradeRequest _request;
|
||||
MqlTradeResult _result;
|
||||
};
|
||||
|
||||
void SendMtEvent(MtEventTypes eventType, MtEvent* mtEvent)
|
||||
{
|
||||
#ifdef __DEBUG_LOG__
|
||||
PrintFormat("%s: eventType = %d", __FUNCTION__, eventType);
|
||||
#endif
|
||||
|
||||
JSONObject* json = mtEvent.CreateJson();
|
||||
if (sendEvent(ExpertHandle, (int)eventType, json.toString(), _error))
|
||||
{
|
||||
#ifdef __DEBUG_LOG__
|
||||
PrintFormat("%s: payload = %s", __FUNCTION__, json.toString());
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintFormat("[ERROR] SendMtEvent: %s", _error);
|
||||
}
|
||||
|
||||
delete json;
|
||||
}
|
||||
|
||||
//-------------JSON converters -----------------------------------------
|
||||
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, "MtExpiration", false);
|
||||
request.expiration = (datetime)jo.getInt("MtExpiration");
|
||||
|
||||
//Comment
|
||||
if (jo.getValue("Comment") != NULL)
|
||||
{
|
||||
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* MqlTickToJson(MqlTick& tick)
|
||||
{
|
||||
JSONObject *jo = new JSONObject();
|
||||
jo.put("MtTime", new JSONNumber(tick.time));
|
||||
jo.put("bid", new JSONNumber(tick.bid));
|
||||
jo.put("ask", new JSONNumber(tick.ask));
|
||||
jo.put("last", new JSONNumber(tick.last));
|
||||
jo.put("volume", new JSONNumber(tick.volume));
|
||||
return jo;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
JSONObject* MqlTradeCheckResultToJson(MqlTradeCheckResult& result)
|
||||
{
|
||||
JSONObject* jo = new JSONObject();
|
||||
jo.put("Retcode", new JSONNumber(result.retcode));
|
||||
jo.put("Balance", new JSONNumber(result.balance));
|
||||
jo.put("Equity", new JSONNumber(result.equity));
|
||||
jo.put("Profit", new JSONNumber(result.profit));
|
||||
jo.put("Margin", new JSONNumber(result.margin));
|
||||
jo.put("Margin_free", new JSONNumber(result.margin_free));
|
||||
jo.put("Margin_level", new JSONNumber(result.margin_level));
|
||||
jo.put("Comment", new JSONString(result.comment));
|
||||
return jo;
|
||||
}
|
||||
|
||||
JSONObject* MqlTradeTransactionToJson(MqlTradeTransaction& trans)
|
||||
{
|
||||
JSONObject *jo = new JSONObject();
|
||||
jo.put("Deal", new JSONNumber(trans.deal));
|
||||
jo.put("Order", new JSONNumber(trans.order));
|
||||
jo.put("Symbol", new JSONString(trans.symbol));
|
||||
jo.put("Type", new JSONNumber((int)trans.type));
|
||||
jo.put("OrderType", new JSONNumber((int)trans.order_type));
|
||||
jo.put("OrderState", new JSONNumber((int)trans.order_state));
|
||||
jo.put("DealType", new JSONNumber((int)trans.deal_type));
|
||||
jo.put("TimeType", new JSONNumber((int)trans.time_type));
|
||||
jo.put("MtTimeExpiration", new JSONNumber((int)trans.time_expiration));
|
||||
jo.put("Price", new JSONNumber(trans.price));
|
||||
jo.put("PriceTrigger", new JSONNumber(trans.price_trigger));
|
||||
jo.put("PriceSl", new JSONNumber(trans.price_sl));
|
||||
jo.put("PriceTp", new JSONNumber(trans.price_tp));
|
||||
jo.put("Volume", new JSONNumber(trans.volume));
|
||||
jo.put("Position", new JSONNumber(trans.position));
|
||||
jo.put("PositionBy", new JSONNumber(trans.position_by));
|
||||
return jo;
|
||||
}
|
||||
|
||||
JSONObject* MqlTradeRequestToJson(MqlTradeRequest& request)
|
||||
{
|
||||
JSONObject *jo = new JSONObject();
|
||||
jo.put("Cction", new JSONNumber((int)request.action));
|
||||
jo.put("Magic", new JSONNumber(request.magic));
|
||||
jo.put("Order", new JSONNumber(request.order));
|
||||
jo.put("Symbol", new JSONString(request.symbol));
|
||||
jo.put("Volume", new JSONNumber(request.volume));
|
||||
jo.put("Price", new JSONNumber(request.price));
|
||||
jo.put("Stoplimit", new JSONNumber(request.stoplimit));
|
||||
jo.put("Sl", new JSONNumber(request.sl));
|
||||
jo.put("Tp", new JSONNumber(request.tp));
|
||||
jo.put("Deviation", new JSONNumber(request.deviation));
|
||||
jo.put("Type", new JSONNumber((int)request.type));
|
||||
jo.put("Type_filling", new JSONNumber((int)request.type_filling));
|
||||
jo.put("Type_time", new JSONNumber((int)request.type_time));
|
||||
jo.put("MtExpiration", new JSONNumber((int)request.expiration));
|
||||
jo.put("Comment", new JSONString(request.comment));
|
||||
return jo;
|
||||
}
|
||||
+1
-1
@@ -257,7 +257,7 @@ public:
|
||||
{
|
||||
return (string)_long;
|
||||
} else {
|
||||
return (string)_dbl;
|
||||
return (_dbl!=0) ? (string)_dbl : "0";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user