Compare commits

...

49 Commits

Author SHA1 Message Date
DW b77516e324 Issue #59: Added event OnChartEvent into MtApi (MT4) 2017-09-05 18:34:26 +03:00
DW 4b48423c3f Issue #57: Added function PositionSelectByTicket into MQL code 2017-09-04 13:08:30 +03:00
DW 9800177b08 Issue #57: Added function PositionSelectByTicket into C# code 2017-08-29 17:40:23 +03:00
Vyacheslav Demidyuk a33d4a4594 Merge pull request #58 from Tr4Dr/master
Refactored and updated enumerations
2017-08-28 13:56:44 +03:00
Unknown 29722f362d Added Position and PositionBy properties to MqlTradeRequest 2017-08-25 15:32:24 +02:00
Unknown e072343fe1 Missing break after PositionGetSymbol 2017-08-25 15:12:41 +02:00
Unknown acb0c20ca8 Missing break after PositionGetDouble 2017-08-25 15:00:24 +02:00
Unknown 83543fee88 Refactored and updated enumerations 2017-08-25 01:31:57 +02:00
DW 3ce6b042de Added files into MtApi.proj 2017-08-21 15:56:21 +03:00
DW 9dd770e768 Fixed small errors in MQL part of chart operations 2017-08-21 15:42:10 +03:00
DW abb8b8afaa Added enums for chart properties. Fixed some mistakes in C# code of Chart Operations 2017-08-21 13:57:38 +03:00
DW 1d6569caa8 Issue #53: Complete add chart operation functions in expert (MQL part) 2017-08-18 18:56:00 +03:00
DW 441a3cb8de Merge with branch auth 2017-08-15 16:42:51 +03:00
DW 443f5c982c Issue #53: Complete chart operation functions into MtApi (client side) 2017-08-15 14:34:41 +03:00
DW 515a12ab15 Added function ChangeAccount 2017-08-12 01:31:36 +03:00
DW 84b00b605a Issue #53: Added some chart operation functions into MtApi (client side) 2017-08-11 23:33:30 +03:00
DW 10e267d031 Fixed bug in function iBarShift 2017-07-20 17:55:29 +03:00
DW abcd489367 Started version 1.0.37 2017-06-21 17:41:10 +03:00
DW d630e61e3c Issue #52: Updated functions OrderSend to use request stucture 2017-05-11 17:26:46 +03:00
DW 280bab7faf Started version 1.0.36 2017-05-11 10:44:30 +03:00
DW 26d270422b Revert version mtapi (MT4) to 1.0.35 2017-05-06 23:34:30 +03:00
DW 9cd2e3b18f Updated test application: added button on function UnlockTicks 2017-05-05 15:51:34 +03:00
DW 50013c0c29 Added command to UnlockTick in backtesting mode that will be locked on each candle. It allows to perform big tasks and send commands to MT4 in time of candle. 2017-05-05 14:16:15 +03:00
DW ca49d23017 Started version 1.0.36 2017-05-05 14:01:29 +03:00
DW 0346836d35 Issue #51: Add support localhost (127.0.0.1) host name 2017-05-05 13:57:43 +03:00
DW 2cc41df01a MtApi (MT4) version 1.0.34. Fixed issue #45 in MtApi.ex4 2017-02-22 17:17:00 +02:00
DW f05ade2cbf Set AppendToFile to True in LogConfigurator 2017-01-12 16:47:41 +02:00
DW d34524d77f Issue #44: Fixed MT5Connector project for using MtAdapter 2017-01-08 14:47:08 +02:00
DW d06cc67a5d MtApi MT5: started version 1.0.12 2017-01-08 14:45:03 +02:00
DW 5b76bf0547 Merge master fixed conflict. 2017-01-05 21:36:55 +02:00
DW 1c269f7339 Issue #32: Added function ObjectName into test client 2017-01-05 02:14:13 +02:00
DW 21fb790d8c Issue #32: Fixed small bugs in EA MtApi.mq4 2017-01-05 01:02:55 +02:00
DW 7c9a0aa8cc Issue #32: Implement object functions in EA MtApi.mq4 2017-01-03 21:29:41 +02:00
DW 18ddf3df1c Issue #32: Added c# implementations of most object functions in MtApi client 2016-12-30 17:16:48 +02:00
DW a8832b79ba Issue #32: Added function ObjectCreate in MtApi (MT4) 2016-12-27 17:41:11 +02:00
vdemydiuk 39146d68b2 Starting work on Object Functions 2016-12-26 17:49:06 +02:00
DW 5b03f01e9b Clear unnecessary witespaces in MtApi.mq4 2016-12-21 14:26:37 +02:00
vdemydiuk 8f5a1c8222 Refactored MtApi.mq4 2016-12-21 12:01:15 +02:00
vdemydiuk f5f13a13cc Issue #32: Added function ChartRedraw 2016-12-12 17:29:52 +02:00
vdemydiuk 9ef970cf1e Refactoring TestApiUiClient (Account Information tab) 2016-11-30 10:57:33 +02:00
vdemydiuk b5878ccb62 Refactoring TestApiUiClient (Check Status tab) 2016-11-29 19:08:53 +02:00
DW 4a7bb6f2cb MtApi (MT5) ver. 1.0.11.1 HotFix 2016-11-29 10:20:55 +02:00
vdemydiuk 5abfeebc90 Issue #32: Added function ChartId 2016-11-28 16:03:40 +02:00
vdemydiuk e333164552 Issue #32: Added ExecutorHandle property to determine which expert will be used for execution command 2016-11-28 14:45:33 +02:00
vdemydiuk 9a6968f618 Refactoring MtApi 2016-11-26 19:27:09 +02:00
DW 88e2d22abe Issue #38: Removed MemoryAppender in LogConfigurator (MtApiService) 2016-11-23 13:09:47 +02:00
DW fcfd741e5b Issue #37: Used ConcurrencyMode.Multiple for server and client side to avoid deadlocks and freezes of MtApiService 2016-11-23 10:51:50 +02:00
DW c722511c03 Refactored MtApiService (ver. 1.0.24): Added ExpertHandle to MtQuote and MtEvent. Added event QuoteUpdate to MtApiClient. 2016-11-18 15:47:55 +02:00
DW 39599436ab Started version 1.0.33 of MtApi MT4 2016-11-18 12:13:00 +02:00
68 changed files with 4416 additions and 1719 deletions
+24 -24
View File
@@ -107,7 +107,7 @@ int _stdcall initExpert(int expertHandle, int port, wchar_t* symbol, double bid,
try
{
MT5Handler^ mtHander = gcnew MT5Handler();
MtServerInstance::GetInstance()->InitExpert(expertHandle, port, gcnew String(symbol), bid, ask, mtHander);
MtAdapter::GetInstance()->InitExpert(expertHandle, port, gcnew String(symbol), bid, ask, mtHander);
}
catch (Exception^ e)
{
@@ -123,7 +123,7 @@ int _stdcall deinitExpert(int expertHandle, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->DeinitExpert(expertHandle);
MtAdapter::GetInstance()->DeinitExpert(expertHandle);
}
catch (Exception^ e)
{
@@ -139,7 +139,7 @@ int _stdcall updateQuote(int expertHandle, wchar_t* symbol, double bid, double a
{
try
{
MtServerInstance::GetInstance()->SendQuote(expertHandle, gcnew String(symbol), bid, ask);
MtAdapter::GetInstance()->SendQuote(expertHandle, gcnew String(symbol), bid, ask);
}
catch (Exception^ e)
{
@@ -155,7 +155,7 @@ int _stdcall sendIntResponse(int expertHandle, int response)
{
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseInt(response));
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseInt(response));
}
catch (Exception^ e)
{
@@ -169,7 +169,7 @@ int _stdcall sendLongResponse(int expertHandle, __int64 response)
{
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLong(response));
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLong(response));
}
catch (Exception^ e)
{
@@ -183,7 +183,7 @@ int _stdcall sendULongResponse(int expertHandle, unsigned __int64 response)
{
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseULong(response));
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseULong(response));
}
catch (Exception^ e)
{
@@ -199,7 +199,7 @@ int _stdcall sendBooleanResponse(int expertHandle, int response)
{
bool value = (response != 0) ? true : false;
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseBool(value));
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseBool(value));
}
catch (Exception^ e)
{
@@ -213,7 +213,7 @@ int _stdcall sendDoubleResponse(int expertHandle, double response)
{
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDouble(response));
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDouble(response));
}
catch (Exception^ e)
{
@@ -227,7 +227,7 @@ int _stdcall sendStringResponse(int expertHandle, wchar_t* response)
{
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseString(gcnew String(response)));
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseString(gcnew String(response)));
}
catch (Exception^ e)
{
@@ -241,7 +241,7 @@ int _stdcall sendVoidResponse(int expertHandle)
{
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, nullptr);
MtAdapter::GetInstance()->SendResponse(expertHandle, nullptr);
}
catch (Exception^ e)
{
@@ -262,7 +262,7 @@ int _stdcall sendDoubleArrayResponse(int expertHandle, double* values, int size)
list[i] = values[i];
}
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDoubleArray(list));
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDoubleArray(list));
}
catch (Exception^ e)
{
@@ -283,7 +283,7 @@ int _stdcall sendIntArrayResponse(int expertHandle, int* values, int size)
list[i] = values[i];
}
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseIntArray(list));
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseIntArray(list));
}
catch (Exception^ e)
{
@@ -304,7 +304,7 @@ int _stdcall sendLongArrayResponse(int expertHandle, __int64* values, int size)
list[i] = values[i];
}
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLongArray(list));
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLongArray(list));
}
catch (Exception^ e)
{
@@ -335,7 +335,7 @@ int _stdcall sendMqlRatesArrayResponse(int expertHandle, CMqlRates values[], int
list[i] = rates;
}
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlRatesArray(list));
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlRatesArray(list));
}
catch (Exception^ e)
{
@@ -357,7 +357,7 @@ int _stdcall sendMqlTickResponse(int expertHandle, CMqlTick* response, int size)
mtResponse->last = response->last;
mtResponse->volume = response->volume;
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlTick(mtResponse));
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlTick(mtResponse));
}
catch (Exception^ e)
{
@@ -384,7 +384,7 @@ int _stdcall sendMqlBookInfoArrayResponse(int expertHandle, CMqlBookInfo values[
list[i] = info;
}
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlBookInfoArray(list));
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlBookInfoArray(list));
}
catch (Exception^ e)
{
@@ -400,7 +400,7 @@ int _stdcall getCommandType(int expertHandle, int* res)
{
try
{
*res = MtServerInstance::GetInstance()->GetCommandType(expertHandle);
*res = MtAdapter::GetInstance()->GetCommandType(expertHandle);
}
catch (Exception^ e)
{
@@ -414,7 +414,7 @@ int _stdcall getIntValue(int expertHandle, int paramIndex, int* res)
{
try
{
*res = (int)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
*res = (int)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
}
catch (Exception^ e)
{
@@ -428,7 +428,7 @@ int _stdcall getDoubleValue(int expertHandle, int paramIndex, double* res)
{
try
{
*res = (double)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
*res = (double)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
}
catch (Exception^ e)
{
@@ -442,7 +442,7 @@ int _stdcall getStringValue(int expertHandle, int paramIndex, wchar_t* res)
{
try
{
convertSystemString(res, (String^)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex));
convertSystemString(res, (String^)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex));
}
catch (Exception^ e)
{
@@ -456,7 +456,7 @@ int _stdcall getULongValue(int expertHandle, int paramIndex, unsigned __int64* r
{
try
{
*res = (unsigned long)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
*res = (unsigned long)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
}
catch (Exception^ e)
{
@@ -470,7 +470,7 @@ int _stdcall getLongValue(int expertHandle, int paramIndex, __int64* res)
{
try
{
*res = (long)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
*res = (long)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
}
catch (Exception^ e)
{
@@ -484,7 +484,7 @@ int _stdcall getBooleanValue(int expertHandle, int paramIndex, int* res)
{
try
{
bool val = (bool)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
bool val = (bool)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
*res = val == true ? 1 : 0;
}
catch (Exception^ e)
@@ -499,7 +499,7 @@ int _stdcall getUIntValue(int expertHandle, int paramIndex, unsigned int* res)
{
try
{
*res = (unsigned int)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
*res = (unsigned int)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
}
catch (Exception^ e)
{
+2 -3
View File
@@ -1,8 +1,7 @@
namespace MTApiService
{
public interface ICommandManager
internal interface ICommandManager
{
void EnqueueCommandTask(MtCommandTask task);
MtCommandTask DequeueCommandTask();
MtCommandTask SendCommand(MtCommand task);
}
}
+9
View File
@@ -0,0 +1,9 @@
namespace MTApiService
{
internal interface ITaskExecutor
{
void Execute(MtCommandTask task);
int Handle { get; }
}
}
+1 -1
View File
@@ -29,7 +29,7 @@ namespace MTApiService
var roller = new RollingFileAppender
{
AppendToFile = false,
AppendToFile = true,
File = $@"{System.IO.Path.GetTempPath()}{profileName}\Logs\{filename}",
Layout = patternLayout,
PreserveLogFileNameExtension = true,
+3 -2
View File
@@ -62,6 +62,7 @@
<ItemGroup>
<Compile Include="ICommandManager.cs" />
<Compile Include="IMetaTraderHandler.cs" />
<Compile Include="ITaskExecutor.cs" />
<Compile Include="LogConfigurator.cs" />
<Compile Include="MtCommandEventArgs.cs" />
<Compile Include="IDisposableChannel.cs" />
@@ -78,11 +79,11 @@
<Compile Include="MtConnectionProfile.cs" />
<Compile Include="MtExecutorManager.cs" />
<Compile Include="MtExpert.cs" />
<Compile Include="MtInstrument.cs" />
<Compile Include="MtQuote.cs" />
<Compile Include="MtResponse.cs" />
<Compile Include="MtServer.cs" />
<Compile Include="MtCommand.cs" />
<Compile Include="MtServerInstance.cs" />
<Compile Include="MtAdapter.cs" />
<Compile Include="MtService.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
+53 -9
View File
@@ -4,13 +4,13 @@ using log4net;
namespace MTApiService
{
public class MtServerInstance
public class MtAdapter
{
#region Fields
private const string LogProfileName = "MtApiService";
private static readonly ILog Log = LogManager.GetLogger(typeof(MtServerInstance));
private static readonly MtServerInstance Instance = new MtServerInstance();
private static readonly ILog Log = LogManager.GetLogger(typeof(MtAdapter));
private static readonly MtAdapter Instance = new MtAdapter();
private readonly Dictionary<int, MtServer> _servers = new Dictionary<int, MtServer>();
private readonly Dictionary<int, MtExpert> _experts = new Dictionary<int, MtExpert>();
@@ -18,16 +18,16 @@ namespace MTApiService
#region Init Instance
private MtServerInstance()
private MtAdapter()
{
LogConfigurator.Setup(LogProfileName);
}
static MtServerInstance()
static MtAdapter()
{
}
public static MtServerInstance GetInstance()
public static MtAdapter GetInstance()
{
return Instance;
}
@@ -60,7 +60,7 @@ namespace MTApiService
}
}
var expert = new MtExpert(expertHandle, new MtQuote(symbol, bid, ask), mtHandler);
var expert = new MtExpert(expertHandle, new MtQuote { Instrument = symbol, Bid = bid, Ask = ask, ExpertHandle = expertHandle }, mtHandler);
lock (_experts)
{
@@ -111,7 +111,7 @@ namespace MTApiService
if (expert != null)
{
expert.Quote = new MtQuote(symbol, bid, ask);
expert.Quote = new MtQuote { Instrument = symbol, Bid = bid, Ask = ask, ExpertHandle = expertHandle };
}
else
{
@@ -133,7 +133,7 @@ namespace MTApiService
if (expert != null)
{
expert.SendEvent(new MtEvent(eventType, payload));
expert.SendEvent(new MtEvent { EventType = eventType, Payload = payload, ExpertHandle = expertHandle });
}
else
{
@@ -208,6 +208,50 @@ namespace MTApiService
return retval;
}
public object GetNamedParameter(int expertHandle, string name)
{
Log.DebugFormat("GetNamedParameter: begin. expertHandle = {0}, name = {1}", expertHandle, name);
MtExpert expert;
lock (_experts)
{
expert = _experts[expertHandle];
}
if (expert == null)
{
Log.WarnFormat("GetNamedParameter: expert with id {0} has not been found.", expertHandle);
}
var retval = expert?.GetNamedParameter(name);
Log.DebugFormat("GetNamedParameter: end. retval = {0}", retval);
return retval;
}
public bool ContainsNamedParameter(int expertHandle, string name)
{
Log.DebugFormat("ContainsNamedParameter: begin. expertHandle = {0}, name = {1}", expertHandle, name);
MtExpert expert;
lock (_experts)
{
expert = _experts[expertHandle];
}
if (expert == null)
{
Log.WarnFormat("ContainsNamedParameter: expert with id {0} has not been found.", expertHandle);
}
bool retval = expert != null ? expert.ContainsNamedParameter(name) : false;
Log.DebugFormat("ContainsNamedParameter: end. retval = {0}", retval);
return retval;
}
#endregion
#region Private Methods
+1 -1
View File
@@ -11,13 +11,13 @@ namespace MTApiService
: base(callbackContext, binding, remoteAddress)
{
InnerDuplexChannel.Faulted += InnerDuplexChannel_Faulted;
InnerDuplexChannel.Open();
}
#region IMtApi Members
public bool Connect()
{
InnerDuplexChannel.Open();
return Channel.Connect();
}
+42 -90
View File
@@ -6,38 +6,33 @@ using log4net;
namespace MTApiService
{
[CallbackBehavior(UseSynchronizationContext = false)]
public class MtClient: IMtApiCallback, IDisposable
[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)]
public class MtClient : IMtApiCallback, IDisposable
{
private const string ServiceName = "MtApiService";
public delegate void MtQuoteHandler(MtQuote quote);
public delegate void MtEventHandler(MtEvent e);
#region Fields
private static readonly ILog Log = LogManager.GetLogger(typeof(MtClient));
private MtApiProxy _proxy;
private bool _isConnected;
private readonly MtApiProxy _proxy;
#endregion
#region Public Methods
public void Open(string host, int port)
#region ctor
public MtClient(string host, int port)
{
Log.DebugFormat("Open: begin. host = {0}, port = {1}", host, port);
if (string.IsNullOrEmpty(host))
throw new ArgumentNullException(nameof(host), "host is null or empty");
if (port < 0 || port > 65536)
throw new ArgumentOutOfRangeException(nameof(port), "port value is invalid");
var urlService = $"net.tcp://{host}:{port}/{ServiceName}";
Host = host;
Port = port;
if (_proxy != null)
{
Log.Warn("Open: end. _proxy is not null.");
return;
}
var urlService = $"net.tcp://{host}:{port}/{ServiceName}";
var bind = new NetTcpBinding(SecurityMode.None)
{
@@ -55,28 +50,19 @@ namespace MTApiService
MaxNameTableCharCount = 2147483647
}
};
// Commented next statement since it is not required
_proxy = new MtApiProxy(new InstanceContext(this), bind, new EndpointAddress(urlService));
_proxy.Faulted += ProxyFaulted;
Log.Debug("Open: end.");
}
public void Open(int port)
public MtClient(int port)
{
Log.DebugFormat("Open: begin. port = {0}", port);
if (port < 0 || port > 65536)
throw new ArgumentOutOfRangeException(nameof(port), "port value is invalid");
var urlService = $"net.pipe://localhost/{ServiceName}_{port}";
Port = port;
if (_proxy != null)
{
Log.Warn("Open: end. _proxy is not null.");
return;
}
var urlService = $"net.pipe://localhost/{ServiceName}_{port}";
var bind = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
{
@@ -94,61 +80,40 @@ namespace MTApiService
MaxNameTableCharCount = 2147483647
}
};
// Commented next statement since it is not required
_proxy = new MtApiProxy(new InstanceContext(this), bind, new EndpointAddress(urlService));
_proxy.Faulted += ProxyFaulted;
Log.Debug("Open: end.");
}
public void Close()
{
Log.Debug("Close: begin.");
if (_proxy != null)
{
_proxy.Faulted -= ProxyFaulted;
_proxy.Dispose();
_proxy = null;
}
_isConnected = false;
Log.Debug("Close: end.");
}
#endregion
#region Public Methods
/// <exception cref="CommunicationException">Thrown when connection failed</exception>
public void Connect()
{
Log.Debug("Connect: begin.");
if (_proxy == null)
if (_proxy.State != CommunicationState.Created)
{
Log.Error("Connect: _proxy is not defined.");
throw new CommunicationException("Connection failed to service. Proxy is not defined (needs to call Open)");
}
if (_isConnected)
{
Log.Warn("Connected: end. Client is already connected.");
Log.ErrorFormat("Connected: end. Client has invalid state {0}", _proxy.State);
return;
}
bool coonected;
try
{
_isConnected = _proxy.Connect();
coonected = _proxy.Connect();
}
catch (Exception ex)
{
Log.ErrorFormat("Connect: Exception - {0}", ex.Message);
Close();
throw new CommunicationException($"Connection failed to service. {ex.Message}");
}
if (_isConnected == false)
if (coonected == false)
{
Log.Error("Connect: end. Connection failed.");
throw new CommunicationException("Connection failed");
@@ -163,72 +128,60 @@ namespace MTApiService
try
{
_isConnected = false;
_proxy?.Disconnect();
_proxy.Disconnect();
}
catch (Exception ex)
{
Log.ErrorFormat("Disconnect: Exception - {0}", ex.Message);
Close();
}
Log.Debug("Disconnect: end.");
}
/// <exception cref="CommunicationException">Thrown when connection failed</exception>
public MtResponse SendCommand(int commandType, ArrayList parameters)
public MtResponse SendCommand(int commandType, ArrayList parameters, Dictionary<string, object> namedParams, int expertHandle)
{
Log.DebugFormat("SendCommand: begin. commandType = {0}, parameters count = {1}", commandType, parameters?.Count);
MtResponse result;
if (_isConnected == false)
if (IsConnected == false)
{
Log.Error("SendCommand: Client is not connected.");
throw new CommunicationException("Client is not connected.");
}
if (_proxy == null)
{
Log.Error("SendCommand: Proxy is not defined.");
throw new CommunicationException("Proxy is not defined.");
}
MtResponse result;
try
{
result = _proxy.SendCommand(new MtCommand(commandType, parameters));
result = _proxy.SendCommand(new MtCommand {
CommandType = commandType,
Parameters = parameters,
NamedParams = namedParams,
ExpertHandle = expertHandle});
}
catch (Exception ex)
{
Log.ErrorFormat("SendCommand: Exception - {0}", ex.Message);
Close();
throw new CommunicationException("Service connection failed! " + ex.Message);
}
Log.DebugFormat("SendCommand: end. result = {0}", result);
return result;
}
/// <exception cref="CommunicationException">Thrown when connection failed</exception>
public IEnumerable<MtQuote> GetQuotes()
public List<MtQuote> GetQuotes()
{
Log.Debug("GetQuotes: begin.");
if (_isConnected == false)
if (IsConnected == false)
{
Log.Warn("GetQuotes: end. Client is not connected.");
return null;
}
if (_proxy == null)
{
Log.Warn("GetQuotes: end. _proxy is not defined.");
return null;
}
List<MtQuote> result;
try
@@ -239,8 +192,6 @@ namespace MTApiService
{
Log.ErrorFormat("GetQuotes: Exception - {0}", ex.Message);
Close();
throw new CommunicationException($"Service connection failed! {ex.Message}");
}
@@ -286,18 +237,17 @@ namespace MTApiService
{
Log.Debug("OnServerStopped: begin.");
Close();
ServerDisconnected?.Invoke(this, EventArgs.Empty);
Log.Debug("OnServerStopped: end.");
}
public void OnMtEvent(MtEvent mtEvent)
public void OnMtEvent(MtEvent e)
{
Log.DebugFormat("OnMtEvent: begin. event = {0}", mtEvent);
Log.DebugFormat("OnMtEvent: begin. event = {0}", e);
MtEventReceived?.Invoke(this, new MtEventArgs(mtEvent));
MtEventReceived?.Invoke(e);
Log.Debug("OnMtEvent: end.");
}
@@ -305,7 +255,10 @@ namespace MTApiService
#endregion
#region Properties
public bool IsConnected => _proxy.State == CommunicationState.Opened && _isConnected;
public string Host { get; private set; }
public int Port { get; private set; }
private bool IsConnected => _proxy.State == CommunicationState.Opened;
#endregion
@@ -315,7 +268,6 @@ namespace MTApiService
{
Log.Debug("ProxyFaulted: begin.");
Close();
ServerFailed?.Invoke(this, EventArgs.Empty);
Log.Debug("ProxyFaulted: end.");
@@ -329,7 +281,7 @@ namespace MTApiService
{
Log.Debug("Dispose: begin.");
Close();
_proxy.Dispose();
Log.Debug("Dispose: end.");
}
@@ -342,7 +294,7 @@ namespace MTApiService
public event MtQuoteHandler QuoteUpdated;
public event EventHandler ServerDisconnected;
public event EventHandler ServerFailed;
public event EventHandler<MtEventArgs> MtEventReceived;
public event MtEventHandler MtEventReceived;
#endregion
}
}
+9 -8
View File
@@ -1,26 +1,27 @@
using System.Runtime.Serialization;
using System.Collections;
using System.Collections.Generic;
namespace MTApiService
{
[DataContract]
public class MtCommand
{
public MtCommand(int commandType, ArrayList parameters)
{
CommandType = commandType;
Parameters = parameters;
}
[DataMember]
public int CommandType { get; set; }
[DataMember]
public int CommandType { get; private set; }
public ArrayList Parameters { get; set; }
[DataMember]
public ArrayList Parameters { get; private set; }
public Dictionary<string, object> NamedParams { get; set; }
[DataMember]
public int ExpertHandle { get; set; }
public override string ToString()
{
return $"CommandType = {CommandType}";
return $"CommandType = {CommandType}; ExpertHandle = {ExpertHandle}";
}
}
}
+5 -18
View File
@@ -7,30 +7,17 @@ namespace MTApiService
public class MtEvent
{
[DataMember]
public int EventType { get; private set; }
public int EventType { get; internal set; }
[DataMember]
public string Payload { get; private set; }
public string Payload { get; internal set; }
public MtEvent(int eventType, string payload)
{
EventType = eventType;
Payload = payload;
}
[DataMember]
public int ExpertHandle { get; internal set; }
public override string ToString()
{
return "MtEvent = " + EventType + ", Payload = " + Payload;
return $"EventType = {EventType}; Payload = {Payload}; ExpertHandle = {ExpertHandle}";
}
}
public class MtEventArgs: EventArgs
{
public MtEventArgs(MtEvent e)
{
Event = e;
}
public MtEvent Event { get; private set; }
}
}
+55 -111
View File
@@ -4,14 +4,13 @@ using log4net;
namespace MTApiService
{
internal class MtCommandExecutorManager : ICommandManager
internal class MtExecutorManager : ICommandManager
{
#region Private Fields
private static readonly ILog Log = LogManager.GetLogger(typeof(MtCommandExecutorManager));
private readonly List<MtExpert> _commandExecutors = new List<MtExpert>();
private readonly Queue<MtCommandTask> _commandTasks = new Queue<MtCommandTask>();
private static readonly ILog Log = LogManager.GetLogger(typeof(MtExecutorManager));
private readonly List<ITaskExecutor> _executorList = new List<ITaskExecutor>();
private readonly Dictionary<int, ITaskExecutor> _executorMap = new Dictionary<int, ITaskExecutor>();
private readonly object _locker = new object();
#endregion
@@ -23,149 +22,94 @@ namespace MTApiService
lock (_locker)
{
_commandExecutors.Clear();
_commandTasks.Clear();
_executorList.Clear();
_executorMap.Clear();
}
Log.Debug("Stop: end.");
}
public void AddCommandExecutor(MtExpert commandExecutor)
public void AddExecutor(ITaskExecutor executor)
{
if (commandExecutor == null)
throw new ArgumentNullException(nameof(commandExecutor));
if (executor == null)
throw new ArgumentNullException(nameof(executor));
Log.DebugFormat("AddCommandExecutor: begin. commandExecutor = {0}", commandExecutor);
Log.DebugFormat("AddExecutor: begin. executor = {0}", executor);
var notify = false;
lock (_locker)
{
if (_commandExecutors.Contains(commandExecutor))
if (_executorList.Contains(executor))
{
Log.Warn("AddCommandExecutor: end. Command executor already exist.");
Log.Warn("AddExecutor: end. Executor already exist.");
return;
}
_commandExecutors.Add(commandExecutor);
if (_commandTasks.Count > 0)
{
notify = true;
}
}
commandExecutor.CommandExecuted += CommandExecutor_CommandExecuted;
commandExecutor.CommandManager = this;
if (notify)
{
NotifyCommandReady();
_executorList.Add(executor);
_executorMap[executor.Handle] = executor;
}
Log.Debug("AddCommandExecutor: end.");
}
public void RemoveCommandExecutor(MtExpert commandExecutor)
public void RemoveExecutor(ITaskExecutor executor)
{
if (commandExecutor == null)
throw new ArgumentNullException(nameof(commandExecutor));
if (executor == null)
throw new ArgumentNullException(nameof(executor));
Log.DebugFormat("RemoveCommandExecutor: begin. commandExecutor = {0}", commandExecutor);
Log.DebugFormat("RemoveExecutor: begin. executor = {0}", executor);
var notify = false;
lock (_locker)
{
if (_commandExecutors.Contains(commandExecutor) == false)
if (_executorList.Contains(executor) == false)
{
Log.Warn("RemoveCommandExecutor: end. Command executor is not exist in collection.");
Log.Warn("RemoveExecutor: end. Executor is not exist in collection.");
return;
}
_commandExecutors.Remove(commandExecutor);
if (_commandTasks.Count > 0)
_executorList.Remove(executor);
_executorMap.Remove(executor.Handle);
}
Log.Debug("RemoveExecutor: end.");
}
public MtCommandTask SendCommand(MtCommand command)
{
if (command == null)
throw new ArgumentNullException(nameof(command));
var task = new MtCommandTask(command);
Log.DebugFormat("SendTask: begin. command = {0}", command);
ITaskExecutor executor;
lock (_locker)
{
if (_executorMap.ContainsKey(command.ExpertHandle))
{
notify = true;
executor = _executorMap[command.ExpertHandle];
}
else
{
executor = _executorList.Count > 0 ? _executorList[0] : null;
}
}
commandExecutor.CommandExecuted -= CommandExecutor_CommandExecuted;
commandExecutor.CommandManager = null;
if (notify)
if (executor == null)
{
NotifyCommandReady();
Log.Error("SendTask: Executor is null!");
}
else
{
executor.Execute(task);
}
Log.Debug("RemoveCommandExecutor: end.");
Log.Debug("SendTask: end.");
return task;
}
public void EnqueueCommandTask(MtCommandTask task)
{
if (task == null)
throw new ArgumentNullException(nameof(task));
Log.DebugFormat("EnqueueCommandTask: begin. task = {0}", task);
lock (_locker)
{
_commandTasks.Enqueue(task);
}
NotifyCommandReady();
Log.Debug("EnqueueCommandTask: end.");
}
public MtCommandTask DequeueCommandTask()
{
Log.Debug("DequeueCommandTask: called.");
lock (_locker)
{
return _commandTasks.Count > 0 ? _commandTasks.Dequeue() : null;
}
}
#endregion
#region Private Methods
private void NotifyCommandReady()
{
Log.Debug("NotifyCommandReady: begin.");
var commandExecutors = new List<MtExpert>();
lock (_locker)
{
commandExecutors.AddRange(_commandExecutors);
}
foreach (var executor in commandExecutors)
{
executor.NotifyCommandReady();
}
Log.DebugFormat("NotifyCommandReady: end. Notified executor count = {0}", commandExecutors.Count);
}
private void CommandExecutor_CommandExecuted(object sender, EventArgs e)
{
Log.Debug("CommandExecutor_CommandExecuted: begin.");
var notify = false;
lock (_locker)
{
if (_commandTasks.Count > 0)
{
notify = true;
}
}
if (notify)
{
NotifyCommandReady();
}
Log.Debug("CommandExecutor_CommandExecuted: end.");
}
#endregion
}
}
+91 -52
View File
@@ -1,18 +1,20 @@
using System;
using log4net;
using System.Collections.Generic;
namespace MTApiService
{
public class MtExpert
internal class MtExpert: ITaskExecutor
{
public delegate void MtQuoteHandler(MtExpert expert, MtQuote quote);
public delegate void MtEventHandler(MtExpert expert, MtEvent e);
#region Private Fields
private static readonly ILog Log = LogManager.GetLogger(typeof(MtExpert));
private readonly IMetaTraderHandler _mtHadler;
private MtCommandTask _commandTask;
private ICommandManager _commandManager;
private MtCommandTask _currentTask;
private readonly Queue<MtCommandTask> _taskQueue = new Queue<MtCommandTask>();
private readonly object _locker = new object();
#endregion
@@ -41,9 +43,8 @@ namespace MTApiService
{
Log.DebugFormat("SendResponse: begin. response = {0}", response);
_commandTask.SetResult(response);
_commandTask = null;
FireOnCommandExecuted();
_currentTask.SetResult(response);
_currentTask = null;
Log.Debug("SendResponse: end.");
}
@@ -52,20 +53,16 @@ namespace MTApiService
{
Log.Debug("GetCommandType: called.");
var commandManager = CommandManager;
if (commandManager != null)
{
_commandTask = commandManager.DequeueCommandTask();
}
_currentTask = DequeueTask();
return _commandTask?.Command?.CommandType ?? 0;
return _currentTask?.Command?.CommandType ?? 0;
}
public object GetCommandParameter(int index)
{
Log.DebugFormat("GetCommandType: called. index = {0}", index);
Log.DebugFormat("GetCommandParameter: called. index = {0}", index);
var command = _commandTask?.Command;
var command = _currentTask?.Command;
if (command?.Parameters != null && index >= 0 && index < command.Parameters.Count)
{
return command.Parameters[index];
@@ -74,6 +71,46 @@ namespace MTApiService
return null;
}
public object GetNamedParameter(string name)
{
Log.DebugFormat("GetNamedParameter: called. name = {0}", name);
var command = _currentTask?.Command;
if (command == null)
{
Log.Warn("GetNamedParameter: command is not defined in task.");
return null;
}
if (command.NamedParams == null)
{
Log.Warn("GetNamedParameter: NamedParams is not defined in command.");
return null;
}
return command.NamedParams[name];
}
public bool ContainsNamedParameter(string name)
{
Log.DebugFormat("ContainsNamedParameter: called. name = {0}", name);
var command = _currentTask?.Command;
if (command == null)
{
Log.Warn("ContainsNamedParameter: command is not defined in task.");
return false;
}
if (command.NamedParams == null)
{
Log.Warn("ContainsNamedParameter: NamedParams is not defined in command.");
return false;
}
return command.NamedParams.ContainsKey(name);
}
public void SendEvent(MtEvent mtEvent)
{
Log.DebugFormat("SendEvent: begin. event = {0}", mtEvent);
@@ -90,7 +127,22 @@ namespace MTApiService
#endregion
#region ITaskExecutor
public void Execute(MtCommandTask task)
{
lock (_taskQueue)
{
_taskQueue.Enqueue(task);
}
NotifyCommandReady();
}
#endregion
#region Properties
private MtQuote _quote;
public MtQuote Quote
{
@@ -133,41 +185,34 @@ namespace MTApiService
}
}
public ICommandManager CommandManager
{
private get
{
lock (_locker)
{
return _commandManager;
}
}
set
{
lock (_locker)
{
_commandManager = value;
}
}
}
#endregion
#region IMtCommandExecutor
public void NotifyCommandReady()
{
Log.Debug("NotifyCommandReady: begin.");
SendTickToMetaTrader();
Log.Debug("NotifyCommandReady: end.");
}
#endregion
#region Private Methods
private void SendTickToMetaTrader()
private MtCommandTask DequeueTask()
{
Log.Debug("DequeueTask: called.");
MtCommandTask task;
int count;
lock (_locker)
{
count = _taskQueue.Count;
task = _taskQueue.Count > 0 ? _taskQueue.Dequeue() : null;
}
Log.DebugFormat("DequeueTask: end. left task count = {0}.", count);
return task;
}
private void NotifyCommandReady()
{
Log.Debug("NotifyCommandReady: begin.");
_mtHadler.SendTickToMetaTrader(Handle);
Log.Debug("NotifyCommandReady: end.");
}
private void FireOnQuoteChanged(MtQuote quote)
@@ -180,22 +225,16 @@ namespace MTApiService
Deinited?.Invoke(this, EventArgs.Empty);
}
private void FireOnCommandExecuted()
{
CommandExecuted?.Invoke(this, EventArgs.Empty);
}
private void FireOnMtEvent(MtEvent mtEvent)
{
OnMtEvent?.Invoke(this, new MtEventArgs(mtEvent));
OnMtEvent?.Invoke(this, mtEvent);
}
#endregion
#region Events
public event EventHandler Deinited;
public event MtQuoteHandler QuoteChanged;
public event EventHandler CommandExecuted;
public event EventHandler<MtEventArgs> OnMtEvent;
public event MtEventHandler OnMtEvent;
#endregion
}
}
-29
View File
@@ -1,29 +0,0 @@
using System.Runtime.Serialization;
namespace MTApiService
{
[DataContract]
public class MtQuote
{
[DataMember]
public string Instrument { get; private set; }
[DataMember]
public double Bid { get; private set; }
[DataMember]
public double Ask { get; private set; }
public MtQuote(string instrument, double bid, double ask)
{
Instrument = instrument;
Bid = bid;
Ask = ask;
}
public override string ToString()
{
return "Instrument = " + Instrument + ", Bid = " + Bid + ", Ask = " + Ask;
}
}
}
+25
View File
@@ -0,0 +1,25 @@
using System.Runtime.Serialization;
namespace MTApiService
{
[DataContract]
public class MtQuote
{
[DataMember]
public string Instrument { get; internal set; }
[DataMember]
public double Bid { get; internal set; }
[DataMember]
public double Ask { get; internal set; }
[DataMember]
public int ExpertHandle { get; internal set; }
public override string ToString()
{
return $"Instrument = {Instrument}; Bid = {Bid}; Ask = {Ask}; ExpertHandle = {ExpertHandle}";
}
}
}
+24 -1
View File
@@ -12,7 +12,8 @@ namespace MTApiService
{
static IEnumerable<Type> GetKnownTypes()
{
return new Type[] { typeof(MtResponseInt), typeof(MtResponseDouble),
return new Type[] { typeof(MtResponseObject),
typeof(MtResponseInt), typeof(MtResponseDouble),
typeof(MtResponseString), typeof(MtResponseBool),
typeof(MtResponseLong), typeof(MtResponseULong),
typeof(MtResponseDoubleArray), typeof(MtResponseIntArray),
@@ -22,6 +23,28 @@ namespace MTApiService
}
public abstract object GetValue();
[DataMember]
public int ErrorCode { get; set; }
}
[DataContract]
public class MtResponseObject : MtResponse
{
public MtResponseObject(object value)
{
Value = value;
}
[DataMember]
public object Value { get; private set; }
public override object GetValue() { return Value; }
public override string ToString()
{
return Value?.ToString() ?? string.Empty;
}
}
[DataContract]
+29 -12
View File
@@ -21,7 +21,7 @@ namespace MTApiService
private readonly MtService _service;
private readonly List<ServiceHost> _hosts = new List<ServiceHost>();
private readonly MtCommandExecutorManager _executorManager = new MtCommandExecutorManager();
private readonly MtExecutorManager _executorManager = new MtExecutorManager();
private readonly List<MtExpert> _experts = new List<MtExpert>();
#endregion
@@ -62,13 +62,21 @@ namespace MTApiService
}
//init local pipe host
var localUrl = CreateConnectionAddress(null, port, true);
var localServiceHost = CreateServiceHost(localUrl, true);
var localPipeUrl = CreateConnectionAddress(null, port, true);
var localPipeServiceHost = CreateServiceHost(localPipeUrl, true);
if (localPipeServiceHost != null)
{
_hosts.Add(localPipeServiceHost);
}
//init localhost
var localUrl = CreateConnectionAddress("localhost", port, false);
var localServiceHost = CreateServiceHost(localUrl, false);
if (localServiceHost != null)
{
_hosts.Add(localServiceHost);
}
//init network hosts
var dnsHostName = Dns.GetHostName();
var ips = Dns.GetHostEntry(dnsHostName);
@@ -149,7 +157,7 @@ namespace MTApiService
_experts.Add(expert);
}
_executorManager.AddCommandExecutor(expert);
_executorManager.AddExecutor(expert);
_service.OnQuoteAdded(expert.Quote);
@@ -170,11 +178,20 @@ namespace MTApiService
return null;
}
var task = new MtCommandTask(command);
_executorManager.EnqueueCommandTask(task);
var task = _executorManager.SendCommand(command);
//wait for execute command in MetaTrader
var response = task.WaitResult(WaitResponseTime);
MtResponse response = null;
try
{
response = task.WaitResult(WaitResponseTime);
}
catch (Exception ex)
{
Log.WarnFormat("SendCommand: Exception - {0}", ex.Message);
}
Log.DebugFormat("SendCommand: end. response = {0}", response);
return response;
}
@@ -371,7 +388,7 @@ namespace MTApiService
expertsCount = _experts.Count;
}
_executorManager.RemoveCommandExecutor(expert);
_executorManager.RemoveExecutor(expert);
expert.Deinited -= expert_Deinited;
expert.QuoteChanged -= expert_QuoteChanged;
@@ -398,11 +415,11 @@ namespace MTApiService
Log.Debug("expert_QuoteChanged: end.");
}
private void Expert_OnMtEvent(object sender, MtEventArgs e)
private void Expert_OnMtEvent(MtExpert expert, MtEvent e)
{
Log.DebugFormat("Expert_OnMtEvent: begin. event = {0}", e.Event);
Log.DebugFormat("Expert_OnMtEvent: begin. expert = {0}, event = {1}", expert, e);
_service.OnMtEvent(e.Event);
_service.OnMtEvent(e);
Log.Debug("Expert_OnMtEvent: end.");
}
+7 -7
View File
@@ -66,7 +66,7 @@ namespace MTApiService
if (callback == null)
{
Log.Warn("Connect: end. Callback is not definded.");
Log.Warn("Connect: end. Callback is not defined.");
return false;
}
@@ -158,7 +158,7 @@ namespace MTApiService
public void QuoteUpdate(MtQuote quote)
{
Log.Debug("QuoteUpdate: begin.");
Log.DebugFormat("QuoteUpdate: begin. quote = {0}", quote);
ExecuteCallbackAction(a => a.OnQuoteUpdate(quote));
@@ -167,7 +167,7 @@ namespace MTApiService
public void OnQuoteAdded(MtQuote quote)
{
Log.Debug("OnQuoteAdded: begin.");
Log.DebugFormat("OnQuoteAdded: begin. quote = {0}", quote);
ExecuteCallbackAction(a => a.OnQuoteAdded(quote));
@@ -176,18 +176,18 @@ namespace MTApiService
public void OnQuoteRemoved(MtQuote quote)
{
Log.Debug("OnQuoteRemoved: begin.");
Log.DebugFormat("OnQuoteRemoved: begin. quote = {0}", quote);
ExecuteCallbackAction(a => a.OnQuoteRemoved(quote));
Log.Debug("OnQuoteRemoved: end.");
}
public void OnMtEvent(MtEvent mtEvent)
public void OnMtEvent(MtEvent e)
{
Log.Debug("OnMtEvent: begin.");
Log.DebugFormat("OnMtEvent: begin.quote = {0}", e);
ExecuteCallbackAction(a => a.OnMtEvent(mtEvent));
ExecuteCallbackAction(a => a.OnMtEvent(e));
Log.Debug("OnMtEvent: end.");
}
+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
// 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.27.0")]
[assembly: AssemblyFileVersion("1.0.27.0")]
+179 -199
View File
@@ -4,7 +4,8 @@
#include "MT4Handler.h"
#include "Windows.h"
#include < vcclr.h >
#include <vcclr.h>
#include <functional>
using namespace System;
using namespace MTApiService;
@@ -17,6 +18,8 @@ using namespace System::IO;
using namespace System::Collections::Generic;
using namespace System::Diagnostics;
#define _DLLAPI extern "C" __declspec(dllexport)
void convertSystemString(wchar_t* dest, String^ src)
{
pin_ptr<const wchar_t> wch = PtrToStringChars(src);
@@ -24,264 +27,241 @@ void convertSystemString(wchar_t* dest, String^ src)
dest[wcslen(wch)] = '\0';
}
int _stdcall initExpert(int expertHandle, int port, wchar_t* symbol, double bid, double ask, wchar_t* err)
template <typename T> T Execute(std::function<T()> func, wchar_t* err, T default_value)
{
T result = default_value;
try
{
result = func();
}
catch (Exception^ e)
{
convertSystemString(err, e->Message);
}
return result;
}
_DLLAPI bool _stdcall initExpert(int expertHandle, int port, wchar_t* symbol, double bid, double ask, wchar_t* err)
{
return Execute<bool>([&expertHandle, &port, symbol, &bid, &ask]() {
MT4Handler^ mtHandler = gcnew MT4Handler();
MtAdapter::GetInstance()->InitExpert(expertHandle, port, gcnew String(symbol), bid, ask, mtHandler);
return true;
}, err, false);
MtServerInstance::GetInstance()->InitExpert(expertHandle, port, gcnew String(symbol), bid, ask, mtHandler);
}
catch (Exception^ e)
{
convertSystemString(err, e->Message);
Debug::WriteLine("[ERROR] MTConnector:initExpert(): " + e->Message);
return 0;
}
return 1;
}
int _stdcall deinitExpert(int expertHandle, wchar_t* err)
_DLLAPI bool _stdcall deinitExpert(int expertHandle, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->DeinitExpert(expertHandle);
}
catch (Exception^ e)
{
convertSystemString(err, e->Message);
Debug::WriteLine("[ERROR] MTConnector:deinitExpert(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle]() {
MtAdapter::GetInstance()->DeinitExpert(expertHandle);
return true;
}, err, false);
}
int _stdcall updateQuote(int expertHandle, wchar_t* symbol, double bid, double ask, wchar_t* err)
_DLLAPI bool _stdcall updateQuote(int expertHandle, wchar_t* symbol, double bid, double ask, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->SendQuote(expertHandle, gcnew String(symbol), bid, ask);
}
catch (Exception^ e)
{
convertSystemString(err, e->Message);
Debug::WriteLine("[ERROR] MTConnector:updateQuote(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, symbol, &bid, &ask]() {
MtAdapter::GetInstance()->SendQuote(expertHandle, gcnew String(symbol), bid, ask);
return true;
}, err, false);
}
int _stdcall sendEvent(int expertHandle, int eventType, wchar_t* payload, wchar_t* err)
_DLLAPI bool _stdcall sendEvent(int expertHandle, int eventType, wchar_t* payload, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->SendEvent(expertHandle, eventType, gcnew String(payload));
}
catch (Exception^ e)
{
convertSystemString(err, e->Message);
Debug::WriteLine("[ERROR] MTConnector:updateTimeBar(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, &eventType, payload]() {
MtAdapter::GetInstance()->SendEvent(expertHandle, eventType, gcnew String(payload));
return true;
}, err, false);
}
int _stdcall sendIntResponse(int expertHandle, int response)
_DLLAPI bool _stdcall sendIntResponse(int expertHandle, int response, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseInt(response));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendIntResponse(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, &response]() {
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseInt(response));
return true;
}, err, false);
}
int _stdcall sendBooleanResponse(int expertHandle, int response)
_DLLAPI bool _stdcall sendBooleanResponse(int expertHandle, bool response, wchar_t* err)
{
try
{
bool value = (response != 0) ? true : false;
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseBool(value));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendBooleanResponse(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, &response]() {
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseBool(response));
return true;
}, err, false);
}
int _stdcall sendDoubleResponse(int expertHandle, double response)
_DLLAPI bool _stdcall sendDoubleResponse(int expertHandle, double response, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDouble(response));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendDoubleResponse(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, &response]() {
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDouble(response));
return true;
}, err, false);
}
int _stdcall sendStringResponse(int expertHandle, wchar_t* response)
_DLLAPI bool _stdcall sendStringResponse(int expertHandle, wchar_t* response, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseString(gcnew String(response)));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendStringResponse(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, response]() {
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseString(gcnew String(response)));
return true;
}, err, false);
}
int _stdcall sendVoidResponse(int expertHandle)
_DLLAPI bool _stdcall sendErrorResponse(int expertHandle, int code, wchar_t* message, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, nullptr);
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendVoidResponse(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, &code, message]() {
MtResponseString^ res = gcnew MtResponseString(gcnew String(message));
res->ErrorCode = code;
MtAdapter::GetInstance()->SendResponse(expertHandle, res);
return true;
}, err, false);
}
int _stdcall sendDoubleArrayResponse(int expertHandle, double* values, int size)
_DLLAPI bool _stdcall sendVoidResponse(int expertHandle, wchar_t* err)
{
try
{
return Execute<bool>([&expertHandle]() {
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseObject(nullptr));
return true;
}, err, false);
}
_DLLAPI bool _stdcall sendDoubleArrayResponse(int expertHandle, double* values, int size, wchar_t* err)
{
return Execute<bool>([&expertHandle, values, &size]() {
array<double>^ list = gcnew array<double>(size);
for(int i = 0; i < size; i++)
for (int i = 0; i < size; i++)
{
list[i] = values[i];
}
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDoubleArray(list));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendDoubleArrayResponse(): " + e->Message);
return 0;
}
return 1;
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDoubleArray(list));
return true;
}, err, false);
}
int _stdcall sendIntArrayResponse(int expertHandle, int* values, int size)
_DLLAPI bool _stdcall sendIntArrayResponse(int expertHandle, int* values, int size, wchar_t* err)
{
try
{
return Execute<bool>([&expertHandle, values, &size]() {
array<int>^ list = gcnew array<int>(size);
for(int i = 0; i < size; i++)
for (int i = 0; i < size; i++)
{
list[i] = values[i];
}
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseIntArray(list));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendIntArrayResponse(): " + e->Message);
return 0;
}
return 1;
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseIntArray(list));
return true;
}, err, false);
}
int _stdcall sendLongResponse(int expertHandle, __int64 response)
_DLLAPI bool _stdcall sendLongResponse(int expertHandle, __int64 response, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLong(response));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendLongResponse(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, &response]() {
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLong(response));
return true;
}, err, false);
}
int _stdcall getCommandType(int expertHandle, int* res)
_DLLAPI bool _stdcall getCommandType(int expertHandle, int* res, wchar_t* err)
{
try
{
*res = MtServerInstance::GetInstance()->GetCommandType(expertHandle);
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:getCommandType(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, res]() {
*res = MtAdapter::GetInstance()->GetCommandType(expertHandle);
return true;
}, err, false);
}
int _stdcall getIntValue(int expertHandle, int paramIndex, int* res)
_DLLAPI bool _stdcall getIntValue(int expertHandle, int paramIndex, int* res, wchar_t* err)
{
try
{
*res = (int)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:getIntValue(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, &paramIndex, res]() {
*res = (int)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
return true;
}, err, false);
}
int _stdcall getDoubleValue(int expertHandle, int paramIndex, double* res)
// --- index parameters
_DLLAPI bool _stdcall getDoubleValue(int expertHandle, int paramIndex, double* res, wchar_t* err)
{
try
{
*res = (double)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:getDoubleValue(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, &paramIndex, res]() {
*res = (double)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
return true;
}, err, false);
}
int _stdcall getStringValue(int expertHandle, int paramIndex, wchar_t* res)
_DLLAPI bool _stdcall getStringValue(int expertHandle, int paramIndex, wchar_t* res, wchar_t* err)
{
try
{
convertSystemString(res, (String^)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:getStringValue(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, &paramIndex, res]() {
convertSystemString(res, (String^)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex));
return true;
}, err, false);
}
int _stdcall getBooleanValue(int expertHandle, int paramIndex, int* res)
_DLLAPI bool _stdcall getBooleanValue(int expertHandle, int paramIndex, int* res, wchar_t* err)
{
try
{
bool val = (bool)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
*res = val == true ? 1 : 0;
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:getBooleanValue(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, &paramIndex, res]() {
*res = (bool)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
return true;
}, err, false);
}
_DLLAPI bool _stdcall getLongValue(int expertHandle, int paramIndex, __int64* res, wchar_t* err)
{
return Execute<bool>([&expertHandle, &paramIndex, res]() {
*res = (__int64)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
return true;
}, err, false);
}
// --- named parameters
_DLLAPI bool _stdcall containsNamedValue(int expertHandle, wchar_t* paramName)
{
wchar_t err[1000];
return Execute<bool>([&expertHandle, paramName]() {
return MtAdapter::GetInstance()->ContainsNamedParameter(expertHandle, gcnew String(paramName));
}, err, false);
}
_DLLAPI bool _stdcall getNamedIntValue(int expertHandle, wchar_t* paramName, int* res, wchar_t* err)
{
return Execute<bool>([&expertHandle, paramName, res]() {
System::Object^ obj = MtAdapter::GetInstance()->GetNamedParameter(expertHandle, gcnew String(paramName));
*res = (int)obj;
return true;
}, err, false);
}
_DLLAPI bool _stdcall getNamedDoubleValue(int expertHandle, wchar_t* paramName, double* res, wchar_t* err)
{
return Execute<bool>([&expertHandle, paramName, res]() {
System::Object^ obj = MtAdapter::GetInstance()->GetNamedParameter(expertHandle, gcnew String(paramName));
*res = (double)obj;
return true;
}, err, false);
}
_DLLAPI bool _stdcall getNamedStringValue(int expertHandle, wchar_t* paramName, wchar_t* res, wchar_t* err)
{
return Execute<bool>([&expertHandle, paramName, res]() {
System::Object^ obj = MtAdapter::GetInstance()->GetNamedParameter(expertHandle, gcnew String(paramName));
convertSystemString(res, (String^)obj);
return true;
}, err, false);
}
_DLLAPI bool _stdcall getNamedBooleanValue(int expertHandle, wchar_t* paramName, int* res, wchar_t* err)
{
return Execute<bool>([&expertHandle, paramName, res]() {
System::Object^ obj = MtAdapter::GetInstance()->GetNamedParameter(expertHandle, gcnew String(paramName));
*res = (bool)obj;
return true;
}, err, false);
}
_DLLAPI bool _stdcall getNamedLongValue(int expertHandle, wchar_t* paramName, __int64* res, wchar_t* err)
{
return Execute<bool>([&expertHandle, paramName, res]() {
System::Object^ obj = MtAdapter::GetInstance()->GetNamedParameter(expertHandle, gcnew String(paramName));
if (obj != nullptr)
*res = (__int64)obj;
return true;
}, err, false);
}
-19
View File
@@ -1,19 +0,0 @@
LIBRARY MTConnector
EXPORTS initExpert
deinitExpert
updateQuote
sendEvent
sendIntResponse
sendBooleanResponse
sendDoubleResponse
sendStringResponse
sendVoidResponse
sendDoubleArrayResponse
sendIntArrayResponse
sendLongResponse
getCommandType
getIntValue
getDoubleValue
getStringValue
getBooleanValue
-5
View File
@@ -96,7 +96,6 @@
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>.\MTConnector.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -109,7 +108,6 @@
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>.\MTConnector.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -121,7 +119,6 @@
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>.\MTConnector.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -133,7 +130,6 @@
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>.\MTConnector.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
@@ -154,7 +150,6 @@
</ItemGroup>
<ItemGroup>
<None Include="app.ico" />
<None Include="MTConnector.def" />
<None Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
-3
View File
@@ -44,9 +44,6 @@
<None Include="app.ico">
<Filter>Resource Files</Filter>
</None>
<None Include="MTConnector.def">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="app.rc">
+24
View File
@@ -0,0 +1,24 @@
using System;
namespace MtApi
{
public class ChartEventArgs : EventArgs
{
internal ChartEventArgs(int expertHandle, MtChartEvent chartEvent)
{
ExpertHandle = expertHandle;
ChartId = chartEvent.ChartId;
EventId = chartEvent.EventId;
Lparam = chartEvent.Lparam;
Dparam = chartEvent.Dparam;
Sparam = chartEvent.Sparam;
}
public int ExpertHandle { get; }
public long ChartId { get; }
public int EventId { get; }
public long Lparam { get; }
public double Dparam { get; }
public string Sparam { get; }
}
}
+9
View File
@@ -0,0 +1,9 @@
namespace MtApi
{
public enum EnumAlignMode
{
ALIGN_LEFT = 1,
ALIGN_CENTER = 2,
ALIGN_RIGHT = 0
}
}
+18
View File
@@ -0,0 +1,18 @@
namespace MtApi
{
public enum EnumChartEvent
{
CHARTEVENT_KEYDOWN = 0,
CHARTEVENT_MOUSE_MOVE = 10,
CHARTEVENT_OBJECT_CREATE = 7,
CHARTEVENT_OBJECT_CHANGE = 8,
CHARTEVENT_OBJECT_DELETE = 6,
CHARTEVENT_CLICK = 4,
CHARTEVENT_OBJECT_CLICK = 1,
CHARTEVENT_OBJECT_DRAG = 2,
CHARTEVENT_OBJECT_ENDEDIT = 3,
CHARTEVENT_CHART_CHANGE = 9,
CHARTEVENT_CUSTOM = 1000,
CHARTEVENT_CUSTOM_LAST = 66534
}
}
+13
View File
@@ -0,0 +1,13 @@
namespace MtApi
{
public enum EnumChartPropertyDouble
{
CHART_SHIFT_SIZE = 3,
CHART_FIXED_POSITION = 41,
CHART_FIXED_MAX = 8,
CHART_FIXED_MIN = 9,
CHART_POINTS_PER_BAR = 11,
CHART_PRICE_MIN = 108,
CHART_PRICE_MAX = 109
}
}
+55
View File
@@ -0,0 +1,55 @@
namespace MtApi
{
public enum EnumChartPropertyInteger
{
CHART_BRING_TO_TOP = 35,
CHART_MOUSE_SCROLL = 42,
CHART_EVENT_MOUSE_MOVE = 40,
CHART_EVENT_OBJECT_CREATE = 38,
CHART_EVENT_OBJECT_DELETE = 39,
CHART_MODE = 0,
CHART_FOREGROUND = 1,
CHART_SHIFT = 2,
CHART_AUTOSCROLL = 4,
CHART_QUICK_NAVIGATION = 45,
CHART_SCALE = 5,
CHART_SCALEFIX = 6,
CHART_SCALEFIX_11 = 7,
CHART_SCALE_PT_PER_BAR = 10,
CHART_SHOW_OHLC = 12,
CHART_SHOW_BID_LINE = 13,
CHART_SHOW_ASK_LINE = 14,
CHART_SHOW_LAST_LINE = 15,
CHART_SHOW_PERIOD_SEP = 16,
CHART_SHOW_GRID = 17,
CHART_SHOW_VOLUMES = 18,
CHART_SHOW_OBJECT_DESCR = 19,
CHART_VISIBLE_BARS = 100,
CHART_WINDOWS_TOTAL = 101,
CHART_WINDOW_IS_VISIBLE = 102,
CHART_WINDOW_HANDLE = 103,
CHART_WINDOW_YDISTANCE = 110,
CHART_FIRST_VISIBLE_BAR = 104,
CHART_WIDTH_IN_BARS = 105,
CHART_WIDTH_IN_PIXELS = 106,
CHART_HEIGHT_IN_PIXELS = 107,
CHART_COLOR_BACKGROUND = 21,
CHART_COLOR_FOREGROUND = 22,
CHART_COLOR_GRID = 23,
CHART_COLOR_VOLUME = 24,
CHART_COLOR_CHART_UP = 25,
CHART_COLOR_CHART_DOWN = 26,
CHART_COLOR_CHART_LINE = 27,
CHART_COLOR_CANDLE_BULL = 28,
CHART_COLOR_CANDLE_BEAR = 29,
CHART_COLOR_BID = 30,
CHART_COLOR_ASK = 31,
CHART_COLOR_LAST = 32,
CHART_COLOR_STOP_LEVEL = 33,
CHART_SHOW_TRADE_LEVELS = 34,
CHART_DRAG_TRADE_LEVELS = 43,
CHART_SHOW_DATE_SCALE = 36,
CHART_SHOW_PRICE_SCALE = 37,
CHART_IS_OFFLINE = 112
}
}
+7
View File
@@ -0,0 +1,7 @@
namespace MtApi
{
public enum EnumChartPropertyString
{
CHART_COMMENT = 20
}
}
+9
View File
@@ -0,0 +1,9 @@
namespace MtApi
{
enum EnumColorFormat
{
COLOR_FORMAT_XRGB_NOALPHA = 0, //The component of the alpha channel is ignored
COLOR_FORMAT_ARGB_RAW = 1, //Color components are not handled by the terminal (must be correctly set by the user)
COLOR_FORMAT_ARGB_NORMALIZE = 2 //Color components are handled by the terminal
}
}
+46
View File
@@ -0,0 +1,46 @@
namespace MtApi
{
public enum EnumObject
{
OBJ_VLINE = 0, //Vertical Line
OBJ_HLINE = 1, //Horizontal Line
OBJ_TREND = 2, //Trend Line
BJ_TRENDBYANGLE = 3, //Trend Line By Angle
OBJ_CYCLES = 20, //Cycle Lines
OBJ_CHANNEL = 5, //Equidistant Channel
OBJ_STDDEVCHANNEL = 6, //Standard Deviation Channel
OBJ_REGRESSION = 4, //Linear Regression Channel
OBJ_PITCHFORK = 19, //Andrews’ Pitchfork
OBJ_GANNLINE = 7, //Gann Line
OBJ_GANNFAN = 8, //Gann Fan
OBJ_GANNGRID = 9, //Gann Grid
OBJ_FIBO = 10, //Fibonacci Retracement
OBJ_FIBOTIMES = 11, //Fibonacci Time Zones
OBJ_FIBOFAN = 12, //Fibonacci Fan
OBJ_FIBOARC = 13, //Fibonacci Arcs
OBJ_FIBOCHANNEL = 15, //Fibonacci Channel
OBJ_EXPANSION = 14, //Fibonacci Expansion
OBJ_RECTANGLE = 16, //Rectangle
OBJ_TRIANGLE = 17, //Triangle
OBJ_ELLIPSE = 18, //Ellipse
OBJ_ARROW_THUMB_UP = 29, //Thumbs Up
OBJ_ARROW_THUMB_DOWN = 30, //Thumbs Down
OBJ_ARROW_UP = 31, //Arrow Up
OBJ_ARROW_DOWN = 32, //Arrow Down
OBJ_ARROW_STOP = 33, //Stop Sign
OBJ_ARROW_CHECK = 34, //Check Sign
OBJ_ARROW_LEFT_PRICE = 35, //Left Price Label
OBJ_ARROW_RIGHT_PRICE = 36, //Right Price Label
OBJ_ARROW_BUY = 37, //Buy Sign
OBJ_ARROW_SELL = 38, //Sell Sign
OBJ_ARROW = 22, //Arrow
OBJ_TEXT = 21, //Text
OBJ_LABEL = 23, //Label
OBJ_BUTTON = 25, //Button
OBJ_BITMAP = 26, //Bitmap
OBJ_BITMAP_LABEL = 24, //Bitmap Label
OBJ_EDIT = 27, //Edit
OBJ_EVENT = 42, //The "Event" object corresponding to an event in the economic calendar
OBJ_RECTANGLE_LABEL = 28 //The "Rectangle label" object for creating and designing the custom graphical interface.
}
}
+11
View File
@@ -0,0 +1,11 @@
namespace MtApi
{
public enum EnumObjectPropertyDouble
{
OBJPROP_PRICE = 20, // Price coordinate
OBJPROP_LEVELVALUE = 204, // Level value
OBJPROP_SCALE = 12, // Scale (properties of Gann objects, Fibonacci Arcs and Ellipse)
OBJPROP_ANGLE = 13, // Angle. For the objects with no angle specified, created from a program, the value is equal to EMPTY_VALUE
OBJPROP_DEVIATION = 16, // Deviation for the Standard Deviation Channel
}
}
+40
View File
@@ -0,0 +1,40 @@
namespace MtApi
{
public enum EnumObjectPropertyInteger
{
OBJPROP_COLOR = 6,
OBJPROP_STYLE = 7,
OBJPROP_WIDTH = 8,
OBJPROP_BACK = 9,
OBJPROP_ZORDER = 207,
OBJPROP_HIDDEN = 208,
OBJPROP_SELECTED = 17,
OBJPROP_READONLY = 1028,
OBJPROP_TYPE = 18,
OBJPROP_TIME = 19,
OBJPROP_SELECTABLE = 1000,
OBJPROP_CREATETIME = 998,
OBJPROP_LEVELS = 200,
OBJPROP_LEVELCOLOR = 201,
OBJPROP_LEVELSTYLE = 202,
OBJPROP_LEVELWIDTH = 203,
OBJPROP_ALIGN = 1036,
OBJPROP_FONTSIZE = 100,
OBJPROP_RAY_RIGHT = 1004,
OBJPROP_ELLIPSE = 11,
OBJPROP_ARROWCODE = 14,
OBJPROP_TIMEFRAMES = 15,
OBJPROP_ANCHOR = 1011,
OBJPROP_XDISTANCE = 102,
OBJPROP_YDISTANCE = 103,
OBJPROP_STATE = 1018,
OBJPROP_XSIZE = 1019,
OBJPROP_YSIZE = 1020,
OBJPROP_XOFFSET = 1033,
OBJPROP_YOFFSET = 1034,
OBJPROP_BGCOLOR = 1025,
OBJPROP_CORNER = 101,
OBJPROP_BORDER_TYPE = 1029,
OBJPROP_BORDER_COLOR = 1035
}
}
+13
View File
@@ -0,0 +1,13 @@
namespace MtApi
{
public enum EnumObjectPropertyString
{
OBJPROP_NAME = 1037,
OBJPROP_TEXT = 999,
OBJPROP_TOOLTIP = 206,
OBJPROP_LEVELTEXT = 205,
OBJPROP_FONT = 1001,
OBJPROP_BMPFILE = 1017,
OBJPROP_SYMBOL = 1021
}
}
-42
View File
@@ -1,42 +0,0 @@
using System;
using System.Threading.Tasks;
namespace MtApi
{
static class ExtensionMethods
{
#region Event Methods
public static Task FireEventAsync(this MtApiQuoteHandler evenHandler, object sender, string symbol, double bid, double ask)
{
return Task.Factory.StartNew(() =>
{
evenHandler?.Invoke(sender, symbol, bid, ask);
});
}
public static Task FireEventAsync(this EventHandler eventHandler, object sender)
{
return Task.Factory.StartNew(() =>
{
eventHandler?.Invoke(sender, EventArgs.Empty);
});
}
public static Task FireEventAsync<T>(this EventHandler<T> eventHandler, object sender, T e)
where T : EventArgs
{
return Task.Factory.StartNew(() =>
{
eventHandler?.Invoke(sender, e);
});
}
#endregion
public static MtQuote Convert(this MTApiService.MtQuote quote)
{
return (quote != null) ? new MtQuote(quote.Instrument, quote.Bid, quote.Ask) : null;
}
}
}
+30
View File
@@ -0,0 +1,30 @@
using System;
namespace MtApi
{
[Flags]
public enum FlagFontStyle
{
//Flags for specifying font style
FONT_ITALIC = -2147483648,
FONT_UNDERLINE = 1073741824,
FONT_STRIKEOUT = 536870912,
//Flags for specifying font width
FW_DONTCARE = 0,
FW_THIN = 1,
FW_EXTRALIGHT = 2,
FW_ULTRALIGHT = 3,
FW_LIGHT = 4,
FW_NORMAL = 5,
FW_REGULAR = 6,
FW_MEDIUM = 7,
FW_SEMIBOLD = 8,
FW_DEMIBOLD = 9,
FW_BOLD = 10,
FW_EXTRABOLD = 11,
FW_ULTRABOLD = 12,
FW_HEAVY = 13,
FW_BLACK = 14
}
}
+12 -1
View File
@@ -58,16 +58,27 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ChartEventArgs.cs" />
<Compile Include="ChartPeriod.cs" />
<Compile Include="EnumAlignMode.cs" />
<Compile Include="EnumChartPropertyDouble.cs" />
<Compile Include="EnumChartPropertyInteger.cs" />
<Compile Include="EnumChartPropertyString.cs" />
<Compile Include="EnumColorFormat.cs" />
<Compile Include="EnumObject.cs" />
<Compile Include="EnumObjectPropertyDouble.cs" />
<Compile Include="EnumObjectPropertyInteger.cs" />
<Compile Include="EnumObjectPropertyString.cs" />
<Compile Include="EnumSeriesInfoInteger.cs" />
<Compile Include="EnumSymbolInfoDouble.cs" />
<Compile Include="EnumSymbolInfoInteger.cs" />
<Compile Include="EnumTerminalInfoDouble.cs" />
<Compile Include="EnumTerminalInfoInteger.cs" />
<Compile Include="ExtensionMethods.cs" />
<Compile Include="FlagFontStyle.cs" />
<Compile Include="Monitors\AvailabilityOrdersEventArgs.cs" />
<Compile Include="MqlRates.cs" />
<Compile Include="MqlTick.cs" />
<Compile Include="MtChartEvent.cs" />
<Compile Include="MtConnectionEventArgs.cs" />
<Compile Include="MtConnectionException.cs" />
<Compile Include="MtConnectionState.cs" />
+1314 -121
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -13,9 +13,9 @@ namespace MtApi
return Color.FromArgb((byte)(color), (byte)(color >> 8), (byte)(color >> 16));
}
public static int ConvertToMtColor(Color color)
public static int ConvertToMtColor(Color? color)
{
return color == Color.Empty ? 0xffffff : (Color.FromArgb(color.B, color.G, color.R).ToArgb() & 0xffffff);
return color == null || color == Color.Empty ? 0xffffff : (Color.FromArgb(color.Value.B, color.Value.G, color.Value.R).ToArgb() & 0xffffff);
}
}
}
+3 -3
View File
@@ -13,13 +13,13 @@ namespace MtApi
return new DateTime(tmpTime.Ticks + (time * 0x989680L));
}
public static int ConvertToMtTime(DateTime time)
public static int ConvertToMtTime(DateTime? time)
{
int result = 0;
if (time != DateTime.MinValue)
if (time != null && time != DateTime.MinValue)
{
DateTime tmpTime = new DateTime(1970, 1, 1);
result = (int)((time.Ticks - tmpTime.Ticks) / 0x989680L);
result = (int)((time.Value.Ticks - tmpTime.Ticks) / 0x989680L);
}
return result;
}
+11
View File
@@ -0,0 +1,11 @@
namespace MtApi
{
internal class MtChartEvent
{
public long ChartId { get; set; }
public int EventId { get; set; }
public long Lparam { get; set; }
public double Dparam { get; set; }
public string Sparam { get; set; }
}
}
Executable → Regular
+85 -9
View File
@@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MtApi
namespace MtApi
{
enum MtCommandType
{
@@ -140,8 +135,8 @@ namespace MtApi
iBullsPower = 106,
iCCI = 107,
iCCIOnArray = 108,
iCustom = 109,
iCustom_d = 10109,
//iCustom = 109,
//iCustom_d = 10109,
iDeMarker = 110,
iEnvelopes = 111,
iEnvelopesOnArray = 112,
@@ -201,6 +196,87 @@ namespace MtApi
SymbolsTotal = 200,
SymbolName = 201,
SymbolSelect = 202,
SymbolInfoInteger = 203
SymbolInfoInteger = 203,
//Object Functions
ObjectCreate = 208,
ObjectName = 209,
ObjectDelete = 210,
ObjectsDeleteAll = 211,
ObjectFind = 212,
ObjectGetTimeByValue = 213,
ObjectGetValueByTime = 214,
ObjectMove = 215,
ObjectsTotal = 216,
ObjectGetDouble = 217,
ObjectGetInteger = 218,
ObjectGetString = 219,
ObjectSetDouble = 220,
ObjectSetInteger = 221,
ObjectSetString = 222,
TextSetFont = 223,
TextOut = 224,
TextGetSize = 225,
ObjectDescription = 226,
ObjectGet = 227,
ObjectGetFiboDescription = 228,
ObjectGetShiftByValue = 229,
ObjectGetValueByShift = 230,
ObjectSet = 231,
ObjectSetFiboDescription = 232,
ObjectSetText = 233,
ObjectType = 234,
UnlockTicks = 235,
//Chart Operations
ChartId = 206,
ChartRedraw = 207,
ChartApplyTemplate = 236,
ChartSaveTemplate = 237,
ChartWindowFind = 238,
ChartTimePriceToXY = 239,
ChartXYToTimePrice = 240,
ChartOpen = 241,
ChartFirst = 242,
ChartNext = 243,
ChartClose = 244,
ChartSymbol = 245,
ChartPeriod = 246,
ChartSetDouble = 247,
ChartSetInteger = 248,
ChartSetString = 249,
ChartGetDouble = 250,
ChartGetInteger = 251,
ChartGetString = 252,
ChartNavigate = 253,
ChartIndicatorDelete = 254,
ChartIndicatorName = 255,
ChartIndicatorsTotal = 256,
ChartWindowOnDropped = 257,
ChartPriceOnDropped = 258,
ChartTimeOnDropped = 259,
ChartXOnDropped = 260,
ChartYOnDropped = 261,
ChartSetSymbolPeriod = 262,
ChartScreenShot = 263,
WindowBarsPerChart = 264,
WindowExpertName = 265,
WindowFind = 266,
WindowFirstVisibleBar = 267,
WindowHandle = 268,
WindowIsVisible = 269,
WindowOnDropped = 270,
WindowPriceMax = 271,
WindowPriceMin = 272,
WindowPriceOnDropped = 273,
WindowRedraw = 274,
WindowScreenShot = 275,
WindowTimeOnDropped = 276,
WindowsTotal = 277,
WindowXOnDropped = 278,
WindowYOnDropped = 279,
ChangeAccount = 280
}
}
+1 -4
View File
@@ -1,14 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MtApi
{
public class MtConnectionEventArgs: EventArgs
{
public MtConnectionState Status { get; private set; }
public String ConnectionMessage { get; private set; }
public string ConnectionMessage { get; private set; }
public MtConnectionEventArgs(MtConnectionState status, string message)
{
+2 -1
View File
@@ -2,6 +2,7 @@
{
public enum MtEventTypes
{
LastTimeBar = 1
LastTimeBar = 1,
ChartEvent = 2
}
}
+9
View File
@@ -5,6 +5,7 @@
public string Instrument { get; private set; }
public double Bid { get; private set; }
public double Ask { get; private set; }
public int ExpertHandle { get; private set; }
public MtQuote(string instrument, double bid, double ask)
{
@@ -12,5 +13,13 @@
Bid = bid;
Ask = ask;
}
internal MtQuote(MTApiService.MtQuote quote)
{
Instrument = quote.Instrument;
Bid = quote.Bid;
Ask = quote.Ask;
ExpertHandle = quote.ExpertHandle;
}
}
}
-3
View File
@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MtApi
{
+2 -11
View File
@@ -11,16 +11,7 @@ namespace MtApi
public double Close { get; set; }
public double High { get; set; }
public double Low { get; set; }
public DateTime OpenTime
{
get { return MtApiTimeConverter.ConvertFromMtTime(MtOpenTime); }
}
public DateTime CloseTime
{
get { return MtApiTimeConverter.ConvertFromMtTime(MtCloseTime); }
}
public DateTime OpenTime => MtApiTimeConverter.ConvertFromMtTime(MtOpenTime);
public DateTime CloseTime => MtApiTimeConverter.ConvertFromMtTime(MtCloseTime);
}
}
Executable → Regular
+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
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.32.1")]
[assembly: AssemblyFileVersion("1.0.32.1")]
[assembly: AssemblyVersion("1.0.38.0")]
[assembly: AssemblyFileVersion("1.0.38.0")]
+8 -5
View File
@@ -1,18 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MtApi
{
public class TimeBarArgs: EventArgs
{
internal TimeBarArgs(int expertHandle, MtTimeBar timeBar)
: this(timeBar)
{
ExpertHandle = expertHandle;
}
public TimeBarArgs(MtTimeBar timeBar)
{
TimeBar = timeBar;
}
public MtTimeBar TimeBar { get; private set; }
public int ExpertHandle { get; }
public MtTimeBar TimeBar { get; }
}
}
-21
View File
@@ -1,21 +0,0 @@
using System;
namespace MtApi5
{
internal static class ExtensionMethods
{
#region Event Methods
public static void FireEvent(this EventHandler eventHandler, object sender)
{
eventHandler?.Invoke(sender, EventArgs.Empty);
}
public static void FireEvent<T>(this EventHandler<T> eventHandler, object sender, T e)
where T : EventArgs
{
eventHandler?.Invoke(sender, e);
}
#endregion
}
}
+3 -1
View File
@@ -5,7 +5,7 @@ namespace MtApi5
public class MqlTradeRequest
{
public ENUM_TRADE_REQUEST_ACTIONS Action { get; set; } // Trade operation type
public uint Magic { get; set; } // Expert Advisor ID (magic number)
public ulong Magic { get; set; } // Expert Advisor ID (magic number)
public ulong Order { get; set; } // Order ticket
public string Symbol { get; set; } // Trade symbol
public double Volume { get; set; } // Requested volume for a deal in lots
@@ -19,5 +19,7 @@ namespace MtApi5
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)
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
}
}
+2
View File
@@ -114,5 +114,7 @@ namespace MtApi5
//Requests
MtRequest = 155,
PositionSelectByTicket = 69
}
}
+1 -4
View File
@@ -1,14 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MtApi5
{
public class Mt5ConnectionEventArgs: EventArgs
{
public Mt5ConnectionState Status { get; private set; }
public String ConnectionMessage { get; private set; }
public string ConnectionMessage { get; private set; }
public Mt5ConnectionEventArgs(Mt5ConnectionState status, string message)
{
+487 -211
View File
@@ -1,200 +1,10 @@
namespace MtApi5
{
public enum ENUM_TRADE_REQUEST_ACTIONS
{
TRADE_ACTION_DEAL = 1, //Place a trade order for an immediate execution with the specified parameters (market order)
TRADE_ACTION_PENDING = 5, //Place a trade order for an immediate execution with the specified parameters (market order)
TRADE_ACTION_SLTP = 6, //Place a trade order for an immediate execution with the specified parameters (market order)
TRADE_ACTION_MODIFY = 7, //Place a trade order for an immediate execution with the specified parameters (market order)
TRADE_ACTION_REMOVE = 8 //Place a trade order for an immediate execution with the specified parameters (market order)
}
public enum ENUM_ORDER_TYPE
{
ORDER_TYPE_BUY = 0, //Market Buy order
ORDER_TYPE_SELL = 1, //Market Sell order
ORDER_TYPE_BUY_LIMIT = 2, //Buy Limit pending order
ORDER_TYPE_SELL_LIMIT = 3, //Sell Limit pending order
ORDER_TYPE_BUY_STOP = 4, //Buy Stop pending order
ORDER_TYPE_SELL_STOP = 5, //Sell Stop pending order
ORDER_TYPE_BUY_STOP_LIMIT = 6, //Upon reaching the order price, a pending Buy Limit order is places at the StopLimit price
ORDER_TYPE_SELL_STOP_LIMIT = 7, //Upon reaching the order price, a pending Sell Limit order is places at the StopLimit price
}
public enum ENUM_ORDER_TYPE_FILLING
{
ORDER_FILLING_FOK = 0,
ORDER_FILLING_IOC = 1,
ORDER_FILLING_RETURN = 2
}
public enum ENUM_ORDER_TYPE_TIME
{
ORDER_TIME_GTC = 0,
ORDER_TIME_DAY = 1,
ORDER_TIME_SPECIFIED = 2,
ORDER_TIME_SPECIFIED_DAY = 3
}
public enum ENUM_POSITION_PROPERTY_DOUBLE
{
POSITION_VOLUME = 3, //Position volume
POSITION_PRICE_OPEN = 4, //Position open price
POSITION_SL = 6, //Stop Loss level of opened position
POSITION_TP = 7, //Take Profit level of opened position
POSITION_PRICE_CURRENT = 5, //Current price of the position symbol
POSITION_COMMISSION = 8, //Commission
POSITION_SWAP = 9, //Cumulative swap
POSITION_PROFIT = 10 //Current profit
}
public enum ENUM_POSITION_PROPERTY_INTEGER
{
POSITION_TIME = 1, //Position open time
POSITION_TYPE = 2, //Position type
POSITION_MAGIC = 12, //Position magic number
POSITION_IDENTIFIER = 13 //Position identifier is a unique number that is assigned to every newly opened position and doesn't change during the entire lifetime of the position. Position turnover doesn't change its identifier.
}
public enum ENUM_POSITION_TYPE
{
POSITION_TYPE_BUY = 0, //Buy
POSITION_TYPE_SELL = 1 //Sell
}
public enum ENUM_POSITION_PROPERTY_STRING
{
POSITION_SYMBOL = 0, //Symbol of the position
POSITION_COMMENT = 11 //Position comment
}
public enum ENUM_ORDER_PROPERTY_DOUBLE
{
ORDER_VOLUME_INITIAL = 7, //Order initial volume
ORDER_VOLUME_CURRENT = 8, //Order current volume
ORDER_PRICE_OPEN = 9, //Price specified in the order
ORDER_SL = 12, //Stop Loss value
ORDER_TP = 13, //Take Profit value
ORDER_PRICE_CURRENT = 10, //The current price of the order symbol
ORDER_PRICE_STOPLIMIT = 11 //The Limit order price for the StopLimit order
}
public enum ENUM_ORDER_PROPERTY_STRING
{
ORDER_SYMBOL = 0, //Symbol of the order
ORDER_COMMENT = 16 //Order comment
}
public enum ENUM_ORDER_PROPERTY_INTEGER
{
ORDER_TIME_SETUP = 1, //Order setup time
ORDER_TYPE = 4, //Order type
ORDER_STATE = 14, //Order state
ORDER_TIME_EXPIRATION = 2, //Order expiration time
ORDER_TIME_DONE = 3, //Order execution or cancellation time
ORDER_TYPE_FILLING = 5, //Order filling type
ORDER_TYPE_TIME = 6, //Order lifetime
ORDER_MAGIC = 15, //ID of an Expert Advisor that has placed the order (designed to ensure that each Expert Advisor places its own unique number)
ORDER_POSITION_ID = 17 //Position identifier that is set to an order as soon as it is executed. Each executed order results in a deal that opens or modifies an already existing position. The identifier of exactly this position is set to the executed order at this moment.
}
public enum ENUM_DEAL_PROPERTY_DOUBLE
{
DEAL_VOLUME = 5,
DEAL_PRICE = 6,
DEAL_COMMISSION = 7,
DEAL_SWAP = 8,
DEAL_PROFIT = 9
}
public enum ENUM_DEAL_PROPERTY_STRING
{
DEAL_SYMBOL = 0,
DEAL_COMMENT = 10
}
public enum ENUM_DEAL_TYPE
{
DEAL_TYPE_BUY = 0,
DEAL_TYPE_SELL = 1,
DEAL_TYPE_BALANCE = 2,
DEAL_TYPE_CREDIT = 3,
DEAL_TYPE_CHARGE = 4,
DEAL_TYPE_CORRECTION = 5,
DEAL_TYPE_BONUS = 6,
DEAL_TYPE_COMMISSION = 7,
DEAL_TYPE_COMMISSION_DAILY = 8,
DEAL_TYPE_COMMISSION_MONTHLY = 9,
DEAL_TYPE_COMMISSION_AGENT_DAILY = 10,
DEAL_TYPE_COMMISSION_AGENT_MONTHLY = 11,
DEAL_TYPE_INTEREST = 12,
DEAL_TYPE_BUY_CANCELED = 13,
DEAL_TYPE_SELL_CANCELED = 14
}
public enum ENUM_DEAL_ENTRY
{
DEAL_ENTRY_IN = 0,
DEAL_ENTRY_OUT = 1,
DEAL_ENTRY_INOUT = 2,
DEAL_ENTRY_STATE = 255
}
public enum ENUM_DEAL_PROPERTY_INTEGER
{
DEAL_ORDER = 1,
DEAL_TIME = 2,
DEAL_TYPE = 3,
DEAL_ENTRY = 4,
DEAL_MAGIC = 11,
DEAL_POSITION_ID = 12
}
public enum ENUM_ACCOUNT_INFO_INTEGER
{
ACCOUNT_LOGIN = 0,
ACCOUNT_TRADE_MODE = 32,
ACCOUNT_LEVERAGE = 35,
ACCOUNT_LIMIT_ORDERS = 47,
ACCOUNT_MARGIN_SO_MODE = 44,
ACCOUNT_TRADE_ALLOWED = 33,
ACCOUNT_TRADE_EXPERT = 34
}
public enum ENUM_ACCOUNT_INFO_DOUBLE
{
ACCOUNT_BALANCE = 37,
ACCOUNT_CREDIT = 38,
ACCOUNT_PROFIT = 39,
ACCOUNT_EQUITY = 40,
ACCOUNT_MARGIN = 41,
ACCOUNT_FREEMARGIN = 42,
ACCOUNT_MARGIN_LEVEL = 43,
ACCOUNT_MARGIN_SO_CALL = 45,
ACCOUNT_MARGIN_SO_SO = 46
}
public enum ENUM_ACCOUNT_INFO_STRING
{
ACCOUNT_NAME = 1,
ACCOUNT_SERVER = 3,
ACCOUNT_CURRENCY = 36,
ACCOUNT_COMPANY = 2
}
public enum ENUM_ACCOUNT_TRADE_MODE
{
ACCOUNT_TRADE_MODE_DEMO = 0,
ACCOUNT_TRADE_MODE_CONTEST = 1,
ACCOUNT_TRADE_MODE_REAL = 2
}
public enum ENUM_ACCOUNT_STOPOUT_MODE
{
ACCOUNT_STOPOUT_MODE_PERCENT = 0,
ACCOUNT_STOPOUT_MODE_MONEY = 1
}
// Chart Constants:
#region Chart Timeframes
public enum ENUM_TIMEFRAMES
{
PERIOD_CURRENT = 0,
@@ -221,19 +31,66 @@
PERIOD_MN1 = 49153
}
public enum ENUM_SERIES_INFO_INTEGER
#endregion //Chart Timeframes
// Environment State:
#region Client Terminal Properties
public enum ENUM_TERMINAL_INFO_INTEGER
{
SERIES_BARS_COUNT = 0,
SERIES_FIRSTDATE = 1,
SERIES_LASTBAR_DATE = 5,
SERIES_SERVER_FIRSTDATE = 2,
SERIES_TERMINAL_FIRSTDATE = 3,
SERIES_SYNCHRONIZED = 4
TERMINAL_BUILD = 5,
TERMINAL_COMMUNITY_ACCOUNT = 23,
TERMINAL_COMMUNITY_CONNECTION = 24,
TERMINAL_CONNECTED = 6,
TERMINAL_DLLS_ALLOWED = 7,
TERMINAL_TRADE_ALLOWED = 8,
TERMINAL_EMAIL_ENABLED = 9,
TERMINAL_FTP_ENABLED = 10,
TERMINAL_NOTIFICATIONS_ENABLED = 26,
TERMINAL_MAXBARS = 11,
TERMINAL_MQID = 22,
TERMINAL_CODEPAGE = 12,
TERMINAL_CPU_CORES = 21,
TERMINAL_DISK_SPACE = 20,
TERMINAL_MEMORY_PHYSICAL = 14,
TERMINAL_MEMORY_TOTAL = 15,
TERMINAL_MEMORY_AVAILABLE = 16,
TERMINAL_MEMORY_USED = 17,
TERMINAL_X64 = 18,
TERMINAL_OPENCL_SUPPORT = 19,
TERMINAL_SCREEN_DPI = 27,
TERMINAL_PING_LAST = 29
}
public enum ENUM_TERMINAL_INFO_DOUBLE
{
TERMINAL_COMMUNITY_BALANCE = 25
}
public enum ENUM_TERMINAL_INFO_STRING
{
TERMINAL_LANGUAGE = 13,
TERMINAL_COMPANY = 0,
TERMINAL_NAME = 1,
TERMINAL_PATH = 2,
TERMINAL_DATA_PATH = 3,
TERMINAL_COMMONDATA_PATH = 4
}
#endregion //Client Terminal Properties
#region Symbol Properties
public enum ENUM_SYMBOL_INFO_INTEGER
{
SYMBOL_CUSTOM = 78,
SYMBOL_BACKGROUND_COLOR = 79,
SYMBOL_CHART_MODE = 80,
SYMBOL_SELECT = 0,
//FIXME: SYMBOL_VISIBLE not found in MQL5 environment!
//SYMBOL_VISIBLE = ?
SYMBOL_SESSION_DEALS = 56,
SYMBOL_SESSION_BUY_ORDERS = 60,
SYMBOL_SESSION_SELL_ORDERS = 62,
@@ -254,8 +111,14 @@
SYMBOL_TRADE_EXEMODE = 33,
SYMBOL_SWAP_MODE = 37,
SYMBOL_SWAP_ROLLOVER3DAYS = 40,
SYMBOL_MARGIN_HEDGED_USE_LEG = 82,
SYMBOL_EXPIRATION_MODE = 49,
SYMBOL_FILLING_MODE = 50
SYMBOL_FILLING_MODE = 50,
SYMBOL_ORDER_MODE = 71,
SYMBOL_ORDER_GTC_MODE = 81,
SYMBOL_ORDER_CLOSEBY = 64,
SYMBOL_OPTION_MODE = 75,
SYMBOL_OPTION_RIGHT = 74,
}
public enum ENUM_SYMBOL_INFO_DOUBLE
@@ -269,12 +132,16 @@
SYMBOL_LAST = 7,
SYMBOL_LASTHIGH = 8,
SYMBOL_LASTLOW = 9,
SYMBOL_OPTION_STRIKE = 72,
SYMBOL_POINT = 16,
SYMBOL_TRADE_TICK_VALUE = 26,
SYMBOL_TRADE_TICK_VALUE_PROFIT = 53,
SYMBOL_TRADE_TICK_VALUE_LOSS = 54,
SYMBOL_TRADE_TICK_SIZE = 27,
SYMBOL_TRADE_CONTRACT_SIZE = 28,
SYMBOL_TRADE_ACCRUED_INTEREST = 87,
SYMBOL_TRADE_FACE_VALUE = 86,
SYMBOL_TRADE_LIQUIDITY_RATE = 85,
SYMBOL_VOLUME_MIN = 34,
SYMBOL_VOLUME_MAX = 35,
SYMBOL_VOLUME_STEP = 36,
@@ -283,11 +150,11 @@
SYMBOL_SWAP_SHORT = 39,
SYMBOL_MARGIN_INITIAL = 42,
SYMBOL_MARGIN_MAINTENANCE = 43,
SYMBOL_MARGIN_LONG = 44,
SYMBOL_MARGIN_SHORT = 45,
SYMBOL_MARGIN_LIMIT = 46,
SYMBOL_MARGIN_STOP = 47,
SYMBOL_MARGIN_STOPLIMIT = 48,
SYMBOL_MARGIN_LONG = 44, //FIXME: Undocumented!
SYMBOL_MARGIN_SHORT = 45, //FIXME: Undocumented!
SYMBOL_MARGIN_LIMIT = 46, //FIXME: Undocumented!
SYMBOL_MARGIN_STOP = 47, //FIXME: Undocumented!
SYMBOL_MARGIN_STOPLIMIT = 48, //FIXME: Undocumented!
SYMBOL_SESSION_VOLUME = 57,
SYMBOL_SESSION_TURNOVER = 58,
SYMBOL_SESSION_INTEREST = 59,
@@ -298,20 +165,80 @@
SYMBOL_SESSION_AW = 66,
SYMBOL_SESSION_PRICE_SETTLEMENT = 67,
SYMBOL_SESSION_PRICE_LIMIT_MIN = 68,
SYMBOL_SESSION_PRICE_LIMIT_MAX = 69
SYMBOL_SESSION_PRICE_LIMIT_MAX = 69,
SYMBOL_MARGIN_HEDGED = 77
}
public enum ENUM_SYMBOL_INFO_STRING
{
SYMBOL_BASIS = 73,
SYMBOL_CURRENCY_BASE = 22,
SYMBOL_CURRENCY_PROFIT = 23,
SYMBOL_CURRENCY_MARGIN = 24,
SYMBOL_BANK = 19,
SYMBOL_DESCRIPTION = 20,
SYMBOL_FORMULA = 84,
SYMBOL_PAGE = 83,
SYMBOL_ISIN = 70,
SYMBOL_PATH = 21
}
public enum ENUM_SYMBOL_CHART_MODE
{
SYMBOL_CHART_MODE_BID = 0,
SYMBOL_CHART_MODE_LAST = 1
}
public enum ENUM_SYMBOL_ORDER_GTC_MODE
{
SYMBOL_ORDERS_GTC = 0,
SYMBOL_ORDERS_DAILY = 1,
SYMBOL_ORDERS_DAILY_EXCLUDING_STOPS = 2
}
public enum ENUM_SYMBOL_CALC_MODE
{
SYMBOL_CALC_MODE_FOREX = 0,
SYMBOL_CALC_MODE_FUTURES = 1,
SYMBOL_CALC_MODE_CFD = 2,
SYMBOL_CALC_MODE_CFDINDEX = 3,
SYMBOL_CALC_MODE_CFDLEVERAGE = 4,
SYMBOL_CALC_MODE_EXCH_STOCKS = 32,
SYMBOL_CALC_MODE_EXCH_FUTURES = 33,
SYMBOL_CALC_MODE_EXCH_FUTURES_FORTS = 34,
SYMBOL_CALC_MODE_SERV_COLLATERAL = 64
}
public enum ENUM_SYMBOL_TRADE_MODE
{
SYMBOL_TRADE_MODE_DISABLED = 0,
SYMBOL_TRADE_MODE_LONGONLY = 1,
SYMBOL_TRADE_MODE_SHORTONLY = 2,
SYMBOL_TRADE_MODE_CLOSEONLY = 3,
SYMBOL_TRADE_MODE_FULL = 4
}
public enum ENUM_SYMBOL_TRADE_EXECUTION
{
SYMBOL_TRADE_EXECUTION_REQUEST = 0,
SYMBOL_TRADE_EXECUTION_INSTANT = 1,
SYMBOL_TRADE_EXECUTION_MARKET = 2,
SYMBOL_TRADE_EXECUTION_EXCHANGE = 3
}
public enum ENUM_SYMBOL_SWAP_MODE
{
SYMBOL_SWAP_MODE_DISABLED = 0,
SYMBOL_SWAP_MODE_POINTS = 1,
SYMBOL_SWAP_MODE_CURRENCY_SYMBOL = 2,
SYMBOL_SWAP_MODE_CURRENCY_MARGIN = 3,
SYMBOL_SWAP_MODE_CURRENCY_DEPOSIT = 4,
SYMBOL_SWAP_MODE_INTEREST_CURRENT = 5,
SYMBOL_SWAP_MODE_INTEREST_OPEN = 6,
SYMBOL_SWAP_MODE_REOPEN_CURRENT = 7,
SYMBOL_SWAP_MODE_REOPEN_BID = 8
}
public enum ENUM_DAY_OF_WEEK
{
SUNDAY = 0,
@@ -323,11 +250,360 @@
SATURDAY = 6
}
public enum ENUM_SYMBOL_OPTION_RIGHT
{
SYMBOL_OPTION_RIGHT_CALL = 0,
SYMBOL_OPTION_RIGHT_PUT = 1
}
public enum ENUM_SYMBOL_OPTION_MODE
{
SYMBOL_OPTION_MODE_EUROPEAN = 0,
SYMBOL_OPTION_MODE_AMERICAN = 1
}
#endregion //Symbol Properties
#region Account Properties
public enum ENUM_ACCOUNT_INFO_INTEGER
{
ACCOUNT_LOGIN = 0, //Account number
ACCOUNT_TRADE_MODE = 32, //Account trade mode
ACCOUNT_LEVERAGE = 35, //Account leverage
ACCOUNT_LIMIT_ORDERS = 47, //Maximum allowed number of active pending orders
ACCOUNT_MARGIN_SO_MODE = 44, //Mode for setting the minimal allowed margin
ACCOUNT_TRADE_ALLOWED = 33, //Allowed trade for the current account
ACCOUNT_TRADE_EXPERT = 34, //Allowed trade for an Expert Advisor
ACCOUNT_MARGIN_MODE = 53 //Margin calculation mode
}
public enum ENUM_ACCOUNT_INFO_DOUBLE
{
ACCOUNT_BALANCE = 37, //Account balance in the deposit currency
ACCOUNT_CREDIT = 38, //Account credit in the deposit currency
ACCOUNT_PROFIT = 39, //Current profit of an account in the deposit currency
ACCOUNT_EQUITY = 40, //Account equity in the deposit currency
ACCOUNT_MARGIN = 41, //Account margin used in the deposit currency
ACCOUNT_MARGIN_FREE = 42, //Free margin of an account in the deposit currency
ACCOUNT_MARGIN_LEVEL = 43, //Account margin level in percents
ACCOUNT_MARGIN_SO_CALL = 45, //Margin call level
ACCOUNT_MARGIN_SO_SO = 46, //Margin stop out level
ACCOUNT_MARGIN_INITIAL = 48, //Initial margin
ACCOUNT_MARGIN_MAINTENANCE = 49, //Maintenance margin
ACCOUNT_ASSETS = 50, //The current assets of an account
ACCOUNT_LIABILITIES = 51, //The current liabilities on an account
ACCOUNT_COMMISSION_BLOCKED = 52 //The current blocked commission amount on an account
}
public enum ENUM_ACCOUNT_INFO_STRING
{
ACCOUNT_NAME = 1, //Client name
ACCOUNT_SERVER = 3, //Trade server name
ACCOUNT_CURRENCY = 36, //Account currency
ACCOUNT_COMPANY = 2 //Name of a company that serves the account
}
public enum ENUM_ACCOUNT_TRADE_MODE
{
ACCOUNT_TRADE_MODE_DEMO = 0, //Demo account
ACCOUNT_TRADE_MODE_CONTEST = 1, //Contest account
ACCOUNT_TRADE_MODE_REAL = 2 //Real account
}
public enum ENUM_ACCOUNT_STOPOUT_MODE
{
ACCOUNT_STOPOUT_MODE_PERCENT = 0, //Account stop out mode in percents
ACCOUNT_STOPOUT_MODE_MONEY = 1 //Account stop out mode in money
}
public enum ENUM_ACCOUNT_MARGIN_MODE
{
ACCOUNT_MARGIN_MODE_RETAIL_NETTING = 0, //Used for the OTC markets to interpret positions in the "netting" mode
ACCOUNT_MARGIN_MODE_EXCHANGE = 1, //Used for the exchange markets
ACCOUNT_MARGIN_MODE_RETAIL_HEDGING = 2 //Used for the exchange markets where individual positions are possible
}
#endregion //Account Properties
// Trade Constants:
#region History Database Properties
public enum ENUM_SERIES_INFO_INTEGER
{
SERIES_BARS_COUNT = 0, //Bars count for the symbol-period for the current moment
SERIES_FIRSTDATE = 1, //The very first date for the symbol-period for the current moment
SERIES_LASTBAR_DATE = 5, //Open time of the last bar of the symbol-period
SERIES_SERVER_FIRSTDATE = 2, //The very first date in the history of the symbol on the server regardless of the timeframe
SERIES_TERMINAL_FIRSTDATE = 3, //The very first date in the history of the symbol in the client terminal, regardless of the timeframe
SERIES_SYNCHRONIZED = 4 //Symbol/period data synchronization flag for the current moment
}
#endregion //History Database Properties
#region Order Properties
public enum ENUM_ORDER_PROPERTY_INTEGER
{
ORDER_TICKET = 22, //Order ticket. Unique number assigned to each order
ORDER_TIME_SETUP = 1, //Order setup time
ORDER_TYPE = 4, //Order type
ORDER_STATE = 14, //Order state
ORDER_TIME_EXPIRATION = 2, //Order expiration time
ORDER_TIME_DONE = 3, //Order execution or cancellation time
ORDER_TIME_SETUP_MSC = 18, //The time of placing an order for execution in milliseconds since 01.01.1970
ORDER_TIME_DONE_MSC = 19, //Order execution/cancellation time in milliseconds since 01.01.1970
ORDER_TYPE_FILLING = 5, //Order filling type
ORDER_TYPE_TIME = 6, //Order lifetime
ORDER_MAGIC = 15, //ID of an Expert Advisor that has placed the order (designed to ensure that each Expert Advisor places its own unique number)
ORDER_REASON = 23, //The reason or source for placing an order
ORDER_POSITION_ID = 17, //Position identifier that is set to an order as soon as it is executed. Each executed order results in a deal that opens or modifies an already existing position. The identifier of exactly this position is set to the executed order at this moment.
ORDER_POSITION_BY_ID = 21 //Identifier of an opposite position used for closing by order ORDER_TYPE_CLOSE_BY
}
public enum ENUM_ORDER_PROPERTY_DOUBLE
{
ORDER_VOLUME_INITIAL = 7, //Order initial volume
ORDER_VOLUME_CURRENT = 8, //Order current volume
ORDER_PRICE_OPEN = 9, //Price specified in the order
ORDER_SL = 12, //Stop Loss value
ORDER_TP = 13, //Take Profit value
ORDER_PRICE_CURRENT = 10, //The current price of the order symbol
ORDER_PRICE_STOPLIMIT = 11 //The Limit order price for the StopLimit order
}
public enum ENUM_ORDER_PROPERTY_STRING
{
ORDER_SYMBOL = 0, //Symbol of the order
ORDER_COMMENT = 16, //Order comment
ORDER_EXTERNAL_ID = 20 //Order identifier in an external trading system (on the Exchange)
}
public enum ENUM_ORDER_TYPE
{
ORDER_TYPE_BUY = 0, //Market Buy order
ORDER_TYPE_SELL = 1, //Market Sell order
ORDER_TYPE_BUY_LIMIT = 2, //Buy Limit pending order
ORDER_TYPE_SELL_LIMIT = 3, //Sell Limit pending order
ORDER_TYPE_BUY_STOP = 4, //Buy Stop pending order
ORDER_TYPE_SELL_STOP = 5, //Sell Stop pending order
ORDER_TYPE_BUY_STOP_LIMIT = 6, //Upon reaching the order price, a pending Buy Limit order is places at the StopLimit price
ORDER_TYPE_SELL_STOP_LIMIT = 7, //Upon reaching the order price, a pending Sell Limit order is places at the StopLimit price
ORDER_TYPE_CLOSE_BY = 8 //Order to close a position by an opposite one
}
public enum ENUM_ORDER_STATE
{
ORDER_STATE_STARTED = 0, //Order checked, but not yet accepted by broker
ORDER_STATE_PLACED = 1, //Order accepted
ORDER_STATE_CANCELED = 2, //Order canceled by client
ORDER_STATE_PARTIAL = 3, //Order partially executed
ORDER_STATE_FILLED = 4, //Order fully executed
ORDER_STATE_REJECTED = 5, //Order rejected
ORDER_STATE_EXPIRED = 6, //Order expired
ORDER_STATE_REQUEST_ADD = 7, //Order is being registered (placing to the trading system)
ORDER_STATE_REQUEST_MODIFY = 8, //Order is being modified (changing its parameters)
ORDER_STATE_REQUEST_CANCEL = 9 //Order is being deleted (deleting from the trading system)
}
public enum ENUM_ORDER_TYPE_FILLING
{
ORDER_FILLING_FOK = 0,
ORDER_FILLING_IOC = 1,
ORDER_FILLING_RETURN = 2
}
public enum ENUM_ORDER_TYPE_TIME
{
ORDER_TIME_GTC = 0,
ORDER_TIME_DAY = 1,
ORDER_TIME_SPECIFIED = 2,
ORDER_TIME_SPECIFIED_DAY = 3
}
public enum ENUM_ORDER_REASON
{
ORDER_REASON_CLIENT = 0, //The order was placed from a desktop terminal
ORDER_REASON_MOBILE = 1, //The order was placed from a mobile application
ORDER_REASON_WEB = 2, //The order was placed from a web platform
ORDER_REASON_EXPERT = 3, //The order was placed from an MQL5-program, i.e. by an Expert Advisor or a script
ORDER_REASON_SL = 4, //The order was placed as a result of Stop Loss activation
ORDER_REASON_TP = 5, //The order was placed as a result of Take Profit activation
ORDER_REASON_SO = 6 //The order was placed as a result of the Stop Out event
}
#endregion //Order Properties
#region Position Properties
public enum ENUM_POSITION_PROPERTY_INTEGER
{
POSITION_TICKET = 17, //Position ticket
POSITION_TIME = 1, //Position open time
POSITION_TIME_MSC = 14, //Position opening time in milliseconds since 01.01.1970
POSITION_TIME_UPDATE = 15, //Position changing time in seconds since 01.01.1970
POSITION_TIME_UPDATE_MSC = 16, //Position changing time in milliseconds since 01.01.1970
POSITION_TYPE = 2, //Position type
POSITION_MAGIC = 12, //Position magic number
POSITION_IDENTIFIER = 13, //Position identifier is a unique number that is assigned to every newly opened position and doesn't change during the entire lifetime of the position. Position turnover doesn't change its identifier.
POSITION_REASON = 18 //The reason for opening a position
}
public enum ENUM_POSITION_PROPERTY_DOUBLE
{
POSITION_VOLUME = 3, //Position volume
POSITION_PRICE_OPEN = 4, //Position open price
POSITION_SL = 6, //Stop Loss level of opened position
POSITION_TP = 7, //Take Profit level of opened position
POSITION_PRICE_CURRENT = 5, //Current price of the position symbol
POSITION_COMMISSION = 8, //FIXME: Undocumented!
POSITION_SWAP = 9, //Cumulative swap
POSITION_PROFIT = 10 //Current profit
}
public enum ENUM_POSITION_PROPERTY_STRING
{
POSITION_SYMBOL = 0, //Symbol of the position
POSITION_COMMENT = 11 //Position comment
}
public enum ENUM_POSITION_TYPE
{
POSITION_TYPE_BUY = 0, //Buy
POSITION_TYPE_SELL = 1 //Sell
}
public enum ENUM_POSITION_REASON
{
POSITION_REASON_CLIENT = 0, //The position was opened as a result of activation of an order placed from a desktop terminal
POSITION_REASON_MOBILE = 1, //The position was opened as a result of activation of an order placed from a mobile application
POSITION_REASON_WEB = 2, //The position was opened as a result of activation of an order placed from the web platform
POSITION_REASON_EXPERT = 3 //The position was opened as a result of activation of an order placed from an MQL5 program
}
#endregion //Position Properties
#region Deal Properties
public enum ENUM_DEAL_PROPERTY_INTEGER
{
DEAL_TICKET = 15, //Deal ticket. Unique number assigned to each deal
DEAL_ORDER = 1, //Deal order number
DEAL_TIME = 2, //Deal time
DEAL_TIME_MSC = 13, //The time of a deal execution in milliseconds since 01.01.1970
DEAL_TYPE = 3, //Deal type
DEAL_ENTRY = 4, //Deal entry - entry in, entry out, reverse
DEAL_MAGIC = 11, //Deal magic number
DEAL_REASON = 16, //The reason or source for deal execution
DEAL_POSITION_ID = 12 //Identifier of a position
}
public enum ENUM_DEAL_PROPERTY_DOUBLE
{
DEAL_VOLUME = 5, //Deal volume
DEAL_PRICE = 6, //Deal price
DEAL_COMMISSION = 7, //Deal commission
DEAL_SWAP = 8, //Cumulative swap on close
DEAL_PROFIT = 9 //Deal profit
}
public enum ENUM_DEAL_PROPERTY_STRING
{
DEAL_SYMBOL = 0, //Deal symbol
DEAL_COMMENT = 10, //Deal comment
DEAL_EXTERNAL_ID = 14 //Deal identifier in an external trading system (on the Exchange)
}
public enum ENUM_DEAL_TYPE
{
DEAL_TYPE_BUY = 0, //Buy
DEAL_TYPE_SELL = 1, //Sell
DEAL_TYPE_BALANCE = 2, //Balance
DEAL_TYPE_CREDIT = 3, //Credit
DEAL_TYPE_CHARGE = 4, //Additional charge
DEAL_TYPE_CORRECTION = 5, //Correction
DEAL_TYPE_BONUS = 6, //Bonus
DEAL_TYPE_COMMISSION = 7, //Additional commission
DEAL_TYPE_COMMISSION_DAILY = 8, //Daily commission
DEAL_TYPE_COMMISSION_MONTHLY = 9, //Monthly commission
DEAL_TYPE_COMMISSION_AGENT_DAILY = 10, //Daily agent commission
DEAL_TYPE_COMMISSION_AGENT_MONTHLY = 11, //Monthly agent commission
DEAL_TYPE_INTEREST = 12, //Interest rate
DEAL_TYPE_BUY_CANCELED = 13, //Canceled buy deal
DEAL_TYPE_SELL_CANCELED = 14, //Canceled sell deal
DEAL_DIVIDEND = 15, //Dividend operations
DEAL_DIVIDEND_FRANKED = 16, //Franked (non-taxable) dividend operations
DEAL_TAX = 17 //Tax charges
}
public enum ENUM_DEAL_ENTRY
{
DEAL_ENTRY_IN = 0, //Entry in
DEAL_ENTRY_OUT = 1, //Entry out
DEAL_ENTRY_INOUT = 2, //Reverse
DEAL_ENTRY_STATE = 255 //Close a position by an opposite one
}
public enum ENUM_DEAL_REASON
{
DEAL_REASON_CLIENT = 0, //The deal was executed as a result of activation of an order placed from a desktop terminal
DEAL_REASON_MOBILE = 1, //The deal was executed as a result of activation of an order placed from a mobile application
DEAL_REASON_WEB = 2, //The deal was executed as a result of activation of an order placed from the web platform
DEAL_REASON_EXPERT = 3, //The deal was executed as a result of activation of an order placed from an MQL5 program, i.e. an Expert Advisor or a script
DEAL_REASON_SL = 4, //The deal was executed as a result of Stop Loss activation
DEAL_REASON_TP = 5, //The deal was executed as a result of Take Profit activation
DEAL_REASON_SO = 6, //The deal was executed as a result of the Stop Out event
DEAL_REASON_ROLLOVER = 7, //The deal was executed due to a rollover
DEAL_REASON_VMARGIN = 8, //The deal was executed after charging the variation margin
DEAL_REASON_SPLIT = 9 //The deal was executed after the split (price reduction) of an instrument, which had an open position during split announcement
}
#endregion //Deal Properties
#region Trade Operation Types
public enum ENUM_TRADE_REQUEST_ACTIONS
{
TRADE_ACTION_DEAL = 1, //Place a trade order for an immediate execution with the specified parameters (market order)
TRADE_ACTION_PENDING = 5, //Place a trade order for the execution under specified conditions (pending order)
TRADE_ACTION_SLTP = 6, //Modify Stop Loss and Take Profit values of an opened position
TRADE_ACTION_MODIFY = 7, //Modify the parameters of the order placed previously
TRADE_ACTION_REMOVE = 8, //Delete the pending order placed previously
TRADE_ACTION_CLOSE_BY = 10 //Close a position by an opposite one
}
#endregion //Trade Operation Types
#region Trade Transaction Types
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
}
#endregion //Trade Transaction Types
#region Trade Orders in Depth Of Market
public enum ENUM_BOOK_TYPE
{
BOOK_TYPE_SELL = 1,
BOOK_TYPE_BUY = 2,
BOOK_TYPE_SELL_MARKET = 3,
BOOK_TYPE_BUY_MARKET = 4
BOOK_TYPE_SELL = 1, //Sell order (Offer)
BOOK_TYPE_BUY = 2, //Buy order (Bid)
BOOK_TYPE_SELL_MARKET = 3, //Sell order by Market
BOOK_TYPE_BUY_MARKET = 4 //Buy order by Market
}
#endregion //Trade Orders in Depth Of Market
}
-1
View File
@@ -56,7 +56,6 @@
<Compile Include="Mt5Enums.cs" />
<Compile Include="Mt5ConnectionEventArgs.cs" />
<Compile Include="Mt5ConnectionState.cs" />
<Compile Include="ExtensionMethods.cs" />
<Compile Include="MqlTradeRequest.cs" />
<Compile Include="MqlTradeResult.cs" />
<Compile Include="Mt5QuoteEventArgs.cs" />
+174 -111
View File
@@ -7,6 +7,7 @@ using System.ServiceModel;
using MtApi5.Requests;
using MtApi5.Responses;
using Newtonsoft.Json;
using System.Threading.Tasks;
namespace MtApi5
{
@@ -31,22 +32,17 @@ namespace MtApi5
#region Private Fields
private readonly MtClient _client = new MtClient();
private MtClient _client;
private readonly object _locker = new object();
private volatile bool _isBacktestingMode = false;
private Mt5ConnectionState _connectionState = Mt5ConnectionState.Disconnected;
private int _executorHandle;
#endregion
#region Public Methods
public MtApi5Client()
{
LogConfigurator.Setup(LogProfileName);
ConnectionState = Mt5ConnectionState.Disconnected;
_client.QuoteAdded += mClient_QuoteAdded;
_client.QuoteRemoved += mClient_QuoteRemoved;
_client.QuoteUpdated += mClient_QuoteUpdated;
_client.ServerDisconnected += mClient_ServerDisconnected;
_client.ServerFailed += mClient_ServerFailed;
}
///<summary>
@@ -56,15 +52,7 @@ namespace MtApi5
///<param name="port">Port of host connection (default 8222) </param>
public void BeginConnect(string host, int port)
{
//if (string.IsNullOrEmpty(host) == false && (host.Equals("localhost") || host.Equals("127.0.0.1")))
//{
// this.BeginConnect(port);
//}
//else
//{
Action<string, int> connectAction = Connect;
connectAction.BeginInvoke(host, port, null, null);
//}
Task.Factory.StartNew(() => Connect(host, port));
}
///<summary>
@@ -73,8 +61,7 @@ namespace MtApi5
///<param name="port">Port of host connection (default 8222) </param>
public void BeginConnect(int port)
{
Action<int> connectAction = Connect;
connectAction.BeginInvoke(port, null, null);
Task.Factory.StartNew(() => Connect(port));
}
///<summary>
@@ -82,8 +69,7 @@ namespace MtApi5
///</summary>
public void BeginDisconnect()
{
Action disconnectAction = Disconnect;
disconnectAction.BeginInvoke(null, null);
Task.Factory.StartNew(() => Disconnect(false));
}
///<summary>
@@ -91,11 +77,8 @@ namespace MtApi5
///</summary>
public IEnumerable<Mt5Quote> GetQuotes()
{
IEnumerable<MtQuote> quotes;
lock (_client)
{
quotes = _client.GetQuotes();
}
var client = Client;
var quotes = client != null ? client.GetQuotes() : null;
return quotes?.Select(q => q.Parse());
}
@@ -240,6 +223,17 @@ namespace MtApi5
return SendCommand<bool>(Mt5CommandType.PositionSelect, commandParameters);
}
///<summary>
///Selects an open position to work with based on the ticket number specified in the position. If successful, returns true. Returns false if the function failed.
///</summary>
///<param name="ticket">Position ticket.</param>
public bool PositionSelectByTicket(ulong ticket)
{
var commandParameters = new ArrayList { ticket };
return SendCommand<bool>(Mt5CommandType.PositionSelectByTicket, commandParameters);
}
///<summary>
///The function returns the requested property of an open position, pre-selected using PositionGetSymbol or PositionSelect.
///</summary>
@@ -1432,7 +1426,37 @@ namespace MtApi5
///<summary>
///Connection status of MetaTrader API.
///</summary>
public Mt5ConnectionState ConnectionState { get; private set; }
public Mt5ConnectionState ConnectionState
{
get
{
lock (_locker)
{
return _connectionState;
}
}
}
///<summary>
///Handle of expert used to execute commands
///</summary>
public int ExecutorHandle
{
get
{
lock (_locker)
{
return _executorHandle;
}
}
set
{
lock (_locker)
{
_executorHandle = value;
}
}
}
#endregion
#region Events
@@ -1443,94 +1467,148 @@ namespace MtApi5
#endregion
#region Private Methods
private void Connect(string host, int port)
private MtClient Client
{
ConnectionState = Mt5ConnectionState.Connecting;
ConnectionStateChanged.FireEvent(this
, new Mt5ConnectionEventArgs(Mt5ConnectionState.Connecting, "Connecting to " + host + ":" + port));
try
get
{
lock (_client)
lock (_locker)
{
_client.Open(host, port);
_client.Connect();
return _client;
}
}
catch (Exception e)
}
private void Connect(MtClient client)
{
lock (_locker)
{
ConnectionState = Mt5ConnectionState.Failed;
ConnectionStateChanged.FireEvent(this
, new Mt5ConnectionEventArgs(Mt5ConnectionState.Failed, "Failed connection to " + host + ":" + port + ". " + e.Message));
return;
if (_connectionState == Mt5ConnectionState.Connected
|| _connectionState == Mt5ConnectionState.Connecting)
{
return;
}
_connectionState = Mt5ConnectionState.Connecting;
}
ConnectionState = Mt5ConnectionState.Connected;
ConnectionStateChanged.FireEvent(this
, new Mt5ConnectionEventArgs(Mt5ConnectionState.Connected, "Connected to " + host + ":" + port));
string message = string.IsNullOrEmpty(client.Host) ? $"Connecting to localhost:{client.Port}" : $"Connecting to {client.Host}:{client.Port}";
ConnectionStateChanged?.Invoke(this, new Mt5ConnectionEventArgs(Mt5ConnectionState.Connecting, message));
OnConnected();
var state = Mt5ConnectionState.Failed;
lock (_locker)
{
try
{
client.Connect();
state = Mt5ConnectionState.Connected;
}
catch (Exception e)
{
client.Dispose();
message = string.IsNullOrEmpty(client.Host) ? $"Failed connection to localhost:{client.Port}. {e.Message}" : $"Failed connection to {client.Host}:{client.Port}. {e.Message}";
}
if (state == Mt5ConnectionState.Connected)
{
_client = client;
_client.QuoteAdded += _client_QuoteAdded;
_client.QuoteRemoved += _client_QuoteRemoved;
_client.QuoteUpdated += _client_QuoteUpdated;
_client.ServerDisconnected += _client_ServerDisconnected;
_client.ServerFailed += _client_ServerFailed;
message = string.IsNullOrEmpty(client.Host) ? $"Connected to localhost:{client.Port}" : $"Connected to { client.Host}:{client.Port}";
}
_connectionState = state;
}
ConnectionStateChanged?.Invoke(this, new Mt5ConnectionEventArgs(state, message));
if (state == Mt5ConnectionState.Connected)
{
OnConnected();
}
}
private void Connect(string host, int port)
{
var client = new MtClient(host, port);
Connect(client);
}
private void Connect(int port)
{
ConnectionState = Mt5ConnectionState.Connecting;
ConnectionStateChanged.FireEvent(this
, new Mt5ConnectionEventArgs(Mt5ConnectionState.Connecting, "Connecting to 'localhost':" + port));
try
{
lock (_client)
{
_client.Open(port);
_client.Connect();
}
}
catch (Exception e)
{
ConnectionState = Mt5ConnectionState.Failed;
ConnectionStateChanged.FireEvent(this
, new Mt5ConnectionEventArgs(Mt5ConnectionState.Failed, "Failed connection to 'localhost':" + port + ". " + e.Message));
return;
}
ConnectionState = Mt5ConnectionState.Connected;
ConnectionStateChanged.FireEvent(this
, new Mt5ConnectionEventArgs(Mt5ConnectionState.Connected, "Connected to 'localhost':" + port));
OnConnected();
var client = new MtClient(port);
Connect(client);
}
private void Disconnect()
private void Disconnect(bool failed)
{
lock (_client)
var state = failed ? Mt5ConnectionState.Failed : Mt5ConnectionState.Disconnected;
var message = failed ? "Connection Failed" : "Disconnected";
lock (_locker)
{
_client.Disconnect();
_client.Close();
if (_connectionState == Mt5ConnectionState.Disconnected
|| _connectionState == Mt5ConnectionState.Failed)
return;
if (_client != null)
{
_client.QuoteAdded -= _client_QuoteAdded;
_client.QuoteRemoved -= _client_QuoteRemoved;
_client.QuoteUpdated -= _client_QuoteUpdated;
_client.ServerDisconnected -= _client_ServerDisconnected;
_client.ServerFailed -= _client_ServerFailed;
if (!failed)
{
_client.Disconnect();
}
_client.Dispose();
_client = null;
}
_connectionState = state;
}
ConnectionState = Mt5ConnectionState.Disconnected;
ConnectionStateChanged.FireEvent(this, new Mt5ConnectionEventArgs(Mt5ConnectionState.Disconnected, "Disconnected"));
ConnectionStateChanged?.Invoke(this, new Mt5ConnectionEventArgs(state, message));
}
private T SendCommand<T>(Mt5CommandType commandType, ArrayList commandParameters)
private T SendCommand<T>(Mt5CommandType commandType, ArrayList commandParameters, Dictionary<string, object> namedParams = null)
{
MtResponse response;
var client = Client;
if (client == null)
{
throw new Exception("No connection");
}
try
{
lock (_client)
{
response = _client.SendCommand((int) commandType, commandParameters);
}
response = client.SendCommand((int)commandType, commandParameters, namedParams, ExecutorHandle);
}
catch (CommunicationException ex)
{
throw new Exception(ex.Message, ex);
}
var responseValue = response?.GetValue();
return responseValue != null ? (T) responseValue : default(T);
if (response == null)
{
throw new ExecutionException(ErrorCode.ErrCustom, "Response from MetaTrader is null");
}
if (response.ErrorCode != 0)
{
throw new ExecutionException((ErrorCode)response.ErrorCode, response.ToString());
}
var responseValue = response.GetValue();
return responseValue != null ? (T)responseValue : default(T);
}
private T SendRequest<T>(RequestBase request) where T : ResponseBase, new()
@@ -1545,25 +1623,14 @@ namespace MtApi5
});
var commandParameters = new ArrayList { serializer };
MtResponseString res;
try
{
lock (_client)
{
res = (MtResponseString)_client.SendCommand((int)Mt5CommandType.MtRequest, commandParameters);
}
}
catch (CommunicationException ex)
{
throw new Exception(ex.Message, ex);
}
var res = SendCommand<string>(Mt5CommandType.MtRequest, commandParameters);
if (res == null)
{
throw new ExecutionException(ErrorCode.ErrCustom, "Response from MetaTrader is null");
}
var response = JsonConvert.DeserializeObject<T>(res.Value);
var response = JsonConvert.DeserializeObject<T>(res);
if (response.ErrorCode != 0)
{
throw new ExecutionException((ErrorCode)response.ErrorCode, response.ErrorMessage);
@@ -1573,7 +1640,7 @@ namespace MtApi5
}
private void mClient_QuoteUpdated(MtQuote quote)
private void _client_QuoteUpdated(MtQuote quote)
{
if (quote != null)
{
@@ -1581,28 +1648,24 @@ namespace MtApi5
}
}
private void mClient_ServerDisconnected(object sender, EventArgs e)
private void _client_ServerDisconnected(object sender, EventArgs e)
{
ConnectionState = Mt5ConnectionState.Disconnected;
ConnectionStateChanged.FireEvent(this
, new Mt5ConnectionEventArgs(Mt5ConnectionState.Disconnected, "MtApi is disconnected"));
Disconnect(false);
}
private void mClient_ServerFailed(object sender, EventArgs e)
private void _client_ServerFailed(object sender, EventArgs e)
{
ConnectionState = Mt5ConnectionState.Failed;
ConnectionStateChanged.FireEvent(this
, new Mt5ConnectionEventArgs(Mt5ConnectionState.Failed, "Failed connection with MtApi"));
Disconnect(true);
}
private void mClient_QuoteRemoved(MtQuote quote)
private void _client_QuoteRemoved(MtQuote quote)
{
QuoteRemoved.FireEvent(this, new Mt5QuoteEventArgs(quote.Parse()));
QuoteRemoved?.Invoke(this, new Mt5QuoteEventArgs(quote.Parse()));
}
private void mClient_QuoteAdded(MtQuote quote)
private void _client_QuoteAdded(MtQuote quote)
{
QuoteAdded.FireEvent(this, new Mt5QuoteEventArgs(quote.Parse()));
QuoteAdded?.Invoke(this, new Mt5QuoteEventArgs(quote.Parse()));
}
private void OnConnected()
+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
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.11.0")]
[assembly: AssemblyFileVersion("1.0.11.0")]
[assembly: AssemblyVersion("1.0.12")]
[assembly: AssemblyFileVersion("1.0.12")]
File diff suppressed because it is too large Load Diff
+447 -271
View File
@@ -33,12 +33,16 @@ namespace TestApiClientUI
comboBox8.DataSource = Enum.GetNames(typeof(MarketInfoModeType));
comboBox9.DataSource = Enum.GetNames(typeof(EnumTerminalInfoInteger));
comboBox10.DataSource = Enum.GetNames(typeof(EnumTerminalInfoDouble));
comboBox11.DataSource = Enum.GetNames(typeof(EnumObject));
comboBoxAccountInfoCmd.DataSource = Enum.GetNames(typeof(TradeOperation));
_apiClient.QuoteUpdated += apiClient_QuoteUpdated;
_apiClient.QuoteUpdate += _apiClient_QuoteUpdate;
_apiClient.QuoteAdded += apiClient_QuoteAdded;
_apiClient.QuoteRemoved += apiClient_QuoteRemoved;
_apiClient.ConnectionStateChanged += apiClient_ConnectionStateChanged;
_apiClient.OnLastTimeBar += _apiClient_OnLastTimeBar;
_apiClient.OnChartEvent += _apiClient_OnChartEvent;
InitOrderCommandsGroup();
@@ -47,6 +51,8 @@ namespace TestApiClientUI
comboBox3.SelectedIndex = 0;
comboBox4.SelectedIndex = 0;
comboBox5.SelectedIndex = 0;
comboBox11.SelectedIndex = 0;
comboBoxAccountInfoCmd.SelectedIndex = 0;
_timerTradeMonitor = new TimerTradeMonitor(_apiClient) { Interval = 10000 }; // 10 sec
_timerTradeMonitor.AvailabilityOrdersChanged += _tradeMonitor_AvailabilityOrdersChanged;
@@ -112,18 +118,32 @@ namespace TestApiClientUI
private void apiClient_QuoteRemoved(object sender, MtQuoteEventArgs e)
{
RunOnUiThread(() => RemoveQuote(e.Quote) );
if (e.Quote != null)
{
RunOnUiThread(() => RemoveQuote(e.Quote));
}
}
private void apiClient_QuoteAdded(object sender, MtQuoteEventArgs e)
{
RunOnUiThread(() => AddNewQuote(e.Quote));
if (e.Quote != null)
{
RunOnUiThread(() => AddNewQuote(e.Quote));
}
}
private void _apiClient_OnLastTimeBar(object sender, TimeBarArgs e)
{
var msg =
$"TimeBar: Symbol = {e.TimeBar.Symbol}, OpenTime = {e.TimeBar.OpenTime}, CloseTime = {e.TimeBar.CloseTime}, Open = {e.TimeBar.Open}, Close = {e.TimeBar.Close}, High = {e.TimeBar.High}, Low = {e.TimeBar.Low}";
$"TimeBar: ExpertHandle = {e.ExpertHandle}, Symbol = {e.TimeBar.Symbol}, OpenTime = {e.TimeBar.OpenTime}, CloseTime = {e.TimeBar.CloseTime}, Open = {e.TimeBar.Open}, Close = {e.TimeBar.Close}, High = {e.TimeBar.High}, Low = {e.TimeBar.Low}";
Console.WriteLine(msg);
PrintLog(msg);
}
private void _apiClient_OnChartEvent(object sender, ChartEventArgs e)
{
var msg =
$"OnChartEvent: ExpertHandle = {e.ExpertHandle}, ChartId = {e.ChartId}, EventId = {e.EventId}, Lparam = {e.Lparam}, Dparam = {e.Dparam}, Sparam = {e.Sparam}";
Console.WriteLine(msg);
PrintLog(msg);
}
@@ -131,72 +151,52 @@ namespace TestApiClientUI
private void apiClient_QuoteUpdated(object sender, string symbol, double bid, double ask)
{
Console.WriteLine(@"Quote: Symbol = {0}, Bid = {1}, Ask = {2}", symbol, bid, ask);
}
private void _apiClient_QuoteUpdate(object sender, MtQuoteEventArgs e)
{
//if UI of quite is busy we are skipping this update
if (_isUiQuoteUpdateReady)
{
RunOnUiThread(() => ChangeQuote(symbol, bid, ask));
RunOnUiThread(() => ChangeQuote(e.Quote));
}
}
private void AddNewQuote(MtQuote quote)
{
if (quote == null)
return;
var key = quote.ExpertHandle.ToString();
if (string.IsNullOrEmpty(quote.Instrument) == false
&& listViewQuotes.Items.ContainsKey(quote.Instrument) == false)
if (listViewQuotes.Items.ContainsKey(key) == false)
{
var item = new ListViewItem(quote.Instrument) { Name = quote.Instrument };
var item = new ListViewItem(quote.Instrument) { Name = key };
item.SubItems.Add(quote.Bid.ToString(CultureInfo.CurrentCulture));
item.SubItems.Add(quote.Ask.ToString(CultureInfo.CurrentCulture));
item.SubItems.Add("1");
item.SubItems.Add(key);
listViewQuotes.Items.Add(item);
}
else
{
var item = listViewQuotes.Items[quote.Instrument];
int feedCount;
int.TryParse(item.SubItems[3].Text, out feedCount);
feedCount++;
item.SubItems[3].Text = feedCount.ToString();
}
}
private void RemoveQuote(MtQuote quote)
{
if (quote == null)
return;
var key = quote.ExpertHandle.ToString();
if (string.IsNullOrEmpty(quote.Instrument) == false
&& listViewQuotes.Items.ContainsKey(quote.Instrument))
if (listViewQuotes.Items.ContainsKey(key))
{
var item = listViewQuotes.Items[quote.Instrument];
int feedCount;
int.TryParse(item.SubItems[3].Text, out feedCount);
feedCount--;
if (feedCount <= 0)
{
listViewQuotes.Items.RemoveByKey(quote.Instrument);
}
else
{
item.SubItems[3].Text = feedCount.ToString();
}
listViewQuotes.Items.RemoveByKey(key);
}
}
private void ChangeQuote(string symbol, double bid, double ask)
private void ChangeQuote(MtQuote quote)
{
_isUiQuoteUpdateReady = false;
if (string.IsNullOrEmpty(symbol) == false)
var key = quote.ExpertHandle.ToString();
if (listViewQuotes.Items.ContainsKey(key))
{
if (listViewQuotes.Items.ContainsKey(symbol))
{
var item = listViewQuotes.Items[symbol];
item.SubItems[1].Text = bid.ToString(CultureInfo.CurrentCulture);
item.SubItems[2].Text = ask.ToString(CultureInfo.CurrentCulture);
}
var item = listViewQuotes.Items[key];
item.SubItems[1].Text = quote.Bid.ToString(CultureInfo.CurrentCulture);
item.SubItems[2].Text = quote.Ask.ToString(CultureInfo.CurrentCulture);
}
_isUiQuoteUpdateReady = true;
@@ -256,6 +256,12 @@ namespace TestApiClientUI
textBoxOrderSymbol.Text = listViewQuotes.SelectedItems[0].Text;
txtMarketInfoSymbol.Text = listViewQuotes.SelectedItems[0].Text;
textBoxSelectedSymbol.Text = listViewQuotes.SelectedItems[0].Text;
textBoxAccountInfoSymbol.Text = listViewQuotes.SelectedItems[0].Text;
if (checkBox2.Checked)
{
_apiClient.ExecutorHandle = int.Parse(listViewQuotes.SelectedItems[0].SubItems[3].Text);
}
}
}
@@ -526,206 +532,6 @@ namespace TestApiClientUI
});
}
private void button3_Click(object sender, EventArgs e)
{
switch (comboBoxStatusCommand.SelectedIndex)
{
case 0:
{
var result = _apiClient.GetLastError();
PrintLog($"GetLastError result: {result}");
}
break;
case 1:
{
var result = _apiClient.IsConnected();
PrintLog($"IsConnected result: {result}");
}
break;
case 2:
{
var result = _apiClient.IsDemo();
PrintLog($"IsDemo result: {result}");
}
break;
case 3:
{
var result = _apiClient.IsDllsAllowed();
PrintLog($"IsDllsAllowed result: {result}");
}
break;
case 4:
{
var result = _apiClient.IsExpertEnabled();
PrintLog($"IsExpertEnabled result: {result}");
}
break;
case 5:
{
var result = _apiClient.IsLibrariesAllowed();
PrintLog($"IsLibrariesAllowed result: {result}");
}
break;
case 6:
{
var result = _apiClient.IsOptimization();
PrintLog($"IsOptimization result: {result}");
}
break;
case 7:
{
var result = _apiClient.IsStopped();
PrintLog($"IsStopped result: {result}");
}
break;
case 8:
{
var result = _apiClient.IsTesting();
PrintLog($"IsTesting result: {result}");
}
break;
case 9:
{
var result = _apiClient.IsTradeAllowed();
PrintLog($"IsTradeAllowed result: {result}");
}
break;
case 10:
{
var result = _apiClient.IsTradeContextBusy();
PrintLog($"IsTradeContextBusy result: {result}");
}
break;
case 11:
{
var result = _apiClient.IsVisualMode();
PrintLog($"IsVisualMode result: {result}");
}
break;
case 12:
{
var result = _apiClient.UninitializeReason();
PrintLog($"UninitializeReason result: {result}");
}
break;
case 13:
{
int errorCode;
int.TryParse(textBoxErrorCode.Text, out errorCode);
var result = _apiClient.ErrorDescription(errorCode);
PrintLog($"ErrorDescription result: {result}");
}
break;
default:
return;
}
}
private void button4_Click(object sender, EventArgs e)
{
switch (listBoxAccountInfo.SelectedIndex)
{
case 0:
{
var result = _apiClient.AccountBalance();
PrintLog($"AccountBalance result: {result}");
}
break;
case 1:
{
var result = _apiClient.AccountCredit();
PrintLog($"AccountCredit result: {result}");
}
break;
case 2:
{
var result = _apiClient.AccountCompany();
PrintLog($"AccountCompany result: {result}");
}
break;
case 3:
{
var result = _apiClient.AccountCurrency();
PrintLog($"AccountCurrency result: {result}");
}
break;
case 4:
{
var result = _apiClient.AccountEquity();
PrintLog($"AccountEquity result: {result}");
}
break;
case 5:
{
var result = _apiClient.AccountFreeMargin();
PrintLog($"AccountFreeMargin result: {result}");
}
break;
case 6:
{
var result = _apiClient.AccountFreeMarginCheck(textBoxAccountInfoSymbol.Text, (TradeOperation)comboBoxAccountInfoCmd.SelectedIndex, int.Parse(textBoxAccountInfoVolume.Text));
PrintLog($"AccountFreeMarginCheck result: {result}");
}
break;
case 7:
{
var result = _apiClient.AccountFreeMarginMode();
PrintLog($"AccountFreeMarginMode result: {result}");
}
break;
case 8:
{
var result = _apiClient.AccountLeverage();
PrintLog($"AccountLeverage result: {result}");
}
break;
case 9:
{
var result = _apiClient.AccountMargin();
PrintLog($"AccountMargin result: {result}");
}
break;
case 10:
{
var result = _apiClient.AccountName();
PrintLog($"AccountName result: {result}");
}
break;
case 11:
{
var result = _apiClient.AccountNumber();
PrintLog($"AccountNumber result: {result}");
}
break;
case 12:
{
var result = _apiClient.AccountProfit();
PrintLog($"AccountProfit result: {result}");
}
break;
case 13:
{
var result = _apiClient.AccountServer();
PrintLog($"AccountServer result: {result}");
}
break;
case 14:
{
var result = _apiClient.AccountStopoutLevel();
PrintLog($"AccountStopoutLevel result: {result}");
}
break;
case 15:
{
var result = _apiClient.AccountStopoutMode();
PrintLog($"AccountStopoutMode result: {result}");
}
break;
default:
return;
}
}
//MarketInfo
private async void button5_Click(object sender, EventArgs e)
{
@@ -753,13 +559,13 @@ namespace TestApiClientUI
Console.WriteLine($"Finished time: {DateTime.Now}");
using (var file = new System.IO.StreamWriter($@"{System.IO.Path.GetTempPath()}\MtApi\test.txt"))
{
foreach (var value in openPriceList)
{
file.WriteLine(value);
}
}
//using (var file = new System.IO.StreamWriter($@"{System.IO.Path.GetTempPath()}\MtApi\test.txt"))
//{
// foreach (var value in openPriceList)
// {
// file.WriteLine(value);
// }
//}
}
private void button7_Click(object sender, EventArgs e)
@@ -832,9 +638,9 @@ namespace TestApiClientUI
listBoxEventLog.Items.Clear();
}
private async Task<TResult> Execute<TResult>(Func<TResult> func)
private Task<TResult> Execute<TResult>(Func<TResult> func)
{
return await Task.Factory.StartNew(() =>
return Task.Factory.StartNew(() =>
{
var result = default(TResult);
try
@@ -854,9 +660,30 @@ namespace TestApiClientUI
});
}
private Task Execute(Action action)
{
return Task.Factory.StartNew(() =>
{
try
{
action();
}
catch (MtConnectionException ex)
{
PrintLog("MtExecutionException: " + ex.Message);
}
catch (MtExecutionException ex)
{
PrintLog("MtExecutionException: " + ex.Message + "; ErrorCode = " + ex.ErrorCode);
}
});
}
//OrderSend
private async void button1_Click(object sender, EventArgs e)
{
var ticket = -1;
var symbol = textBoxOrderSymbol.Text;
var cmd = (TradeOperation) comboBoxOrderCommand.SelectedIndex;
@@ -877,28 +704,43 @@ namespace TestApiClientUI
var comment = textBoxOrderComment.Text;
int magic;
int.TryParse(textBoxOrderMagic.Text, out magic);
var expiration = DateTime.Now;
Color arrowColor;
switch (comboBoxOrderColor.SelectedIndex)
if (string.IsNullOrEmpty(comment))
{
case 0:
arrowColor = Color.Green;
break;
case 1:
arrowColor = Color.Blue;
break;
case 2:
arrowColor = Color.Red;
break;
default:
return;
ticket = await Execute(() => _apiClient.OrderSend(symbol, cmd, volume, price, slippage, stoploss, takeprofit));
}
else
{
int magic;
if (!int.TryParse(textBoxOrderMagic.Text, out magic))
{
ticket = await Execute(() => _apiClient.OrderSend(symbol, cmd, volume, price, slippage, stoploss, takeprofit, comment));
}
else
{
if (comboBoxOrderColor.SelectedIndex < 0 || comboBoxOrderColor.SelectedIndex > 2)
{
ticket = await Execute(() => _apiClient.OrderSend(symbol, cmd, volume, price, slippage, stoploss, takeprofit, comment, magic));
}
else
{
var expiration = DateTime.Now.AddDays(1);
Color arrowColor = Color.White;
switch (comboBoxOrderColor.SelectedIndex)
{
case 0:
arrowColor = Color.Green;
break;
case 1:
arrowColor = Color.Blue;
break;
case 2:
arrowColor = Color.Red;
break;
}
ticket = await Execute(() => _apiClient.OrderSend(symbol, cmd, volume, price, slippage, stoploss, takeprofit, comment, magic, expiration, arrowColor));
}
}
}
var ticket = await Execute(() => _apiClient.OrderSend(symbol, cmd, volume, price, slippage, stoploss, takeprofit, comment, magic, expiration, arrowColor));
PrintLog($"Sended order result: ticket = {ticket}");
}
@@ -1286,5 +1128,339 @@ namespace TestApiClientUI
var result = await Execute(() => _apiClient.TerminalInfoDouble(propId));
PrintLog($"TerminalInfoDouble: result = {result}");
}
private void checkBox2_CheckedChanged(object sender, EventArgs e)
{
var checkbox = sender as CheckBox;
if (checkbox == null)
return;
int expertHandle = 0;
if (checkbox.Checked)
{
if (listViewQuotes.SelectedItems.Count > 0)
{
expertHandle = int.Parse(listViewQuotes.SelectedItems[0].SubItems[3].Text);
}
}
_apiClient.ExecutorHandle = expertHandle;
}
//GetLastError
private async void button40_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.GetLastError);
PrintLog($"GetLastError: result = {result}");
RunOnUiThread(() => { textBoxErrorCode.Text = result.ToString(); });
}
//ErrorDescription
private async void button39_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxErrorCode.Text))
{
MessageBox.Show(@"Error code is not defined!");
textBoxErrorCode.Focus();
return;
}
int errorCode;
if (int.TryParse(textBoxErrorCode.Text, out errorCode) == false)
{
MessageBox.Show(@"Failed to parse error code!");
textBoxErrorCode.Focus();
return;
}
var result = await Execute(() => _apiClient.ErrorDescription(errorCode));
PrintLog($"ErrorDescription: code = {errorCode}, description = {result}");
}
//IsConnected
private async void button41_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.IsConnected);
PrintLog($"IsConnected: result = {result}");
}
//IsDemo
private async void button42_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.IsDemo);
PrintLog($"IsDemo: result = {result}");
}
//IsDllsAllowed
private async void button43_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.IsDllsAllowed);
PrintLog($"IsDllsAllowed: result = {result}");
}
//IsExpertEnabled
private async void button44_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.IsExpertEnabled);
PrintLog($"IsExpertEnabled: result = {result}");
}
//IsLibrariesAllowed
private async void button45_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.IsLibrariesAllowed);
PrintLog($"IsLibrariesAllowed: result = {result}");
}
//IsOptimization
private async void button46_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.IsOptimization);
PrintLog($"IsOptimization: result = {result}");
}
//IsStopped
private async void button47_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.IsStopped);
PrintLog($"IsStopped: result = {result}");
}
//IsTesting
private async void button48_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.IsTesting);
PrintLog($"IsTesting: result = {result}");
}
//IsTradeAllowed
private async void button49_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.IsTradeAllowed);
PrintLog($"IsTradeAllowed: result = {result}");
}
//IsTradeContextBusy
private async void button50_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.IsTradeContextBusy);
PrintLog($"IsTradeContextBusy: result = {result}");
}
//IsVisualMode
private async void button51_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.IsVisualMode);
PrintLog($"IsVisualMode: result = {result}");
}
//UninitializeReason
private async void button52_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.UninitializeReason);
PrintLog($"UninitializeReason: result = {result}");
}
//AccountBalance
private async void button3_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.AccountBalance);
PrintLog($"AccountBalance result: {result}");
}
//AccountCredit
private async void button53_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.AccountCredit);
PrintLog($"AccountCredit result: {result}");
}
//AccountCompany
private async void button54_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.AccountCompany);
PrintLog($"AccountCompany result: {result}");
}
//AccountCurrency
private async void button55_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.AccountCurrency);
PrintLog($"AccountCurrency result: {result}");
}
//AccountEquity
private async void button56_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.AccountEquity);
PrintLog($"AccountEquity result: {result}");
}
//AccountFreeMargin
private async void button57_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.AccountFreeMargin);
PrintLog($"AccountFreeMargin result: {result}");
}
//AccountFreeMarginCheck
private async void button58_Click(object sender, EventArgs e)
{
var symbol = textBoxAccountInfoSymbol.Text;
if (string.IsNullOrEmpty(symbol))
{
MessageBox.Show(@"Symbol is not defined!");
textBoxAccountInfoSymbol.Focus();
return;
}
double volume;
if (double.TryParse(textBoxAccountInfoVolume.Text, out volume) == false)
{
MessageBox.Show(@"Failed to parse volume value!");
textBoxAccountInfoVolume.Focus();
return;
}
TradeOperation cmd;
Enum.TryParse(comboBoxAccountInfoCmd.Text, out cmd);
var result = await Execute(() => _apiClient.AccountFreeMarginCheck(symbol, cmd, volume));
PrintLog($"AccountFreeMarginCheck result: {result}");
}
//AccountFreeMarginMode
private async void button59_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.AccountFreeMarginMode);
PrintLog($"AccountFreeMarginMode result: {result}");
}
//AccountLeverage
private async void button60_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.AccountLeverage);
PrintLog($"AccountLeverage result: {result}");
}
//AccountMargin
private async void button61_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.AccountMargin);
PrintLog($"AccountMargin result: {result}");
}
//AccountName
private async void button62_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.AccountName);
PrintLog($"AccountName result: {result}");
}
//AccountNumber
private async void button63_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.AccountNumber);
PrintLog($"AccountNumber result: {result}");
}
//AccountProfit
private async void button64_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.AccountProfit);
PrintLog($"AccountProfit result: {result}");
}
//AccountServer
private async void button65_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.AccountServer);
PrintLog($"AccountServer result: {result}");
}
//AccountStopoutLevel
private async void button66_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.AccountStopoutLevel);
PrintLog($"AccountStopoutLevel result: {result}");
}
//AccountStopoutMode
private async void button67_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.AccountStopoutMode);
PrintLog($"AccountStopoutMode result: {result}");
}
//CharID
private async void button37_Click(object sender, EventArgs e)
{
var result = await Execute(_apiClient.ChartId);
PrintLog($"CharID: result = {result}");
RunOnUiThread(() => textBoxChartId.Text = result.ToString());
}
//ChartRedraw
private async void button38_Click(object sender, EventArgs e)
{
await Execute(() => _apiClient.ChartRedraw());
PrintLog($"ChartRedraw: called.");
}
//ObjectCreate
private async void button4_Click(object sender, EventArgs e)
{
const long chartId = 0;
const string objectName = "label_object";
EnumObject objectType;
Enum.TryParse(comboBox11.Text, out objectType);
var result = await Execute(() => _apiClient.ObjectCreate(chartId, objectName, objectType, 0, null, 0));
PrintLog($"ObjectCreate result: {result}");
}
//ObjectName
private async void button68_Click(object sender, EventArgs e)
{
const long chartId = 0;
const int objectIndex = 0;
var result = await Execute(() => _apiClient.ObjectName(chartId, objectIndex));
PrintLog($"ObjectName result: {result}");
}
private void button69_Click(object sender, EventArgs e)
{
_apiClient.UnlockTicks();
}
private async void button70_Click(object sender, EventArgs e)
{
var login = textBoxAccountLogin.Text;
var password = textBoxAccountPassword.Text;
var host = textBoxAccountHost.Text;
if (string.IsNullOrEmpty(login))
{
MessageBox.Show(@"Login is not defined!", @"Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
textBoxAccountLogin.Focus();
return;
}
if (string.IsNullOrEmpty(password))
{
MessageBox.Show(@"Password is not defined!", @"Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
textBoxAccountPassword.Focus();
return;
}
if (string.IsNullOrEmpty(host))
{
MessageBox.Show(@"Host is not defined!", @"Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
textBoxAccountHost.Focus();
return;
}
var result = await Execute(() => _apiClient.ChangeAccount(login, password, host));
PrintLog($"ChangeAccount result: {result}");
}
}
}
+3 -3
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client" />
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
</startup>
</configuration>
</configuration>
@@ -1,7 +1,7 @@
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:4.0.30319.17929
' Runtime Version:4.0.30319.42000
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
@@ -1,7 +1,7 @@
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:4.0.30319.17929
' Runtime Version:4.0.30319.42000
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
@@ -11,6 +11,7 @@
Option Strict On
Option Explicit On
Imports System
Namespace My.Resources
@@ -21,20 +22,20 @@ Namespace My.Resources
'''<summary>
''' A strongly-typed resource class, for looking up localized strings, etc.
'''</summary>
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0"), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0"), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
Friend Module Resources
Private resourceMan As Global.System.Resources.ResourceManager
Private resourceCulture As Global.System.Globalization.CultureInfo
'''<summary>
''' Returns the cached ResourceManager instance used by this class.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
Get
If Object.ReferenceEquals(resourceMan, Nothing) Then
@@ -44,17 +45,17 @@ Namespace My.Resources
Return resourceMan
End Get
End Property
'''<summary>
''' Overrides the current thread's CurrentUICulture property for all
''' resource lookups using this strongly typed resource class.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend Property Culture() As Global.System.Globalization.CultureInfo
Get
Return resourceCulture
End Get
Set(ByVal value As Global.System.Globalization.CultureInfo)
Set
resourceCulture = value
End Set
End Property
@@ -1,7 +1,7 @@
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:4.0.30319.17929
' Runtime Version:4.0.30319.42000
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
@@ -13,42 +13,42 @@ Option Explicit On
Namespace My
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0"), _
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0"), _
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Partial Friend NotInheritable Class MySettings
Inherits Global.System.Configuration.ApplicationSettingsBase
Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings)
Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings)
#Region "My.Settings Auto-Save Functionality"
#If _MyType = "WindowsForms" Then
Private Shared addedHandler As Boolean
Private Shared addedHandler As Boolean
Private Shared addedHandlerLockObject As New Object
Private Shared addedHandlerLockObject As New Object
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs)
If My.Application.SaveMySettingsOnExit Then
My.Settings.Save()
End If
End Sub
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs)
If My.Application.SaveMySettingsOnExit Then
My.Settings.Save()
End If
End Sub
#End If
#End Region
Public Shared ReadOnly Property [Default]() As MySettings
Get
#If _MyType = "WindowsForms" Then
If Not addedHandler Then
SyncLock addedHandlerLockObject
If Not addedHandler Then
AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
addedHandler = True
End If
End SyncLock
End If
If Not addedHandler Then
SyncLock addedHandlerLockObject
If Not addedHandler Then
AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
addedHandler = True
End If
End SyncLock
End If
#End If
Return defaultInstance
End Get
@@ -13,8 +13,9 @@
<AssemblyName>TestMtApi</AssemblyName>
<FileAlignment>512</FileAlignment>
<MyType>WindowsForms</MyType>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
@@ -40,6 +41,7 @@
<OutputPath>bin\Debug\</OutputPath>
<DocumentationFile>TestMtApi.xml</DocumentationFile>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>x86</PlatformTarget>
@@ -50,6 +52,7 @@
<OutputPath>bin\Release\</OutputPath>
<DocumentationFile>TestMtApi.xml</DocumentationFile>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<OptionExplicit>On</OptionExplicit>
@@ -67,7 +70,6 @@
<ApplicationManifest>My Project\app.manifest</ApplicationManifest>
</PropertyGroup>
<ItemGroup>
<Reference Include="MtApi, Version=1.0.7.0, Culture=neutral, processorArchitecture=MSIL" />
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
@@ -126,6 +128,7 @@
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="My Project\app.manifest" />
<None Include="My Project\Application.myapp">
<Generator>MyApplicationCodeGenerator</Generator>
@@ -159,6 +162,12 @@
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\MtApi\MtApi.csproj">
<Project>{7a76c388-a8fb-4949-8170-24d4742e934e}</Project>
<Name>MtApi</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+163
View File
@@ -0,0 +1,163 @@
//+----------------------------------------------------------------------------+
//| mql4-auth.mqh |
//+----------------------------------------------------------------------------+
//| Built by Sergey Lukin |
//| contact@sergeylukin.com |
//+----------------------------------------------------------------------------+
#include <WinUser32.mqh>
#import "user32.dll"
int GetAncestor(int,int);
int GetLastActivePopup(int);
int GetDlgItem(int,int);
int GetParent(int hWnd);
#import
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool loginDialogIsOpen()
{
int hwnd=WindowHandle(Symbol(),Period());
int hMetaTrader,hLoginDialog=0;
// Retrieve Terminal Window Handler
while(!IsStopped())
{
hwnd=GetParent(hwnd);
if(hwnd==0) break;
hMetaTrader=hwnd;
}
hLoginDialog=GetLastActivePopup(hMetaTrader);
if(hLoginDialog!=0)
{
return(true);
} else {
return(false);
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void closeLoginDialog()
{
int hwnd=WindowHandle(Symbol(),Period());
int hMetaTrader,hLoginDialog=0,hCancelButton=0;
// Retrieve Terminal Window Handler
while(!IsStopped())
{
hwnd=GetParent(hwnd);
if(hwnd==0) break;
hMetaTrader=hwnd;
}
Sleep(60);
hLoginDialog=GetLastActivePopup(hMetaTrader);
if(hLoginDialog!=0)
{
hCancelButton=GetDlgItem(hLoginDialog,0x2);
if(hCancelButton!=0)
{
// Click "Cancel" button in Login Dialog
PostMessageA(hCancelButton,0x00F5,0,0);
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool auth(string login,string passwd,string server)
{
datetime s=TimeLocal();
int h = 0, e = 0, a = GetAncestor(WindowHandle(Symbol(), NULL), 2);
int i = 0;
PostMessageA(a,WM_COMMAND,35429,0);
while(e==0)
{
// Give us up to a minute to find the Login dialog
if(TimeLocal()-s>60)
{
return(false);
}
h=GetLastActivePopup(a);
// Select login field
e=GetDlgItem(h,0x49d);
Sleep(1);
}
// Press DELETE key many times in login field to remove current value
for(i=1; i<=100; i++)
{
PostMessageA(e,WM_KEYDOWN,0x2E,1);
}
// Iterate over characters in "login" string and pass them to login field one by one
char login_chars[];
string2CharsArray(login,login_chars);
for(i=0; i<ArraySize(login_chars); i++)
{
PostMessageA(e,WM_CHAR,login_chars[i],0);
}
// Select password field
e=GetDlgItem(h,0x4c4);
// Press DELETE key many times in password field to remove current value
for(i=1; i<=100; i++)
{
PostMessageA(e,WM_KEYDOWN,0x2E,1);
}
// Iterate over characters in "passwd" string and pass them to password field one by one
char password_chars[];
string2CharsArray(passwd,password_chars);
for(i=0; i<ArraySize(password_chars); i++)
{
PostMessageA(e,WM_CHAR,password_chars[i],0);
}
// Select server field
e=GetDlgItem(h,0x50d);
// Press DELETE key many times in server field to remove current value
for(i=1; i<=100; i++)
{
PostMessageA(e,WM_KEYDOWN,0x2E,1);
}
// Iterate over characters in "server" string and pass them to server field one by one
char server_chars[];
string2CharsArray(server,server_chars);
for(i=0; i<ArraySize(server_chars); i++)
{
PostMessageA(e,WM_CHAR,server_chars[i],0);
}
Sleep(2*1000);
// Press submit button
e=GetDlgItem(h,0x1);
SendMessageA(e,0x00F5,0,0);
return(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
/*
* Iterates over string and puts each character code in array
*/
void string2CharsArray(string myString,char &chars[])
{
int cnt=StringLen(myString);
ArrayResize(chars,cnt);
for(int i=0; i<cnt; i++)
{
chars[i]=StringGetChar(myString,i);
}
}
//+------------------------------------------------------------------+
BIN
View File
Binary file not shown.
+20 -5
View File
@@ -360,6 +360,7 @@ int executeCommand()
sendStringResponse(ExpertHandle, PositionGetSymbol(index));
}
break;
case 8: //PositionSelect
{
@@ -379,6 +380,7 @@ int executeCommand()
sendDoubleResponse(ExpertHandle, PositionGetDouble(property_id));
}
break;
case 10: //PositionGetInteger
{
@@ -1717,15 +1719,19 @@ int executeCommand()
case 68: //Print
{
string printMsg;
StringInit(printMsg, 1000, 0);
string printMsg;
StringInit(printMsg, 1000, 0);
getStringValue(ExpertHandle, 0, printMsg);
getStringValue(ExpertHandle, 0, printMsg);
Print(printMsg);
sendBooleanResponse(ExpertHandle, true);
Print(printMsg);
sendBooleanResponse(ExpertHandle, true);
}
break;
case 69: //PositionSelectByTicket
Execute_PositionSelectByTicket();
break;
default:
Print("Unknown command type = ", commandType);
@@ -1736,6 +1742,13 @@ int executeCommand()
return (commandType);
}
void Execute_PositionSelectByTicket()
{
ulong ticket;
getULongValue(ExpertHandle, 0, ticket);
sendBooleanResponse(ExpertHandle, PositionSelectByTicket(ticket));
}
void PrintParamError(string paramName)
{
Print("[ERROR] parameter: ", paramName);
@@ -1775,6 +1788,8 @@ void ReadMqlTradeRequestFromCommand(MqlTradeRequest& request)
request.expiration = (datetime)tmpEnumValue;
getStringValue(ExpertHandle, 14, commentValue);
request.comment = commentValue;
getULongValue(ExpertHandle, 15, request.position);
getULongValue(ExpertHandle, 16, request.position_by);
}
string BoolToString(bool value)