mirror of
https://github.com/vdemydiuk/mtapi.git
synced 2026-07-30 20:17:46 +00:00
Compare commits
36 Commits
mt4-1.0.32
...
auth
| Author | SHA1 | Date | |
|---|---|---|---|
| 515a12ab15 | |||
| 10e267d031 | |||
| abcd489367 | |||
| d630e61e3c | |||
| 280bab7faf | |||
| 26d270422b | |||
| 9cd2e3b18f | |||
| 50013c0c29 | |||
| ca49d23017 | |||
| 0346836d35 | |||
| 2cc41df01a | |||
| f05ade2cbf | |||
| d34524d77f | |||
| d06cc67a5d | |||
| 5b76bf0547 | |||
| 1c269f7339 | |||
| 21fb790d8c | |||
| 7c9a0aa8cc | |||
| 18ddf3df1c | |||
| a8832b79ba | |||
| 39146d68b2 | |||
| 5b03f01e9b | |||
| 8f5a1c8222 | |||
| f5f13a13cc | |||
| 9ef970cf1e | |||
| b5878ccb62 | |||
| 4a7bb6f2cb | |||
| 5abfeebc90 | |||
| e333164552 | |||
| 9a6968f618 | |||
| d63a53b8a9 | |||
| 7e821fcade | |||
| 88e2d22abe | |||
| fcfd741e5b | |||
| c722511c03 | |||
| 39599436ab |
@@ -107,7 +107,7 @@ int _stdcall initExpert(int expertHandle, int port, wchar_t* symbol, double bid,
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
MT5Handler^ mtHander = gcnew MT5Handler();
|
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)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
@@ -123,7 +123,7 @@ int _stdcall deinitExpert(int expertHandle, wchar_t* err)
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MtServerInstance::GetInstance()->DeinitExpert(expertHandle);
|
MtAdapter::GetInstance()->DeinitExpert(expertHandle);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
@@ -139,7 +139,7 @@ int _stdcall updateQuote(int expertHandle, wchar_t* symbol, double bid, double a
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MtServerInstance::GetInstance()->SendQuote(expertHandle, gcnew String(symbol), bid, ask);
|
MtAdapter::GetInstance()->SendQuote(expertHandle, gcnew String(symbol), bid, ask);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
@@ -155,7 +155,7 @@ int _stdcall sendIntResponse(int expertHandle, int response)
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseInt(response));
|
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseInt(response));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
@@ -169,7 +169,7 @@ int _stdcall sendLongResponse(int expertHandle, __int64 response)
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLong(response));
|
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLong(response));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
@@ -183,7 +183,7 @@ int _stdcall sendULongResponse(int expertHandle, unsigned __int64 response)
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseULong(response));
|
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseULong(response));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
@@ -199,7 +199,7 @@ int _stdcall sendBooleanResponse(int expertHandle, int response)
|
|||||||
{
|
{
|
||||||
bool value = (response != 0) ? true : false;
|
bool value = (response != 0) ? true : false;
|
||||||
|
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseBool(value));
|
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseBool(value));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
@@ -213,7 +213,7 @@ int _stdcall sendDoubleResponse(int expertHandle, double response)
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDouble(response));
|
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDouble(response));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
@@ -227,7 +227,7 @@ int _stdcall sendStringResponse(int expertHandle, wchar_t* response)
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseString(gcnew String(response)));
|
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseString(gcnew String(response)));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
@@ -241,7 +241,7 @@ int _stdcall sendVoidResponse(int expertHandle)
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, nullptr);
|
MtAdapter::GetInstance()->SendResponse(expertHandle, nullptr);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
@@ -262,7 +262,7 @@ int _stdcall sendDoubleArrayResponse(int expertHandle, double* values, int size)
|
|||||||
list[i] = values[i];
|
list[i] = values[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDoubleArray(list));
|
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDoubleArray(list));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
@@ -283,7 +283,7 @@ int _stdcall sendIntArrayResponse(int expertHandle, int* values, int size)
|
|||||||
list[i] = values[i];
|
list[i] = values[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseIntArray(list));
|
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseIntArray(list));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
@@ -304,7 +304,7 @@ int _stdcall sendLongArrayResponse(int expertHandle, __int64* values, int size)
|
|||||||
list[i] = values[i];
|
list[i] = values[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLongArray(list));
|
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLongArray(list));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
@@ -335,7 +335,7 @@ int _stdcall sendMqlRatesArrayResponse(int expertHandle, CMqlRates values[], int
|
|||||||
list[i] = rates;
|
list[i] = rates;
|
||||||
}
|
}
|
||||||
|
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlRatesArray(list));
|
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlRatesArray(list));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
@@ -357,7 +357,7 @@ int _stdcall sendMqlTickResponse(int expertHandle, CMqlTick* response, int size)
|
|||||||
mtResponse->last = response->last;
|
mtResponse->last = response->last;
|
||||||
mtResponse->volume = response->volume;
|
mtResponse->volume = response->volume;
|
||||||
|
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlTick(mtResponse));
|
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlTick(mtResponse));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
@@ -384,7 +384,7 @@ int _stdcall sendMqlBookInfoArrayResponse(int expertHandle, CMqlBookInfo values[
|
|||||||
list[i] = info;
|
list[i] = info;
|
||||||
}
|
}
|
||||||
|
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlBookInfoArray(list));
|
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlBookInfoArray(list));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
@@ -400,7 +400,7 @@ int _stdcall getCommandType(int expertHandle, int* res)
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
*res = MtServerInstance::GetInstance()->GetCommandType(expertHandle);
|
*res = MtAdapter::GetInstance()->GetCommandType(expertHandle);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
@@ -414,7 +414,7 @@ int _stdcall getIntValue(int expertHandle, int paramIndex, int* res)
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
*res = (int)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
*res = (int)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
@@ -428,7 +428,7 @@ int _stdcall getDoubleValue(int expertHandle, int paramIndex, double* res)
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
*res = (double)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
*res = (double)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
@@ -442,7 +442,7 @@ int _stdcall getStringValue(int expertHandle, int paramIndex, wchar_t* res)
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
convertSystemString(res, (String^)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex));
|
convertSystemString(res, (String^)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
@@ -456,7 +456,7 @@ int _stdcall getULongValue(int expertHandle, int paramIndex, unsigned __int64* r
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
*res = (unsigned long)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
*res = (unsigned long)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
@@ -470,7 +470,7 @@ int _stdcall getLongValue(int expertHandle, int paramIndex, __int64* res)
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
*res = (long)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
*res = (long)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
@@ -484,7 +484,7 @@ int _stdcall getBooleanValue(int expertHandle, int paramIndex, int* res)
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bool val = (bool)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
bool val = (bool)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
||||||
*res = val == true ? 1 : 0;
|
*res = val == true ? 1 : 0;
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
@@ -499,7 +499,7 @@ int _stdcall getUIntValue(int expertHandle, int paramIndex, unsigned int* res)
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
*res = (unsigned int)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
*res = (unsigned int)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
namespace MTApiService
|
namespace MTApiService
|
||||||
{
|
{
|
||||||
public interface ICommandManager
|
internal interface ICommandManager
|
||||||
{
|
{
|
||||||
void EnqueueCommandTask(MtCommandTask task);
|
MtCommandTask SendCommand(MtCommand task);
|
||||||
MtCommandTask DequeueCommandTask();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
namespace MTApiService
|
||||||
|
{
|
||||||
|
internal interface ITaskExecutor
|
||||||
|
{
|
||||||
|
void Execute(MtCommandTask task);
|
||||||
|
|
||||||
|
int Handle { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,7 +29,7 @@ namespace MTApiService
|
|||||||
|
|
||||||
var roller = new RollingFileAppender
|
var roller = new RollingFileAppender
|
||||||
{
|
{
|
||||||
AppendToFile = false,
|
AppendToFile = true,
|
||||||
File = $@"{System.IO.Path.GetTempPath()}{profileName}\Logs\{filename}",
|
File = $@"{System.IO.Path.GetTempPath()}{profileName}\Logs\{filename}",
|
||||||
Layout = patternLayout,
|
Layout = patternLayout,
|
||||||
PreserveLogFileNameExtension = true,
|
PreserveLogFileNameExtension = true,
|
||||||
@@ -41,10 +41,6 @@ namespace MTApiService
|
|||||||
roller.ActivateOptions();
|
roller.ActivateOptions();
|
||||||
hierarchy.Root.AddAppender(roller);
|
hierarchy.Root.AddAppender(roller);
|
||||||
|
|
||||||
var memory = new MemoryAppender();
|
|
||||||
memory.ActivateOptions();
|
|
||||||
hierarchy.Root.AddAppender(memory);
|
|
||||||
|
|
||||||
#if (DEBUG)
|
#if (DEBUG)
|
||||||
hierarchy.Root.Level = Level.Debug;
|
hierarchy.Root.Level = Level.Debug;
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -62,6 +62,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="ICommandManager.cs" />
|
<Compile Include="ICommandManager.cs" />
|
||||||
<Compile Include="IMetaTraderHandler.cs" />
|
<Compile Include="IMetaTraderHandler.cs" />
|
||||||
|
<Compile Include="ITaskExecutor.cs" />
|
||||||
<Compile Include="LogConfigurator.cs" />
|
<Compile Include="LogConfigurator.cs" />
|
||||||
<Compile Include="MtCommandEventArgs.cs" />
|
<Compile Include="MtCommandEventArgs.cs" />
|
||||||
<Compile Include="IDisposableChannel.cs" />
|
<Compile Include="IDisposableChannel.cs" />
|
||||||
@@ -78,11 +79,11 @@
|
|||||||
<Compile Include="MtConnectionProfile.cs" />
|
<Compile Include="MtConnectionProfile.cs" />
|
||||||
<Compile Include="MtExecutorManager.cs" />
|
<Compile Include="MtExecutorManager.cs" />
|
||||||
<Compile Include="MtExpert.cs" />
|
<Compile Include="MtExpert.cs" />
|
||||||
<Compile Include="MtInstrument.cs" />
|
<Compile Include="MtQuote.cs" />
|
||||||
<Compile Include="MtResponse.cs" />
|
<Compile Include="MtResponse.cs" />
|
||||||
<Compile Include="MtServer.cs" />
|
<Compile Include="MtServer.cs" />
|
||||||
<Compile Include="MtCommand.cs" />
|
<Compile Include="MtCommand.cs" />
|
||||||
<Compile Include="MtServerInstance.cs" />
|
<Compile Include="MtAdapter.cs" />
|
||||||
<Compile Include="MtService.cs" />
|
<Compile Include="MtService.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
Executable → Regular
+53
-9
@@ -4,13 +4,13 @@ using log4net;
|
|||||||
|
|
||||||
namespace MTApiService
|
namespace MTApiService
|
||||||
{
|
{
|
||||||
public class MtServerInstance
|
public class MtAdapter
|
||||||
{
|
{
|
||||||
#region Fields
|
#region Fields
|
||||||
private const string LogProfileName = "MtApiService";
|
private const string LogProfileName = "MtApiService";
|
||||||
|
|
||||||
private static readonly ILog Log = LogManager.GetLogger(typeof(MtServerInstance));
|
private static readonly ILog Log = LogManager.GetLogger(typeof(MtAdapter));
|
||||||
private static readonly MtServerInstance Instance = new MtServerInstance();
|
private static readonly MtAdapter Instance = new MtAdapter();
|
||||||
|
|
||||||
private readonly Dictionary<int, MtServer> _servers = new Dictionary<int, MtServer>();
|
private readonly Dictionary<int, MtServer> _servers = new Dictionary<int, MtServer>();
|
||||||
private readonly Dictionary<int, MtExpert> _experts = new Dictionary<int, MtExpert>();
|
private readonly Dictionary<int, MtExpert> _experts = new Dictionary<int, MtExpert>();
|
||||||
@@ -18,16 +18,16 @@ namespace MTApiService
|
|||||||
|
|
||||||
#region Init Instance
|
#region Init Instance
|
||||||
|
|
||||||
private MtServerInstance()
|
private MtAdapter()
|
||||||
{
|
{
|
||||||
LogConfigurator.Setup(LogProfileName);
|
LogConfigurator.Setup(LogProfileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MtServerInstance()
|
static MtAdapter()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MtServerInstance GetInstance()
|
public static MtAdapter GetInstance()
|
||||||
{
|
{
|
||||||
return Instance;
|
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)
|
lock (_experts)
|
||||||
{
|
{
|
||||||
@@ -111,7 +111,7 @@ namespace MTApiService
|
|||||||
|
|
||||||
if (expert != null)
|
if (expert != null)
|
||||||
{
|
{
|
||||||
expert.Quote = new MtQuote(symbol, bid, ask);
|
expert.Quote = new MtQuote { Instrument = symbol, Bid = bid, Ask = ask, ExpertHandle = expertHandle };
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -133,7 +133,7 @@ namespace MTApiService
|
|||||||
|
|
||||||
if (expert != null)
|
if (expert != null)
|
||||||
{
|
{
|
||||||
expert.SendEvent(new MtEvent(eventType, payload));
|
expert.SendEvent(new MtEvent { EventType = eventType, Payload = payload, ExpertHandle = expertHandle });
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -208,6 +208,50 @@ namespace MTApiService
|
|||||||
|
|
||||||
return retval;
|
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
|
#endregion
|
||||||
|
|
||||||
#region Private Methods
|
#region Private Methods
|
||||||
@@ -11,13 +11,13 @@ namespace MTApiService
|
|||||||
: base(callbackContext, binding, remoteAddress)
|
: base(callbackContext, binding, remoteAddress)
|
||||||
{
|
{
|
||||||
InnerDuplexChannel.Faulted += InnerDuplexChannel_Faulted;
|
InnerDuplexChannel.Faulted += InnerDuplexChannel_Faulted;
|
||||||
InnerDuplexChannel.Open();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region IMtApi Members
|
#region IMtApi Members
|
||||||
|
|
||||||
public bool Connect()
|
public bool Connect()
|
||||||
{
|
{
|
||||||
|
InnerDuplexChannel.Open();
|
||||||
return Channel.Connect();
|
return Channel.Connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+42
-90
@@ -6,38 +6,33 @@ using log4net;
|
|||||||
|
|
||||||
namespace MTApiService
|
namespace MTApiService
|
||||||
{
|
{
|
||||||
[CallbackBehavior(UseSynchronizationContext = false)]
|
[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)]
|
||||||
public class MtClient: IMtApiCallback, IDisposable
|
public class MtClient : IMtApiCallback, IDisposable
|
||||||
{
|
{
|
||||||
private const string ServiceName = "MtApiService";
|
private const string ServiceName = "MtApiService";
|
||||||
|
|
||||||
public delegate void MtQuoteHandler(MtQuote quote);
|
public delegate void MtQuoteHandler(MtQuote quote);
|
||||||
|
public delegate void MtEventHandler(MtEvent e);
|
||||||
|
|
||||||
#region Fields
|
#region Fields
|
||||||
private static readonly ILog Log = LogManager.GetLogger(typeof(MtClient));
|
private static readonly ILog Log = LogManager.GetLogger(typeof(MtClient));
|
||||||
|
|
||||||
private MtApiProxy _proxy;
|
private readonly MtApiProxy _proxy;
|
||||||
private bool _isConnected;
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Public Methods
|
#region ctor
|
||||||
public void Open(string host, int port)
|
public MtClient(string host, int port)
|
||||||
{
|
{
|
||||||
Log.DebugFormat("Open: begin. host = {0}, port = {1}", host, port);
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(host))
|
if (string.IsNullOrEmpty(host))
|
||||||
throw new ArgumentNullException(nameof(host), "host is null or empty");
|
throw new ArgumentNullException(nameof(host), "host is null or empty");
|
||||||
|
|
||||||
if (port < 0 || port > 65536)
|
if (port < 0 || port > 65536)
|
||||||
throw new ArgumentOutOfRangeException(nameof(port), "port value is invalid");
|
throw new ArgumentOutOfRangeException(nameof(port), "port value is invalid");
|
||||||
|
|
||||||
var urlService = $"net.tcp://{host}:{port}/{ServiceName}";
|
Host = host;
|
||||||
|
Port = port;
|
||||||
|
|
||||||
if (_proxy != null)
|
var urlService = $"net.tcp://{host}:{port}/{ServiceName}";
|
||||||
{
|
|
||||||
Log.Warn("Open: end. _proxy is not null.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var bind = new NetTcpBinding(SecurityMode.None)
|
var bind = new NetTcpBinding(SecurityMode.None)
|
||||||
{
|
{
|
||||||
@@ -55,28 +50,19 @@ namespace MTApiService
|
|||||||
MaxNameTableCharCount = 2147483647
|
MaxNameTableCharCount = 2147483647
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// Commented next statement since it is not required
|
|
||||||
|
|
||||||
_proxy = new MtApiProxy(new InstanceContext(this), bind, new EndpointAddress(urlService));
|
_proxy = new MtApiProxy(new InstanceContext(this), bind, new EndpointAddress(urlService));
|
||||||
_proxy.Faulted += ProxyFaulted;
|
_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)
|
if (port < 0 || port > 65536)
|
||||||
throw new ArgumentOutOfRangeException(nameof(port), "port value is invalid");
|
throw new ArgumentOutOfRangeException(nameof(port), "port value is invalid");
|
||||||
|
|
||||||
var urlService = $"net.pipe://localhost/{ServiceName}_{port}";
|
Port = port;
|
||||||
|
|
||||||
if (_proxy != null)
|
var urlService = $"net.pipe://localhost/{ServiceName}_{port}";
|
||||||
{
|
|
||||||
Log.Warn("Open: end. _proxy is not null.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var bind = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
|
var bind = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
|
||||||
{
|
{
|
||||||
@@ -94,61 +80,40 @@ namespace MTApiService
|
|||||||
MaxNameTableCharCount = 2147483647
|
MaxNameTableCharCount = 2147483647
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// Commented next statement since it is not required
|
|
||||||
|
|
||||||
_proxy = new MtApiProxy(new InstanceContext(this), bind, new EndpointAddress(urlService));
|
_proxy = new MtApiProxy(new InstanceContext(this), bind, new EndpointAddress(urlService));
|
||||||
_proxy.Faulted += ProxyFaulted;
|
_proxy.Faulted += ProxyFaulted;
|
||||||
|
|
||||||
Log.Debug("Open: end.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Close()
|
|
||||||
{
|
|
||||||
Log.Debug("Close: begin.");
|
|
||||||
|
|
||||||
if (_proxy != null)
|
#endregion
|
||||||
{
|
|
||||||
_proxy.Faulted -= ProxyFaulted;
|
|
||||||
_proxy.Dispose();
|
|
||||||
_proxy = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
_isConnected = false;
|
|
||||||
|
|
||||||
Log.Debug("Close: end.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#region Public Methods
|
||||||
/// <exception cref="CommunicationException">Thrown when connection failed</exception>
|
/// <exception cref="CommunicationException">Thrown when connection failed</exception>
|
||||||
public void Connect()
|
public void Connect()
|
||||||
{
|
{
|
||||||
Log.Debug("Connect: begin.");
|
Log.Debug("Connect: begin.");
|
||||||
|
|
||||||
if (_proxy == null)
|
if (_proxy.State != CommunicationState.Created)
|
||||||
{
|
{
|
||||||
Log.Error("Connect: _proxy is not defined.");
|
Log.ErrorFormat("Connected: end. Client has invalid state {0}", _proxy.State);
|
||||||
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.");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool coonected;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_isConnected = _proxy.Connect();
|
coonected = _proxy.Connect();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.ErrorFormat("Connect: Exception - {0}", ex.Message);
|
Log.ErrorFormat("Connect: Exception - {0}", ex.Message);
|
||||||
|
|
||||||
Close();
|
|
||||||
|
|
||||||
throw new CommunicationException($"Connection failed to service. {ex.Message}");
|
throw new CommunicationException($"Connection failed to service. {ex.Message}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_isConnected == false)
|
if (coonected == false)
|
||||||
{
|
{
|
||||||
Log.Error("Connect: end. Connection failed.");
|
Log.Error("Connect: end. Connection failed.");
|
||||||
throw new CommunicationException("Connection failed");
|
throw new CommunicationException("Connection failed");
|
||||||
@@ -163,72 +128,60 @@ namespace MTApiService
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_isConnected = false;
|
_proxy.Disconnect();
|
||||||
|
|
||||||
_proxy?.Disconnect();
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.ErrorFormat("Disconnect: Exception - {0}", ex.Message);
|
Log.ErrorFormat("Disconnect: Exception - {0}", ex.Message);
|
||||||
|
|
||||||
Close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.Debug("Disconnect: end.");
|
Log.Debug("Disconnect: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <exception cref="CommunicationException">Thrown when connection failed</exception>
|
/// <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);
|
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.");
|
Log.Error("SendCommand: Client is not connected.");
|
||||||
throw new CommunicationException("Client is not connected.");
|
throw new CommunicationException("Client is not connected.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_proxy == null)
|
MtResponse result;
|
||||||
{
|
|
||||||
Log.Error("SendCommand: Proxy is not defined.");
|
|
||||||
throw new CommunicationException("Proxy is not defined.");
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
result = _proxy.SendCommand(new MtCommand(commandType, parameters));
|
result = _proxy.SendCommand(new MtCommand {
|
||||||
|
CommandType = commandType,
|
||||||
|
Parameters = parameters,
|
||||||
|
NamedParams = namedParams,
|
||||||
|
ExpertHandle = expertHandle});
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.ErrorFormat("SendCommand: Exception - {0}", ex.Message);
|
Log.ErrorFormat("SendCommand: Exception - {0}", ex.Message);
|
||||||
|
|
||||||
Close();
|
|
||||||
|
|
||||||
throw new CommunicationException("Service connection failed! " + ex.Message);
|
throw new CommunicationException("Service connection failed! " + ex.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.DebugFormat("SendCommand: end. result = {0}", result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <exception cref="CommunicationException">Thrown when connection failed</exception>
|
/// <exception cref="CommunicationException">Thrown when connection failed</exception>
|
||||||
public IEnumerable<MtQuote> GetQuotes()
|
public List<MtQuote> GetQuotes()
|
||||||
{
|
{
|
||||||
Log.Debug("GetQuotes: begin.");
|
Log.Debug("GetQuotes: begin.");
|
||||||
|
|
||||||
if (_isConnected == false)
|
if (IsConnected == false)
|
||||||
{
|
{
|
||||||
Log.Warn("GetQuotes: end. Client is not connected.");
|
Log.Warn("GetQuotes: end. Client is not connected.");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_proxy == null)
|
|
||||||
{
|
|
||||||
Log.Warn("GetQuotes: end. _proxy is not defined.");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<MtQuote> result;
|
List<MtQuote> result;
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -239,8 +192,6 @@ namespace MTApiService
|
|||||||
{
|
{
|
||||||
Log.ErrorFormat("GetQuotes: Exception - {0}", ex.Message);
|
Log.ErrorFormat("GetQuotes: Exception - {0}", ex.Message);
|
||||||
|
|
||||||
Close();
|
|
||||||
|
|
||||||
throw new CommunicationException($"Service connection failed! {ex.Message}");
|
throw new CommunicationException($"Service connection failed! {ex.Message}");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,18 +237,17 @@ namespace MTApiService
|
|||||||
{
|
{
|
||||||
Log.Debug("OnServerStopped: begin.");
|
Log.Debug("OnServerStopped: begin.");
|
||||||
|
|
||||||
Close();
|
|
||||||
ServerDisconnected?.Invoke(this, EventArgs.Empty);
|
ServerDisconnected?.Invoke(this, EventArgs.Empty);
|
||||||
|
|
||||||
Log.Debug("OnServerStopped: end.");
|
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.");
|
Log.Debug("OnMtEvent: end.");
|
||||||
}
|
}
|
||||||
@@ -305,7 +255,10 @@ namespace MTApiService
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Properties
|
#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
|
#endregion
|
||||||
|
|
||||||
@@ -315,7 +268,6 @@ namespace MTApiService
|
|||||||
{
|
{
|
||||||
Log.Debug("ProxyFaulted: begin.");
|
Log.Debug("ProxyFaulted: begin.");
|
||||||
|
|
||||||
Close();
|
|
||||||
ServerFailed?.Invoke(this, EventArgs.Empty);
|
ServerFailed?.Invoke(this, EventArgs.Empty);
|
||||||
|
|
||||||
Log.Debug("ProxyFaulted: end.");
|
Log.Debug("ProxyFaulted: end.");
|
||||||
@@ -329,7 +281,7 @@ namespace MTApiService
|
|||||||
{
|
{
|
||||||
Log.Debug("Dispose: begin.");
|
Log.Debug("Dispose: begin.");
|
||||||
|
|
||||||
Close();
|
_proxy.Dispose();
|
||||||
|
|
||||||
Log.Debug("Dispose: end.");
|
Log.Debug("Dispose: end.");
|
||||||
}
|
}
|
||||||
@@ -342,7 +294,7 @@ namespace MTApiService
|
|||||||
public event MtQuoteHandler QuoteUpdated;
|
public event MtQuoteHandler QuoteUpdated;
|
||||||
public event EventHandler ServerDisconnected;
|
public event EventHandler ServerDisconnected;
|
||||||
public event EventHandler ServerFailed;
|
public event EventHandler ServerFailed;
|
||||||
public event EventHandler<MtEventArgs> MtEventReceived;
|
public event MtEventHandler MtEventReceived;
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,27 @@
|
|||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace MTApiService
|
namespace MTApiService
|
||||||
{
|
{
|
||||||
[DataContract]
|
[DataContract]
|
||||||
public class MtCommand
|
public class MtCommand
|
||||||
{
|
{
|
||||||
public MtCommand(int commandType, ArrayList parameters)
|
[DataMember]
|
||||||
{
|
public int CommandType { get; set; }
|
||||||
CommandType = commandType;
|
|
||||||
Parameters = parameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public int CommandType { get; private set; }
|
public ArrayList Parameters { get; set; }
|
||||||
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public ArrayList Parameters { get; private set; }
|
public Dictionary<string, object> NamedParams { get; set; }
|
||||||
|
|
||||||
|
[DataMember]
|
||||||
|
public int ExpertHandle { get; set; }
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return $"CommandType = {CommandType}";
|
return $"CommandType = {CommandType}; ExpertHandle = {ExpertHandle}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-18
@@ -7,30 +7,17 @@ namespace MTApiService
|
|||||||
public class MtEvent
|
public class MtEvent
|
||||||
{
|
{
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public int EventType { get; private set; }
|
public int EventType { get; internal set; }
|
||||||
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public string Payload { get; private set; }
|
public string Payload { get; internal set; }
|
||||||
|
|
||||||
public MtEvent(int eventType, string payload)
|
[DataMember]
|
||||||
{
|
public int ExpertHandle { get; internal set; }
|
||||||
EventType = eventType;
|
|
||||||
Payload = payload;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
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; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,14 +4,13 @@ using log4net;
|
|||||||
|
|
||||||
namespace MTApiService
|
namespace MTApiService
|
||||||
{
|
{
|
||||||
internal class MtCommandExecutorManager : ICommandManager
|
internal class MtExecutorManager : ICommandManager
|
||||||
{
|
{
|
||||||
#region Private Fields
|
#region Private Fields
|
||||||
private static readonly ILog Log = LogManager.GetLogger(typeof(MtCommandExecutorManager));
|
private static readonly ILog Log = LogManager.GetLogger(typeof(MtExecutorManager));
|
||||||
|
|
||||||
private readonly List<MtExpert> _commandExecutors = new List<MtExpert>();
|
|
||||||
private readonly Queue<MtCommandTask> _commandTasks = new Queue<MtCommandTask>();
|
|
||||||
|
|
||||||
|
private readonly List<ITaskExecutor> _executorList = new List<ITaskExecutor>();
|
||||||
|
private readonly Dictionary<int, ITaskExecutor> _executorMap = new Dictionary<int, ITaskExecutor>();
|
||||||
private readonly object _locker = new object();
|
private readonly object _locker = new object();
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -23,149 +22,94 @@ namespace MTApiService
|
|||||||
|
|
||||||
lock (_locker)
|
lock (_locker)
|
||||||
{
|
{
|
||||||
_commandExecutors.Clear();
|
_executorList.Clear();
|
||||||
_commandTasks.Clear();
|
_executorMap.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.Debug("Stop: end.");
|
Log.Debug("Stop: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddCommandExecutor(MtExpert commandExecutor)
|
public void AddExecutor(ITaskExecutor executor)
|
||||||
{
|
{
|
||||||
if (commandExecutor == null)
|
if (executor == null)
|
||||||
throw new ArgumentNullException(nameof(commandExecutor));
|
throw new ArgumentNullException(nameof(executor));
|
||||||
|
|
||||||
Log.DebugFormat("AddCommandExecutor: begin. commandExecutor = {0}", commandExecutor);
|
Log.DebugFormat("AddExecutor: begin. executor = {0}", executor);
|
||||||
|
|
||||||
var notify = false;
|
|
||||||
lock (_locker)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_commandExecutors.Add(commandExecutor);
|
_executorList.Add(executor);
|
||||||
if (_commandTasks.Count > 0)
|
_executorMap[executor.Handle] = executor;
|
||||||
{
|
|
||||||
notify = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
commandExecutor.CommandExecuted += CommandExecutor_CommandExecuted;
|
|
||||||
commandExecutor.CommandManager = this;
|
|
||||||
|
|
||||||
if (notify)
|
|
||||||
{
|
|
||||||
NotifyCommandReady();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.Debug("AddCommandExecutor: end.");
|
Log.Debug("AddCommandExecutor: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveCommandExecutor(MtExpert commandExecutor)
|
public void RemoveExecutor(ITaskExecutor executor)
|
||||||
{
|
{
|
||||||
if (commandExecutor == null)
|
if (executor == null)
|
||||||
throw new ArgumentNullException(nameof(commandExecutor));
|
throw new ArgumentNullException(nameof(executor));
|
||||||
|
|
||||||
Log.DebugFormat("RemoveCommandExecutor: begin. commandExecutor = {0}", commandExecutor);
|
Log.DebugFormat("RemoveExecutor: begin. executor = {0}", executor);
|
||||||
|
|
||||||
var notify = false;
|
|
||||||
lock (_locker)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_commandExecutors.Remove(commandExecutor);
|
_executorList.Remove(executor);
|
||||||
if (_commandTasks.Count > 0)
|
_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;
|
if (executor == null)
|
||||||
commandExecutor.CommandManager = null;
|
|
||||||
|
|
||||||
if (notify)
|
|
||||||
{
|
{
|
||||||
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
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+91
-52
@@ -1,18 +1,20 @@
|
|||||||
using System;
|
using System;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace MTApiService
|
namespace MTApiService
|
||||||
{
|
{
|
||||||
public class MtExpert
|
internal class MtExpert: ITaskExecutor
|
||||||
{
|
{
|
||||||
public delegate void MtQuoteHandler(MtExpert expert, MtQuote quote);
|
public delegate void MtQuoteHandler(MtExpert expert, MtQuote quote);
|
||||||
|
public delegate void MtEventHandler(MtExpert expert, MtEvent e);
|
||||||
|
|
||||||
#region Private Fields
|
#region Private Fields
|
||||||
private static readonly ILog Log = LogManager.GetLogger(typeof(MtExpert));
|
private static readonly ILog Log = LogManager.GetLogger(typeof(MtExpert));
|
||||||
|
|
||||||
private readonly IMetaTraderHandler _mtHadler;
|
private readonly IMetaTraderHandler _mtHadler;
|
||||||
private MtCommandTask _commandTask;
|
private MtCommandTask _currentTask;
|
||||||
private ICommandManager _commandManager;
|
private readonly Queue<MtCommandTask> _taskQueue = new Queue<MtCommandTask>();
|
||||||
private readonly object _locker = new object();
|
private readonly object _locker = new object();
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -41,9 +43,8 @@ namespace MTApiService
|
|||||||
{
|
{
|
||||||
Log.DebugFormat("SendResponse: begin. response = {0}", response);
|
Log.DebugFormat("SendResponse: begin. response = {0}", response);
|
||||||
|
|
||||||
_commandTask.SetResult(response);
|
_currentTask.SetResult(response);
|
||||||
_commandTask = null;
|
_currentTask = null;
|
||||||
FireOnCommandExecuted();
|
|
||||||
|
|
||||||
Log.Debug("SendResponse: end.");
|
Log.Debug("SendResponse: end.");
|
||||||
}
|
}
|
||||||
@@ -52,20 +53,16 @@ namespace MTApiService
|
|||||||
{
|
{
|
||||||
Log.Debug("GetCommandType: called.");
|
Log.Debug("GetCommandType: called.");
|
||||||
|
|
||||||
var commandManager = CommandManager;
|
_currentTask = DequeueTask();
|
||||||
if (commandManager != null)
|
|
||||||
{
|
|
||||||
_commandTask = commandManager.DequeueCommandTask();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _commandTask?.Command?.CommandType ?? 0;
|
return _currentTask?.Command?.CommandType ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public object GetCommandParameter(int index)
|
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)
|
if (command?.Parameters != null && index >= 0 && index < command.Parameters.Count)
|
||||||
{
|
{
|
||||||
return command.Parameters[index];
|
return command.Parameters[index];
|
||||||
@@ -74,6 +71,46 @@ namespace MTApiService
|
|||||||
return null;
|
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)
|
public void SendEvent(MtEvent mtEvent)
|
||||||
{
|
{
|
||||||
Log.DebugFormat("SendEvent: begin. event = {0}", mtEvent);
|
Log.DebugFormat("SendEvent: begin. event = {0}", mtEvent);
|
||||||
@@ -90,7 +127,22 @@ namespace MTApiService
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region ITaskExecutor
|
||||||
|
|
||||||
|
public void Execute(MtCommandTask task)
|
||||||
|
{
|
||||||
|
lock (_taskQueue)
|
||||||
|
{
|
||||||
|
_taskQueue.Enqueue(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
NotifyCommandReady();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
|
|
||||||
private MtQuote _quote;
|
private MtQuote _quote;
|
||||||
public 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
|
#endregion
|
||||||
|
|
||||||
#region Private Methods
|
#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);
|
_mtHadler.SendTickToMetaTrader(Handle);
|
||||||
|
|
||||||
|
Log.Debug("NotifyCommandReady: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FireOnQuoteChanged(MtQuote quote)
|
private void FireOnQuoteChanged(MtQuote quote)
|
||||||
@@ -180,22 +225,16 @@ namespace MTApiService
|
|||||||
Deinited?.Invoke(this, EventArgs.Empty);
|
Deinited?.Invoke(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FireOnCommandExecuted()
|
|
||||||
{
|
|
||||||
CommandExecuted?.Invoke(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void FireOnMtEvent(MtEvent mtEvent)
|
private void FireOnMtEvent(MtEvent mtEvent)
|
||||||
{
|
{
|
||||||
OnMtEvent?.Invoke(this, new MtEventArgs(mtEvent));
|
OnMtEvent?.Invoke(this, mtEvent);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
public event EventHandler Deinited;
|
public event EventHandler Deinited;
|
||||||
public event MtQuoteHandler QuoteChanged;
|
public event MtQuoteHandler QuoteChanged;
|
||||||
public event EventHandler CommandExecuted;
|
public event MtEventHandler OnMtEvent;
|
||||||
public event EventHandler<MtEventArgs> OnMtEvent;
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,7 +12,8 @@ namespace MTApiService
|
|||||||
{
|
{
|
||||||
static IEnumerable<Type> GetKnownTypes()
|
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(MtResponseString), typeof(MtResponseBool),
|
||||||
typeof(MtResponseLong), typeof(MtResponseULong),
|
typeof(MtResponseLong), typeof(MtResponseULong),
|
||||||
typeof(MtResponseDoubleArray), typeof(MtResponseIntArray),
|
typeof(MtResponseDoubleArray), typeof(MtResponseIntArray),
|
||||||
@@ -22,6 +23,28 @@ namespace MTApiService
|
|||||||
}
|
}
|
||||||
|
|
||||||
public abstract object GetValue();
|
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]
|
[DataContract]
|
||||||
|
|||||||
+28
-11
@@ -21,7 +21,7 @@ namespace MTApiService
|
|||||||
|
|
||||||
private readonly MtService _service;
|
private readonly MtService _service;
|
||||||
private readonly List<ServiceHost> _hosts = new List<ServiceHost>();
|
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>();
|
private readonly List<MtExpert> _experts = new List<MtExpert>();
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -62,8 +62,16 @@ namespace MTApiService
|
|||||||
}
|
}
|
||||||
|
|
||||||
//init local pipe host
|
//init local pipe host
|
||||||
var localUrl = CreateConnectionAddress(null, port, true);
|
var localPipeUrl = CreateConnectionAddress(null, port, true);
|
||||||
var localServiceHost = CreateServiceHost(localUrl, 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)
|
if (localServiceHost != null)
|
||||||
{
|
{
|
||||||
_hosts.Add(localServiceHost);
|
_hosts.Add(localServiceHost);
|
||||||
@@ -149,7 +157,7 @@ namespace MTApiService
|
|||||||
_experts.Add(expert);
|
_experts.Add(expert);
|
||||||
}
|
}
|
||||||
|
|
||||||
_executorManager.AddCommandExecutor(expert);
|
_executorManager.AddExecutor(expert);
|
||||||
|
|
||||||
_service.OnQuoteAdded(expert.Quote);
|
_service.OnQuoteAdded(expert.Quote);
|
||||||
|
|
||||||
@@ -170,11 +178,20 @@ namespace MTApiService
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var task = new MtCommandTask(command);
|
var task = _executorManager.SendCommand(command);
|
||||||
_executorManager.EnqueueCommandTask(task);
|
|
||||||
|
|
||||||
//wait for execute command in MetaTrader
|
//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;
|
return response;
|
||||||
}
|
}
|
||||||
@@ -371,7 +388,7 @@ namespace MTApiService
|
|||||||
expertsCount = _experts.Count;
|
expertsCount = _experts.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
_executorManager.RemoveCommandExecutor(expert);
|
_executorManager.RemoveExecutor(expert);
|
||||||
|
|
||||||
expert.Deinited -= expert_Deinited;
|
expert.Deinited -= expert_Deinited;
|
||||||
expert.QuoteChanged -= expert_QuoteChanged;
|
expert.QuoteChanged -= expert_QuoteChanged;
|
||||||
@@ -398,11 +415,11 @@ namespace MTApiService
|
|||||||
Log.Debug("expert_QuoteChanged: end.");
|
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.");
|
Log.Debug("Expert_OnMtEvent: end.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ namespace MTApiService
|
|||||||
|
|
||||||
if (callback == null)
|
if (callback == null)
|
||||||
{
|
{
|
||||||
Log.Warn("Connect: end. Callback is not definded.");
|
Log.Warn("Connect: end. Callback is not defined.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ namespace MTApiService
|
|||||||
|
|
||||||
public void QuoteUpdate(MtQuote quote)
|
public void QuoteUpdate(MtQuote quote)
|
||||||
{
|
{
|
||||||
Log.Debug("QuoteUpdate: begin.");
|
Log.DebugFormat("QuoteUpdate: begin. quote = {0}", quote);
|
||||||
|
|
||||||
ExecuteCallbackAction(a => a.OnQuoteUpdate(quote));
|
ExecuteCallbackAction(a => a.OnQuoteUpdate(quote));
|
||||||
|
|
||||||
@@ -167,7 +167,7 @@ namespace MTApiService
|
|||||||
|
|
||||||
public void OnQuoteAdded(MtQuote quote)
|
public void OnQuoteAdded(MtQuote quote)
|
||||||
{
|
{
|
||||||
Log.Debug("OnQuoteAdded: begin.");
|
Log.DebugFormat("OnQuoteAdded: begin. quote = {0}", quote);
|
||||||
|
|
||||||
ExecuteCallbackAction(a => a.OnQuoteAdded(quote));
|
ExecuteCallbackAction(a => a.OnQuoteAdded(quote));
|
||||||
|
|
||||||
@@ -176,18 +176,18 @@ namespace MTApiService
|
|||||||
|
|
||||||
public void OnQuoteRemoved(MtQuote quote)
|
public void OnQuoteRemoved(MtQuote quote)
|
||||||
{
|
{
|
||||||
Log.Debug("OnQuoteRemoved: begin.");
|
Log.DebugFormat("OnQuoteRemoved: begin. quote = {0}", quote);
|
||||||
|
|
||||||
ExecuteCallbackAction(a => a.OnQuoteRemoved(quote));
|
ExecuteCallbackAction(a => a.OnQuoteRemoved(quote));
|
||||||
|
|
||||||
Log.Debug("OnQuoteRemoved: end.");
|
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.");
|
Log.Debug("OnMtEvent: end.");
|
||||||
}
|
}
|
||||||
|
|||||||
Executable → Regular
+2
-2
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.0.23.0")]
|
[assembly: AssemblyVersion("1.0.27.0")]
|
||||||
[assembly: AssemblyFileVersion("1.0.23.0")]
|
[assembly: AssemblyFileVersion("1.0.27.0")]
|
||||||
+179
-199
@@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
#include "MT4Handler.h"
|
#include "MT4Handler.h"
|
||||||
#include "Windows.h"
|
#include "Windows.h"
|
||||||
#include < vcclr.h >
|
#include <vcclr.h>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
using namespace System;
|
using namespace System;
|
||||||
using namespace MTApiService;
|
using namespace MTApiService;
|
||||||
@@ -17,6 +18,8 @@ using namespace System::IO;
|
|||||||
using namespace System::Collections::Generic;
|
using namespace System::Collections::Generic;
|
||||||
using namespace System::Diagnostics;
|
using namespace System::Diagnostics;
|
||||||
|
|
||||||
|
#define _DLLAPI extern "C" __declspec(dllexport)
|
||||||
|
|
||||||
void convertSystemString(wchar_t* dest, String^ src)
|
void convertSystemString(wchar_t* dest, String^ src)
|
||||||
{
|
{
|
||||||
pin_ptr<const wchar_t> wch = PtrToStringChars(src);
|
pin_ptr<const wchar_t> wch = PtrToStringChars(src);
|
||||||
@@ -24,264 +27,241 @@ void convertSystemString(wchar_t* dest, String^ src)
|
|||||||
dest[wcslen(wch)] = '\0';
|
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
|
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();
|
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
|
return Execute<bool>([&expertHandle]() {
|
||||||
{
|
MtAdapter::GetInstance()->DeinitExpert(expertHandle);
|
||||||
MtServerInstance::GetInstance()->DeinitExpert(expertHandle);
|
return true;
|
||||||
}
|
}, err, false);
|
||||||
catch (Exception^ e)
|
|
||||||
{
|
|
||||||
convertSystemString(err, e->Message);
|
|
||||||
Debug::WriteLine("[ERROR] MTConnector:deinitExpert(): " + e->Message);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
return Execute<bool>([&expertHandle, symbol, &bid, &ask]() {
|
||||||
{
|
MtAdapter::GetInstance()->SendQuote(expertHandle, gcnew String(symbol), bid, ask);
|
||||||
MtServerInstance::GetInstance()->SendQuote(expertHandle, gcnew String(symbol), bid, ask);
|
return true;
|
||||||
}
|
}, err, false);
|
||||||
catch (Exception^ e)
|
|
||||||
{
|
|
||||||
convertSystemString(err, e->Message);
|
|
||||||
Debug::WriteLine("[ERROR] MTConnector:updateQuote(): " + e->Message);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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
|
return Execute<bool>([&expertHandle, &eventType, payload]() {
|
||||||
{
|
MtAdapter::GetInstance()->SendEvent(expertHandle, eventType, gcnew String(payload));
|
||||||
MtServerInstance::GetInstance()->SendEvent(expertHandle, eventType, gcnew String(payload));
|
return true;
|
||||||
}
|
}, err, false);
|
||||||
catch (Exception^ e)
|
|
||||||
{
|
|
||||||
convertSystemString(err, e->Message);
|
|
||||||
Debug::WriteLine("[ERROR] MTConnector:updateTimeBar(): " + e->Message);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall sendIntResponse(int expertHandle, int response)
|
_DLLAPI bool _stdcall sendIntResponse(int expertHandle, int response, wchar_t* err)
|
||||||
{
|
{
|
||||||
try
|
return Execute<bool>([&expertHandle, &response]() {
|
||||||
{
|
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseInt(response));
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseInt(response));
|
return true;
|
||||||
}
|
}, err, false);
|
||||||
catch (Exception^ e)
|
|
||||||
{
|
|
||||||
Debug::WriteLine("[ERROR] MTConnector:sendIntResponse(): " + e->Message);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall sendBooleanResponse(int expertHandle, int response)
|
_DLLAPI bool _stdcall sendBooleanResponse(int expertHandle, bool response, wchar_t* err)
|
||||||
{
|
{
|
||||||
try
|
return Execute<bool>([&expertHandle, &response]() {
|
||||||
{
|
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseBool(response));
|
||||||
bool value = (response != 0) ? true : false;
|
return true;
|
||||||
|
}, err, false);
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseBool(value));
|
|
||||||
}
|
|
||||||
catch (Exception^ e)
|
|
||||||
{
|
|
||||||
Debug::WriteLine("[ERROR] MTConnector:sendBooleanResponse(): " + e->Message);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall sendDoubleResponse(int expertHandle, double response)
|
_DLLAPI bool _stdcall sendDoubleResponse(int expertHandle, double response, wchar_t* err)
|
||||||
{
|
{
|
||||||
try
|
return Execute<bool>([&expertHandle, &response]() {
|
||||||
{
|
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDouble(response));
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDouble(response));
|
return true;
|
||||||
}
|
}, err, false);
|
||||||
catch (Exception^ e)
|
|
||||||
{
|
|
||||||
Debug::WriteLine("[ERROR] MTConnector:sendDoubleResponse(): " + e->Message);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall sendStringResponse(int expertHandle, wchar_t* response)
|
_DLLAPI bool _stdcall sendStringResponse(int expertHandle, wchar_t* response, wchar_t* err)
|
||||||
{
|
{
|
||||||
try
|
return Execute<bool>([&expertHandle, response]() {
|
||||||
{
|
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseString(gcnew String(response)));
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseString(gcnew String(response)));
|
return true;
|
||||||
}
|
}, err, false);
|
||||||
catch (Exception^ e)
|
|
||||||
{
|
|
||||||
Debug::WriteLine("[ERROR] MTConnector:sendStringResponse(): " + e->Message);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall sendVoidResponse(int expertHandle)
|
_DLLAPI bool _stdcall sendErrorResponse(int expertHandle, int code, wchar_t* message, wchar_t* err)
|
||||||
{
|
{
|
||||||
try
|
return Execute<bool>([&expertHandle, &code, message]() {
|
||||||
{
|
MtResponseString^ res = gcnew MtResponseString(gcnew String(message));
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, nullptr);
|
res->ErrorCode = code;
|
||||||
}
|
MtAdapter::GetInstance()->SendResponse(expertHandle, res);
|
||||||
catch (Exception^ e)
|
return true;
|
||||||
{
|
}, err, false);
|
||||||
Debug::WriteLine("[ERROR] MTConnector:sendVoidResponse(): " + e->Message);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
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];
|
list[i] = values[i];
|
||||||
}
|
}
|
||||||
|
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDoubleArray(list));
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDoubleArray(list));
|
return true;
|
||||||
}
|
}, err, false);
|
||||||
catch (Exception^ e)
|
|
||||||
{
|
|
||||||
Debug::WriteLine("[ERROR] MTConnector:sendDoubleArrayResponse(): " + e->Message);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
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];
|
list[i] = values[i];
|
||||||
}
|
}
|
||||||
|
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseIntArray(list));
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseIntArray(list));
|
return true;
|
||||||
}
|
}, err, false);
|
||||||
catch (Exception^ e)
|
|
||||||
{
|
|
||||||
Debug::WriteLine("[ERROR] MTConnector:sendIntArrayResponse(): " + e->Message);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall sendLongResponse(int expertHandle, __int64 response)
|
_DLLAPI bool _stdcall sendLongResponse(int expertHandle, __int64 response, wchar_t* err)
|
||||||
{
|
{
|
||||||
try
|
return Execute<bool>([&expertHandle, &response]() {
|
||||||
{
|
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLong(response));
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLong(response));
|
return true;
|
||||||
}
|
}, err, false);
|
||||||
catch (Exception^ e)
|
|
||||||
{
|
|
||||||
Debug::WriteLine("[ERROR] MTConnector:sendLongResponse(): " + e->Message);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall getCommandType(int expertHandle, int* res)
|
_DLLAPI bool _stdcall getCommandType(int expertHandle, int* res, wchar_t* err)
|
||||||
{
|
{
|
||||||
try
|
return Execute<bool>([&expertHandle, res]() {
|
||||||
{
|
*res = MtAdapter::GetInstance()->GetCommandType(expertHandle);
|
||||||
*res = MtServerInstance::GetInstance()->GetCommandType(expertHandle);
|
return true;
|
||||||
}
|
}, err, false);
|
||||||
catch (Exception^ e)
|
|
||||||
{
|
|
||||||
Debug::WriteLine("[ERROR] MTConnector:getCommandType(): " + e->Message);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall getIntValue(int expertHandle, int paramIndex, int* res)
|
_DLLAPI bool _stdcall getIntValue(int expertHandle, int paramIndex, int* res, wchar_t* err)
|
||||||
{
|
{
|
||||||
try
|
return Execute<bool>([&expertHandle, ¶mIndex, res]() {
|
||||||
{
|
*res = (int)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
||||||
*res = (int)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
return true;
|
||||||
}
|
}, err, false);
|
||||||
catch (Exception^ e)
|
|
||||||
{
|
|
||||||
Debug::WriteLine("[ERROR] MTConnector:getIntValue(): " + e->Message);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
return Execute<bool>([&expertHandle, ¶mIndex, res]() {
|
||||||
{
|
*res = (double)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
||||||
*res = (double)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
return true;
|
||||||
}
|
}, err, false);
|
||||||
catch (Exception^ e)
|
|
||||||
{
|
|
||||||
Debug::WriteLine("[ERROR] MTConnector:getDoubleValue(): " + e->Message);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
return Execute<bool>([&expertHandle, ¶mIndex, res]() {
|
||||||
{
|
convertSystemString(res, (String^)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex));
|
||||||
convertSystemString(res, (String^)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex));
|
return true;
|
||||||
}
|
}, err, false);
|
||||||
catch (Exception^ e)
|
|
||||||
{
|
|
||||||
Debug::WriteLine("[ERROR] MTConnector:getStringValue(): " + e->Message);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall getBooleanValue(int expertHandle, int paramIndex, int* res)
|
_DLLAPI bool _stdcall getBooleanValue(int expertHandle, int paramIndex, int* res, wchar_t* err)
|
||||||
{
|
{
|
||||||
try
|
return Execute<bool>([&expertHandle, ¶mIndex, res]() {
|
||||||
{
|
*res = (bool)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
||||||
bool val = (bool)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
return true;
|
||||||
*res = val == true ? 1 : 0;
|
}, err, false);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
|
||||||
{
|
_DLLAPI bool _stdcall getLongValue(int expertHandle, int paramIndex, __int64* res, wchar_t* err)
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:getBooleanValue(): " + e->Message);
|
{
|
||||||
return 0;
|
return Execute<bool>([&expertHandle, ¶mIndex, res]() {
|
||||||
}
|
*res = (__int64)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
||||||
return 1;
|
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);
|
||||||
}
|
}
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
LIBRARY MTConnector
|
|
||||||
|
|
||||||
EXPORTS initExpert
|
|
||||||
deinitExpert
|
|
||||||
updateQuote
|
|
||||||
sendEvent
|
|
||||||
sendIntResponse
|
|
||||||
sendBooleanResponse
|
|
||||||
sendDoubleResponse
|
|
||||||
sendStringResponse
|
|
||||||
sendVoidResponse
|
|
||||||
sendDoubleArrayResponse
|
|
||||||
sendIntArrayResponse
|
|
||||||
sendLongResponse
|
|
||||||
getCommandType
|
|
||||||
getIntValue
|
|
||||||
getDoubleValue
|
|
||||||
getStringValue
|
|
||||||
getBooleanValue
|
|
||||||
@@ -96,7 +96,6 @@
|
|||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
<ModuleDefinitionFile>.\MTConnector.def</ModuleDefinitionFile>
|
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
@@ -109,7 +108,6 @@
|
|||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
<ModuleDefinitionFile>.\MTConnector.def</ModuleDefinitionFile>
|
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
@@ -121,7 +119,6 @@
|
|||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
<ModuleDefinitionFile>.\MTConnector.def</ModuleDefinitionFile>
|
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
@@ -133,7 +130,6 @@
|
|||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
<ModuleDefinitionFile>.\MTConnector.def</ModuleDefinitionFile>
|
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -154,7 +150,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="app.ico" />
|
<None Include="app.ico" />
|
||||||
<None Include="MTConnector.def" />
|
|
||||||
<None Include="ReadMe.txt" />
|
<None Include="ReadMe.txt" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -44,9 +44,6 @@
|
|||||||
<None Include="app.ico">
|
<None Include="app.ico">
|
||||||
<Filter>Resource Files</Filter>
|
<Filter>Resource Files</Filter>
|
||||||
</None>
|
</None>
|
||||||
<None Include="MTConnector.def">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="app.rc">
|
<ResourceCompile Include="app.rc">
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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.
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
-1
@@ -59,12 +59,17 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="ChartPeriod.cs" />
|
<Compile Include="ChartPeriod.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="EnumSeriesInfoInteger.cs" />
|
||||||
<Compile Include="EnumSymbolInfoDouble.cs" />
|
<Compile Include="EnumSymbolInfoDouble.cs" />
|
||||||
<Compile Include="EnumSymbolInfoInteger.cs" />
|
<Compile Include="EnumSymbolInfoInteger.cs" />
|
||||||
<Compile Include="EnumTerminalInfoDouble.cs" />
|
<Compile Include="EnumTerminalInfoDouble.cs" />
|
||||||
<Compile Include="EnumTerminalInfoInteger.cs" />
|
<Compile Include="EnumTerminalInfoInteger.cs" />
|
||||||
<Compile Include="ExtensionMethods.cs" />
|
<Compile Include="FlagFontStyle.cs" />
|
||||||
<Compile Include="Monitors\AvailabilityOrdersEventArgs.cs" />
|
<Compile Include="Monitors\AvailabilityOrdersEventArgs.cs" />
|
||||||
<Compile Include="MqlRates.cs" />
|
<Compile Include="MqlRates.cs" />
|
||||||
<Compile Include="MqlTick.cs" />
|
<Compile Include="MqlTick.cs" />
|
||||||
|
|||||||
+700
-114
File diff suppressed because it is too large
Load Diff
@@ -13,9 +13,9 @@ namespace MtApi
|
|||||||
return Color.FromArgb((byte)(color), (byte)(color >> 8), (byte)(color >> 16));
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,13 +13,13 @@ namespace MtApi
|
|||||||
return new DateTime(tmpTime.Ticks + (time * 0x989680L));
|
return new DateTime(tmpTime.Ticks + (time * 0x989680L));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int ConvertToMtTime(DateTime time)
|
public static int ConvertToMtTime(DateTime? time)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
if (time != DateTime.MinValue)
|
if (time != null && time != DateTime.MinValue)
|
||||||
{
|
{
|
||||||
DateTime tmpTime = new DateTime(1970, 1, 1);
|
DateTime tmpTime = new DateTime(1970, 1, 1);
|
||||||
result = (int)((time.Ticks - tmpTime.Ticks) / 0x989680L);
|
result = (int)((time.Value.Ticks - tmpTime.Ticks) / 0x989680L);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
+38
-9
@@ -1,9 +1,4 @@
|
|||||||
using System;
|
namespace MtApi
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace MtApi
|
|
||||||
{
|
{
|
||||||
enum MtCommandType
|
enum MtCommandType
|
||||||
{
|
{
|
||||||
@@ -140,8 +135,8 @@ namespace MtApi
|
|||||||
iBullsPower = 106,
|
iBullsPower = 106,
|
||||||
iCCI = 107,
|
iCCI = 107,
|
||||||
iCCIOnArray = 108,
|
iCCIOnArray = 108,
|
||||||
iCustom = 109,
|
//iCustom = 109,
|
||||||
iCustom_d = 10109,
|
//iCustom_d = 10109,
|
||||||
iDeMarker = 110,
|
iDeMarker = 110,
|
||||||
iEnvelopes = 111,
|
iEnvelopes = 111,
|
||||||
iEnvelopesOnArray = 112,
|
iEnvelopesOnArray = 112,
|
||||||
@@ -201,6 +196,40 @@ namespace MtApi
|
|||||||
SymbolsTotal = 200,
|
SymbolsTotal = 200,
|
||||||
SymbolName = 201,
|
SymbolName = 201,
|
||||||
SymbolSelect = 202,
|
SymbolSelect = 202,
|
||||||
SymbolInfoInteger = 203
|
SymbolInfoInteger = 203,
|
||||||
|
ChartId = 206,
|
||||||
|
ChartRedraw = 207,
|
||||||
|
|
||||||
|
//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,
|
||||||
|
ChangeAccount = 280
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace MtApi
|
namespace MtApi
|
||||||
{
|
{
|
||||||
public class MtConnectionEventArgs: EventArgs
|
public class MtConnectionEventArgs: EventArgs
|
||||||
{
|
{
|
||||||
public MtConnectionState Status { get; private set; }
|
public MtConnectionState Status { get; private set; }
|
||||||
public String ConnectionMessage { get; private set; }
|
public string ConnectionMessage { get; private set; }
|
||||||
|
|
||||||
public MtConnectionEventArgs(MtConnectionState status, string message)
|
public MtConnectionEventArgs(MtConnectionState status, string message)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
public string Instrument { get; private set; }
|
public string Instrument { get; private set; }
|
||||||
public double Bid { get; private set; }
|
public double Bid { get; private set; }
|
||||||
public double Ask { get; private set; }
|
public double Ask { get; private set; }
|
||||||
|
public int ExpertHandle { get; private set; }
|
||||||
|
|
||||||
public MtQuote(string instrument, double bid, double ask)
|
public MtQuote(string instrument, double bid, double ask)
|
||||||
{
|
{
|
||||||
@@ -12,5 +13,13 @@
|
|||||||
Bid = bid;
|
Bid = bid;
|
||||||
Ask = ask;
|
Ask = ask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal MtQuote(MTApiService.MtQuote quote)
|
||||||
|
{
|
||||||
|
Instrument = quote.Instrument;
|
||||||
|
Bid = quote.Bid;
|
||||||
|
Ask = quote.Ask;
|
||||||
|
ExpertHandle = quote.ExpertHandle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace MtApi
|
namespace MtApi
|
||||||
{
|
{
|
||||||
|
|||||||
Executable → Regular
+2
-2
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.0.32.0")]
|
[assembly: AssemblyVersion("1.0.37.0")]
|
||||||
[assembly: AssemblyFileVersion("1.0.32.0")]
|
[assembly: AssemblyFileVersion("1.0.37.0")]
|
||||||
@@ -1,8 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace MtApi
|
namespace MtApi
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace MtApi5
|
namespace MtApi5
|
||||||
{
|
{
|
||||||
public class Mt5ConnectionEventArgs: EventArgs
|
public class Mt5ConnectionEventArgs: EventArgs
|
||||||
{
|
{
|
||||||
public Mt5ConnectionState Status { get; private set; }
|
public Mt5ConnectionState Status { get; private set; }
|
||||||
public String ConnectionMessage { get; private set; }
|
public string ConnectionMessage { get; private set; }
|
||||||
|
|
||||||
public Mt5ConnectionEventArgs(Mt5ConnectionState status, string message)
|
public Mt5ConnectionEventArgs(Mt5ConnectionState status, string message)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -56,7 +56,6 @@
|
|||||||
<Compile Include="Mt5Enums.cs" />
|
<Compile Include="Mt5Enums.cs" />
|
||||||
<Compile Include="Mt5ConnectionEventArgs.cs" />
|
<Compile Include="Mt5ConnectionEventArgs.cs" />
|
||||||
<Compile Include="Mt5ConnectionState.cs" />
|
<Compile Include="Mt5ConnectionState.cs" />
|
||||||
<Compile Include="ExtensionMethods.cs" />
|
|
||||||
<Compile Include="MqlTradeRequest.cs" />
|
<Compile Include="MqlTradeRequest.cs" />
|
||||||
<Compile Include="MqlTradeResult.cs" />
|
<Compile Include="MqlTradeResult.cs" />
|
||||||
<Compile Include="Mt5QuoteEventArgs.cs" />
|
<Compile Include="Mt5QuoteEventArgs.cs" />
|
||||||
|
|||||||
+163
-111
@@ -7,6 +7,7 @@ using System.ServiceModel;
|
|||||||
using MtApi5.Requests;
|
using MtApi5.Requests;
|
||||||
using MtApi5.Responses;
|
using MtApi5.Responses;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace MtApi5
|
namespace MtApi5
|
||||||
{
|
{
|
||||||
@@ -31,22 +32,17 @@ namespace MtApi5
|
|||||||
|
|
||||||
|
|
||||||
#region Private Fields
|
#region Private Fields
|
||||||
private readonly MtClient _client = new MtClient();
|
private MtClient _client;
|
||||||
|
private readonly object _locker = new object();
|
||||||
private volatile bool _isBacktestingMode = false;
|
private volatile bool _isBacktestingMode = false;
|
||||||
|
private Mt5ConnectionState _connectionState = Mt5ConnectionState.Disconnected;
|
||||||
|
private int _executorHandle;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Public Methods
|
#region Public Methods
|
||||||
public MtApi5Client()
|
public MtApi5Client()
|
||||||
{
|
{
|
||||||
LogConfigurator.Setup(LogProfileName);
|
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>
|
///<summary>
|
||||||
@@ -56,15 +52,7 @@ namespace MtApi5
|
|||||||
///<param name="port">Port of host connection (default 8222) </param>
|
///<param name="port">Port of host connection (default 8222) </param>
|
||||||
public void BeginConnect(string host, int port)
|
public void BeginConnect(string host, int port)
|
||||||
{
|
{
|
||||||
//if (string.IsNullOrEmpty(host) == false && (host.Equals("localhost") || host.Equals("127.0.0.1")))
|
Task.Factory.StartNew(() => Connect(host, port));
|
||||||
//{
|
|
||||||
// this.BeginConnect(port);
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
//{
|
|
||||||
Action<string, int> connectAction = Connect;
|
|
||||||
connectAction.BeginInvoke(host, port, null, null);
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///<summary>
|
///<summary>
|
||||||
@@ -73,8 +61,7 @@ namespace MtApi5
|
|||||||
///<param name="port">Port of host connection (default 8222) </param>
|
///<param name="port">Port of host connection (default 8222) </param>
|
||||||
public void BeginConnect(int port)
|
public void BeginConnect(int port)
|
||||||
{
|
{
|
||||||
Action<int> connectAction = Connect;
|
Task.Factory.StartNew(() => Connect(port));
|
||||||
connectAction.BeginInvoke(port, null, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///<summary>
|
///<summary>
|
||||||
@@ -82,8 +69,7 @@ namespace MtApi5
|
|||||||
///</summary>
|
///</summary>
|
||||||
public void BeginDisconnect()
|
public void BeginDisconnect()
|
||||||
{
|
{
|
||||||
Action disconnectAction = Disconnect;
|
Task.Factory.StartNew(() => Disconnect(false));
|
||||||
disconnectAction.BeginInvoke(null, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///<summary>
|
///<summary>
|
||||||
@@ -91,11 +77,8 @@ namespace MtApi5
|
|||||||
///</summary>
|
///</summary>
|
||||||
public IEnumerable<Mt5Quote> GetQuotes()
|
public IEnumerable<Mt5Quote> GetQuotes()
|
||||||
{
|
{
|
||||||
IEnumerable<MtQuote> quotes;
|
var client = Client;
|
||||||
lock (_client)
|
var quotes = client != null ? client.GetQuotes() : null;
|
||||||
{
|
|
||||||
quotes = _client.GetQuotes();
|
|
||||||
}
|
|
||||||
return quotes?.Select(q => q.Parse());
|
return quotes?.Select(q => q.Parse());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1432,7 +1415,37 @@ namespace MtApi5
|
|||||||
///<summary>
|
///<summary>
|
||||||
///Connection status of MetaTrader API.
|
///Connection status of MetaTrader API.
|
||||||
///</summary>
|
///</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
|
#endregion
|
||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
@@ -1443,94 +1456,148 @@ namespace MtApi5
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Private Methods
|
#region Private Methods
|
||||||
private void Connect(string host, int port)
|
private MtClient Client
|
||||||
{
|
{
|
||||||
ConnectionState = Mt5ConnectionState.Connecting;
|
get
|
||||||
ConnectionStateChanged.FireEvent(this
|
|
||||||
, new Mt5ConnectionEventArgs(Mt5ConnectionState.Connecting, "Connecting to " + host + ":" + port));
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
lock (_client)
|
lock (_locker)
|
||||||
{
|
{
|
||||||
_client.Open(host, port);
|
return _client;
|
||||||
_client.Connect();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
}
|
||||||
|
|
||||||
|
private void Connect(MtClient client)
|
||||||
|
{
|
||||||
|
lock (_locker)
|
||||||
{
|
{
|
||||||
ConnectionState = Mt5ConnectionState.Failed;
|
if (_connectionState == Mt5ConnectionState.Connected
|
||||||
ConnectionStateChanged.FireEvent(this
|
|| _connectionState == Mt5ConnectionState.Connecting)
|
||||||
, new Mt5ConnectionEventArgs(Mt5ConnectionState.Failed, "Failed connection to " + host + ":" + port + ". " + e.Message));
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_connectionState = Mt5ConnectionState.Connecting;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectionState = Mt5ConnectionState.Connected;
|
string message = string.IsNullOrEmpty(client.Host) ? $"Connecting to localhost:{client.Port}" : $"Connecting to {client.Host}:{client.Port}";
|
||||||
ConnectionStateChanged.FireEvent(this
|
ConnectionStateChanged?.Invoke(this, new Mt5ConnectionEventArgs(Mt5ConnectionState.Connecting, message));
|
||||||
, new Mt5ConnectionEventArgs(Mt5ConnectionState.Connected, "Connected to " + host + ":" + port));
|
|
||||||
|
|
||||||
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)
|
private void Connect(int port)
|
||||||
{
|
{
|
||||||
ConnectionState = Mt5ConnectionState.Connecting;
|
var client = new MtClient(port);
|
||||||
ConnectionStateChanged.FireEvent(this
|
Connect(client);
|
||||||
, 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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
if (_connectionState == Mt5ConnectionState.Disconnected
|
||||||
_client.Close();
|
|| _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?.Invoke(this, new Mt5ConnectionEventArgs(state, message));
|
||||||
ConnectionStateChanged.FireEvent(this, new Mt5ConnectionEventArgs(Mt5ConnectionState.Disconnected, "Disconnected"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private T SendCommand<T>(Mt5CommandType commandType, ArrayList commandParameters)
|
private T SendCommand<T>(Mt5CommandType commandType, ArrayList commandParameters, Dictionary<string, object> namedParams = null)
|
||||||
{
|
{
|
||||||
MtResponse response;
|
MtResponse response;
|
||||||
|
|
||||||
|
var client = Client;
|
||||||
|
if (client == null)
|
||||||
|
{
|
||||||
|
throw new Exception("No connection");
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
lock (_client)
|
response = client.SendCommand((int)commandType, commandParameters, namedParams, ExecutorHandle);
|
||||||
{
|
|
||||||
response = _client.SendCommand((int) commandType, commandParameters);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (CommunicationException ex)
|
catch (CommunicationException ex)
|
||||||
{
|
{
|
||||||
throw new Exception(ex.Message, ex);
|
throw new Exception(ex.Message, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
var responseValue = response?.GetValue();
|
if (response == null)
|
||||||
return responseValue != null ? (T) responseValue : default(T);
|
{
|
||||||
|
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()
|
private T SendRequest<T>(RequestBase request) where T : ResponseBase, new()
|
||||||
@@ -1545,25 +1612,14 @@ namespace MtApi5
|
|||||||
});
|
});
|
||||||
var commandParameters = new ArrayList { serializer };
|
var commandParameters = new ArrayList { serializer };
|
||||||
|
|
||||||
MtResponseString res;
|
var res = SendCommand<string>(Mt5CommandType.MtRequest, commandParameters);
|
||||||
try
|
|
||||||
{
|
|
||||||
lock (_client)
|
|
||||||
{
|
|
||||||
res = (MtResponseString)_client.SendCommand((int)Mt5CommandType.MtRequest, commandParameters);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (CommunicationException ex)
|
|
||||||
{
|
|
||||||
throw new Exception(ex.Message, ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res == null)
|
if (res == null)
|
||||||
{
|
{
|
||||||
throw new ExecutionException(ErrorCode.ErrCustom, "Response from MetaTrader is 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)
|
if (response.ErrorCode != 0)
|
||||||
{
|
{
|
||||||
throw new ExecutionException((ErrorCode)response.ErrorCode, response.ErrorMessage);
|
throw new ExecutionException((ErrorCode)response.ErrorCode, response.ErrorMessage);
|
||||||
@@ -1573,7 +1629,7 @@ namespace MtApi5
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void mClient_QuoteUpdated(MtQuote quote)
|
private void _client_QuoteUpdated(MtQuote quote)
|
||||||
{
|
{
|
||||||
if (quote != null)
|
if (quote != null)
|
||||||
{
|
{
|
||||||
@@ -1581,28 +1637,24 @@ namespace MtApi5
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void mClient_ServerDisconnected(object sender, EventArgs e)
|
private void _client_ServerDisconnected(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
ConnectionState = Mt5ConnectionState.Disconnected;
|
Disconnect(false);
|
||||||
ConnectionStateChanged.FireEvent(this
|
|
||||||
, new Mt5ConnectionEventArgs(Mt5ConnectionState.Disconnected, "MtApi is disconnected"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void mClient_ServerFailed(object sender, EventArgs e)
|
private void _client_ServerFailed(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
ConnectionState = Mt5ConnectionState.Failed;
|
Disconnect(true);
|
||||||
ConnectionStateChanged.FireEvent(this
|
|
||||||
, new Mt5ConnectionEventArgs(Mt5ConnectionState.Failed, "Failed connection with MtApi"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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()
|
private void OnConnected()
|
||||||
|
|||||||
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.0.11.0")]
|
[assembly: AssemblyVersion("1.0.12")]
|
||||||
[assembly: AssemblyFileVersion("1.0.11.0")]
|
[assembly: AssemblyFileVersion("1.0.12")]
|
||||||
|
|||||||
+775
-247
File diff suppressed because it is too large
Load Diff
@@ -33,8 +33,11 @@ namespace TestApiClientUI
|
|||||||
comboBox8.DataSource = Enum.GetNames(typeof(MarketInfoModeType));
|
comboBox8.DataSource = Enum.GetNames(typeof(MarketInfoModeType));
|
||||||
comboBox9.DataSource = Enum.GetNames(typeof(EnumTerminalInfoInteger));
|
comboBox9.DataSource = Enum.GetNames(typeof(EnumTerminalInfoInteger));
|
||||||
comboBox10.DataSource = Enum.GetNames(typeof(EnumTerminalInfoDouble));
|
comboBox10.DataSource = Enum.GetNames(typeof(EnumTerminalInfoDouble));
|
||||||
|
comboBox11.DataSource = Enum.GetNames(typeof(EnumObject));
|
||||||
|
comboBoxAccountInfoCmd.DataSource = Enum.GetNames(typeof(TradeOperation));
|
||||||
|
|
||||||
_apiClient.QuoteUpdated += apiClient_QuoteUpdated;
|
_apiClient.QuoteUpdated += apiClient_QuoteUpdated;
|
||||||
|
_apiClient.QuoteUpdate += _apiClient_QuoteUpdate;
|
||||||
_apiClient.QuoteAdded += apiClient_QuoteAdded;
|
_apiClient.QuoteAdded += apiClient_QuoteAdded;
|
||||||
_apiClient.QuoteRemoved += apiClient_QuoteRemoved;
|
_apiClient.QuoteRemoved += apiClient_QuoteRemoved;
|
||||||
_apiClient.ConnectionStateChanged += apiClient_ConnectionStateChanged;
|
_apiClient.ConnectionStateChanged += apiClient_ConnectionStateChanged;
|
||||||
@@ -47,6 +50,8 @@ namespace TestApiClientUI
|
|||||||
comboBox3.SelectedIndex = 0;
|
comboBox3.SelectedIndex = 0;
|
||||||
comboBox4.SelectedIndex = 0;
|
comboBox4.SelectedIndex = 0;
|
||||||
comboBox5.SelectedIndex = 0;
|
comboBox5.SelectedIndex = 0;
|
||||||
|
comboBox11.SelectedIndex = 0;
|
||||||
|
comboBoxAccountInfoCmd.SelectedIndex = 0;
|
||||||
|
|
||||||
_timerTradeMonitor = new TimerTradeMonitor(_apiClient) { Interval = 10000 }; // 10 sec
|
_timerTradeMonitor = new TimerTradeMonitor(_apiClient) { Interval = 10000 }; // 10 sec
|
||||||
_timerTradeMonitor.AvailabilityOrdersChanged += _tradeMonitor_AvailabilityOrdersChanged;
|
_timerTradeMonitor.AvailabilityOrdersChanged += _tradeMonitor_AvailabilityOrdersChanged;
|
||||||
@@ -112,12 +117,18 @@ namespace TestApiClientUI
|
|||||||
|
|
||||||
private void apiClient_QuoteRemoved(object sender, MtQuoteEventArgs e)
|
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)
|
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)
|
private void _apiClient_OnLastTimeBar(object sender, TimeBarArgs e)
|
||||||
@@ -131,72 +142,52 @@ namespace TestApiClientUI
|
|||||||
private void apiClient_QuoteUpdated(object sender, string symbol, double bid, double ask)
|
private void apiClient_QuoteUpdated(object sender, string symbol, double bid, double ask)
|
||||||
{
|
{
|
||||||
Console.WriteLine(@"Quote: Symbol = {0}, Bid = {1}, Ask = {2}", symbol, bid, 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 UI of quite is busy we are skipping this update
|
||||||
if (_isUiQuoteUpdateReady)
|
if (_isUiQuoteUpdateReady)
|
||||||
{
|
{
|
||||||
RunOnUiThread(() => ChangeQuote(symbol, bid, ask));
|
RunOnUiThread(() => ChangeQuote(e.Quote));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddNewQuote(MtQuote quote)
|
private void AddNewQuote(MtQuote quote)
|
||||||
{
|
{
|
||||||
if (quote == null)
|
var key = quote.ExpertHandle.ToString();
|
||||||
return;
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(quote.Instrument) == false
|
if (listViewQuotes.Items.ContainsKey(key) == false)
|
||||||
&& listViewQuotes.Items.ContainsKey(quote.Instrument) == 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.Bid.ToString(CultureInfo.CurrentCulture));
|
||||||
item.SubItems.Add(quote.Ask.ToString(CultureInfo.CurrentCulture));
|
item.SubItems.Add(quote.Ask.ToString(CultureInfo.CurrentCulture));
|
||||||
item.SubItems.Add("1");
|
item.SubItems.Add(key);
|
||||||
listViewQuotes.Items.Add(item);
|
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)
|
private void RemoveQuote(MtQuote quote)
|
||||||
{
|
{
|
||||||
if (quote == null)
|
var key = quote.ExpertHandle.ToString();
|
||||||
return;
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(quote.Instrument) == false
|
if (listViewQuotes.Items.ContainsKey(key))
|
||||||
&& listViewQuotes.Items.ContainsKey(quote.Instrument))
|
|
||||||
{
|
{
|
||||||
var item = listViewQuotes.Items[quote.Instrument];
|
listViewQuotes.Items.RemoveByKey(key);
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ChangeQuote(string symbol, double bid, double ask)
|
private void ChangeQuote(MtQuote quote)
|
||||||
{
|
{
|
||||||
_isUiQuoteUpdateReady = false;
|
_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[key];
|
||||||
{
|
item.SubItems[1].Text = quote.Bid.ToString(CultureInfo.CurrentCulture);
|
||||||
var item = listViewQuotes.Items[symbol];
|
item.SubItems[2].Text = quote.Ask.ToString(CultureInfo.CurrentCulture);
|
||||||
item.SubItems[1].Text = bid.ToString(CultureInfo.CurrentCulture);
|
|
||||||
item.SubItems[2].Text = ask.ToString(CultureInfo.CurrentCulture);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_isUiQuoteUpdateReady = true;
|
_isUiQuoteUpdateReady = true;
|
||||||
@@ -256,6 +247,12 @@ namespace TestApiClientUI
|
|||||||
textBoxOrderSymbol.Text = listViewQuotes.SelectedItems[0].Text;
|
textBoxOrderSymbol.Text = listViewQuotes.SelectedItems[0].Text;
|
||||||
txtMarketInfoSymbol.Text = listViewQuotes.SelectedItems[0].Text;
|
txtMarketInfoSymbol.Text = listViewQuotes.SelectedItems[0].Text;
|
||||||
textBoxSelectedSymbol.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 +523,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
|
//MarketInfo
|
||||||
private async void button5_Click(object sender, EventArgs e)
|
private async void button5_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
@@ -753,13 +550,13 @@ namespace TestApiClientUI
|
|||||||
|
|
||||||
Console.WriteLine($"Finished time: {DateTime.Now}");
|
Console.WriteLine($"Finished time: {DateTime.Now}");
|
||||||
|
|
||||||
using (var file = new System.IO.StreamWriter($@"{System.IO.Path.GetTempPath()}\MtApi\test.txt"))
|
//using (var file = new System.IO.StreamWriter($@"{System.IO.Path.GetTempPath()}\MtApi\test.txt"))
|
||||||
{
|
//{
|
||||||
foreach (var value in openPriceList)
|
// foreach (var value in openPriceList)
|
||||||
{
|
// {
|
||||||
file.WriteLine(value);
|
// file.WriteLine(value);
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void button7_Click(object sender, EventArgs e)
|
private void button7_Click(object sender, EventArgs e)
|
||||||
@@ -832,9 +629,9 @@ namespace TestApiClientUI
|
|||||||
listBoxEventLog.Items.Clear();
|
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);
|
var result = default(TResult);
|
||||||
try
|
try
|
||||||
@@ -854,9 +651,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
|
//OrderSend
|
||||||
private async void button1_Click(object sender, EventArgs e)
|
private async void button1_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
var ticket = -1;
|
||||||
|
|
||||||
var symbol = textBoxOrderSymbol.Text;
|
var symbol = textBoxOrderSymbol.Text;
|
||||||
|
|
||||||
var cmd = (TradeOperation) comboBoxOrderCommand.SelectedIndex;
|
var cmd = (TradeOperation) comboBoxOrderCommand.SelectedIndex;
|
||||||
@@ -877,28 +695,43 @@ namespace TestApiClientUI
|
|||||||
|
|
||||||
var comment = textBoxOrderComment.Text;
|
var comment = textBoxOrderComment.Text;
|
||||||
|
|
||||||
int magic;
|
if (string.IsNullOrEmpty(comment))
|
||||||
int.TryParse(textBoxOrderMagic.Text, out magic);
|
|
||||||
|
|
||||||
var expiration = DateTime.Now;
|
|
||||||
|
|
||||||
Color arrowColor;
|
|
||||||
switch (comboBoxOrderColor.SelectedIndex)
|
|
||||||
{
|
{
|
||||||
case 0:
|
ticket = await Execute(() => _apiClient.OrderSend(symbol, cmd, volume, price, slippage, stoploss, takeprofit));
|
||||||
arrowColor = Color.Green;
|
}
|
||||||
break;
|
else
|
||||||
case 1:
|
{
|
||||||
arrowColor = Color.Blue;
|
int magic;
|
||||||
break;
|
if (!int.TryParse(textBoxOrderMagic.Text, out magic))
|
||||||
case 2:
|
{
|
||||||
arrowColor = Color.Red;
|
ticket = await Execute(() => _apiClient.OrderSend(symbol, cmd, volume, price, slippage, stoploss, takeprofit, comment));
|
||||||
break;
|
}
|
||||||
default:
|
else
|
||||||
return;
|
{
|
||||||
|
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}");
|
PrintLog($"Sended order result: ticket = {ticket}");
|
||||||
}
|
}
|
||||||
@@ -1286,5 +1119,339 @@ namespace TestApiClientUI
|
|||||||
var result = await Execute(() => _apiClient.TerminalInfoDouble(propId));
|
var result = await Execute(() => _apiClient.TerminalInfoDouble(propId));
|
||||||
PrintLog($"TerminalInfoDouble: result = {result}");
|
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}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<startup>
|
<startup>
|
||||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client" />
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
|
||||||
</startup>
|
</startup>
|
||||||
</configuration>
|
</configuration>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
'------------------------------------------------------------------------------
|
'------------------------------------------------------------------------------
|
||||||
' <auto-generated>
|
' <auto-generated>
|
||||||
' This code was generated by a tool.
|
' 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
|
' Changes to this file may cause incorrect behavior and will be lost if
|
||||||
' the code is regenerated.
|
' the code is regenerated.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
'------------------------------------------------------------------------------
|
'------------------------------------------------------------------------------
|
||||||
' <auto-generated>
|
' <auto-generated>
|
||||||
' This code was generated by a tool.
|
' 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
|
' Changes to this file may cause incorrect behavior and will be lost if
|
||||||
' the code is regenerated.
|
' the code is regenerated.
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
Option Strict On
|
Option Strict On
|
||||||
Option Explicit On
|
Option Explicit On
|
||||||
|
|
||||||
|
Imports System
|
||||||
|
|
||||||
Namespace My.Resources
|
Namespace My.Resources
|
||||||
|
|
||||||
@@ -21,10 +22,10 @@ Namespace My.Resources
|
|||||||
'''<summary>
|
'''<summary>
|
||||||
''' A strongly-typed resource class, for looking up localized strings, etc.
|
''' A strongly-typed resource class, for looking up localized strings, etc.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0"), _
|
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0"), _
|
||||||
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
||||||
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
||||||
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
|
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
|
||||||
Friend Module Resources
|
Friend Module Resources
|
||||||
|
|
||||||
Private resourceMan As Global.System.Resources.ResourceManager
|
Private resourceMan As Global.System.Resources.ResourceManager
|
||||||
@@ -34,7 +35,7 @@ Namespace My.Resources
|
|||||||
'''<summary>
|
'''<summary>
|
||||||
''' Returns the cached ResourceManager instance used by this class.
|
''' Returns the cached ResourceManager instance used by this class.
|
||||||
'''</summary>
|
'''</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
|
Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
|
||||||
Get
|
Get
|
||||||
If Object.ReferenceEquals(resourceMan, Nothing) Then
|
If Object.ReferenceEquals(resourceMan, Nothing) Then
|
||||||
@@ -49,12 +50,12 @@ Namespace My.Resources
|
|||||||
''' Overrides the current thread's CurrentUICulture property for all
|
''' Overrides the current thread's CurrentUICulture property for all
|
||||||
''' resource lookups using this strongly typed resource class.
|
''' resource lookups using this strongly typed resource class.
|
||||||
'''</summary>
|
'''</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
|
Friend Property Culture() As Global.System.Globalization.CultureInfo
|
||||||
Get
|
Get
|
||||||
Return resourceCulture
|
Return resourceCulture
|
||||||
End Get
|
End Get
|
||||||
Set(ByVal value As Global.System.Globalization.CultureInfo)
|
Set
|
||||||
resourceCulture = value
|
resourceCulture = value
|
||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
|
|||||||
+21
-21
@@ -1,7 +1,7 @@
|
|||||||
'------------------------------------------------------------------------------
|
'------------------------------------------------------------------------------
|
||||||
' <auto-generated>
|
' <auto-generated>
|
||||||
' This code was generated by a tool.
|
' 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
|
' Changes to this file may cause incorrect behavior and will be lost if
|
||||||
' the code is regenerated.
|
' the code is regenerated.
|
||||||
@@ -14,26 +14,26 @@ Option Explicit On
|
|||||||
|
|
||||||
Namespace My
|
Namespace My
|
||||||
|
|
||||||
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
||||||
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0"), _
|
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0"), _
|
||||||
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||||
Partial Friend NotInheritable Class MySettings
|
Partial Friend NotInheritable Class MySettings
|
||||||
Inherits Global.System.Configuration.ApplicationSettingsBase
|
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"
|
#Region "My.Settings Auto-Save Functionality"
|
||||||
#If _MyType = "WindowsForms" Then
|
#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)> _
|
<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)
|
Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs)
|
||||||
If My.Application.SaveMySettingsOnExit Then
|
If My.Application.SaveMySettingsOnExit Then
|
||||||
My.Settings.Save()
|
My.Settings.Save()
|
||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
#End If
|
#End If
|
||||||
#End Region
|
#End Region
|
||||||
|
|
||||||
@@ -41,14 +41,14 @@ Namespace My
|
|||||||
Get
|
Get
|
||||||
|
|
||||||
#If _MyType = "WindowsForms" Then
|
#If _MyType = "WindowsForms" Then
|
||||||
If Not addedHandler Then
|
If Not addedHandler Then
|
||||||
SyncLock addedHandlerLockObject
|
SyncLock addedHandlerLockObject
|
||||||
If Not addedHandler Then
|
If Not addedHandler Then
|
||||||
AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
|
AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
|
||||||
addedHandler = True
|
addedHandler = True
|
||||||
End If
|
End If
|
||||||
End SyncLock
|
End SyncLock
|
||||||
End If
|
End If
|
||||||
#End If
|
#End If
|
||||||
Return defaultInstance
|
Return defaultInstance
|
||||||
End Get
|
End Get
|
||||||
|
|||||||
@@ -13,8 +13,9 @@
|
|||||||
<AssemblyName>TestMtApi</AssemblyName>
|
<AssemblyName>TestMtApi</AssemblyName>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<MyType>WindowsForms</MyType>
|
<MyType>WindowsForms</MyType>
|
||||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||||
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
|
<TargetFrameworkProfile>
|
||||||
|
</TargetFrameworkProfile>
|
||||||
<PublishUrl>publish\</PublishUrl>
|
<PublishUrl>publish\</PublishUrl>
|
||||||
<Install>true</Install>
|
<Install>true</Install>
|
||||||
<InstallFrom>Disk</InstallFrom>
|
<InstallFrom>Disk</InstallFrom>
|
||||||
@@ -40,6 +41,7 @@
|
|||||||
<OutputPath>bin\Debug\</OutputPath>
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
<DocumentationFile>TestMtApi.xml</DocumentationFile>
|
<DocumentationFile>TestMtApi.xml</DocumentationFile>
|
||||||
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||||
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
@@ -50,6 +52,7 @@
|
|||||||
<OutputPath>bin\Release\</OutputPath>
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
<DocumentationFile>TestMtApi.xml</DocumentationFile>
|
<DocumentationFile>TestMtApi.xml</DocumentationFile>
|
||||||
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||||
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OptionExplicit>On</OptionExplicit>
|
<OptionExplicit>On</OptionExplicit>
|
||||||
@@ -67,7 +70,6 @@
|
|||||||
<ApplicationManifest>My Project\app.manifest</ApplicationManifest>
|
<ApplicationManifest>My Project\app.manifest</ApplicationManifest>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="MtApi, Version=1.0.7.0, Culture=neutral, processorArchitecture=MSIL" />
|
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Data" />
|
<Reference Include="System.Data" />
|
||||||
<Reference Include="System.Deployment" />
|
<Reference Include="System.Deployment" />
|
||||||
@@ -126,6 +128,7 @@
|
|||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<None Include="App.config" />
|
||||||
<None Include="My Project\app.manifest" />
|
<None Include="My Project\app.manifest" />
|
||||||
<None Include="My Project\Application.myapp">
|
<None Include="My Project\Application.myapp">
|
||||||
<Generator>MyApplicationCodeGenerator</Generator>
|
<Generator>MyApplicationCodeGenerator</Generator>
|
||||||
@@ -159,6 +162,12 @@
|
|||||||
<Install>true</Install>
|
<Install>true</Install>
|
||||||
</BootstrapperPackage>
|
</BootstrapperPackage>
|
||||||
</ItemGroup>
|
</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" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- 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.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
|
||||||
Reference in New Issue
Block a user