diff --git a/MTApiService/MtClient.cs b/MTApiService/MtClient.cs index 45a13ad4..b7cb090a 100755 --- a/MTApiService/MtClient.cs +++ b/MTApiService/MtClient.cs @@ -1,6 +1,4 @@ using System; -using System.Linq; -using System.Text; using System.Diagnostics; using System.Collections; using System.ServiceModel; @@ -13,7 +11,6 @@ namespace MTApiService { private static string SERVICE_NAME = "MtApiService"; -// public delegate void MtInstrumentsChangedHandler(string addedInstrument, string removedInstrument); public delegate void MtQuoteHandler(MtQuote quote); #region Public Methods @@ -21,29 +18,34 @@ namespace MTApiService { Debug.WriteLine("[INFO] MtClient::Open"); - if (string.IsNullOrEmpty(host) == true) - throw new ArgumentNullException("host", "host is null or epmty"); + if (string.IsNullOrEmpty(host)) + throw new ArgumentNullException("host", "host is null or empty"); if (port < 0 || port > 65536) throw new ArgumentOutOfRangeException("port", "port value is invalid"); - string urlService = string.Format("net.tcp://{0}:{1}/{2}", host, port, SERVICE_NAME); + var urlService = string.Format("net.tcp://{0}:{1}/{2}", host, port, SERVICE_NAME); lock (mClientLocker) { if (mProxy != null) return; - var bind = new NetTcpBinding(SecurityMode.None); - bind.MaxReceivedMessageSize = 2147483647; - bind.MaxBufferSize = 2147483647; + var bind = new NetTcpBinding(SecurityMode.None) + { + MaxReceivedMessageSize = 2147483647, + MaxBufferSize = 2147483647, + MaxBufferPoolSize = 2147483647, + ReaderQuotas = + { + MaxArrayLength = 2147483647, + MaxBytesPerRead = 2147483647, + MaxDepth = 2147483647, + MaxStringContentLength = 2147483647, + MaxNameTableCharCount = 2147483647 + } + }; // Commented next statement since it is not required - bind.MaxBufferPoolSize = 2147483647; - bind.ReaderQuotas.MaxArrayLength = 2147483647; - bind.ReaderQuotas.MaxBytesPerRead = 2147483647; - bind.ReaderQuotas.MaxDepth = 2147483647; - bind.ReaderQuotas.MaxStringContentLength = 2147483647; - bind.ReaderQuotas.MaxNameTableCharCount = 2147483647; mProxy = new MtApiProxy(new InstanceContext(this), bind, new EndpointAddress(urlService)); mProxy.Faulted += mProxy_Faulted; @@ -55,23 +57,28 @@ namespace MTApiService if (port < 0 || port > 65536) throw new ArgumentOutOfRangeException("port", "port value is invalid"); - string urlService = "net.pipe://localhost/" + SERVICE_NAME + "_" + port.ToString(); + var urlService = string.Format("net.pipe://localhost/{0}_{1}", SERVICE_NAME, port); lock (mClientLocker) { if (mProxy != null) return; - var bind = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None); - bind.MaxReceivedMessageSize = 2147483647; - bind.MaxBufferSize = 2147483647; + var bind = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None) + { + MaxReceivedMessageSize = 2147483647, + MaxBufferSize = 2147483647, + MaxBufferPoolSize = 2147483647, + ReaderQuotas = + { + MaxArrayLength = 2147483647, + MaxBytesPerRead = 2147483647, + MaxDepth = 2147483647, + MaxStringContentLength = 2147483647, + MaxNameTableCharCount = 2147483647 + } + }; // Commented next statement since it is not required - bind.MaxBufferPoolSize = 2147483647; - bind.ReaderQuotas.MaxArrayLength = 2147483647; - bind.ReaderQuotas.MaxBytesPerRead = 2147483647; - bind.ReaderQuotas.MaxDepth = 2147483647; - bind.ReaderQuotas.MaxStringContentLength = 2147483647; - bind.ReaderQuotas.MaxNameTableCharCount = 2147483647; mProxy = new MtApiProxy(new InstanceContext(this), bind, new EndpointAddress(urlService)); mProxy.Faulted += mProxy_Faulted; diff --git a/MTApiService/MtService.cs b/MTApiService/MtService.cs index 36bf885c..56dfa4d4 100755 --- a/MTApiService/MtService.cs +++ b/MTApiService/MtService.cs @@ -1,9 +1,6 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using System.ServiceModel; -using System.Diagnostics; using System.Threading; namespace MTApiService @@ -23,7 +20,8 @@ namespace MTApiService [OperationContract] IEnumerable GetQuotes(); } - + + [ServiceContract] public interface IMtApiCallback { [OperationContract(IsOneWay = true)] diff --git a/MTApiService/Properties/AssemblyInfo.cs b/MTApiService/Properties/AssemblyInfo.cs index 0b96c155..7e6cc793 100755 --- a/MTApiService/Properties/AssemblyInfo.cs +++ b/MTApiService/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.18.0")] -[assembly: AssemblyFileVersion("1.0.18.0")] +[assembly: AssemblyVersion("1.0.19.0")] +[assembly: AssemblyFileVersion("1.0.19.0")] diff --git a/MtApi/MtApi.csproj b/MtApi/MtApi.csproj index 677110f8..06b04942 100755 --- a/MtApi/MtApi.csproj +++ b/MtApi/MtApi.csproj @@ -81,6 +81,7 @@ + diff --git a/MtApi/MtApiClient.cs b/MtApi/MtApiClient.cs index 0d88c19e..fc3826a0 100755 --- a/MtApi/MtApiClient.cs +++ b/MtApi/MtApiClient.cs @@ -28,11 +28,11 @@ namespace MtApi public MtApiClient() { - mClient.QuoteAdded +=new MtClient.MtQuoteHandler(mClient_QuoteAdded); - mClient.QuoteRemoved += new MtClient.MtQuoteHandler(mClient_QuoteRemoved); - mClient.QuoteUpdated += new MtClient.MtQuoteHandler(mClient_QuoteUpdated); - mClient.ServerDisconnected += new EventHandler(mClient_ServerDisconnected); - mClient.ServerFailed += new EventHandler(mClient_ServerFailed); + _client.QuoteAdded +=new MtClient.MtQuoteHandler(mClient_QuoteAdded); + _client.QuoteRemoved += new MtClient.MtQuoteHandler(mClient_QuoteRemoved); + _client.QuoteUpdated += new MtClient.MtQuoteHandler(mClient_QuoteUpdated); + _client.ServerDisconnected += new EventHandler(mClient_ServerDisconnected); + _client.ServerFailed += new EventHandler(mClient_ServerFailed); } #endregion @@ -79,16 +79,26 @@ namespace MtApi /// public IEnumerable GetQuotes() { - var quotes = mClient.GetQuotes(); + var quotes = _client.GetQuotes(); return quotes != null ? (from q in quotes select q.Parse()) : null; } #endregion #region Properties + /// ///Connection status of MetaTrader API. /// - public MtConnectionState ConnectionState { get; private set; } + public MtConnectionState ConnectionState + { + get + { + lock (_locker) + { + return _connectionState; + } + } + } #endregion @@ -411,13 +421,29 @@ namespace MtApi public bool OrderModify(int ticket, double price, double stoploss, double takeprofit, DateTime expiration, Color arrow_color) { - var commandParameters = new ArrayList { ticket, price, stoploss, takeprofit, MtApiTimeConverter.ConvertToMtTime(expiration), MtApiColorConverter.ConvertToMtColor(arrow_color) }; - return SendCommand(MtCommandType.OrderModify, commandParameters); + var response = SendRequest(new OrderModifyRequest + { + Ticket = ticket, + Price = price, + Stoploss = stoploss, + Takeprofit = takeprofit, + Expiration = MtApiTimeConverter.ConvertToMtTime(expiration), + ArrowColor = MtApiColorConverter.ConvertToMtColor(arrow_color) + }); + return response != null; } public bool OrderModify(int ticket, double price, double stoploss, double takeprofit, DateTime expiration) { - return OrderModify(ticket, price, stoploss, takeprofit, expiration, Color.Empty); + var response = SendRequest(new OrderModifyRequest + { + Ticket = ticket, + Price = price, + Stoploss = stoploss, + Takeprofit = takeprofit, + Expiration = MtApiTimeConverter.ConvertToMtTime(expiration), + }); + return response != null; } public void OrderPrint() @@ -1342,60 +1368,64 @@ namespace MtApi #region Private Methods private void Connect(string host, int port) { - ConnectionState = MtConnectionState.Connecting; - ConnectionStateChanged.FireEvent(this - , new MtConnectionEventArgs(MtConnectionState.Connecting, "Connecting to " + host + ":" + port)); + UpdateConnectionState(MtConnectionState.Connecting, string.Format("Connecting to {0}:{1}", host, port)); try { - mClient.Open(host, port); - mClient.Connect(); + _client.Open(host, port); + _client.Connect(); } catch (Exception e) { - ConnectionState = MtConnectionState.Failed; - ConnectionStateChanged.FireEvent(this - , new MtConnectionEventArgs(MtConnectionState.Failed, "Failed connection to " + host + ":" + port + ". " + e.Message)); + UpdateConnectionState(MtConnectionState.Failed, string.Format("Failed connection to {0}:{1}. {2}", host, port, e.Message)); return; } - ConnectionState = MtConnectionState.Connected; - ConnectionStateChanged.FireEvent(this - , new MtConnectionEventArgs(MtConnectionState.Connected, "Connected to " + host + ":" + port)); + UpdateConnectionState(MtConnectionState.Connected, string.Format("Connected to {0}:{1}", host, port)); } private void Connect(int port) { - ConnectionState = MtConnectionState.Connecting; - ConnectionStateChanged.FireEvent(this - , new MtConnectionEventArgs(MtConnectionState.Connecting, "Connecting to 'localhost':" + port)); + UpdateConnectionState(MtConnectionState.Connecting, string.Format("Connecting to 'localhost':{0}", port)); try { - mClient.Open(port); - mClient.Connect(); + _client.Open(port); + _client.Connect(); } catch (Exception e) { - ConnectionState = MtConnectionState.Failed; - ConnectionStateChanged.FireEvent(this - , new MtConnectionEventArgs(MtConnectionState.Failed, "Failed connection to 'localhost':" + port + ". " + e.Message)); - + UpdateConnectionState(MtConnectionState.Failed, string.Format("Failed connection to 'localhost':{0}. {1}", port, e.Message)); return; } - ConnectionState = MtConnectionState.Connected; - ConnectionStateChanged.FireEvent(this - , new MtConnectionEventArgs(MtConnectionState.Connected, "Connected to 'localhost':" + port)); + UpdateConnectionState(MtConnectionState.Connected, string.Format("Connected to 'localhost':{0}", port)); } private void Disconnect() { - mClient.Disconnect(); - mClient.Close(); + _client.Disconnect(); + _client.Close(); - ConnectionState = MtConnectionState.Disconnected; - ConnectionStateChanged.FireEvent(this, new MtConnectionEventArgs(MtConnectionState.Disconnected, "Disconnected")); + UpdateConnectionState(MtConnectionState.Disconnected, "Disconnected"); + } + + private void UpdateConnectionState(MtConnectionState state, string message) + { + var changed = false; + lock (_locker) + { + if (_connectionState != state) + { + _connectionState = state; + changed = true; + } + } + + if (changed) + { + ConnectionStateChanged.FireEvent(this, new MtConnectionEventArgs(state, message)); + } } private T SendCommand(MtCommandType commandType, ArrayList commandParameters) @@ -1403,7 +1433,7 @@ namespace MtApi MtResponse response; try { - response = mClient.SendCommand((int)commandType, commandParameters); + response = _client.SendCommand((int)commandType, commandParameters); } catch (CommunicationException ex) { @@ -1451,7 +1481,7 @@ namespace MtApi MtResponseString res; try { - res = (MtResponseString)mClient.SendCommand((int)MtCommandType.MtRequest, commandParameters); + res = (MtResponseString)_client.SendCommand((int)MtCommandType.MtRequest, commandParameters); } catch (CommunicationException ex) { @@ -1482,16 +1512,12 @@ namespace MtApi private void mClient_ServerDisconnected(object sender, EventArgs e) { - ConnectionState = MtConnectionState.Disconnected; - ConnectionStateChanged.FireEvent(this - , new MtConnectionEventArgs(MtConnectionState.Disconnected, "MtApi is disconnected")); + UpdateConnectionState(MtConnectionState.Disconnected, "MtApi is disconnected"); } private void mClient_ServerFailed(object sender, EventArgs e) { - ConnectionState = MtConnectionState.Failed; - ConnectionStateChanged.FireEvent(this - , new MtConnectionEventArgs(MtConnectionState.Failed, "Failed connection with MtApi")); + UpdateConnectionState(MtConnectionState.Failed, "Failed connection with MtApi"); } private void mClient_QuoteRemoved(MTApiService.MtQuote quote) @@ -1513,7 +1539,9 @@ namespace MtApi #endregion #region Private Fields - private readonly MtClient mClient = new MtClient(); + private readonly MtClient _client = new MtClient(); + private readonly object _locker = new object(); + private MtConnectionState _connectionState = MtConnectionState.Disconnected; #endregion } } diff --git a/MtApi/MtOrder.cs b/MtApi/MtOrder.cs index b48c8b4a..092c1ae5 100644 --- a/MtApi/MtOrder.cs +++ b/MtApi/MtOrder.cs @@ -17,6 +17,7 @@ namespace MtApi public double Commission { get; set; } public int MagicNumber { get; set; } public double Swap { get; set; } + public int MtExpiration { get; set; } public DateTime OpenTime { @@ -27,5 +28,10 @@ namespace MtApi { get { return MtApiTimeConverter.ConvertFromMtTime(MtCloseTime); } } + + public DateTime Expiration + { + get { return MtApiTimeConverter.ConvertFromMtTime(MtExpiration); } + } } } \ No newline at end of file diff --git a/MtApi/Properties/AssemblyInfo.cs b/MtApi/Properties/AssemblyInfo.cs index 67888fbc..c1cf20c9 100755 --- a/MtApi/Properties/AssemblyInfo.cs +++ b/MtApi/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.24.0")] -[assembly: AssemblyFileVersion("1.0.24.0")] +[assembly: AssemblyVersion("1.0.25.0")] +[assembly: AssemblyFileVersion("1.0.25.0")] diff --git a/MtApi/Requests/OrderModifyRequest.cs b/MtApi/Requests/OrderModifyRequest.cs new file mode 100644 index 00000000..ca8edbea --- /dev/null +++ b/MtApi/Requests/OrderModifyRequest.cs @@ -0,0 +1,18 @@ +namespace MtApi.Requests +{ + public class OrderModifyRequest: RequestBase + { + public int Ticket { get; set; } + public double Price { get; set; } + public double Stoploss { get; set; } + public double Takeprofit { get; set; } + public int Expiration { get; set; } + + public int? ArrowColor { get; set; } + + public override RequestType RequestType + { + get { return RequestType.OrderModify; } + } + } +} \ No newline at end of file diff --git a/MtApi/Requests/RequestType.cs b/MtApi/Requests/RequestType.cs index a6d92a53..b91cbbdf 100644 --- a/MtApi/Requests/RequestType.cs +++ b/MtApi/Requests/RequestType.cs @@ -8,6 +8,7 @@ OrderSend = 3, OrderClose = 4, OrderCloseBy = 5, - OrderDelete = 6 + OrderDelete = 6, + OrderModify = 7 } } \ No newline at end of file diff --git a/MtApiInstaller/Product.wxs b/MtApiInstaller/Product.wxs index eae44785..76e1e5cc 100755 --- a/MtApiInstaller/Product.wxs +++ b/MtApiInstaller/Product.wxs @@ -1,7 +1,7 @@ - + diff --git a/TestApiClientUI/Form1.Designer.cs b/TestApiClientUI/Form1.Designer.cs index c32e19a5..ae0949e2 100755 --- a/TestApiClientUI/Form1.Designer.cs +++ b/TestApiClientUI/Form1.Designer.cs @@ -128,6 +128,7 @@ this.textBoxOppositeTicket = new System.Windows.Forms.TextBox(); this.label3 = new System.Windows.Forms.Label(); this.button21 = new System.Windows.Forms.Button(); + this.button22 = new System.Windows.Forms.Button(); this.groupBox1.SuspendLayout(); this.statusStrip1.SuspendLayout(); this.groupBox2.SuspendLayout(); @@ -308,6 +309,7 @@ // // tabPage2 // + this.tabPage2.Controls.Add(this.button22); this.tabPage2.Controls.Add(this.button21); this.tabPage2.Controls.Add(this.label3); this.tabPage2.Controls.Add(this.textBoxOppositeTicket); @@ -1228,6 +1230,16 @@ this.button21.UseVisualStyleBackColor = true; this.button21.Click += new System.EventHandler(this.button21_Click); // + // button22 + // + this.button22.Location = new System.Drawing.Point(216, 293); + this.button22.Name = "button22"; + this.button22.Size = new System.Drawing.Size(75, 23); + this.button22.TabIndex = 19; + this.button22.Text = "OrderModify"; + this.button22.UseVisualStyleBackColor = true; + this.button22.Click += new System.EventHandler(this.button22_Click); + // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -1368,6 +1380,7 @@ private System.Windows.Forms.TextBox textBoxOppositeTicket; private System.Windows.Forms.Button button15; private System.Windows.Forms.Button button21; + private System.Windows.Forms.Button button22; } } diff --git a/TestApiClientUI/Form1.cs b/TestApiClientUI/Form1.cs index 57028368..dd120cc6 100755 --- a/TestApiClientUI/Form1.cs +++ b/TestApiClientUI/Form1.cs @@ -57,7 +57,10 @@ namespace TestApiClientUI private void RunOnUiThread(Action action) { - this.BeginInvoke(action); + if (!IsDisposed) + { + this.BeginInvoke(action); + } } private void apiClient_ConnectionStateChanged(object sender, MtConnectionEventArgs e) @@ -875,8 +878,8 @@ namespace TestApiClientUI { var result = string.Format( - "Order: Ticket = {0}, Symbol = {1}, Operation = {2}, OpenPrice = {3}, ClosePrice = {4}, Lots = {5}, Profit = {6}, Comment = {7}, Commission = {8}, MagicNumber = {9}, OpenTime = {10}, CloseTime = {11}, Swap = {12}", - order.Ticket, order.Symbol, order.Operation, order.OpenPrice, order.ClosePrice, order.Lots, order.Profit, order.Comment, order.Commission, order.MagicNumber, order.OpenTime, order.CloseTime, order.Swap); + "Order: Ticket = {0}, Symbol = {1}, Operation = {2}, OpenPrice = {3}, ClosePrice = {4}, Lots = {5}, Profit = {6}, Comment = {7}, Commission = {8}, MagicNumber = {9}, OpenTime = {10}, CloseTime = {11}, Swap = {12}, Expiration = {13}", + order.Ticket, order.Symbol, order.Operation, order.OpenPrice, order.ClosePrice, order.Lots, order.Profit, order.Comment, order.Commission, order.MagicNumber, order.OpenTime, order.CloseTime, order.Swap, order.Expiration); AddToLog(result); } } @@ -895,8 +898,8 @@ namespace TestApiClientUI { var result = string.Format( - "Order: Ticket = {0}, Symbol = {1}, Operation = {2}, OpenPrice = {3}, ClosePrice = {4}, Lots = {5}, Profit = {6}, Comment = {7}, Commission = {8}, MagicNumber = {9}, OpenTime = {10}, CloseTime = {11}, Swap = {12}", - order.Ticket, order.Symbol, order.Operation, order.OpenPrice, order.ClosePrice, order.Lots, order.Profit, order.Comment, order.Commission, order.MagicNumber, order.OpenTime, order.CloseTime, order.Swap); + "Order: Ticket = {0}, Symbol = {1}, Operation = {2}, OpenPrice = {3}, ClosePrice = {4}, Lots = {5}, Profit = {6}, Comment = {7}, Commission = {8}, MagicNumber = {9}, OpenTime = {10}, CloseTime = {11}, Swap = {12}, Expiration = {13}", + order.Ticket, order.Symbol, order.Operation, order.OpenPrice, order.ClosePrice, order.Lots, order.Profit, order.Comment, order.Commission, order.MagicNumber, order.OpenTime, order.CloseTime, order.Swap, order.Expiration); AddToLog(result); } } @@ -979,5 +982,25 @@ namespace TestApiClientUI AddToLog(string.Format("Delete order result: {0}, ticket = {1}", deleted, ticket)); } + + private async void button22_Click(object sender, EventArgs e) + { + var ticket = int.Parse(textBoxIndexTicket.Text); + + double price; + double.TryParse(textBoxOrderPrice.Text, out price); + + double stoploss; + double.TryParse(textBoxOrderStoploss.Text, out stoploss); + + double takeprofit; + double.TryParse(textBoxOrderProffit.Text, out takeprofit); + + var expiration = DateTime.MinValue; + + var modified = await Execute(() => _apiClient.OrderModify(ticket, price, stoploss, takeprofit, expiration)); + + AddToLog(string.Format("Modify order result: {0}, ticket = {1}", modified, ticket)); + } } } diff --git a/mq4/MtApi.ex4 b/mq4/MtApi.ex4 index 3faed062..68957fa7 100755 Binary files a/mq4/MtApi.ex4 and b/mq4/MtApi.ex4 differ diff --git a/mq4/MtApi.mq4 b/mq4/MtApi.mq4 index 0ee12994..5c5ec2af 100755 --- a/mq4/MtApi.mq4 +++ b/mq4/MtApi.mq4 @@ -3422,9 +3422,12 @@ string OnRequest(string json) case 5: //OrderCloseBy response = ExecuteRequestOrderCloseBy(jo); break; - case 6: + case 6: //OrderDelete response = ExecuteRequestOrderDelete(jo); break; + case 7: //OrderModify + response = ExecuteRequestOrderModify(jo); + break; default: Print("OnRequest [WARNING]: Unknown request type ", requestType); response = CreateErrorResponse(-1, "Unknown request type"); @@ -3462,6 +3465,7 @@ JSONObject* GetOrderJson(int index, int select, int pool) datetime openTime = OrderOpenTime(); datetime closeTime = OrderCloseTime(); double swap = OrderSwap(); + datetime expiration = OrderExpiration(); JSONObject *joOrder = new JSONObject(); joOrder.put("Ticket", new JSONNumber(ticket)); @@ -3479,6 +3483,7 @@ JSONObject* GetOrderJson(int index, int select, int pool) joOrder.put("MtOpenTime", new JSONNumber(openTime)); joOrder.put("MtCloseTime", new JSONNumber(closeTime)); joOrder.put("Swap", new JSONNumber(swap)); + joOrder.put("MtExpiration", new JSONNumber(expiration)); return joOrder; } @@ -3665,4 +3670,31 @@ string ExecuteRequestOrderDelete(JSONObject *jo) if (!OrderDelete(ticket, arrowcolor)) return CreateErrorResponse(GetLastError(), "OrderDelete failed"); return CreateSuccessResponse("", NULL); +} + +string ExecuteRequestOrderModify(JSONObject *jo) +{ + if (jo.getValue("Ticket") == NULL) + return CreateErrorResponse(-1, "Undefinded mandatory parameter Ticket"); + if (jo.getValue("Price") == NULL) + return CreateErrorResponse(-1, "Undefinded mandatory parameter Price"); + if (jo.getValue("Stoploss") == NULL) + return CreateErrorResponse(-1, "Undefinded mandatory parameter Stoploss"); + if (jo.getValue("Takeprofit") == NULL) + return CreateErrorResponse(-1, "Undefinded mandatory parameter Takeprofit"); + if (jo.getValue("Expiration") == NULL) + return CreateErrorResponse(-1, "Undefinded mandatory parameter Expiration"); + + int ticket = jo.getInt("Ticket"); + double price = jo.getDouble("Price"); + double stoploss = jo.getDouble("Stoploss"); + double takeprofit = jo.getDouble("Takeprofit"); + int expiration = jo.getInt("Expiration"); + + JSONValue *jvArrowColor = jo.getValue("ArrowColor"); + int arrowcolor = (jvArrowColor != NULL) ? jvArrowColor.getInt() : CLR_NONE; + + if (!OrderModify(ticket, price, stoploss, takeprofit, expiration, arrowcolor)) + return CreateErrorResponse(GetLastError(), "OrderModify failed"); + return CreateSuccessResponse("", NULL); } \ No newline at end of file