mirror of
https://github.com/vdemydiuk/mtapi.git
synced 2026-08-06 07:27:50 +00:00
Compare commits
42 Commits
v1.0.30
...
mt4-1.0.32
| Author | SHA1 | Date | |
|---|---|---|---|
| 8e3f206c76 | |||
| 8e5dcbd2ee | |||
| 563a5a895b | |||
| 32f6018858 | |||
| c64417474a | |||
| 6d4b5f4c00 | |||
| 601c95369e | |||
| 0542dd3e71 | |||
| 15068ca99c | |||
| c3617549f8 | |||
| aa91196e31 | |||
| ba7b50e241 | |||
| ddcd6fa2d5 | |||
| ad55740bc7 | |||
| 26a3db9ae1 | |||
| 7d3af82e1f | |||
| 09b72fc64d | |||
| 834b0af430 | |||
| 5dd1e4831d | |||
| 39f11bfc34 | |||
| c6faaf0602 | |||
| c14726bdba | |||
| 05452e3b90 | |||
| 094cdcc448 | |||
| a63e628124 | |||
| 7fec3da7bc | |||
| 1d407b5e16 | |||
| e373f7976c | |||
| 3785ee4ace | |||
| b4b8e7eaf0 | |||
| 22f7915a4a | |||
| 84dfd21f9f | |||
| d4ee2cfada | |||
| 0b3d686f05 | |||
| cacc0ea787 | |||
| d96dc18ea3 | |||
| 6b4adfaa97 | |||
| 7aa2a1b691 | |||
| 5739423d6c | |||
| db4bb44fb3 | |||
| 68d5fa98af | |||
| dc28823ca9 |
Executable
BIN
Binary file not shown.
+341
-341
@@ -21,57 +21,57 @@ using namespace System::Security;
|
|||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
public struct CMqlRates
|
public struct CMqlRates
|
||||||
{
|
{
|
||||||
__int64 time; // Period start time
|
__int64 time; // Period start time
|
||||||
double open; // Open price
|
double open; // Open price
|
||||||
double high; // The highest price of the period
|
double high; // The highest price of the period
|
||||||
double low; // The lowest price of the period
|
double low; // The lowest price of the period
|
||||||
double close; // Close price
|
double close; // Close price
|
||||||
__int64 tick_volume; // Tick volume
|
__int64 tick_volume; // Tick volume
|
||||||
int spread; // Spread
|
int spread; // Spread
|
||||||
__int64 real_volume; // Trade volume
|
__int64 real_volume; // Trade volume
|
||||||
};
|
};
|
||||||
|
|
||||||
public struct CMqlTick
|
public struct CMqlTick
|
||||||
{
|
{
|
||||||
__int64 time; // Time of the last prices update
|
__int64 time; // Time of the last prices update
|
||||||
double bid; // Current Bid price
|
double bid; // Current Bid price
|
||||||
double ask; // Current Ask price
|
double ask; // Current Ask price
|
||||||
double last; // Price of the last deal (Last)
|
double last; // Price of the last deal (Last)
|
||||||
unsigned __int64 volume; // Volume for the current Last price
|
unsigned __int64 volume; // Volume for the current Last price
|
||||||
};
|
};
|
||||||
|
|
||||||
public struct CMqlBookInfo
|
public struct CMqlBookInfo
|
||||||
{
|
{
|
||||||
int type; // Order type from ENUM_BOOK_TYPE enumeration
|
int type; // Order type from ENUM_BOOK_TYPE enumeration
|
||||||
double price; // Price
|
double price; // Price
|
||||||
__int64 volume; // Volume
|
__int64 volume; // Volume
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
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);
|
||||||
memcpy(dest, wch, wcslen(wch) * sizeof(wchar_t));
|
memcpy(dest, wch, wcslen(wch) * sizeof(wchar_t));
|
||||||
dest[wcslen(wch)] = '\0';
|
dest[wcslen(wch)] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VerifySignature(System::String^ inputData, System::String^ signature, System::String^ publicKey)
|
bool VerifySignature(System::String^ inputData, System::String^ signature, System::String^ publicKey)
|
||||||
{
|
{
|
||||||
bool verifyResult = false;
|
bool verifyResult = false;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
DSACryptoServiceProvider^ dsa = gcnew DSACryptoServiceProvider();
|
DSACryptoServiceProvider^ dsa = gcnew DSACryptoServiceProvider();
|
||||||
dsa->FromXmlString(publicKey);
|
dsa->FromXmlString(publicKey);
|
||||||
array<System::Byte>^ data = UTF8Encoding::ASCII->GetBytes(inputData);
|
array<System::Byte>^ data = UTF8Encoding::ASCII->GetBytes(inputData);
|
||||||
array<System::Byte>^ signatureData = Convert::FromBase64String(signature);
|
array<System::Byte>^ signatureData = Convert::FromBase64String(signature);
|
||||||
verifyResult = dsa->VerifyData(data, signatureData);
|
verifyResult = dsa->VerifyData(data, signatureData);
|
||||||
}
|
}
|
||||||
catch(Exception^ e)
|
catch(Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:VerifySignature(): failed. " + e->Message);
|
Debug::WriteLine("[ERROR] MT5Connector:VerifySignature(): failed. " + e->Message);
|
||||||
verifyResult = false;
|
verifyResult = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return verifyResult;
|
return verifyResult;
|
||||||
}
|
}
|
||||||
@@ -80,431 +80,431 @@ bool g_IsVerified = true;
|
|||||||
|
|
||||||
void _stdcall verify(int isDemo, wchar_t* accountName, long accountNumber)
|
void _stdcall verify(int isDemo, wchar_t* accountName, long accountNumber)
|
||||||
{
|
{
|
||||||
if (isDemo != 0)
|
if (isDemo != 0)
|
||||||
{
|
{
|
||||||
g_IsVerified = true;
|
g_IsVerified = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
System::String^ signature = MtRegistryManager::ReadSignatureKey(gcnew String(accountName), accountNumber.ToString());
|
System::String^ signature = MtRegistryManager::ReadSignatureKey(gcnew String(accountName), accountNumber.ToString());
|
||||||
Resources::ResourceManager^ rm = gcnew Resources::ResourceManager(L"MT5Connector.cl", Assembly::GetExecutingAssembly());
|
Resources::ResourceManager^ rm = gcnew Resources::ResourceManager(L"MT5Connector.cl", Assembly::GetExecutingAssembly());
|
||||||
System::String^ inputData = gcnew System::String(accountName);
|
System::String^ inputData = gcnew System::String(accountName);
|
||||||
inputData += accountNumber.ToString();
|
inputData += accountNumber.ToString();
|
||||||
System::String^ publicKey = rm->GetString(L"cl");
|
System::String^ publicKey = rm->GetString(L"cl");
|
||||||
g_IsVerified = VerifySignature(inputData, gcnew System::String(signature), publicKey);
|
g_IsVerified = VerifySignature(inputData, gcnew System::String(signature), publicKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall initExpert(int expertHandle, int port, wchar_t* symbol, double bid, double ask, wchar_t* err)
|
int _stdcall initExpert(int expertHandle, int port, wchar_t* symbol, double bid, double ask, wchar_t* err)
|
||||||
{
|
{
|
||||||
if (g_IsVerified == false)
|
if (g_IsVerified == false)
|
||||||
{
|
{
|
||||||
System::String^ errorVerified = "Verification is failed!\nPlease contact with support.";
|
System::String^ errorVerified = "Verification is failed!\nPlease contact with support.";
|
||||||
convertSystemString(err, errorVerified);
|
convertSystemString(err, errorVerified);
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:initExpert(): not verified");
|
Debug::WriteLine("[ERROR] MT5Connector:initExpert(): not verified");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MT5Handler^ mtHander = gcnew MT5Handler();
|
MT5Handler^ mtHander = gcnew MT5Handler();
|
||||||
MtServerInstance::GetInstance()->InitExpert(expertHandle, port, gcnew String(symbol), bid, ask, mtHander);
|
MtServerInstance::GetInstance()->InitExpert(expertHandle, port, gcnew String(symbol), bid, ask, mtHander);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
convertSystemString(err, e->Message);
|
convertSystemString(err, e->Message);
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:initExpert(): " + e->Message);
|
Debug::WriteLine("[ERROR] MT5Connector:initExpert(): " + e->Message);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall deinitExpert(int expertHandle, wchar_t* err)
|
int _stdcall deinitExpert(int expertHandle, wchar_t* err)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MtServerInstance::GetInstance()->DeinitExpert(expertHandle);
|
MtServerInstance::GetInstance()->DeinitExpert(expertHandle);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
convertSystemString(err, e->Message);
|
convertSystemString(err, e->Message);
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:deinitExpert(): " + e->Message);
|
Debug::WriteLine("[ERROR] MT5Connector:deinitExpert(): " + e->Message);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall updateQuote(int expertHandle, wchar_t* symbol, double bid, double ask, wchar_t* err)
|
int _stdcall updateQuote(int expertHandle, wchar_t* symbol, double bid, double ask, wchar_t* err)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MtServerInstance::GetInstance()->SendQuote(expertHandle, gcnew String(symbol), bid, ask);
|
MtServerInstance::GetInstance()->SendQuote(expertHandle, gcnew String(symbol), bid, ask);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
convertSystemString(err, e->Message);
|
convertSystemString(err, e->Message);
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:updateQuote(): " + e->Message);
|
Debug::WriteLine("[ERROR] MT5Connector:updateQuote(): " + e->Message);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall sendIntResponse(int expertHandle, int response)
|
int _stdcall sendIntResponse(int expertHandle, int response)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseInt(response));
|
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseInt(response));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:sendIntResponse(): " + e->Message);
|
Debug::WriteLine("[ERROR] MT5Connector:sendIntResponse(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall sendLongResponse(int expertHandle, __int64 response)
|
int _stdcall sendLongResponse(int expertHandle, __int64 response)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLong(response));
|
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLong(response));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:sendLongResponse(): " + e->Message);
|
Debug::WriteLine("[ERROR] MT5Connector:sendLongResponse(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall sendULongResponse(int expertHandle, unsigned __int64 response)
|
int _stdcall sendULongResponse(int expertHandle, unsigned __int64 response)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseULong(response));
|
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseULong(response));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:sendLongResponse(): " + e->Message);
|
Debug::WriteLine("[ERROR] MT5Connector:sendLongResponse(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall sendBooleanResponse(int expertHandle, int response)
|
int _stdcall sendBooleanResponse(int expertHandle, int response)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bool value = (response != 0) ? true : false;
|
bool value = (response != 0) ? true : false;
|
||||||
|
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseBool(value));
|
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseBool(value));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:sendBooleanResponse(): " + e->Message);
|
Debug::WriteLine("[ERROR] MT5Connector:sendBooleanResponse(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall sendDoubleResponse(int expertHandle, double response)
|
int _stdcall sendDoubleResponse(int expertHandle, double response)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDouble(response));
|
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDouble(response));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:sendDoubleResponse(): " + e->Message);
|
Debug::WriteLine("[ERROR] MT5Connector:sendDoubleResponse(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall sendStringResponse(int expertHandle, wchar_t* response)
|
int _stdcall sendStringResponse(int expertHandle, wchar_t* response)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseString(gcnew String(response)));
|
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseString(gcnew String(response)));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:sendStringResponse(): " + e->Message);
|
Debug::WriteLine("[ERROR] MT5Connector:sendStringResponse(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall sendVoidResponse(int expertHandle)
|
int _stdcall sendVoidResponse(int expertHandle)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, nullptr);
|
MtServerInstance::GetInstance()->SendResponse(expertHandle, nullptr);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:sendVoidResponse(): " + e->Message);
|
Debug::WriteLine("[ERROR] MT5Connector:sendVoidResponse(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall sendDoubleArrayResponse(int expertHandle, double* values, int size)
|
int _stdcall sendDoubleArrayResponse(int expertHandle, double* values, int size)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
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];
|
||||||
}
|
}
|
||||||
|
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDoubleArray(list));
|
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDoubleArray(list));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:sendDoubleArrayResponse(): " + e->Message);
|
Debug::WriteLine("[ERROR] MT5Connector:sendDoubleArrayResponse(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall sendIntArrayResponse(int expertHandle, int* values, int size)
|
int _stdcall sendIntArrayResponse(int expertHandle, int* values, int size)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
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];
|
||||||
}
|
}
|
||||||
|
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseIntArray(list));
|
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseIntArray(list));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:sendIntArrayResponse(): " + e->Message);
|
Debug::WriteLine("[ERROR] MT5Connector:sendIntArrayResponse(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall sendLongArrayResponse(int expertHandle, __int64* values, int size)
|
int _stdcall sendLongArrayResponse(int expertHandle, __int64* values, int size)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
array<System::Int64>^ list = gcnew array<System::Int64>(size);
|
array<System::Int64>^ list = gcnew array<System::Int64>(size);
|
||||||
|
|
||||||
for(int i = 0; i < size; i++)
|
for(int i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
list[i] = values[i];
|
list[i] = values[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLongArray(list));
|
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLongArray(list));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:sendLongArrayResponse(): " + e->Message);
|
Debug::WriteLine("[ERROR] MT5Connector:sendLongArrayResponse(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall sendMqlRatesArrayResponse(int expertHandle, CMqlRates values[], int size)
|
int _stdcall sendMqlRatesArrayResponse(int expertHandle, CMqlRates values[], int size)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
array<MtMqlRates^>^ list = gcnew array<MtMqlRates^>(size);
|
array<MtMqlRates^>^ list = gcnew array<MtMqlRates^>(size);
|
||||||
|
|
||||||
for(int i = 0; i < size; i++)
|
for(int i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
MtMqlRates^ rates = gcnew MtMqlRates();
|
MtMqlRates^ rates = gcnew MtMqlRates();
|
||||||
rates->time = values[i].time;
|
rates->time = values[i].time;
|
||||||
rates->open = values[i].open;
|
rates->open = values[i].open;
|
||||||
rates->high = values[i].high;
|
rates->high = values[i].high;
|
||||||
rates->low = values[i].low;
|
rates->low = values[i].low;
|
||||||
rates->close = values[i].close;
|
rates->close = values[i].close;
|
||||||
rates->tick_volume = values[i].tick_volume;
|
rates->tick_volume = values[i].tick_volume;
|
||||||
rates->spread = values[i].spread;
|
rates->spread = values[i].spread;
|
||||||
rates->real_volume = values[i].real_volume;
|
rates->real_volume = values[i].real_volume;
|
||||||
|
|
||||||
list[i] = rates;
|
list[i] = rates;
|
||||||
}
|
}
|
||||||
|
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlRatesArray(list));
|
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlRatesArray(list));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:sendMqlRatesArrayResponse(): " + e->Message);
|
Debug::WriteLine("[ERROR] MT5Connector:sendMqlRatesArrayResponse(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall sendMqlTickResponse(int expertHandle, CMqlTick* response, int size)
|
int _stdcall sendMqlTickResponse(int expertHandle, CMqlTick* response, int size)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MtMqlTick^ mtResponse = gcnew MtMqlTick();
|
MtMqlTick^ mtResponse = gcnew MtMqlTick();
|
||||||
|
|
||||||
mtResponse->time = response->time;
|
mtResponse->time = response->time;
|
||||||
mtResponse->bid = response->bid;
|
mtResponse->bid = response->bid;
|
||||||
mtResponse->ask = response->ask;
|
mtResponse->ask = response->ask;
|
||||||
mtResponse->last = response->last;
|
mtResponse->last = response->last;
|
||||||
mtResponse->volume = response->volume;
|
mtResponse->volume = response->volume;
|
||||||
|
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlTick(mtResponse));
|
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlTick(mtResponse));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:sendMqlTickResponse(): " + e->Message);
|
Debug::WriteLine("[ERROR] MT5Connector:sendMqlTickResponse(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall sendMqlBookInfoArrayResponse(int expertHandle, CMqlBookInfo values[], int size)
|
int _stdcall sendMqlBookInfoArrayResponse(int expertHandle, CMqlBookInfo values[], int size)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
array<MtMqlBookInfo^>^ list = gcnew array<MtMqlBookInfo^>(size);
|
array<MtMqlBookInfo^>^ list = gcnew array<MtMqlBookInfo^>(size);
|
||||||
|
|
||||||
for(int i = 0; i < size; i++)
|
for(int i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
MtMqlBookInfo^ info = gcnew MtMqlBookInfo();
|
MtMqlBookInfo^ info = gcnew MtMqlBookInfo();
|
||||||
|
|
||||||
info->type = values[i].type;
|
info->type = values[i].type;
|
||||||
info->price = values[i].price;
|
info->price = values[i].price;
|
||||||
info->volume = values[i].volume;
|
info->volume = values[i].volume;
|
||||||
|
|
||||||
list[i] = info;
|
list[i] = info;
|
||||||
}
|
}
|
||||||
|
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlBookInfoArray(list));
|
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlBookInfoArray(list));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:sendMqlRatesArrayResponse(): " + e->Message);
|
Debug::WriteLine("[ERROR] MT5Connector:sendMqlRatesArrayResponse(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------- get values -------------------------------
|
//----------- get values -------------------------------
|
||||||
|
|
||||||
int _stdcall getCommandType(int expertHandle, int* res)
|
int _stdcall getCommandType(int expertHandle, int* res)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
*res = MtServerInstance::GetInstance()->GetCommandType(expertHandle);
|
*res = MtServerInstance::GetInstance()->GetCommandType(expertHandle);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:getCommandType(): " + e->Message);
|
Debug::WriteLine("[ERROR] MT5Connector:getCommandType(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall getIntValue(int expertHandle, int paramIndex, int* res)
|
int _stdcall getIntValue(int expertHandle, int paramIndex, int* res)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
*res = (int)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
*res = (int)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:getIntValue(): " + e->Message);
|
Debug::WriteLine("[ERROR] MT5Connector:getIntValue(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall getDoubleValue(int expertHandle, int paramIndex, double* res)
|
int _stdcall getDoubleValue(int expertHandle, int paramIndex, double* res)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
*res = (double)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
*res = (double)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:getDoubleValue(): " + e->Message);
|
Debug::WriteLine("[ERROR] MT5Connector:getDoubleValue(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall getStringValue(int expertHandle, int paramIndex, wchar_t* res)
|
int _stdcall getStringValue(int expertHandle, int paramIndex, wchar_t* res)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
convertSystemString(res, (String^)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex));
|
convertSystemString(res, (String^)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:getStringValue(): " + e->Message);
|
Debug::WriteLine("[ERROR] MT5Connector:getStringValue(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall getULongValue(int expertHandle, int paramIndex, unsigned __int64* res)
|
int _stdcall getULongValue(int expertHandle, int paramIndex, unsigned __int64* res)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
*res = (unsigned long)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
*res = (unsigned long)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:getULongValue(): " + e->Message);
|
Debug::WriteLine("[ERROR] MT5Connector:getULongValue(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall getLongValue(int expertHandle, int paramIndex, __int64* res)
|
int _stdcall getLongValue(int expertHandle, int paramIndex, __int64* res)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
*res = (long)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
*res = (long)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:getLongValue(): " + e->Message);
|
Debug::WriteLine("[ERROR] MT5Connector:getLongValue(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall getBooleanValue(int expertHandle, int paramIndex, int* res)
|
int _stdcall getBooleanValue(int expertHandle, int paramIndex, int* res)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bool val = (bool)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
bool val = (bool)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
||||||
*res = val == true ? 1 : 0;
|
*res = val == true ? 1 : 0;
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:getBooleanValue(): " + e->Message);
|
Debug::WriteLine("[ERROR] MT5Connector:getBooleanValue(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall getUIntValue(int expertHandle, int paramIndex, unsigned int* res)
|
int _stdcall getUIntValue(int expertHandle, int paramIndex, unsigned int* res)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
*res = (unsigned int)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
*res = (unsigned int)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MT5Connector:getUIntValue(): " + e->Message);
|
Debug::WriteLine("[ERROR] MT5Connector:getUIntValue(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -9,16 +9,16 @@ using namespace MTApiService;
|
|||||||
ref class MT5Handler: IMetaTraderHandler
|
ref class MT5Handler: IMetaTraderHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MT5Handler()
|
MT5Handler()
|
||||||
{
|
{
|
||||||
msgId = WM_USER + 4096;
|
msgId = WM_TIMER;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void SendTickToMetaTrader(int handle)
|
virtual void SendTickToMetaTrader(int handle)
|
||||||
{
|
{
|
||||||
PostMessage((HWND)handle, msgId, 0x00000011, 0);
|
PostMessage((HWND)handle, msgId, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int msgId;
|
unsigned int msgId;
|
||||||
};
|
};
|
||||||
Executable
+67
@@ -0,0 +1,67 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<!-- -->
|
||||||
|
<!-- ILMerge project-specific settings. Almost never need to be set explicitly. -->
|
||||||
|
<!-- for details, see http://research.microsoft.com/en-us/people/mbarnett/ilmerge.aspx -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- *** set this file to Type=None, CopyToOutput=Never *** -->
|
||||||
|
|
||||||
|
<!-- If True, all copy local dependencies will also be merged from referenced projects whether they are referenced in the current project explicitly or not -->
|
||||||
|
<ILMergeTransitive>true</ILMergeTransitive>
|
||||||
|
|
||||||
|
<!-- Extra ILMerge library paths (semicolon-separated). Dont put your package dependencies here, they will be added automagically -->
|
||||||
|
<ILMergeLibraryPath></ILMergeLibraryPath>
|
||||||
|
|
||||||
|
<!-- The solution NuGet package directory if not standard 'SOLUTION\packages' -->
|
||||||
|
<ILMergePackagesPath></ILMergePackagesPath>
|
||||||
|
|
||||||
|
<!-- The merge order file name if differs from standard 'ILMergeOrder.txt' -->
|
||||||
|
<ILMergeOrderFile></ILMergeOrderFile>
|
||||||
|
|
||||||
|
<!-- The strong key file name if not specified in the project -->
|
||||||
|
<ILMergeKeyFile>MtApiKey.snk</ILMergeKeyFile>
|
||||||
|
|
||||||
|
<!-- The assembly version if differs for the version of the main assembly -->
|
||||||
|
<ILMergeAssemblyVersion></ILMergeAssemblyVersion>
|
||||||
|
|
||||||
|
<!-- added in Version 1.0.4 -->
|
||||||
|
<ILMergeFileAlignment></ILMergeFileAlignment>
|
||||||
|
|
||||||
|
<!-- added in Version 1.0.4, default=none -->
|
||||||
|
<ILMergeAllowDuplicateType></ILMergeAllowDuplicateType>
|
||||||
|
|
||||||
|
<!-- If the <see cref="CopyAttributes"/> is also set, any assembly-level attributes names that have the same type are copied over into the target assembly -->
|
||||||
|
<ILMergeAllowMultipleAssemblyLevelAttributes></ILMergeAllowMultipleAssemblyLevelAttributes>
|
||||||
|
|
||||||
|
<!-- See ILMerge documentation -->
|
||||||
|
<ILMergeAllowZeroPeKind></ILMergeAllowZeroPeKind>
|
||||||
|
|
||||||
|
<!-- The assembly level attributes of each input assembly are copied over into the target assembly -->
|
||||||
|
<ILMergeCopyAttributes></ILMergeCopyAttributes>
|
||||||
|
|
||||||
|
<!-- Creates a .pdb file for the output assembly and merges into it any .pdb files found for input assemblies, default=true -->
|
||||||
|
<ILMergeDebugInfo></ILMergeDebugInfo>
|
||||||
|
|
||||||
|
<!-- Target assembly will be delay signed -->
|
||||||
|
<ILMergeDelaySign></ILMergeDelaySign>
|
||||||
|
|
||||||
|
<!-- Types in assemblies other than the primary assembly have their visibility modified -->
|
||||||
|
<ILMergeInternalize></ILMergeInternalize>
|
||||||
|
|
||||||
|
<!-- The path name of the file that will be used to identify types that are not to have their visibility modified -->
|
||||||
|
<ILMergeInternalizeExcludeFile></ILMergeInternalizeExcludeFile>
|
||||||
|
|
||||||
|
<!-- XML documentation files are merged to produce an XML documentation file for the target assembly -->
|
||||||
|
<ILMergeXmlDocumentation></ILMergeXmlDocumentation>
|
||||||
|
|
||||||
|
<!-- External assembly references in the manifest of the target assembly will use full public keys (false) or public key tokens (true, default value) -->
|
||||||
|
<ILMergePublicKeyTokens></ILMergePublicKeyTokens>
|
||||||
|
|
||||||
|
<!-- Types with the same name are all merged into a single type in the target assembly -->
|
||||||
|
<ILMergeUnionMerge></ILMergeUnionMerge>
|
||||||
|
|
||||||
|
<!-- The version of the target framework, default 40 (works for 45 too) -->
|
||||||
|
<ILTargetPlatform></ILTargetPlatform>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
Executable
+4
@@ -0,0 +1,4 @@
|
|||||||
|
# this file contains the partial list of the merged assemblies in the merge order
|
||||||
|
# you can fill it from the obj\CONFIG\PROJECT.ilmerge generated on every build
|
||||||
|
# and finetune merge order to your satisfaction
|
||||||
|
|
||||||
@@ -1,13 +1,10 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace MTApiService
|
namespace MTApiService
|
||||||
{
|
{
|
||||||
public interface IMtApiServer
|
public interface IMtApiServer
|
||||||
{
|
{
|
||||||
MtResponse SendCommand(MtCommand command);
|
MtResponse SendCommand(MtCommand command);
|
||||||
IEnumerable<MtQuote> GetQuotes();
|
List<MtQuote> GetQuotes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Executable
+56
@@ -0,0 +1,56 @@
|
|||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using log4net;
|
||||||
|
using log4net.Appender;
|
||||||
|
using log4net.Core;
|
||||||
|
using log4net.Layout;
|
||||||
|
using log4net.Repository.Hierarchy;
|
||||||
|
|
||||||
|
namespace MTApiService
|
||||||
|
{
|
||||||
|
public class LogConfigurator
|
||||||
|
{
|
||||||
|
private const string LogFileNameExtension = "txt";
|
||||||
|
|
||||||
|
public static void Setup(string profileName)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(profileName))
|
||||||
|
throw new ArgumentNullException();
|
||||||
|
|
||||||
|
var hierarchy = (Hierarchy) LogManager.GetRepository();
|
||||||
|
|
||||||
|
var patternLayout = new PatternLayout
|
||||||
|
{
|
||||||
|
ConversionPattern = "%date [%thread] %-5level %logger - %message%newline"
|
||||||
|
};
|
||||||
|
patternLayout.ActivateOptions();
|
||||||
|
|
||||||
|
string filename = $"{DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss")}-{Process.GetCurrentProcess().Id}.{LogFileNameExtension}";
|
||||||
|
|
||||||
|
var roller = new RollingFileAppender
|
||||||
|
{
|
||||||
|
AppendToFile = false,
|
||||||
|
File = $@"{System.IO.Path.GetTempPath()}{profileName}\Logs\{filename}",
|
||||||
|
Layout = patternLayout,
|
||||||
|
PreserveLogFileNameExtension = true,
|
||||||
|
MaxSizeRollBackups = 5,
|
||||||
|
MaximumFileSize = "1GB",
|
||||||
|
RollingStyle = RollingFileAppender.RollingMode.Size,
|
||||||
|
StaticLogFileName = false
|
||||||
|
};
|
||||||
|
roller.ActivateOptions();
|
||||||
|
hierarchy.Root.AddAppender(roller);
|
||||||
|
|
||||||
|
var memory = new MemoryAppender();
|
||||||
|
memory.ActivateOptions();
|
||||||
|
hierarchy.Root.AddAppender(memory);
|
||||||
|
|
||||||
|
#if (DEBUG)
|
||||||
|
hierarchy.Root.Level = Level.Debug;
|
||||||
|
#else
|
||||||
|
hierarchy.Root.Level = Level.Info;
|
||||||
|
#endif
|
||||||
|
hierarchy.Configured = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="..\packages\MSBuild.ILMerge.Task.1.0.5\build\MSBuild.ILMerge.Task.props" Condition="Exists('..\packages\MSBuild.ILMerge.Task.1.0.5\build\MSBuild.ILMerge.Task.props')" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
@@ -14,6 +15,8 @@
|
|||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<TargetFrameworkProfile>
|
<TargetFrameworkProfile>
|
||||||
</TargetFrameworkProfile>
|
</TargetFrameworkProfile>
|
||||||
|
<NuGetPackageImportStamp>
|
||||||
|
</NuGetPackageImportStamp>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
@@ -35,12 +38,17 @@
|
|||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<SignAssembly>true</SignAssembly>
|
<SignAssembly>false</SignAssembly>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<AssemblyOriginatorKeyFile>MtApiKey.pfx</AssemblyOriginatorKeyFile>
|
<AssemblyOriginatorKeyFile>
|
||||||
|
</AssemblyOriginatorKeyFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Reference Include="log4net, Version=1.2.15.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\log4net.2.0.5\lib\net40-full\log4net.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.Runtime.Serialization" />
|
<Reference Include="System.Runtime.Serialization" />
|
||||||
@@ -54,6 +62,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="ICommandManager.cs" />
|
<Compile Include="ICommandManager.cs" />
|
||||||
<Compile Include="IMetaTraderHandler.cs" />
|
<Compile Include="IMetaTraderHandler.cs" />
|
||||||
|
<Compile Include="LogConfigurator.cs" />
|
||||||
<Compile Include="MtCommandEventArgs.cs" />
|
<Compile Include="MtCommandEventArgs.cs" />
|
||||||
<Compile Include="IDisposableChannel.cs" />
|
<Compile Include="IDisposableChannel.cs" />
|
||||||
<Compile Include="IMtApiServer.cs" />
|
<Compile Include="IMtApiServer.cs" />
|
||||||
@@ -78,13 +87,28 @@
|
|||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="MtApiKey.pfx" />
|
<None Include="ILMerge.props">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</None>
|
||||||
|
<None Include="MtApiKey.snk" />
|
||||||
|
<None Include="packages.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="ILMergeOrder.txt" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||||
|
<PropertyGroup>
|
||||||
|
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Error Condition="!Exists('..\packages\MSBuild.ILMerge.Task.1.0.5\build\MSBuild.ILMerge.Task.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSBuild.ILMerge.Task.1.0.5\build\MSBuild.ILMerge.Task.props'))" />
|
||||||
|
<Error Condition="!Exists('..\packages\MSBuild.ILMerge.Task.1.0.5\build\MSBuild.ILMerge.Task.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSBuild.ILMerge.Task.1.0.5\build\MSBuild.ILMerge.Task.targets'))" />
|
||||||
|
</Target>
|
||||||
|
<Import Project="..\packages\MSBuild.ILMerge.Task.1.0.5\build\MSBuild.ILMerge.Task.targets" Condition="Exists('..\packages\MSBuild.ILMerge.Task.1.0.5\build\MSBuild.ILMerge.Task.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.
|
||||||
<Target Name="BeforeBuild">
|
<Target Name="BeforeBuild">
|
||||||
|
|||||||
Binary file not shown.
Executable
BIN
Binary file not shown.
+11
-14
@@ -1,20 +1,17 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.ServiceModel;
|
using System.ServiceModel;
|
||||||
using System.ServiceModel.Channels;
|
using System.ServiceModel.Channels;
|
||||||
|
|
||||||
namespace MTApiService
|
namespace MTApiService
|
||||||
{
|
{
|
||||||
class MtApiProxy : DuplexClientBase<IMtApi>, IMtApi, IDisposable
|
internal class MtApiProxy : DuplexClientBase<IMtApi>, IMtApi, IDisposable
|
||||||
{
|
{
|
||||||
public MtApiProxy(InstanceContext callbackContext, Binding binding,
|
public MtApiProxy(InstanceContext callbackContext, Binding binding, EndpointAddress remoteAddress)
|
||||||
EndpointAddress remoteAddress)
|
|
||||||
: base(callbackContext, binding, remoteAddress)
|
: base(callbackContext, binding, remoteAddress)
|
||||||
{
|
{
|
||||||
base.InnerDuplexChannel.Faulted += new EventHandler(InnerDuplexChannel_Faulted);
|
InnerDuplexChannel.Faulted += InnerDuplexChannel_Faulted;
|
||||||
base.InnerDuplexChannel.Open();
|
InnerDuplexChannel.Open();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region IMtApi Members
|
#region IMtApi Members
|
||||||
@@ -34,7 +31,7 @@ namespace MTApiService
|
|||||||
return Channel.SendCommand(command);
|
return Channel.SendCommand(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<MtQuote> GetQuotes()
|
public List<MtQuote> GetQuotes()
|
||||||
{
|
{
|
||||||
return Channel.GetQuotes();
|
return Channel.GetQuotes();
|
||||||
}
|
}
|
||||||
@@ -47,19 +44,19 @@ namespace MTApiService
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
this.Close();
|
Close();
|
||||||
}
|
}
|
||||||
catch (CommunicationException)
|
catch (CommunicationException)
|
||||||
{
|
{
|
||||||
this.Abort();
|
Abort();
|
||||||
}
|
}
|
||||||
catch (TimeoutException)
|
catch (TimeoutException)
|
||||||
{
|
{
|
||||||
this.Abort();
|
Abort();
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
this.Abort();
|
Abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,9 +65,9 @@ namespace MTApiService
|
|||||||
#region Private Methods
|
#region Private Methods
|
||||||
private void InnerDuplexChannel_Faulted(object sender, EventArgs e)
|
private void InnerDuplexChannel_Faulted(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (Faulted != null)
|
Faulted?.Invoke(this, e);
|
||||||
Faulted(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
|
|||||||
+175
-137
@@ -1,173 +1,208 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.ServiceModel;
|
using System.ServiceModel;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using log4net;
|
||||||
|
|
||||||
namespace MTApiService
|
namespace MTApiService
|
||||||
{
|
{
|
||||||
[CallbackBehavior(UseSynchronizationContext = false)]
|
[CallbackBehavior(UseSynchronizationContext = false)]
|
||||||
public class MtClient: IMtApiCallback, IDisposable
|
public class MtClient: IMtApiCallback, IDisposable
|
||||||
{
|
{
|
||||||
private static string SERVICE_NAME = "MtApiService";
|
private const string ServiceName = "MtApiService";
|
||||||
|
|
||||||
public delegate void MtQuoteHandler(MtQuote quote);
|
public delegate void MtQuoteHandler(MtQuote quote);
|
||||||
|
|
||||||
|
#region Fields
|
||||||
|
private static readonly ILog Log = LogManager.GetLogger(typeof(MtClient));
|
||||||
|
|
||||||
|
private MtApiProxy _proxy;
|
||||||
|
private bool _isConnected;
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Public Methods
|
#region Public Methods
|
||||||
public void Open(string host, int port)
|
public void Open(string host, int port)
|
||||||
{
|
{
|
||||||
Debug.WriteLine("[INFO] MtClient::Open");
|
Log.DebugFormat("Open: begin. host = {0}, port = {1}", host, port);
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(host))
|
if (string.IsNullOrEmpty(host))
|
||||||
throw new ArgumentNullException("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("port", "port value is invalid");
|
throw new ArgumentOutOfRangeException(nameof(port), "port value is invalid");
|
||||||
|
|
||||||
var urlService = string.Format("net.tcp://{0}:{1}/{2}", host, port, SERVICE_NAME);
|
var urlService = $"net.tcp://{host}:{port}/{ServiceName}";
|
||||||
|
|
||||||
lock (mClientLocker)
|
if (_proxy != null)
|
||||||
{
|
{
|
||||||
if (mProxy != null)
|
Log.Warn("Open: end. _proxy is not null.");
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var bind = new NetTcpBinding(SecurityMode.None)
|
|
||||||
{
|
|
||||||
MaxReceivedMessageSize = 2147483647,
|
|
||||||
MaxBufferSize = 2147483647,
|
|
||||||
MaxBufferPoolSize = 2147483647,
|
|
||||||
ReaderQuotas =
|
|
||||||
{
|
|
||||||
MaxArrayLength = 2147483647,
|
|
||||||
MaxBytesPerRead = 2147483647,
|
|
||||||
MaxDepth = 2147483647,
|
|
||||||
MaxStringContentLength = 2147483647,
|
|
||||||
MaxNameTableCharCount = 2147483647
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// Commented next statement since it is not required
|
|
||||||
|
|
||||||
mProxy = new MtApiProxy(new InstanceContext(this), bind, new EndpointAddress(urlService));
|
|
||||||
mProxy.Faulted += mProxy_Faulted;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var bind = new NetTcpBinding(SecurityMode.None)
|
||||||
|
{
|
||||||
|
MaxReceivedMessageSize = 2147483647,
|
||||||
|
MaxBufferSize = 2147483647,
|
||||||
|
MaxBufferPoolSize = 2147483647,
|
||||||
|
SendTimeout = new TimeSpan(12, 0, 0),
|
||||||
|
ReceiveTimeout = new TimeSpan(12, 0, 0),
|
||||||
|
ReaderQuotas =
|
||||||
|
{
|
||||||
|
MaxArrayLength = 2147483647,
|
||||||
|
MaxBytesPerRead = 2147483647,
|
||||||
|
MaxDepth = 2147483647,
|
||||||
|
MaxStringContentLength = 2147483647,
|
||||||
|
MaxNameTableCharCount = 2147483647
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Commented next statement since it is not required
|
||||||
|
|
||||||
|
_proxy = new MtApiProxy(new InstanceContext(this), bind, new EndpointAddress(urlService));
|
||||||
|
_proxy.Faulted += ProxyFaulted;
|
||||||
|
|
||||||
|
Log.Debug("Open: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Open(int port)
|
public void Open(int port)
|
||||||
{
|
{
|
||||||
|
Log.DebugFormat("Open: begin. port = {0}", port);
|
||||||
|
|
||||||
if (port < 0 || port > 65536)
|
if (port < 0 || port > 65536)
|
||||||
throw new ArgumentOutOfRangeException("port", "port value is invalid");
|
throw new ArgumentOutOfRangeException(nameof(port), "port value is invalid");
|
||||||
|
|
||||||
var urlService = string.Format("net.pipe://localhost/{0}_{1}", SERVICE_NAME, port);
|
var urlService = $"net.pipe://localhost/{ServiceName}_{port}";
|
||||||
|
|
||||||
lock (mClientLocker)
|
if (_proxy != null)
|
||||||
{
|
{
|
||||||
if (mProxy != null)
|
Log.Warn("Open: end. _proxy is not null.");
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var bind = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
|
|
||||||
{
|
|
||||||
MaxReceivedMessageSize = 2147483647,
|
|
||||||
MaxBufferSize = 2147483647,
|
|
||||||
MaxBufferPoolSize = 2147483647,
|
|
||||||
ReaderQuotas =
|
|
||||||
{
|
|
||||||
MaxArrayLength = 2147483647,
|
|
||||||
MaxBytesPerRead = 2147483647,
|
|
||||||
MaxDepth = 2147483647,
|
|
||||||
MaxStringContentLength = 2147483647,
|
|
||||||
MaxNameTableCharCount = 2147483647
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// Commented next statement since it is not required
|
|
||||||
|
|
||||||
mProxy = new MtApiProxy(new InstanceContext(this), bind, new EndpointAddress(urlService));
|
|
||||||
mProxy.Faulted += mProxy_Faulted;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var bind = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
|
||||||
|
{
|
||||||
|
MaxReceivedMessageSize = 2147483647,
|
||||||
|
MaxBufferSize = 2147483647,
|
||||||
|
MaxBufferPoolSize = 2147483647,
|
||||||
|
SendTimeout = new TimeSpan(12, 0, 0),
|
||||||
|
ReceiveTimeout = new TimeSpan(12, 0, 0),
|
||||||
|
ReaderQuotas =
|
||||||
|
{
|
||||||
|
MaxArrayLength = 2147483647,
|
||||||
|
MaxBytesPerRead = 2147483647,
|
||||||
|
MaxDepth = 2147483647,
|
||||||
|
MaxStringContentLength = 2147483647,
|
||||||
|
MaxNameTableCharCount = 2147483647
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Commented next statement since it is not required
|
||||||
|
|
||||||
|
_proxy = new MtApiProxy(new InstanceContext(this), bind, new EndpointAddress(urlService));
|
||||||
|
_proxy.Faulted += ProxyFaulted;
|
||||||
|
|
||||||
|
Log.Debug("Open: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
Debug.WriteLine("[INFO] MtClient::Close");
|
Log.Debug("Close: begin.");
|
||||||
|
|
||||||
lock (mClientLocker)
|
if (_proxy != null)
|
||||||
{
|
{
|
||||||
if (mProxy != null)
|
_proxy.Faulted -= ProxyFaulted;
|
||||||
{
|
_proxy.Dispose();
|
||||||
mProxy.Faulted -= mProxy_Faulted;
|
_proxy = null;
|
||||||
mProxy.Dispose();
|
|
||||||
mProxy = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
mIsConnected = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_isConnected = false;
|
||||||
|
|
||||||
|
Log.Debug("Close: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <exception cref="CommunicationException">Thrown when connection failed</exception>
|
||||||
public void Connect()
|
public void Connect()
|
||||||
{
|
{
|
||||||
Debug.WriteLine("[INFO] MtClient::Connect");
|
Log.Debug("Connect: begin.");
|
||||||
|
|
||||||
|
if (_proxy == null)
|
||||||
|
{
|
||||||
|
Log.Error("Connect: _proxy is not defined.");
|
||||||
|
throw new CommunicationException("Connection failed to service. Proxy is not defined (needs to call Open)");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_isConnected)
|
||||||
|
{
|
||||||
|
Log.Warn("Connected: end. Client is already connected.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
lock (mClientLocker)
|
_isConnected = _proxy.Connect();
|
||||||
{
|
|
||||||
if (mProxy != null && mIsConnected == true)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mIsConnected = mProxy.Connect();
|
|
||||||
|
|
||||||
if (mIsConnected == false)
|
|
||||||
throw new Exception("Connected failed");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Debug.WriteLine("[ERROR] MtClient::Connect: {0}", ex.Message);
|
Log.ErrorFormat("Connect: Exception - {0}", ex.Message);
|
||||||
|
|
||||||
Close();
|
Close();
|
||||||
|
|
||||||
throw new CommunicationException(string.Format("Connection failed to service"));
|
throw new CommunicationException($"Connection failed to service. {ex.Message}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_isConnected == false)
|
||||||
|
{
|
||||||
|
Log.Error("Connect: end. Connection failed.");
|
||||||
|
throw new CommunicationException("Connection failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.Debug("Connect: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Disconnect()
|
public void Disconnect()
|
||||||
{
|
{
|
||||||
Debug.WriteLine("[INFO] MtClient::Disconnect");
|
Log.Debug("Disconnect: begin.");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
lock (mClientLocker)
|
_isConnected = false;
|
||||||
{
|
|
||||||
mIsConnected = false;
|
|
||||||
|
|
||||||
if (mProxy != null)
|
_proxy?.Disconnect();
|
||||||
mProxy.Disconnect();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Debug.WriteLine("[ERROR] MtClient::Disconnect: {0}", ex.Message);
|
Log.ErrorFormat("Disconnect: Exception - {0}", ex.Message);
|
||||||
|
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.Debug("Disconnect: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public MtResponse SendCommand(int commandType, ArrayList commandParameters)
|
/// <exception cref="CommunicationException">Thrown when connection failed</exception>
|
||||||
|
public MtResponse SendCommand(int commandType, ArrayList parameters)
|
||||||
{
|
{
|
||||||
Debug.WriteLine("[INFO] MtClient::SendCommand: commandType = {0}", commandType);
|
Log.DebugFormat("SendCommand: begin. commandType = {0}, parameters count = {1}", commandType, parameters?.Count);
|
||||||
|
|
||||||
MtResponse result = null;
|
MtResponse result;
|
||||||
|
|
||||||
|
if (_isConnected == false)
|
||||||
|
{
|
||||||
|
Log.Error("SendCommand: Client is not connected.");
|
||||||
|
throw new CommunicationException("Client is not connected.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_proxy == null)
|
||||||
|
{
|
||||||
|
Log.Error("SendCommand: Proxy is not defined.");
|
||||||
|
throw new CommunicationException("Proxy is not defined.");
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
lock (mClientLocker)
|
result = _proxy.SendCommand(new MtCommand(commandType, parameters));
|
||||||
{
|
|
||||||
if (mProxy != null && mIsConnected == true)
|
|
||||||
result = mProxy.SendCommand(new MtCommand(commandType, commandParameters));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Debug.WriteLine("[ERROR] MtClient::SendCommand: {0}", ex.Message);
|
Log.ErrorFormat("SendCommand: Exception - {0}", ex.Message);
|
||||||
|
|
||||||
Close();
|
Close();
|
||||||
|
|
||||||
@@ -177,30 +212,41 @@ namespace MTApiService
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <exception cref="CommunicationException">Thrown when connection failed</exception>
|
||||||
public IEnumerable<MtQuote> GetQuotes()
|
public IEnumerable<MtQuote> GetQuotes()
|
||||||
{
|
{
|
||||||
Debug.WriteLine("[INFO] MtClient::GetQuotes");
|
Log.Debug("GetQuotes: begin.");
|
||||||
|
|
||||||
IEnumerable<MtQuote> result = null;
|
if (_isConnected == false)
|
||||||
|
{
|
||||||
|
Log.Warn("GetQuotes: end. Client is not connected.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_proxy == null)
|
||||||
|
{
|
||||||
|
Log.Warn("GetQuotes: end. _proxy is not defined.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<MtQuote> result;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
lock (mClientLocker)
|
result = _proxy.GetQuotes();
|
||||||
{
|
|
||||||
if (mProxy != null && mIsConnected == true)
|
|
||||||
result = mProxy.GetQuotes();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Debug.WriteLine("[ERROR] MtClient::GetQuotes: {0}", ex.Message);
|
Log.ErrorFormat("GetQuotes: Exception - {0}", ex.Message);
|
||||||
|
|
||||||
Close();
|
Close();
|
||||||
|
|
||||||
throw new CommunicationException("Service connection failed");
|
throw new CommunicationException($"Service connection failed! {ex.Message}");
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;;
|
Log.DebugFormat("GetQuotes: end. quotes count = {0}", result?.Count);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -209,74 +255,70 @@ namespace MTApiService
|
|||||||
|
|
||||||
public void OnQuoteUpdate(MtQuote quote)
|
public void OnQuoteUpdate(MtQuote quote)
|
||||||
{
|
{
|
||||||
if (quote != null)
|
Log.DebugFormat("OnQuoteUpdate: begin. quote = {0}", quote);
|
||||||
{
|
|
||||||
if (QuoteUpdated != null)
|
|
||||||
{
|
|
||||||
QuoteUpdated(quote);
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug.WriteLine("[INFO] MtClient::OnQuoteUpdate: " + quote);
|
if (quote == null) return;
|
||||||
}
|
|
||||||
|
QuoteUpdated?.Invoke(quote);
|
||||||
|
|
||||||
|
Log.Debug("OnQuoteUpdate: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnQuoteAdded(MtQuote quote)
|
public void OnQuoteAdded(MtQuote quote)
|
||||||
{
|
{
|
||||||
Debug.WriteLine("[INFO] MtClient::OnQuoteAdded");
|
Log.DebugFormat("OnQuoteAdded: begin. quote = {0}", quote);
|
||||||
|
|
||||||
QuoteAdded?.Invoke(quote);
|
QuoteAdded?.Invoke(quote);
|
||||||
|
|
||||||
|
Log.Debug("OnQuoteAdded: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnQuoteRemoved(MtQuote quote)
|
public void OnQuoteRemoved(MtQuote quote)
|
||||||
{
|
{
|
||||||
Debug.WriteLine("[INFO] MtClient::OnQuoteRemoved");
|
Log.DebugFormat("OnQuoteRemoved: begin. quote = {0}", quote);
|
||||||
|
|
||||||
QuoteRemoved?.Invoke(quote);
|
QuoteRemoved?.Invoke(quote);
|
||||||
|
|
||||||
|
Log.Debug("OnQuoteRemoved: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnServerStopped()
|
public void OnServerStopped()
|
||||||
{
|
{
|
||||||
Debug.WriteLine("[INFO] MtClient::OnServerStopped");
|
Log.Debug("OnServerStopped: begin.");
|
||||||
|
|
||||||
Close();
|
Close();
|
||||||
|
|
||||||
ServerDisconnected?.Invoke(this, EventArgs.Empty);
|
ServerDisconnected?.Invoke(this, EventArgs.Empty);
|
||||||
|
|
||||||
|
Log.Debug("OnServerStopped: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void OnMtEvent(MtEvent mtEvent)
|
public void OnMtEvent(MtEvent mtEvent)
|
||||||
{
|
{
|
||||||
|
Log.DebugFormat("OnMtEvent: begin. event = {0}", mtEvent);
|
||||||
|
|
||||||
MtEventReceived?.Invoke(this, new MtEventArgs(mtEvent));
|
MtEventReceived?.Invoke(this, new MtEventArgs(mtEvent));
|
||||||
|
|
||||||
|
Log.Debug("OnMtEvent: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
public bool IsConnected
|
public bool IsConnected => _proxy.State == CommunicationState.Opened && _isConnected;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
lock (mClientLocker)
|
|
||||||
{
|
|
||||||
return mProxy.State == CommunicationState.Opened && mIsConnected == true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Private Methods
|
#region Private Methods
|
||||||
|
|
||||||
void mProxy_Faulted(object sender, EventArgs e)
|
private void ProxyFaulted(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Debug.WriteLine("[INFO] MtClient::mProxy_Faulted");
|
Log.Debug("ProxyFaulted: begin.");
|
||||||
|
|
||||||
Close();
|
Close();
|
||||||
|
ServerFailed?.Invoke(this, EventArgs.Empty);
|
||||||
|
|
||||||
if (ServerFailed != null)
|
Log.Debug("ProxyFaulted: end.");
|
||||||
{
|
|
||||||
ServerFailed(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -285,9 +327,11 @@ namespace MTApiService
|
|||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Debug.WriteLine("[INFO] MtClient::Dispose");
|
Log.Debug("Dispose: begin.");
|
||||||
|
|
||||||
Close();
|
Close();
|
||||||
|
|
||||||
|
Log.Debug("Dispose: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -300,11 +344,5 @@ namespace MTApiService
|
|||||||
public event EventHandler ServerFailed;
|
public event EventHandler ServerFailed;
|
||||||
public event EventHandler<MtEventArgs> MtEventReceived;
|
public event EventHandler<MtEventArgs> MtEventReceived;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Fields
|
|
||||||
private readonly object mClientLocker = new object();
|
|
||||||
private MtApiProxy mProxy = null;
|
|
||||||
private bool mIsConnected = false;
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
using System;
|
using System.Runtime.Serialization;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.ServiceModel;
|
|
||||||
using System.Runtime.Serialization;
|
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
|
||||||
namespace MTApiService
|
namespace MTApiService
|
||||||
@@ -22,5 +18,9 @@ namespace MTApiService
|
|||||||
[DataMember]
|
[DataMember]
|
||||||
public ArrayList Parameters { get; private set; }
|
public ArrayList Parameters { get; private set; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"CommandType = {CommandType}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Regular → Executable
+9
-1
@@ -1,4 +1,5 @@
|
|||||||
using System.Threading;
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace MTApiService
|
namespace MTApiService
|
||||||
{
|
{
|
||||||
@@ -10,6 +11,9 @@ namespace MTApiService
|
|||||||
|
|
||||||
public MtCommandTask(MtCommand command)
|
public MtCommandTask(MtCommand command)
|
||||||
{
|
{
|
||||||
|
if (command == null)
|
||||||
|
throw new ArgumentNullException(nameof(command));
|
||||||
|
|
||||||
Command = command;
|
Command = command;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,5 +37,9 @@ namespace MTApiService
|
|||||||
_responseWaiter.Set();
|
_responseWaiter.Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"Command = {Command}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,4 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace MTApiService
|
namespace MTApiService
|
||||||
{
|
{
|
||||||
public class MtConnectionProfile
|
public class MtConnectionProfile
|
||||||
|
|||||||
@@ -1,31 +1,50 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using log4net;
|
||||||
|
|
||||||
namespace MTApiService
|
namespace MTApiService
|
||||||
{
|
{
|
||||||
internal class MtCommandExecutorManager : ICommandManager
|
internal class MtCommandExecutorManager : ICommandManager
|
||||||
{
|
{
|
||||||
|
#region Private Fields
|
||||||
|
private static readonly ILog Log = LogManager.GetLogger(typeof(MtCommandExecutorManager));
|
||||||
|
|
||||||
|
private readonly List<MtExpert> _commandExecutors = new List<MtExpert>();
|
||||||
|
private readonly Queue<MtCommandTask> _commandTasks = new Queue<MtCommandTask>();
|
||||||
|
|
||||||
|
private readonly object _locker = new object();
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Public Methods
|
#region Public Methods
|
||||||
|
|
||||||
public void Stop()
|
public void Stop()
|
||||||
{
|
{
|
||||||
|
Log.Debug("Stop: begin.");
|
||||||
|
|
||||||
lock (_locker)
|
lock (_locker)
|
||||||
{
|
{
|
||||||
_commandExecutors.Clear();
|
_commandExecutors.Clear();
|
||||||
_commandTasks.Clear();
|
_commandTasks.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.Debug("Stop: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddCommandExecutor(MtExpert commandExecutor)
|
public void AddCommandExecutor(MtExpert commandExecutor)
|
||||||
{
|
{
|
||||||
if (commandExecutor == null)
|
if (commandExecutor == null)
|
||||||
return;
|
throw new ArgumentNullException(nameof(commandExecutor));
|
||||||
|
|
||||||
|
Log.DebugFormat("AddCommandExecutor: begin. commandExecutor = {0}", commandExecutor);
|
||||||
|
|
||||||
var notify = false;
|
var notify = false;
|
||||||
lock (_locker)
|
lock (_locker)
|
||||||
{
|
{
|
||||||
if (_commandExecutors.Contains(commandExecutor))
|
if (_commandExecutors.Contains(commandExecutor))
|
||||||
|
{
|
||||||
|
Log.Warn("AddCommandExecutor: end. Command executor already exist.");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_commandExecutors.Add(commandExecutor);
|
_commandExecutors.Add(commandExecutor);
|
||||||
if (_commandTasks.Count > 0)
|
if (_commandTasks.Count > 0)
|
||||||
@@ -41,18 +60,25 @@ namespace MTApiService
|
|||||||
{
|
{
|
||||||
NotifyCommandReady();
|
NotifyCommandReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.Debug("AddCommandExecutor: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveCommandExecutor(MtExpert commandExecutor)
|
public void RemoveCommandExecutor(MtExpert commandExecutor)
|
||||||
{
|
{
|
||||||
if (commandExecutor == null)
|
if (commandExecutor == null)
|
||||||
return;
|
throw new ArgumentNullException(nameof(commandExecutor));
|
||||||
|
|
||||||
|
Log.DebugFormat("RemoveCommandExecutor: begin. commandExecutor = {0}", commandExecutor);
|
||||||
|
|
||||||
var notify = false;
|
var notify = false;
|
||||||
lock (_locker)
|
lock (_locker)
|
||||||
{
|
{
|
||||||
if (_commandExecutors.Contains(commandExecutor) == false)
|
if (_commandExecutors.Contains(commandExecutor) == false)
|
||||||
|
{
|
||||||
|
Log.Warn("RemoveCommandExecutor: end. Command executor is not exist in collection.");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_commandExecutors.Remove(commandExecutor);
|
_commandExecutors.Remove(commandExecutor);
|
||||||
if (_commandTasks.Count > 0)
|
if (_commandTasks.Count > 0)
|
||||||
@@ -68,12 +94,16 @@ namespace MTApiService
|
|||||||
{
|
{
|
||||||
NotifyCommandReady();
|
NotifyCommandReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.Debug("RemoveCommandExecutor: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EnqueueCommandTask(MtCommandTask task)
|
public void EnqueueCommandTask(MtCommandTask task)
|
||||||
{
|
{
|
||||||
if (task == null)
|
if (task == null)
|
||||||
return;
|
throw new ArgumentNullException(nameof(task));
|
||||||
|
|
||||||
|
Log.DebugFormat("EnqueueCommandTask: begin. task = {0}", task);
|
||||||
|
|
||||||
lock (_locker)
|
lock (_locker)
|
||||||
{
|
{
|
||||||
@@ -81,10 +111,14 @@ namespace MTApiService
|
|||||||
}
|
}
|
||||||
|
|
||||||
NotifyCommandReady();
|
NotifyCommandReady();
|
||||||
|
|
||||||
|
Log.Debug("EnqueueCommandTask: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public MtCommandTask DequeueCommandTask()
|
public MtCommandTask DequeueCommandTask()
|
||||||
{
|
{
|
||||||
|
Log.Debug("DequeueCommandTask: called.");
|
||||||
|
|
||||||
lock (_locker)
|
lock (_locker)
|
||||||
{
|
{
|
||||||
return _commandTasks.Count > 0 ? _commandTasks.Dequeue() : null;
|
return _commandTasks.Count > 0 ? _commandTasks.Dequeue() : null;
|
||||||
@@ -96,6 +130,8 @@ namespace MTApiService
|
|||||||
#region Private Methods
|
#region Private Methods
|
||||||
private void NotifyCommandReady()
|
private void NotifyCommandReady()
|
||||||
{
|
{
|
||||||
|
Log.Debug("NotifyCommandReady: begin.");
|
||||||
|
|
||||||
var commandExecutors = new List<MtExpert>();
|
var commandExecutors = new List<MtExpert>();
|
||||||
lock (_locker)
|
lock (_locker)
|
||||||
{
|
{
|
||||||
@@ -106,10 +142,14 @@ namespace MTApiService
|
|||||||
{
|
{
|
||||||
executor.NotifyCommandReady();
|
executor.NotifyCommandReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.DebugFormat("NotifyCommandReady: end. Notified executor count = {0}", commandExecutors.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CommandExecutor_CommandExecuted(object sender, EventArgs e)
|
private void CommandExecutor_CommandExecuted(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
Log.Debug("CommandExecutor_CommandExecuted: begin.");
|
||||||
|
|
||||||
var notify = false;
|
var notify = false;
|
||||||
lock (_locker)
|
lock (_locker)
|
||||||
{
|
{
|
||||||
@@ -124,14 +164,8 @@ namespace MTApiService
|
|||||||
NotifyCommandReady();
|
NotifyCommandReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.Debug("CommandExecutor_CommandExecuted: end.");
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Private Fields
|
|
||||||
private readonly List<MtExpert> _commandExecutors = new List<MtExpert>();
|
|
||||||
private readonly Queue<MtCommandTask> _commandTasks = new Queue<MtCommandTask>();
|
|
||||||
|
|
||||||
private readonly object _locker = new object();
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+91
-66
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using log4net;
|
||||||
|
|
||||||
namespace MTApiService
|
namespace MTApiService
|
||||||
{
|
{
|
||||||
@@ -6,6 +7,89 @@ namespace MTApiService
|
|||||||
{
|
{
|
||||||
public delegate void MtQuoteHandler(MtExpert expert, MtQuote quote);
|
public delegate void MtQuoteHandler(MtExpert expert, MtQuote quote);
|
||||||
|
|
||||||
|
#region Private Fields
|
||||||
|
private static readonly ILog Log = LogManager.GetLogger(typeof(MtExpert));
|
||||||
|
|
||||||
|
private readonly IMetaTraderHandler _mtHadler;
|
||||||
|
private MtCommandTask _commandTask;
|
||||||
|
private ICommandManager _commandManager;
|
||||||
|
private readonly object _locker = new object();
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Methods
|
||||||
|
public MtExpert(int handle, MtQuote quote, IMetaTraderHandler mtHandler)
|
||||||
|
{
|
||||||
|
if (mtHandler == null)
|
||||||
|
throw new ArgumentNullException(nameof(mtHandler));
|
||||||
|
|
||||||
|
Quote = quote;
|
||||||
|
Handle = handle;
|
||||||
|
_mtHadler = mtHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Deinit()
|
||||||
|
{
|
||||||
|
Log.Debug("Deinit: begin.");
|
||||||
|
|
||||||
|
IsEnable = false;
|
||||||
|
FireOnDeinited();
|
||||||
|
|
||||||
|
Log.Debug("Deinit: end.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendResponse(MtResponse response)
|
||||||
|
{
|
||||||
|
Log.DebugFormat("SendResponse: begin. response = {0}", response);
|
||||||
|
|
||||||
|
_commandTask.SetResult(response);
|
||||||
|
_commandTask = null;
|
||||||
|
FireOnCommandExecuted();
|
||||||
|
|
||||||
|
Log.Debug("SendResponse: end.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetCommandType()
|
||||||
|
{
|
||||||
|
Log.Debug("GetCommandType: called.");
|
||||||
|
|
||||||
|
var commandManager = CommandManager;
|
||||||
|
if (commandManager != null)
|
||||||
|
{
|
||||||
|
_commandTask = commandManager.DequeueCommandTask();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _commandTask?.Command?.CommandType ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object GetCommandParameter(int index)
|
||||||
|
{
|
||||||
|
Log.DebugFormat("GetCommandType: called. index = {0}", index);
|
||||||
|
|
||||||
|
var command = _commandTask?.Command;
|
||||||
|
if (command?.Parameters != null && index >= 0 && index < command.Parameters.Count)
|
||||||
|
{
|
||||||
|
return command.Parameters[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendEvent(MtEvent mtEvent)
|
||||||
|
{
|
||||||
|
Log.DebugFormat("SendEvent: begin. event = {0}", mtEvent);
|
||||||
|
|
||||||
|
FireOnMtEvent(mtEvent);
|
||||||
|
|
||||||
|
Log.Debug("SendEvent: end.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"ExpertHandle = {Handle}";
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
private MtQuote _quote;
|
private MtQuote _quote;
|
||||||
public MtQuote Quote
|
public MtQuote Quote
|
||||||
@@ -19,7 +103,7 @@ namespace MTApiService
|
|||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
lock(_locker)
|
lock (_locker)
|
||||||
{
|
{
|
||||||
_quote = value;
|
_quote = value;
|
||||||
}
|
}
|
||||||
@@ -28,7 +112,7 @@ namespace MTApiService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Handle { get; private set; }
|
public int Handle { get; }
|
||||||
|
|
||||||
private bool _isEnable = true;
|
private bool _isEnable = true;
|
||||||
public bool IsEnable
|
public bool IsEnable
|
||||||
@@ -69,73 +153,21 @@ namespace MTApiService
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
public MtExpert(int handle, MtQuote quote, IMetaTraderHandler mtHandler)
|
|
||||||
{
|
|
||||||
Quote = quote;
|
|
||||||
Handle = handle;
|
|
||||||
_mtHadler = mtHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Deinit()
|
|
||||||
{
|
|
||||||
IsEnable = false;
|
|
||||||
FireOnDeinited();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendResponse(MtResponse response)
|
|
||||||
{
|
|
||||||
_commandTask.SetResult(response);
|
|
||||||
_commandTask = null;
|
|
||||||
FireOnCommandExecuted();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetCommandType()
|
|
||||||
{
|
|
||||||
var commandManager = CommandManager;
|
|
||||||
if (commandManager != null)
|
|
||||||
{
|
|
||||||
_commandTask = commandManager.DequeueCommandTask();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _commandTask != null && _commandTask.Command != null ? _commandTask.Command.CommandType : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public object GetCommandParameter(int index)
|
|
||||||
{
|
|
||||||
if (_commandTask != null)
|
|
||||||
{
|
|
||||||
var command = _commandTask.Command;
|
|
||||||
if (command != null && command.Parameters != null
|
|
||||||
&& index >= 0 && index < command.Parameters.Count)
|
|
||||||
{
|
|
||||||
return command.Parameters[index];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendEvent(MtEvent mtEvent)
|
|
||||||
{
|
|
||||||
FireOnMtEvent(mtEvent);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IMtCommandExecutor
|
#region IMtCommandExecutor
|
||||||
public void NotifyCommandReady()
|
public void NotifyCommandReady()
|
||||||
{
|
{
|
||||||
|
Log.Debug("NotifyCommandReady: begin.");
|
||||||
|
|
||||||
SendTickToMetaTrader();
|
SendTickToMetaTrader();
|
||||||
|
|
||||||
|
Log.Debug("NotifyCommandReady: end.");
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Private Methods
|
#region Private Methods
|
||||||
private void SendTickToMetaTrader()
|
private void SendTickToMetaTrader()
|
||||||
{
|
{
|
||||||
if (_mtHadler != null)
|
_mtHadler.SendTickToMetaTrader(Handle);
|
||||||
{
|
|
||||||
_mtHadler.SendTickToMetaTrader(Handle);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FireOnQuoteChanged(MtQuote quote)
|
private void FireOnQuoteChanged(MtQuote quote)
|
||||||
@@ -165,12 +197,5 @@ namespace MTApiService
|
|||||||
public event EventHandler CommandExecuted;
|
public event EventHandler CommandExecuted;
|
||||||
public event EventHandler<MtEventArgs> OnMtEvent;
|
public event EventHandler<MtEventArgs> OnMtEvent;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Private Fields
|
|
||||||
private readonly IMetaTraderHandler _mtHadler;
|
|
||||||
private MtCommandTask _commandTask;
|
|
||||||
private ICommandManager _commandManager;
|
|
||||||
private readonly object _locker = new object();
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
using System;
|
using System.Runtime.Serialization;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Runtime.Serialization;
|
|
||||||
|
|
||||||
namespace MTApiService
|
namespace MTApiService
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
using System;
|
using System.Runtime.Serialization;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Runtime.Serialization;
|
|
||||||
|
|
||||||
namespace MTApiService
|
namespace MTApiService
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
using System;
|
using System.Runtime.Serialization;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Runtime.Serialization;
|
|
||||||
|
|
||||||
namespace MTApiService
|
namespace MTApiService
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
using System;
|
using System.Runtime.Serialization;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Runtime.Serialization;
|
|
||||||
|
|
||||||
namespace MTApiService
|
namespace MTApiService
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
|
|
||||||
namespace MTApiService
|
namespace MTApiService
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
@@ -9,12 +7,12 @@ namespace MTApiService
|
|||||||
{
|
{
|
||||||
public class MtRegistryManager
|
public class MtRegistryManager
|
||||||
{
|
{
|
||||||
private const string SOFTWARE = "Software";
|
private const string Software = "Software";
|
||||||
private const string APP_NAME = "MtApi";
|
private const string AppName = "MtApi";
|
||||||
private const string PROFILES_REGKEY = "ConnectionProfiles";
|
private const string ProfilesRegkey = "ConnectionProfiles";
|
||||||
private const string HOST_REGVALUE_NAME = "Host";
|
private const string HostRegvalueName = "Host";
|
||||||
private const string PORT_REGVALUE_NAME = "Port";
|
private const string PortRegvalueName = "Port";
|
||||||
private const string SIGNATURE_REGVALUE_NAME = "MtSignature";
|
private const string SignatureRegvalueName = "MtSignature";
|
||||||
|
|
||||||
#region Public Methods
|
#region Public Methods
|
||||||
public static IEnumerable<MtConnectionProfile> LoadConnectionProfiles()
|
public static IEnumerable<MtConnectionProfile> LoadConnectionProfiles()
|
||||||
@@ -53,12 +51,12 @@ namespace MTApiService
|
|||||||
|
|
||||||
string signature = null;
|
string signature = null;
|
||||||
|
|
||||||
var softwareRegKey = Registry.CurrentUser.OpenSubKey(SOFTWARE, true);
|
var softwareRegKey = Registry.CurrentUser.OpenSubKey(Software, true);
|
||||||
if (softwareRegKey != null)
|
if (softwareRegKey != null)
|
||||||
{
|
{
|
||||||
using (softwareRegKey)
|
using (softwareRegKey)
|
||||||
{
|
{
|
||||||
var appRegKey = softwareRegKey.OpenSubKey(APP_NAME, true);
|
var appRegKey = softwareRegKey.OpenSubKey(AppName, true);
|
||||||
if (appRegKey != null)
|
if (appRegKey != null)
|
||||||
{
|
{
|
||||||
using (appRegKey)
|
using (appRegKey)
|
||||||
@@ -73,7 +71,7 @@ namespace MTApiService
|
|||||||
{
|
{
|
||||||
using (numberKey)
|
using (numberKey)
|
||||||
{
|
{
|
||||||
signature = numberKey.GetValue(SIGNATURE_REGVALUE_NAME).ToString();
|
signature = numberKey.GetValue(SignatureRegvalueName).ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -94,7 +92,7 @@ namespace MTApiService
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
RegistryKey softwareRgKey = Registry.CurrentUser.OpenSubKey(SOFTWARE, true);
|
var softwareRgKey = Registry.CurrentUser.OpenSubKey(Software, true);
|
||||||
|
|
||||||
if (softwareRgKey == null)
|
if (softwareRgKey == null)
|
||||||
return null;
|
return null;
|
||||||
@@ -105,35 +103,33 @@ namespace MTApiService
|
|||||||
{
|
{
|
||||||
|
|
||||||
//app name
|
//app name
|
||||||
var appRegKey = softwareRgKey.OpenSubKey(APP_NAME, true);
|
var appRegKey = softwareRgKey.OpenSubKey(AppName, true) ?? softwareRgKey.CreateSubKey(AppName);
|
||||||
if (appRegKey == null)
|
|
||||||
|
if (appRegKey != null)
|
||||||
{
|
{
|
||||||
appRegKey = softwareRgKey.CreateSubKey(APP_NAME);
|
using (appRegKey)
|
||||||
}
|
|
||||||
|
|
||||||
using (appRegKey)
|
|
||||||
{
|
|
||||||
//account name
|
|
||||||
var accountKey = appRegKey.OpenSubKey(accountName, true);
|
|
||||||
if (accountKey == null)
|
|
||||||
{
|
{
|
||||||
accountKey = appRegKey.CreateSubKey(accountName);
|
//account name
|
||||||
}
|
var accountKey = appRegKey.OpenSubKey(accountName, true) ?? appRegKey.CreateSubKey(accountName);
|
||||||
|
|
||||||
using (accountKey)
|
if (accountKey != null)
|
||||||
{
|
|
||||||
//account number
|
|
||||||
var numberKey = accountKey.OpenSubKey(accountNumber, true);
|
|
||||||
if (numberKey == null)
|
|
||||||
{
|
{
|
||||||
numberKey = accountKey.CreateSubKey(accountNumber);
|
using (accountKey)
|
||||||
}
|
{
|
||||||
|
//account number
|
||||||
|
var numberKey = accountKey.OpenSubKey(accountNumber, true) ??
|
||||||
|
accountKey.CreateSubKey(accountNumber);
|
||||||
|
|
||||||
using (numberKey)
|
if (numberKey != null)
|
||||||
{
|
{
|
||||||
numberKey.SetValue(SIGNATURE_REGVALUE_NAME, signature);
|
using (numberKey)
|
||||||
|
{
|
||||||
|
numberKey.SetValue(SignatureRegvalueName, signature);
|
||||||
|
|
||||||
retVal = numberKey.ToString();
|
retVal = numberKey.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,20 +138,19 @@ namespace MTApiService
|
|||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool ExportKey(string RegKey, string SavePath)
|
public static bool ExportKey(string regKey, string savePath)
|
||||||
{
|
{
|
||||||
string path = "\"" + SavePath + "\"";
|
var path = $"\"{savePath}\"";
|
||||||
string key = "\"" + RegKey + "\"";
|
var key = $"\"{regKey}\"";
|
||||||
|
|
||||||
Process proc = new Process();
|
var proc = new Process();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
proc.StartInfo.FileName = "regedit.exe";
|
proc.StartInfo.FileName = "regedit.exe";
|
||||||
proc.StartInfo.UseShellExecute = false;
|
proc.StartInfo.UseShellExecute = false;
|
||||||
proc = Process.Start("regedit.exe", "/e " + path + " " + key + "");
|
proc = Process.Start("regedit.exe", "/e " + path + " " + key + "");
|
||||||
|
|
||||||
if (proc != null)
|
proc?.WaitForExit();
|
||||||
proc.WaitForExit();
|
|
||||||
}
|
}
|
||||||
catch(Exception)
|
catch(Exception)
|
||||||
{
|
{
|
||||||
@@ -163,8 +158,7 @@ namespace MTApiService
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if (proc != null)
|
proc?.Dispose();
|
||||||
proc.Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -177,33 +171,38 @@ namespace MTApiService
|
|||||||
{
|
{
|
||||||
List<MtConnectionProfile> profiles = null;
|
List<MtConnectionProfile> profiles = null;
|
||||||
|
|
||||||
var softwareRegKey = Registry.CurrentUser.OpenSubKey(SOFTWARE, true);
|
var softwareRegKey = Registry.CurrentUser.OpenSubKey(Software, true);
|
||||||
if (softwareRegKey != null)
|
if (softwareRegKey != null)
|
||||||
{
|
{
|
||||||
using (softwareRegKey)
|
using (softwareRegKey)
|
||||||
{
|
{
|
||||||
var appRegKey = softwareRegKey.OpenSubKey(APP_NAME, true);
|
var appRegKey = softwareRegKey.OpenSubKey(AppName, true);
|
||||||
if (appRegKey != null)
|
if (appRegKey != null)
|
||||||
{
|
{
|
||||||
using (appRegKey)
|
using (appRegKey)
|
||||||
{
|
{
|
||||||
var profilesRegKey = appRegKey.OpenSubKey(PROFILES_REGKEY, true);
|
var profilesRegKey = appRegKey.OpenSubKey(ProfilesRegkey, true);
|
||||||
if (profilesRegKey != null)
|
if (profilesRegKey != null)
|
||||||
{
|
{
|
||||||
using (profilesRegKey)
|
using (profilesRegKey)
|
||||||
{
|
{
|
||||||
profiles = new List<MtConnectionProfile>();
|
profiles = new List<MtConnectionProfile>();
|
||||||
|
|
||||||
foreach (string profileNameKey in profilesRegKey.GetSubKeyNames())
|
foreach (var profileNameKey in profilesRegKey.GetSubKeyNames())
|
||||||
{
|
{
|
||||||
using (RegistryKey tempKey = profilesRegKey.OpenSubKey(profileNameKey))
|
var tempKey = profilesRegKey.OpenSubKey(profileNameKey);
|
||||||
|
if (tempKey != null)
|
||||||
{
|
{
|
||||||
var profile = new MtConnectionProfile(profileNameKey);
|
using (tempKey)
|
||||||
|
{
|
||||||
|
var profile = new MtConnectionProfile(profileNameKey)
|
||||||
|
{
|
||||||
|
Host = tempKey.GetValue(HostRegvalueName).ToString(),
|
||||||
|
Port = (int) tempKey.GetValue(PortRegvalueName)
|
||||||
|
};
|
||||||
|
|
||||||
profile.Host = tempKey.GetValue(HOST_REGVALUE_NAME).ToString();
|
profiles.Add(profile);
|
||||||
profile.Port = (int)tempKey.GetValue(PORT_REGVALUE_NAME);
|
}
|
||||||
|
|
||||||
profiles.Add(profile);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -220,27 +219,33 @@ namespace MTApiService
|
|||||||
{
|
{
|
||||||
MtConnectionProfile profile = null;
|
MtConnectionProfile profile = null;
|
||||||
|
|
||||||
var softwareRegKey = Registry.CurrentUser.OpenSubKey(SOFTWARE, true);
|
var softwareRegKey = Registry.CurrentUser.OpenSubKey(Software, true);
|
||||||
if (softwareRegKey != null)
|
if (softwareRegKey != null)
|
||||||
{
|
{
|
||||||
using (softwareRegKey)
|
using (softwareRegKey)
|
||||||
{
|
{
|
||||||
var appRegKey = softwareRegKey.OpenSubKey(APP_NAME, true);
|
var appRegKey = softwareRegKey.OpenSubKey(AppName, true);
|
||||||
if (appRegKey != null)
|
if (appRegKey != null)
|
||||||
{
|
{
|
||||||
using (appRegKey)
|
using (appRegKey)
|
||||||
{
|
{
|
||||||
var profilesRegKey = appRegKey.OpenSubKey(PROFILES_REGKEY, true);
|
var profilesRegKey = appRegKey.OpenSubKey(ProfilesRegkey, true);
|
||||||
if (profilesRegKey != null)
|
if (profilesRegKey != null)
|
||||||
{
|
{
|
||||||
using (profilesRegKey)
|
using (profilesRegKey)
|
||||||
{
|
{
|
||||||
using (RegistryKey tempKey = profilesRegKey.OpenSubKey(profileName))
|
var tempKey = profilesRegKey.OpenSubKey(profileName);
|
||||||
|
if (tempKey != null)
|
||||||
{
|
{
|
||||||
profile = new MtConnectionProfile(profileName);
|
using (tempKey)
|
||||||
|
{
|
||||||
|
profile = new MtConnectionProfile(profileName)
|
||||||
|
{
|
||||||
|
Host = tempKey.GetValue(HostRegvalueName).ToString(),
|
||||||
|
Port = (int) tempKey.GetValue(PortRegvalueName)
|
||||||
|
};
|
||||||
|
|
||||||
profile.Host = tempKey.GetValue(HOST_REGVALUE_NAME).ToString();
|
}
|
||||||
profile.Port = (int)tempKey.GetValue(PORT_REGVALUE_NAME);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -254,7 +259,7 @@ namespace MTApiService
|
|||||||
|
|
||||||
private static void SaveConnectionProfileToRegistry(MtConnectionProfile profile)
|
private static void SaveConnectionProfileToRegistry(MtConnectionProfile profile)
|
||||||
{
|
{
|
||||||
RegistryKey softwareRgKey = Registry.CurrentUser.OpenSubKey(SOFTWARE, true);
|
var softwareRgKey = Registry.CurrentUser.OpenSubKey(Software, true);
|
||||||
|
|
||||||
if (softwareRgKey == null)
|
if (softwareRgKey == null)
|
||||||
return;
|
return;
|
||||||
@@ -262,29 +267,30 @@ namespace MTApiService
|
|||||||
using (softwareRgKey)
|
using (softwareRgKey)
|
||||||
{
|
{
|
||||||
//app name
|
//app name
|
||||||
var appRegKey = softwareRgKey.OpenSubKey(APP_NAME, true);
|
var appRegKey = softwareRgKey.OpenSubKey(AppName, true) ?? softwareRgKey.CreateSubKey(AppName);
|
||||||
if (appRegKey == null)
|
|
||||||
|
if (appRegKey != null)
|
||||||
{
|
{
|
||||||
appRegKey = softwareRgKey.CreateSubKey(APP_NAME);
|
using (appRegKey)
|
||||||
}
|
|
||||||
|
|
||||||
using (appRegKey)
|
|
||||||
{
|
|
||||||
//ConnectionProfiles key
|
|
||||||
var profilesRegKey = appRegKey.OpenSubKey(PROFILES_REGKEY, true);
|
|
||||||
if (profilesRegKey == null)
|
|
||||||
{
|
{
|
||||||
profilesRegKey = appRegKey.CreateSubKey(PROFILES_REGKEY);
|
//ConnectionProfiles key
|
||||||
}
|
var profilesRegKey = appRegKey.OpenSubKey(ProfilesRegkey, true) ??
|
||||||
|
appRegKey.CreateSubKey(ProfilesRegkey);
|
||||||
|
|
||||||
using (profilesRegKey)
|
if (profilesRegKey != null)
|
||||||
{
|
|
||||||
var profileKey = profilesRegKey.CreateSubKey(profile.Name);
|
|
||||||
|
|
||||||
using (profileKey)
|
|
||||||
{
|
{
|
||||||
profileKey.SetValue(HOST_REGVALUE_NAME, profile.Host);
|
using (profilesRegKey)
|
||||||
profileKey.SetValue(PORT_REGVALUE_NAME, profile.Port);
|
{
|
||||||
|
var profileKey = profilesRegKey.CreateSubKey(profile.Name);
|
||||||
|
if (profileKey != null)
|
||||||
|
{
|
||||||
|
using (profileKey)
|
||||||
|
{
|
||||||
|
profileKey.SetValue(HostRegvalueName, profile.Host);
|
||||||
|
profileKey.SetValue(PortRegvalueName, profile.Port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -293,19 +299,19 @@ namespace MTApiService
|
|||||||
|
|
||||||
private static void DeleteConnectionProfileFromRegistry(string profileName)
|
private static void DeleteConnectionProfileFromRegistry(string profileName)
|
||||||
{
|
{
|
||||||
var softwareRegKey = Registry.CurrentUser.OpenSubKey(SOFTWARE, true);
|
var softwareRegKey = Registry.CurrentUser.OpenSubKey(Software, true);
|
||||||
if (softwareRegKey == null)
|
if (softwareRegKey == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
using (softwareRegKey)
|
using (softwareRegKey)
|
||||||
{
|
{
|
||||||
var appRegKey = softwareRegKey.OpenSubKey(APP_NAME, true);
|
var appRegKey = softwareRegKey.OpenSubKey(AppName, true);
|
||||||
if (appRegKey == null)
|
if (appRegKey == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
using (appRegKey)
|
using (appRegKey)
|
||||||
{
|
{
|
||||||
var profilesRegKey = appRegKey.OpenSubKey(PROFILES_REGKEY, true);
|
var profilesRegKey = appRegKey.OpenSubKey(ProfilesRegkey, true);
|
||||||
if (profilesRegKey == null)
|
if (profilesRegKey == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
namespace MTApiService
|
namespace MTApiService
|
||||||
{
|
{
|
||||||
@@ -21,6 +20,8 @@ namespace MTApiService
|
|||||||
typeof(MtResponseArrayList), typeof(MtResponseMqlRatesArray),
|
typeof(MtResponseArrayList), typeof(MtResponseMqlRatesArray),
|
||||||
typeof(MtResponseMqlBookInfoArray)};
|
typeof(MtResponseMqlBookInfoArray)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract object GetValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
[DataContract]
|
[DataContract]
|
||||||
@@ -33,6 +34,13 @@ namespace MTApiService
|
|||||||
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public int Value { get; private set; }
|
public int Value { get; private set; }
|
||||||
|
|
||||||
|
public override object GetValue() { return Value; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Value.ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[DataContract]
|
[DataContract]
|
||||||
@@ -45,6 +53,13 @@ namespace MTApiService
|
|||||||
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public long Value { get; private set; }
|
public long Value { get; private set; }
|
||||||
|
|
||||||
|
public override object GetValue() { return Value; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Value.ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[DataContract]
|
[DataContract]
|
||||||
@@ -57,6 +72,13 @@ namespace MTApiService
|
|||||||
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public ulong Value { get; private set; }
|
public ulong Value { get; private set; }
|
||||||
|
|
||||||
|
public override object GetValue() { return Value; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Value.ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[DataContract]
|
[DataContract]
|
||||||
@@ -69,6 +91,13 @@ namespace MTApiService
|
|||||||
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public double Value { get; private set; }
|
public double Value { get; private set; }
|
||||||
|
|
||||||
|
public override object GetValue() { return Value; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Value.ToString(CultureInfo.CurrentCulture);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[DataContract]
|
[DataContract]
|
||||||
@@ -81,6 +110,13 @@ namespace MTApiService
|
|||||||
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public string Value { get; private set; }
|
public string Value { get; private set; }
|
||||||
|
|
||||||
|
public override object GetValue() { return Value; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[DataContract]
|
[DataContract]
|
||||||
@@ -93,6 +129,13 @@ namespace MTApiService
|
|||||||
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public bool Value { get; private set; }
|
public bool Value { get; private set; }
|
||||||
|
|
||||||
|
public override object GetValue() { return Value; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Value.ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[DataContract]
|
[DataContract]
|
||||||
@@ -105,6 +148,13 @@ namespace MTApiService
|
|||||||
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public double[] Value { get; private set; }
|
public double[] Value { get; private set; }
|
||||||
|
|
||||||
|
public override object GetValue() { return Value; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Value.ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[DataContract]
|
[DataContract]
|
||||||
@@ -117,6 +167,13 @@ namespace MTApiService
|
|||||||
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public int[] Value { get; private set; }
|
public int[] Value { get; private set; }
|
||||||
|
|
||||||
|
public override object GetValue() { return Value; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Value.ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[DataContract]
|
[DataContract]
|
||||||
@@ -129,6 +186,13 @@ namespace MTApiService
|
|||||||
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public long[] Value { get; private set; }
|
public long[] Value { get; private set; }
|
||||||
|
|
||||||
|
public override object GetValue() { return Value; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Value.ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[DataContract]
|
[DataContract]
|
||||||
@@ -141,6 +205,13 @@ namespace MTApiService
|
|||||||
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public ArrayList Value { get; private set; }
|
public ArrayList Value { get; private set; }
|
||||||
|
|
||||||
|
public override object GetValue() { return Value; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Value.ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[DataContract]
|
[DataContract]
|
||||||
@@ -153,6 +224,13 @@ namespace MTApiService
|
|||||||
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public MtMqlRates[] Value { get; private set; }
|
public MtMqlRates[] Value { get; private set; }
|
||||||
|
|
||||||
|
public override object GetValue() { return Value; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Value.ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[DataContract]
|
[DataContract]
|
||||||
@@ -165,6 +243,13 @@ namespace MTApiService
|
|||||||
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public MtMqlTick Value { get; private set; }
|
public MtMqlTick Value { get; private set; }
|
||||||
|
|
||||||
|
public override object GetValue() { return Value; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Value.ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[DataContract]
|
[DataContract]
|
||||||
@@ -177,6 +262,13 @@ namespace MTApiService
|
|||||||
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public MtMqlBookInfo[] Value { get; private set; }
|
public MtMqlBookInfo[] Value { get; private set; }
|
||||||
|
|
||||||
|
public override object GetValue() { return Value; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Value.ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+196
-106
@@ -3,17 +3,26 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.ServiceModel;
|
using System.ServiceModel;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.ServiceModel.Channels;
|
using System.ServiceModel.Channels;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
using log4net;
|
||||||
|
|
||||||
namespace MTApiService
|
namespace MTApiService
|
||||||
{
|
{
|
||||||
internal class MtServer : IDisposable, IMtApiServer
|
internal class MtServer : IDisposable, IMtApiServer
|
||||||
{
|
{
|
||||||
#region Constants
|
#region Constants
|
||||||
private const int WAIT_RESPONSE_TIME = 40000; // 40 sec
|
private const int WaitResponseTime = 40000; // 40 sec
|
||||||
private const int STOP_EXPERT_INTERVAL = 1000; // 1 sec
|
private const int StopExpertInterval = 1000; // 1 sec
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Fields
|
||||||
|
private static readonly ILog Log = LogManager.GetLogger(typeof(MtServer));
|
||||||
|
|
||||||
|
private readonly MtService _service;
|
||||||
|
private readonly List<ServiceHost> _hosts = new List<ServiceHost>();
|
||||||
|
private readonly MtCommandExecutorManager _executorManager = new MtCommandExecutorManager();
|
||||||
|
private readonly List<MtExpert> _experts = new List<MtExpert>();
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ctor
|
#region ctor
|
||||||
@@ -25,99 +34,126 @@ namespace MTApiService
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
public int Port { get; private set; }
|
public int Port { get; }
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Public Methods
|
#region Public Methods
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
|
Log.Debug("Start: begin");
|
||||||
|
|
||||||
var hostsInitialized = InitHosts(Port);
|
var hostsInitialized = InitHosts(Port);
|
||||||
if (hostsInitialized == false)
|
|
||||||
{
|
Log.DebugFormat("Start: end. hostsInitialized = {0}", hostsInitialized);
|
||||||
Debug.WriteLine("Start: InitHosts failed. ");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool InitHosts(int port)
|
private bool InitHosts(int port)
|
||||||
{
|
{
|
||||||
|
Log.DebugFormat("InitHosts: begin. port = {0}", port);
|
||||||
|
|
||||||
|
int count;
|
||||||
|
|
||||||
lock (_hosts)
|
lock (_hosts)
|
||||||
{
|
{
|
||||||
if (_hosts.Count > 0)
|
if (_hosts.Count > 0)
|
||||||
|
{
|
||||||
|
Log.Info("InitHosts: end. Host's has been initialized");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//init local pipe host
|
//init local pipe host
|
||||||
string localUrl = CreateConnectionAddress(null, port, true);
|
var localUrl = CreateConnectionAddress(null, port, true);
|
||||||
ServiceHost localServiceHost = CreateServiceHost(localUrl, true);
|
var localServiceHost = CreateServiceHost(localUrl, true);
|
||||||
if (localServiceHost != null)
|
if (localServiceHost != null)
|
||||||
{
|
{
|
||||||
_hosts.Add(localServiceHost);
|
_hosts.Add(localServiceHost);
|
||||||
}
|
}
|
||||||
|
|
||||||
//init network hosts
|
//init network hosts
|
||||||
IPHostEntry ips = Dns.GetHostEntry(Dns.GetHostName());
|
var dnsHostName = Dns.GetHostName();
|
||||||
if (ips != null)
|
var ips = Dns.GetHostEntry(dnsHostName);
|
||||||
|
if (ips == null)
|
||||||
{
|
{
|
||||||
foreach (IPAddress ipAddress in ips.AddressList)
|
Log.WarnFormat("InitHosts: end. Dns.GetHostEntry has returned null for DNS Host Name {0}", dnsHostName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var ipAddress in ips.AddressList)
|
||||||
|
{
|
||||||
|
if (ipAddress?.AddressFamily == AddressFamily.InterNetwork)
|
||||||
{
|
{
|
||||||
if (ipAddress != null)
|
var ip = ipAddress.ToString();
|
||||||
|
var networkUrl = CreateConnectionAddress(ip, port, false);
|
||||||
|
var serviceHost = CreateServiceHost(networkUrl, false);
|
||||||
|
if (serviceHost != null)
|
||||||
{
|
{
|
||||||
if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
|
_hosts.Add(serviceHost);
|
||||||
{
|
|
||||||
string ip = ipAddress.ToString();
|
|
||||||
string networkUrl = CreateConnectionAddress(ip, port, false);
|
|
||||||
ServiceHost serviceHost = CreateServiceHost(networkUrl, false);
|
|
||||||
if (serviceHost != null)
|
|
||||||
{
|
|
||||||
_hosts.Add(serviceHost);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
count = _hosts.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.DebugFormat("InitHosts: end. Host's count = {0}", count);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ServiceHost CreateServiceHost(string serverUrlAdress, bool local)
|
private ServiceHost CreateServiceHost(string serverUrlAdress, bool local)
|
||||||
{
|
{
|
||||||
ServiceHost serviceHost = null;
|
Log.DebugFormat("CreateServiceHost: begin. serverUrlAdress = {0}; local = {1}", serverUrlAdress, local);
|
||||||
if (serverUrlAdress != null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
serviceHost = new ServiceHost(_service);
|
|
||||||
var binding = CreateConnectionBinding(local);
|
|
||||||
|
|
||||||
serviceHost.AddServiceEndpoint(typeof(IMtApi), binding, serverUrlAdress);
|
if (serverUrlAdress == null)
|
||||||
serviceHost.Open();
|
{
|
||||||
}
|
Log.Warn("CreateServiceHost: end. serverUrlAdress is not defined");
|
||||||
catch(Exception e)
|
return null;
|
||||||
{
|
|
||||||
Debug.WriteLine("CreateServiceHost: Create ServiceHost failed. " + e.Message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ServiceHost serviceHost;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
serviceHost = new ServiceHost(_service);
|
||||||
|
var binding = CreateConnectionBinding(local);
|
||||||
|
|
||||||
|
serviceHost.AddServiceEndpoint(typeof(IMtApi), binding, serverUrlAdress);
|
||||||
|
serviceHost.Open();
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
Log.ErrorFormat("CreateServiceHost: Error! {0}", e.Message);
|
||||||
|
serviceHost = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.Debug("CreateServiceHost: end.");
|
||||||
|
|
||||||
return serviceHost;
|
return serviceHost;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddExpert(MtExpert expert)
|
public void AddExpert(MtExpert expert)
|
||||||
{
|
{
|
||||||
if (expert != null)
|
Log.DebugFormat("AddExpert: begin. expert {0}", expert);
|
||||||
|
|
||||||
|
if (expert == null)
|
||||||
{
|
{
|
||||||
expert.Deinited += expert_Deinited;
|
Log.Warn("AddExpert: end. expert is not defined");
|
||||||
expert.QuoteChanged += expert_QuoteChanged;
|
return;
|
||||||
expert.OnMtEvent += Expert_OnMtEvent;
|
|
||||||
|
|
||||||
lock (_experts)
|
|
||||||
{
|
|
||||||
_experts.Add(expert);
|
|
||||||
}
|
|
||||||
|
|
||||||
_executorManager.AddCommandExecutor(expert);
|
|
||||||
|
|
||||||
_service.OnQuoteAdded(expert.Quote);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expert.Deinited += expert_Deinited;
|
||||||
|
expert.QuoteChanged += expert_QuoteChanged;
|
||||||
|
expert.OnMtEvent += Expert_OnMtEvent;
|
||||||
|
|
||||||
|
lock (_experts)
|
||||||
|
{
|
||||||
|
_experts.Add(expert);
|
||||||
|
}
|
||||||
|
|
||||||
|
_executorManager.AddCommandExecutor(expert);
|
||||||
|
|
||||||
|
_service.OnQuoteAdded(expert.Quote);
|
||||||
|
|
||||||
|
Log.Debug("AddExpert: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -126,25 +162,30 @@ namespace MTApiService
|
|||||||
|
|
||||||
public MtResponse SendCommand(MtCommand command)
|
public MtResponse SendCommand(MtCommand command)
|
||||||
{
|
{
|
||||||
MtResponse response = null;
|
Log.DebugFormat("SendCommand: begin. command {0}", command);
|
||||||
|
|
||||||
if (command != null)
|
if (command == null)
|
||||||
{
|
{
|
||||||
var task = new MtCommandTask(command);
|
Log.Warn("SendCommand: end. command is not defined");
|
||||||
_executorManager.EnqueueCommandTask(task);
|
return null;
|
||||||
|
|
||||||
//wait for execute command in MetaTrader
|
|
||||||
response = task.WaitResult(WAIT_RESPONSE_TIME);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var task = new MtCommandTask(command);
|
||||||
|
_executorManager.EnqueueCommandTask(task);
|
||||||
|
|
||||||
|
//wait for execute command in MetaTrader
|
||||||
|
var response = task.WaitResult(WaitResponseTime);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<MtQuote> GetQuotes()
|
public List<MtQuote> GetQuotes()
|
||||||
{
|
{
|
||||||
|
Log.Debug("GetQuotes: called");
|
||||||
|
|
||||||
lock (_experts)
|
lock (_experts)
|
||||||
{
|
{
|
||||||
return (from s in _experts select s.Quote);
|
return _experts.Select(s => s.Quote).ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,99 +194,131 @@ namespace MTApiService
|
|||||||
#region Private Methods
|
#region Private Methods
|
||||||
private void stopTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
private void stopTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
||||||
{
|
{
|
||||||
var expertsCount = 0;
|
Log.DebugFormat("stopTimer_Elapsed: begin");
|
||||||
|
|
||||||
|
int expertsCount;
|
||||||
|
|
||||||
lock (_experts)
|
lock (_experts)
|
||||||
{
|
{
|
||||||
expertsCount = _experts.Count();
|
expertsCount = _experts.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expertsCount == 0)
|
if (expertsCount == 0)
|
||||||
{
|
{
|
||||||
_service.OnStopServer();
|
_service.OnStopServer();
|
||||||
|
|
||||||
|
Log.DebugFormat("stopTimer_Elapsed: experts count is 0. Call Stop().");
|
||||||
|
|
||||||
Stop();
|
Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
var stopTimer = sender as System.Timers.Timer;
|
var stopTimer = sender as System.Timers.Timer;
|
||||||
if (stopTimer != null)
|
if (stopTimer == null) return;
|
||||||
{
|
|
||||||
stopTimer.Stop();
|
stopTimer.Stop();
|
||||||
stopTimer.Elapsed -= stopTimer_Elapsed;
|
stopTimer.Elapsed -= stopTimer_Elapsed;
|
||||||
}
|
|
||||||
|
Log.DebugFormat("stopTimer_Elapsed: end");
|
||||||
}
|
}
|
||||||
|
|
||||||
private string CreateConnectionAddress(string host, int port, bool local)
|
private static string CreateConnectionAddress(string host, int port, bool local)
|
||||||
{
|
{
|
||||||
|
Log.DebugFormat("CreateConnectionAddress: begin. host = {0}, port = {1}, local = {2}", host, port, local);
|
||||||
|
|
||||||
string connectionAddress = null;
|
string connectionAddress = null;
|
||||||
|
|
||||||
if (local == true)
|
if (local)
|
||||||
{
|
{
|
||||||
//by Pipe
|
//by Pipe
|
||||||
connectionAddress = "net.pipe://localhost/MtApiService_" + port.ToString();
|
connectionAddress = "net.pipe://localhost/MtApiService_" + port;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//by Socket
|
//by Socket
|
||||||
if (host != null)
|
if (host != null)
|
||||||
{
|
{
|
||||||
connectionAddress = "net.tcp://" + host.ToString() + ":" + port.ToString() + "/MtApiService";
|
connectionAddress = "net.tcp://" + host + ":" + port + "/MtApiService";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.DebugFormat("CreateConnectionAddress: end. connectionAddress = {0}", connectionAddress);
|
||||||
|
|
||||||
return connectionAddress;
|
return connectionAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Binding CreateConnectionBinding(bool local)
|
private static Binding CreateConnectionBinding(bool local)
|
||||||
{
|
{
|
||||||
Binding connectionBinding = null;
|
Log.DebugFormat("CreateConnectionBinding: begin. local = {0}", local);
|
||||||
|
|
||||||
if (local == true)
|
Binding connectionBinding;
|
||||||
|
|
||||||
|
if (local)
|
||||||
{
|
{
|
||||||
//by Pipe
|
//by Pipe
|
||||||
var bind = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
|
var bind = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
|
||||||
bind.MaxReceivedMessageSize = 2147483647;
|
{
|
||||||
bind.MaxBufferSize = 2147483647;
|
MaxReceivedMessageSize = 2147483647,
|
||||||
|
MaxBufferSize = 2147483647,
|
||||||
|
MaxBufferPoolSize = 2147483647,
|
||||||
|
SendTimeout = new TimeSpan(12, 0, 0),
|
||||||
|
ReceiveTimeout = new TimeSpan(12, 0, 0),
|
||||||
|
ReaderQuotas =
|
||||||
|
{
|
||||||
|
MaxArrayLength = 2147483647,
|
||||||
|
MaxBytesPerRead = 2147483647,
|
||||||
|
MaxDepth = 2147483647,
|
||||||
|
MaxStringContentLength = 2147483647,
|
||||||
|
MaxNameTableCharCount = 2147483647
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Commented next statement since it is not required
|
// Commented next statement since it is not required
|
||||||
bind.MaxBufferPoolSize = 2147483647;
|
|
||||||
bind.ReaderQuotas.MaxArrayLength = 2147483647;
|
|
||||||
bind.ReaderQuotas.MaxBytesPerRead = 2147483647;
|
|
||||||
bind.ReaderQuotas.MaxDepth = 2147483647;
|
|
||||||
bind.ReaderQuotas.MaxStringContentLength = 2147483647;
|
|
||||||
bind.ReaderQuotas.MaxNameTableCharCount = 2147483647;
|
|
||||||
|
|
||||||
connectionBinding = bind;
|
connectionBinding = bind;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//by Socket
|
//by Socket
|
||||||
var bind = new NetTcpBinding(SecurityMode.None);
|
var bind = new NetTcpBinding(SecurityMode.None)
|
||||||
bind.MaxReceivedMessageSize = 2147483647;
|
{
|
||||||
bind.MaxBufferSize = 2147483647;
|
MaxReceivedMessageSize = 2147483647,
|
||||||
|
MaxBufferSize = 2147483647,
|
||||||
|
MaxBufferPoolSize = 2147483647,
|
||||||
|
SendTimeout = new TimeSpan(12, 0, 0),
|
||||||
|
ReceiveTimeout = new TimeSpan(12, 0, 0),
|
||||||
|
ReaderQuotas =
|
||||||
|
{
|
||||||
|
MaxArrayLength = 2147483647,
|
||||||
|
MaxBytesPerRead = 2147483647,
|
||||||
|
MaxDepth = 2147483647,
|
||||||
|
MaxStringContentLength = 2147483647,
|
||||||
|
MaxNameTableCharCount = 2147483647
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Commented next statement since it is not required
|
// Commented next statement since it is not required
|
||||||
bind.MaxBufferPoolSize = 2147483647;
|
|
||||||
bind.ReaderQuotas.MaxArrayLength = 2147483647;
|
|
||||||
bind.ReaderQuotas.MaxBytesPerRead = 2147483647;
|
|
||||||
bind.ReaderQuotas.MaxDepth = 2147483647;
|
|
||||||
bind.ReaderQuotas.MaxStringContentLength = 2147483647;
|
|
||||||
bind.ReaderQuotas.MaxNameTableCharCount = 2147483647;
|
|
||||||
|
|
||||||
connectionBinding = bind;
|
connectionBinding = bind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.Debug("CreateConnectionBinding: end.");
|
||||||
|
|
||||||
return connectionBinding;
|
return connectionBinding;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Stop()
|
private void Stop()
|
||||||
{
|
{
|
||||||
|
Log.Debug("Stop: begin.");
|
||||||
|
|
||||||
_executorManager.Stop();
|
_executorManager.Stop();
|
||||||
|
|
||||||
lock (_hosts)
|
lock (_hosts)
|
||||||
{
|
{
|
||||||
if (_hosts.Count == 0)
|
if (_hosts.Count == 0)
|
||||||
|
{
|
||||||
|
Log.Debug("Stop: end. Host count is 0.");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -254,15 +327,18 @@ namespace MTApiService
|
|||||||
host.Close();
|
host.Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (TimeoutException)
|
catch (TimeoutException ex)
|
||||||
{
|
{
|
||||||
|
Log.ErrorFormat("Stop: TimeoutException - {0}", ex.Message);
|
||||||
|
|
||||||
foreach (var host in _hosts)
|
foreach (var host in _hosts)
|
||||||
{
|
{
|
||||||
host.Abort();
|
host.Abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
Log.ErrorFormat("Stop: Exception - {0}", ex.Message);
|
||||||
// ignored
|
// ignored
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@@ -272,20 +348,27 @@ namespace MTApiService
|
|||||||
}
|
}
|
||||||
|
|
||||||
FireOnStopped();
|
FireOnStopped();
|
||||||
|
|
||||||
|
Log.Debug("Stop: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void expert_Deinited(object sender, EventArgs e)
|
private void expert_Deinited(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (sender == null)
|
Log.Debug("expert_Deinited: begin.");
|
||||||
return;
|
|
||||||
|
|
||||||
var expert = (MtExpert)sender;
|
var expert = sender as MtExpert;
|
||||||
var expertsCount = 0;
|
if (expert == null)
|
||||||
|
{
|
||||||
|
Log.Warn("expert_Deinited: end. Expert is not defined.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int expertsCount;
|
||||||
|
|
||||||
lock (_experts)
|
lock (_experts)
|
||||||
{
|
{
|
||||||
_experts.Remove(expert);
|
_experts.Remove(expert);
|
||||||
expertsCount = _experts.Count();
|
expertsCount = _experts.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
_executorManager.RemoveCommandExecutor(expert);
|
_executorManager.RemoveCommandExecutor(expert);
|
||||||
@@ -299,19 +382,29 @@ namespace MTApiService
|
|||||||
{
|
{
|
||||||
var stopTimer = new System.Timers.Timer();
|
var stopTimer = new System.Timers.Timer();
|
||||||
stopTimer.Elapsed += stopTimer_Elapsed;
|
stopTimer.Elapsed += stopTimer_Elapsed;
|
||||||
stopTimer.Interval = STOP_EXPERT_INTERVAL;
|
stopTimer.Interval = StopExpertInterval;
|
||||||
stopTimer.Start();
|
stopTimer.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.Debug("expert_Deinited: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void expert_QuoteChanged(MtExpert expert, MtQuote quote)
|
private void expert_QuoteChanged(MtExpert expert, MtQuote quote)
|
||||||
{
|
{
|
||||||
|
Log.DebugFormat("expert_QuoteChanged: begin. expert = {0}, quote = {1}", expert, quote);
|
||||||
|
|
||||||
_service.QuoteUpdate(quote);
|
_service.QuoteUpdate(quote);
|
||||||
|
|
||||||
|
Log.Debug("expert_QuoteChanged: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Expert_OnMtEvent(object sender, MtEventArgs e)
|
private void Expert_OnMtEvent(object sender, MtEventArgs e)
|
||||||
{
|
{
|
||||||
|
Log.DebugFormat("Expert_OnMtEvent: begin. event = {0}", e.Event);
|
||||||
|
|
||||||
_service.OnMtEvent(e.Event);
|
_service.OnMtEvent(e.Event);
|
||||||
|
|
||||||
|
Log.Debug("Expert_OnMtEvent: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FireOnStopped()
|
private void FireOnStopped()
|
||||||
@@ -328,16 +421,13 @@ namespace MTApiService
|
|||||||
#region IDispose
|
#region IDispose
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
Log.Debug("Dispose: begin");
|
||||||
|
|
||||||
Stop();
|
Stop();
|
||||||
|
|
||||||
|
Log.Debug("Dispose: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Fields
|
|
||||||
private readonly MtService _service;
|
|
||||||
private readonly List<ServiceHost> _hosts = new List<ServiceHost>();
|
|
||||||
private readonly MtCommandExecutorManager _executorManager = new MtCommandExecutorManager();
|
|
||||||
private readonly List<MtExpert> _experts = new List<MtExpert>();
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,26 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using log4net;
|
||||||
using System.Text;
|
|
||||||
using System.ServiceModel;
|
|
||||||
using System.Net;
|
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace MTApiService
|
namespace MTApiService
|
||||||
{
|
{
|
||||||
public class MtServerInstance
|
public class MtServerInstance
|
||||||
{
|
{
|
||||||
#region Init_Instance
|
#region Fields
|
||||||
|
private const string LogProfileName = "MtApiService";
|
||||||
|
|
||||||
static readonly MtServerInstance mInstance = new MtServerInstance();
|
private static readonly ILog Log = LogManager.GetLogger(typeof(MtServerInstance));
|
||||||
|
private static readonly MtServerInstance Instance = new MtServerInstance();
|
||||||
|
|
||||||
|
private readonly Dictionary<int, MtServer> _servers = new Dictionary<int, MtServer>();
|
||||||
|
private readonly Dictionary<int, MtExpert> _experts = new Dictionary<int, MtExpert>();
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Init Instance
|
||||||
|
|
||||||
private MtServerInstance()
|
private MtServerInstance()
|
||||||
{
|
{
|
||||||
|
LogConfigurator.Setup(LogProfileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MtServerInstance()
|
static MtServerInstance()
|
||||||
@@ -24,7 +29,7 @@ namespace MTApiService
|
|||||||
|
|
||||||
public static MtServerInstance GetInstance()
|
public static MtServerInstance GetInstance()
|
||||||
{
|
{
|
||||||
return mInstance;
|
return Instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -33,20 +38,23 @@ namespace MTApiService
|
|||||||
#region Public Methods
|
#region Public Methods
|
||||||
public void InitExpert(int expertHandle, int port, string symbol, double bid, double ask, IMetaTraderHandler mtHandler)
|
public void InitExpert(int expertHandle, int port, string symbol, double bid, double ask, IMetaTraderHandler mtHandler)
|
||||||
{
|
{
|
||||||
Debug.WriteLine("MtApiServerInstance::InitExpert: symbol = {0}, expertHandle = {1}, port = {2}", symbol, expertHandle, port);
|
if (mtHandler == null)
|
||||||
|
throw new ArgumentNullException(nameof(mtHandler));
|
||||||
|
|
||||||
MtServer server = null;
|
Log.InfoFormat("InitExpert: begin. symbol = {0}, expertHandle = {1}, port = {2}", symbol, expertHandle, port);
|
||||||
lock (mServersDictionary)
|
|
||||||
|
MtServer server;
|
||||||
|
lock (_servers)
|
||||||
{
|
{
|
||||||
if (mServersDictionary.ContainsKey(port))
|
if (_servers.ContainsKey(port))
|
||||||
{
|
{
|
||||||
server = mServersDictionary[port];
|
server = _servers[port];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
server = new MtServer(port);
|
server = new MtServer(port);
|
||||||
server.Stopped += new EventHandler(server_Stopped);
|
server.Stopped += server_Stopped;
|
||||||
mServersDictionary[port] = server;
|
_servers[port] = server;
|
||||||
|
|
||||||
server.Start();
|
server.Start();
|
||||||
}
|
}
|
||||||
@@ -54,26 +62,28 @@ namespace MTApiService
|
|||||||
|
|
||||||
var expert = new MtExpert(expertHandle, new MtQuote(symbol, bid, ask), mtHandler);
|
var expert = new MtExpert(expertHandle, new MtQuote(symbol, bid, ask), mtHandler);
|
||||||
|
|
||||||
lock (mExpertsDictionary)
|
lock (_experts)
|
||||||
{
|
{
|
||||||
mExpertsDictionary[expert.Handle] = expert;
|
_experts[expert.Handle] = expert;
|
||||||
}
|
}
|
||||||
|
|
||||||
server.AddExpert(expert);
|
server.AddExpert(expert);
|
||||||
|
|
||||||
|
Log.Info("InitExpert: end");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeinitExpert(int expertHandle)
|
public void DeinitExpert(int expertHandle)
|
||||||
{
|
{
|
||||||
Debug.WriteLine("MtApiServerInstance::DeinitExpert: expertHandle = {0}", expertHandle);
|
Log.InfoFormat("DeinitExpert: begin. expertHandle = {0}", expertHandle);
|
||||||
|
|
||||||
MtExpert expert = null;
|
MtExpert expert = null;
|
||||||
|
|
||||||
lock (mExpertsDictionary)
|
lock (_experts)
|
||||||
{
|
{
|
||||||
if (mExpertsDictionary.ContainsKey(expertHandle) == true)
|
if (_experts.ContainsKey(expertHandle))
|
||||||
{
|
{
|
||||||
expert = mExpertsDictionary[expertHandle];
|
expert = _experts[expertHandle];
|
||||||
mExpertsDictionary.Remove(expertHandle);
|
_experts.Remove(expertHandle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,110 +91,143 @@ namespace MTApiService
|
|||||||
{
|
{
|
||||||
expert.Deinit();
|
expert.Deinit();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.WarnFormat("DeinitExpert: expert with id {0} has not been found.", expertHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.Info("DeinitExpert: end");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendQuote(int expertHandle, string symbol, double bid, double ask)
|
public void SendQuote(int expertHandle, string symbol, double bid, double ask)
|
||||||
{
|
{
|
||||||
Debug.WriteLine("MtApiServerInstance::SendQuote: enter. symbol = {0}, bid = {1}, ask = {2}", symbol, bid, ask);
|
Log.DebugFormat("SendQuote: begin. symbol = {0}, bid = {1}, ask = {2}", symbol, bid, ask);
|
||||||
|
|
||||||
MtExpert expert = null;
|
MtExpert expert;
|
||||||
lock (mExpertsDictionary)
|
lock (_experts)
|
||||||
{
|
{
|
||||||
expert = mExpertsDictionary[expertHandle];
|
expert = _experts[expertHandle];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expert != null)
|
if (expert != null)
|
||||||
{
|
{
|
||||||
expert.Quote = new MtQuote(symbol, bid, ask);
|
expert.Quote = new MtQuote(symbol, bid, ask);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.WarnFormat("SendQuote: expert with id {0} has not been found.", expertHandle);
|
||||||
|
}
|
||||||
|
|
||||||
Debug.WriteLine("MtApiServerInstance::SendQuote: finish.");
|
Log.Debug("SendQuote: end");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendEvent(int expertHandle, int eventType, string payload)
|
public void SendEvent(int expertHandle, int eventType, string payload)
|
||||||
{
|
{
|
||||||
Debug.WriteLine("MtApiServerInstance::SendEvent called. eventType = {0}, payload = {1}", eventType, payload);
|
Log.DebugFormat("SendEvent: begin. eventType = {0}, payload = {1}", eventType, payload);
|
||||||
|
|
||||||
MtExpert expert = null;
|
MtExpert expert;
|
||||||
lock (mExpertsDictionary)
|
lock (_experts)
|
||||||
{
|
{
|
||||||
expert = mExpertsDictionary[expertHandle];
|
expert = _experts[expertHandle];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expert != null)
|
if (expert != null)
|
||||||
{
|
{
|
||||||
expert.SendEvent(new MtEvent(eventType, payload));
|
expert.SendEvent(new MtEvent(eventType, payload));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.WarnFormat("SendEvent: expert with id {0} has not been found.", expertHandle);
|
||||||
|
}
|
||||||
|
|
||||||
Debug.WriteLine("MtApiServerInstance::SendEvent: finished");
|
Log.Debug("SendEvent: end");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendResponse(int expertHandle, MtResponse response)
|
public void SendResponse(int expertHandle, MtResponse response)
|
||||||
{
|
{
|
||||||
Debug.WriteLine("MtApiServerInstance::SendResponse: id = {0}, response = {1}", expertHandle, response);
|
Log.DebugFormat("SendResponse: begin. id = {0}, response = {1}", expertHandle, response);
|
||||||
|
|
||||||
MtExpert expert = null;
|
MtExpert expert;
|
||||||
lock (mExpertsDictionary)
|
lock (_experts)
|
||||||
{
|
{
|
||||||
expert = mExpertsDictionary[expertHandle];
|
expert = _experts[expertHandle];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expert != null)
|
if (expert != null)
|
||||||
{
|
{
|
||||||
expert.SendResponse(response);
|
expert.SendResponse(response);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.WarnFormat("SendResponse: expert with id {0} has not been found.", expertHandle);
|
||||||
|
}
|
||||||
|
|
||||||
Debug.WriteLine("MtApiServerInstance::SendResponse: finish");
|
Log.Debug("SendResponse: end");
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetCommandType(int expertHandle)
|
public int GetCommandType(int expertHandle)
|
||||||
{
|
{
|
||||||
Debug.WriteLine("MtApiServerInstance::GetCommandType: expertHandle = {0}", expertHandle);
|
Log.DebugFormat("GetCommandType: begin. expertHandle = {0}", expertHandle);
|
||||||
|
|
||||||
MtExpert expert = null;
|
MtExpert expert;
|
||||||
lock (mExpertsDictionary)
|
lock (_experts)
|
||||||
{
|
{
|
||||||
expert = mExpertsDictionary[expertHandle];
|
expert = _experts[expertHandle];
|
||||||
}
|
}
|
||||||
|
|
||||||
return (expert != null) ? expert.GetCommandType() : 0;
|
if (expert == null)
|
||||||
|
{
|
||||||
|
Log.WarnFormat("GetCommandType: expert with id {0} has not been found.", expertHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
var retval = expert?.GetCommandType() ?? 0;
|
||||||
|
|
||||||
|
Log.DebugFormat("GetCommandType: end. retval = {0}", retval);
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
public object GetCommandParameter(int expertHandle, int index)
|
public object GetCommandParameter(int expertHandle, int index)
|
||||||
{
|
{
|
||||||
Debug.WriteLine("MtApiServerInstance::GetCommandParameter: expertHandle = {0}, index = {1}", expertHandle, index);
|
Log.DebugFormat("GetCommandParameter: begin. expertHandle = {0}, index = {1}", expertHandle, index);
|
||||||
|
|
||||||
MtExpert expert = null;
|
MtExpert expert;
|
||||||
lock (mExpertsDictionary)
|
lock (_experts)
|
||||||
{
|
{
|
||||||
expert = mExpertsDictionary[expertHandle];
|
expert = _experts[expertHandle];
|
||||||
}
|
}
|
||||||
|
|
||||||
return (expert != null) ? expert.GetCommandParameter(index) : null;
|
if (expert == null)
|
||||||
|
{
|
||||||
|
Log.WarnFormat("GetCommandParameter: expert with id {0} has not been found.", expertHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
var retval = expert?.GetCommandParameter(index);
|
||||||
|
|
||||||
|
Log.DebugFormat("GetCommandParameter: end. retval = {0}", retval);
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Private Methods
|
#region Private Methods
|
||||||
private void server_Stopped(object sender, EventArgs e)
|
private void server_Stopped(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
MtServer server = (MtServer)sender;
|
var server = (MtServer)sender;
|
||||||
server.Stopped -= server_Stopped;
|
server.Stopped -= server_Stopped;
|
||||||
|
|
||||||
var port = server.Port;
|
var port = server.Port;
|
||||||
lock (mServersDictionary)
|
|
||||||
|
Log.InfoFormat("server_Stopped: port = {0}", port);
|
||||||
|
|
||||||
|
lock (_servers)
|
||||||
{
|
{
|
||||||
if (mServersDictionary.ContainsKey(port))
|
if (_servers.ContainsKey(port))
|
||||||
{
|
{
|
||||||
mServersDictionary.Remove(port);
|
_servers.Remove(port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Fields
|
|
||||||
private readonly MtRegistryManager mConnectionManager = new MtRegistryManager();
|
|
||||||
private readonly Dictionary<int, MtServer> mServersDictionary = new Dictionary<int, MtServer>();
|
|
||||||
private readonly Dictionary<int, MtExpert> mExpertsDictionary = new Dictionary<int, MtExpert>();
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+96
-45
@@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ServiceModel;
|
using System.ServiceModel;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using log4net;
|
||||||
|
|
||||||
namespace MTApiService
|
namespace MTApiService
|
||||||
{
|
{
|
||||||
@@ -18,7 +19,7 @@ namespace MTApiService
|
|||||||
MtResponse SendCommand(MtCommand command);
|
MtResponse SendCommand(MtCommand command);
|
||||||
|
|
||||||
[OperationContract]
|
[OperationContract]
|
||||||
IEnumerable<MtQuote> GetQuotes();
|
List<MtQuote> GetQuotes();
|
||||||
}
|
}
|
||||||
|
|
||||||
[ServiceContract]
|
[ServiceContract]
|
||||||
@@ -46,107 +47,149 @@ namespace MTApiService
|
|||||||
InstanceContextMode = InstanceContextMode.Single)]
|
InstanceContextMode = InstanceContextMode.Single)]
|
||||||
public sealed class MtService : IMtApi
|
public sealed class MtService : IMtApi
|
||||||
{
|
{
|
||||||
|
private static readonly ILog Log = LogManager.GetLogger(typeof(MtService));
|
||||||
|
|
||||||
public MtService(IMtApiServer serverCallback)
|
public MtService(IMtApiServer serverCallback)
|
||||||
{
|
{
|
||||||
if (serverCallback == null)
|
if (serverCallback == null)
|
||||||
throw new ArgumentNullException("serverCallback");
|
throw new ArgumentNullException(nameof(serverCallback));
|
||||||
|
|
||||||
mServer = serverCallback;
|
_server = serverCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region IMtApi
|
#region IMtApi
|
||||||
public bool Connect()
|
public bool Connect()
|
||||||
{
|
{
|
||||||
bool connected = false;
|
Log.Debug("Connect: begin");
|
||||||
|
|
||||||
IMtApiCallback callback = OperationContext.Current.GetCallbackChannel<IMtApiCallback>();
|
var callback = OperationContext.Current.GetCallbackChannel<IMtApiCallback>();
|
||||||
|
|
||||||
if (callback != null)
|
if (callback == null)
|
||||||
{
|
{
|
||||||
|
Log.Warn("Connect: end. Callback is not definded.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var connected = false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_clientsLocker.AcquireWriterLock(10000);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
mClientsLocker.AcquireWriterLock(10000);
|
if (_clientCallbacks.Contains(callback) == false)
|
||||||
|
_clientCallbacks.Add(callback);
|
||||||
|
|
||||||
try
|
connected = true;
|
||||||
{
|
|
||||||
if (mClientCallbacks.Contains(callback) == false)
|
|
||||||
mClientCallbacks.Add(callback);
|
|
||||||
|
|
||||||
connected = true;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
mClientsLocker.ReleaseWriterLock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (ApplicationException)
|
finally
|
||||||
{
|
{
|
||||||
|
_clientsLocker.ReleaseWriterLock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (ApplicationException ex)
|
||||||
|
{
|
||||||
|
Log.ErrorFormat("Connect: ApplicationException - {0}", ex.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.DebugFormat("Connect: end. connected = {0}", connected);
|
||||||
|
|
||||||
return connected;
|
return connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Disconnect()
|
public void Disconnect()
|
||||||
{
|
{
|
||||||
IMtApiCallback callback = OperationContext.Current.GetCallbackChannel<IMtApiCallback>();
|
Log.Debug("Disconnect: begin");
|
||||||
|
|
||||||
if (callback != null)
|
var callback = OperationContext.Current.GetCallbackChannel<IMtApiCallback>();
|
||||||
|
|
||||||
|
if (callback == null)
|
||||||
{
|
{
|
||||||
|
Log.Warn("Disconnect: end. Callback is not definded.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_clientsLocker.AcquireWriterLock(10000);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
mClientsLocker.AcquireWriterLock(10000);
|
_clientCallbacks.Remove(callback);
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
mClientCallbacks.Remove(callback);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
mClientsLocker.ReleaseWriterLock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (ApplicationException)
|
finally
|
||||||
{
|
{
|
||||||
|
_clientsLocker.ReleaseWriterLock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (ApplicationException ex)
|
||||||
|
{
|
||||||
|
Log.ErrorFormat("Disconnect: ApplicationException - {0}", ex.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.Debug("Disconnect: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public MtResponse SendCommand(MtCommand command)
|
public MtResponse SendCommand(MtCommand command)
|
||||||
{
|
{
|
||||||
return mServer.SendCommand(command);
|
Log.DebugFormat("SendCommand: called. command = {0}", command);
|
||||||
|
|
||||||
|
return _server.SendCommand(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<MtQuote> GetQuotes()
|
public List<MtQuote> GetQuotes()
|
||||||
{
|
{
|
||||||
return mServer.GetQuotes();
|
Log.Debug("GetQuotes: called.");
|
||||||
|
|
||||||
|
return _server.GetQuotes();
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Public Methods
|
#region Public Methods
|
||||||
public void OnStopServer()
|
public void OnStopServer()
|
||||||
{
|
{
|
||||||
|
Log.Debug("OnStopServer: begin.");
|
||||||
|
|
||||||
ExecuteCallbackAction(a => a.OnServerStopped());
|
ExecuteCallbackAction(a => a.OnServerStopped());
|
||||||
|
|
||||||
|
Log.Debug("OnStopServer: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void QuoteUpdate(MtQuote quote)
|
public void QuoteUpdate(MtQuote quote)
|
||||||
{
|
{
|
||||||
|
Log.Debug("QuoteUpdate: begin.");
|
||||||
|
|
||||||
ExecuteCallbackAction(a => a.OnQuoteUpdate(quote));
|
ExecuteCallbackAction(a => a.OnQuoteUpdate(quote));
|
||||||
|
|
||||||
|
Log.Debug("QuoteUpdate: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnQuoteAdded(MtQuote quote)
|
public void OnQuoteAdded(MtQuote quote)
|
||||||
{
|
{
|
||||||
|
Log.Debug("OnQuoteAdded: begin.");
|
||||||
|
|
||||||
ExecuteCallbackAction(a => a.OnQuoteAdded(quote));
|
ExecuteCallbackAction(a => a.OnQuoteAdded(quote));
|
||||||
|
|
||||||
|
Log.Debug("OnQuoteAdded: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnQuoteRemoved(MtQuote quote)
|
public void OnQuoteRemoved(MtQuote quote)
|
||||||
{
|
{
|
||||||
|
Log.Debug("OnQuoteRemoved: begin.");
|
||||||
|
|
||||||
ExecuteCallbackAction(a => a.OnQuoteRemoved(quote));
|
ExecuteCallbackAction(a => a.OnQuoteRemoved(quote));
|
||||||
|
|
||||||
|
Log.Debug("OnQuoteRemoved: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnMtEvent(MtEvent mtEvent)
|
public void OnMtEvent(MtEvent mtEvent)
|
||||||
{
|
{
|
||||||
|
Log.Debug("OnMtEvent: begin.");
|
||||||
|
|
||||||
ExecuteCallbackAction(a => a.OnMtEvent(mtEvent));
|
ExecuteCallbackAction(a => a.OnMtEvent(mtEvent));
|
||||||
|
|
||||||
|
Log.Debug("OnMtEvent: end.");
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -154,22 +197,26 @@ namespace MTApiService
|
|||||||
|
|
||||||
private void ExecuteCallbackAction(Action<IMtApiCallback> action)
|
private void ExecuteCallbackAction(Action<IMtApiCallback> action)
|
||||||
{
|
{
|
||||||
|
Log.Debug("ExecuteCallbackAction: begin.");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
mClientsLocker.AcquireReaderLock(2000);
|
_clientsLocker.AcquireReaderLock(2000);
|
||||||
|
|
||||||
List<IMtApiCallback> crashedClientCallbacks = null;
|
List<IMtApiCallback> crashedClientCallbacks = null;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
foreach (var callback in mClientCallbacks)
|
foreach (var callback in _clientCallbacks)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
action(callback);
|
action(callback);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
Log.ErrorFormat("ExecuteCallbackAction: Exception - {0}", ex.Message);
|
||||||
|
|
||||||
if (crashedClientCallbacks == null)
|
if (crashedClientCallbacks == null)
|
||||||
crashedClientCallbacks = new List<IMtApiCallback>();
|
crashedClientCallbacks = new List<IMtApiCallback>();
|
||||||
|
|
||||||
@@ -179,29 +226,33 @@ namespace MTApiService
|
|||||||
|
|
||||||
if (crashedClientCallbacks != null)
|
if (crashedClientCallbacks != null)
|
||||||
{
|
{
|
||||||
|
Log.WarnFormat("ExecuteCallbackAction: crashed callback count = {0}", crashedClientCallbacks.Count);
|
||||||
|
|
||||||
foreach (var crashedCallback in crashedClientCallbacks)
|
foreach (var crashedCallback in crashedClientCallbacks)
|
||||||
{
|
{
|
||||||
mClientCallbacks.Remove(crashedCallback);
|
_clientCallbacks.Remove(crashedCallback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
mClientsLocker.ReleaseReaderLock();
|
_clientsLocker.ReleaseReaderLock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (ApplicationException)
|
catch (ApplicationException ex)
|
||||||
{
|
{
|
||||||
//TODO: add logging
|
Log.ErrorFormat("ExecuteCallbackAction: ApplicationException - {0}", ex.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.Debug("ExecuteCallbackAction: end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Fields
|
#region Fields
|
||||||
private readonly IMtApiServer mServer;
|
private readonly IMtApiServer _server;
|
||||||
private readonly List<IMtApiCallback> mClientCallbacks = new List<IMtApiCallback>();
|
private readonly List<IMtApiCallback> _clientCallbacks = new List<IMtApiCallback>();
|
||||||
private readonly ReaderWriterLock mClientsLocker = new ReaderWriterLock();
|
private readonly ReaderWriterLock _clientsLocker = new ReaderWriterLock();
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.21.0")]
|
[assembly: AssemblyVersion("1.0.23.0")]
|
||||||
[assembly: AssemblyFileVersion("1.0.21.0")]
|
[assembly: AssemblyFileVersion("1.0.23.0")]
|
||||||
|
|||||||
Executable
+6
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<packages>
|
||||||
|
<package id="ILMerge" version="2.13.0307" targetFramework="net40" />
|
||||||
|
<package id="log4net" version="2.0.5" targetFramework="net40" />
|
||||||
|
<package id="MSBuild.ILMerge.Task" version="1.0.5" targetFramework="net40" />
|
||||||
|
</packages>
|
||||||
@@ -11,13 +11,11 @@ ref class MT4Handler: IMetaTraderHandler
|
|||||||
public:
|
public:
|
||||||
MT4Handler()
|
MT4Handler()
|
||||||
{
|
{
|
||||||
//msgId = RegisterWindowMessage("MetaTrader4_Internal_Message");
|
|
||||||
msgId = WM_TIMER;
|
msgId = WM_TIMER;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void SendTickToMetaTrader(int handle)
|
virtual void SendTickToMetaTrader(int handle)
|
||||||
{
|
{
|
||||||
//PostMessage((HWND)handle, msgId, 2, 1);
|
|
||||||
PostMessage((HWND)handle, msgId, 0, 0);
|
PostMessage((HWND)handle, msgId, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+187
-158
@@ -19,56 +19,56 @@ using namespace System::Diagnostics;
|
|||||||
|
|
||||||
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);
|
||||||
memcpy(dest, wch, wcslen(wch) * sizeof(wchar_t));
|
memcpy(dest, wch, wcslen(wch) * sizeof(wchar_t));
|
||||||
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)
|
int _stdcall initExpert(int expertHandle, int port, wchar_t* symbol, double bid, double ask, wchar_t* err)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MT4Handler^ mtHandler = gcnew MT4Handler();
|
MT4Handler^ mtHandler = gcnew MT4Handler();
|
||||||
|
|
||||||
MtServerInstance::GetInstance()->InitExpert(expertHandle, port, gcnew String(symbol), bid, ask, mtHandler);
|
MtServerInstance::GetInstance()->InitExpert(expertHandle, port, gcnew String(symbol), bid, ask, mtHandler);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
convertSystemString(err, e->Message);
|
convertSystemString(err, e->Message);
|
||||||
Debug::WriteLine("[ERROR] MTConnector:initExpert(): " + e->Message);
|
Debug::WriteLine("[ERROR] MTConnector:initExpert(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall deinitExpert(int expertHandle, wchar_t* err)
|
int _stdcall deinitExpert(int expertHandle, wchar_t* err)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MtServerInstance::GetInstance()->DeinitExpert(expertHandle);
|
MtServerInstance::GetInstance()->DeinitExpert(expertHandle);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
convertSystemString(err, e->Message);
|
convertSystemString(err, e->Message);
|
||||||
Debug::WriteLine("[ERROR] MTConnector:deinitExpert(): " + e->Message);
|
Debug::WriteLine("[ERROR] MTConnector:deinitExpert(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall updateQuote(int expertHandle, wchar_t* symbol, double bid, double ask, wchar_t* err)
|
int _stdcall updateQuote(int expertHandle, wchar_t* symbol, double bid, double ask, wchar_t* err)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MtServerInstance::GetInstance()->SendQuote(expertHandle, gcnew String(symbol), bid, ask);
|
MtServerInstance::GetInstance()->SendQuote(expertHandle, gcnew String(symbol), bid, ask);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
convertSystemString(err, e->Message);
|
convertSystemString(err, e->Message);
|
||||||
Debug::WriteLine("[ERROR] MTConnector:updateQuote(): " + e->Message);
|
Debug::WriteLine("[ERROR] MTConnector:updateQuote(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -89,170 +89,199 @@ int _stdcall sendEvent(int expertHandle, int eventType, wchar_t* payload, wchar_
|
|||||||
|
|
||||||
int _stdcall sendIntResponse(int expertHandle, int response)
|
int _stdcall sendIntResponse(int expertHandle, int response)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseInt(response));
|
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseInt(response));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MTConnector:sendIntResponse(): " + e->Message);
|
Debug::WriteLine("[ERROR] MTConnector:sendIntResponse(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall sendBooleanResponse(int expertHandle, int response)
|
int _stdcall sendBooleanResponse(int expertHandle, int response)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bool value = (response != 0) ? true : false;
|
bool value = (response != 0) ? true : false;
|
||||||
|
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseBool(value));
|
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseBool(value));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MTConnector:sendBooleanResponse(): " + e->Message);
|
Debug::WriteLine("[ERROR] MTConnector:sendBooleanResponse(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall sendDoubleResponse(int expertHandle, double response)
|
int _stdcall sendDoubleResponse(int expertHandle, double response)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDouble(response));
|
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDouble(response));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MTConnector:sendDoubleResponse(): " + e->Message);
|
Debug::WriteLine("[ERROR] MTConnector:sendDoubleResponse(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall sendStringResponse(int expertHandle, wchar_t* response)
|
int _stdcall sendStringResponse(int expertHandle, wchar_t* response)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseString(gcnew String(response)));
|
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseString(gcnew String(response)));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MTConnector:sendStringResponse(): " + e->Message);
|
Debug::WriteLine("[ERROR] MTConnector:sendStringResponse(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall sendVoidResponse(int expertHandle)
|
int _stdcall sendVoidResponse(int expertHandle)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, nullptr);
|
MtServerInstance::GetInstance()->SendResponse(expertHandle, nullptr);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MTConnector:sendVoidResponse(): " + e->Message);
|
Debug::WriteLine("[ERROR] MTConnector:sendVoidResponse(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall sendDoubleArrayResponse(int expertHandle, double* values, int size)
|
int _stdcall sendDoubleArrayResponse(int expertHandle, double* values, int size)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
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];
|
||||||
}
|
}
|
||||||
|
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDoubleArray(list));
|
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDoubleArray(list));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MTConnector:sendDoubleArrayResponse(): " + e->Message);
|
Debug::WriteLine("[ERROR] MTConnector:sendDoubleArrayResponse(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall sendIntArrayResponse(int expertHandle, int* values, int size)
|
int _stdcall sendIntArrayResponse(int expertHandle, int* values, int size)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
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];
|
||||||
}
|
}
|
||||||
|
|
||||||
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseIntArray(list));
|
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseIntArray(list));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MTConnector:sendIntArrayResponse(): " + e->Message);
|
Debug::WriteLine("[ERROR] MTConnector:sendIntArrayResponse(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _stdcall sendLongResponse(int expertHandle, __int64 response)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLong(response));
|
||||||
|
}
|
||||||
|
catch (Exception^ e)
|
||||||
|
{
|
||||||
|
Debug::WriteLine("[ERROR] MTConnector:sendLongResponse(): " + e->Message);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall getCommandType(int expertHandle, int* res)
|
int _stdcall getCommandType(int expertHandle, int* res)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
*res = MtServerInstance::GetInstance()->GetCommandType(expertHandle);
|
*res = MtServerInstance::GetInstance()->GetCommandType(expertHandle);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MTConnector:getCommandType(): " + e->Message);
|
Debug::WriteLine("[ERROR] MTConnector:getCommandType(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall getIntValue(int expertHandle, int paramIndex, int* res)
|
int _stdcall getIntValue(int expertHandle, int paramIndex, int* res)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
*res = (int)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
*res = (int)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MTConnector:getIntValue(): " + e->Message);
|
Debug::WriteLine("[ERROR] MTConnector:getIntValue(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall getDoubleValue(int expertHandle, int paramIndex, double* res)
|
int _stdcall getDoubleValue(int expertHandle, int paramIndex, double* res)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
*res = (double)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
*res = (double)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MTConnector:getDoubleValue(): " + e->Message);
|
Debug::WriteLine("[ERROR] MTConnector:getDoubleValue(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _stdcall getStringValue(int expertHandle, int paramIndex, wchar_t* res)
|
int _stdcall getStringValue(int expertHandle, int paramIndex, wchar_t* res)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
convertSystemString(res, (String^)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex));
|
convertSystemString(res, (String^)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex));
|
||||||
}
|
}
|
||||||
catch (Exception^ e)
|
catch (Exception^ e)
|
||||||
{
|
{
|
||||||
Debug::WriteLine("[ERROR] MTConnector:getStringValue(): " + e->Message);
|
Debug::WriteLine("[ERROR] MTConnector:getStringValue(): " + e->Message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _stdcall getBooleanValue(int expertHandle, int paramIndex, int* res)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bool val = (bool)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
|
||||||
|
*res = val == true ? 1 : 0;
|
||||||
|
}
|
||||||
|
catch (Exception^ e)
|
||||||
|
{
|
||||||
|
Debug::WriteLine("[ERROR] MT5Connector:getBooleanValue(): " + e->Message);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
+14
-12
@@ -3,15 +3,17 @@ LIBRARY MTConnector
|
|||||||
EXPORTS initExpert
|
EXPORTS initExpert
|
||||||
deinitExpert
|
deinitExpert
|
||||||
updateQuote
|
updateQuote
|
||||||
sendEvent
|
sendEvent
|
||||||
sendIntResponse
|
sendIntResponse
|
||||||
sendBooleanResponse
|
sendBooleanResponse
|
||||||
sendDoubleResponse
|
sendDoubleResponse
|
||||||
sendStringResponse
|
sendStringResponse
|
||||||
sendVoidResponse
|
sendVoidResponse
|
||||||
sendDoubleArrayResponse
|
sendDoubleArrayResponse
|
||||||
sendIntArrayResponse
|
sendIntArrayResponse
|
||||||
getCommandType
|
sendLongResponse
|
||||||
getIntValue
|
getCommandType
|
||||||
getDoubleValue
|
getIntValue
|
||||||
getStringValue
|
getDoubleValue
|
||||||
|
getStringValue
|
||||||
|
getBooleanValue
|
||||||
+37
-1
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 14
|
# Visual Studio 14
|
||||||
VisualStudioVersion = 14.0.25123.0
|
VisualStudioVersion = 14.0.25420.1
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestApiClientUI", "TestClients\TestApiClientUI\TestApiClientUI.csproj", "{663CC515-EAAE-47D4-8933-5008C2DA1160}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestApiClientUI", "TestClients\TestApiClientUI\TestApiClientUI.csproj", "{663CC515-EAAE-47D4-8933-5008C2DA1160}"
|
||||||
EndProject
|
EndProject
|
||||||
@@ -37,6 +37,16 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MtApiSetupActions", "MtApiS
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TestClients", "TestClients", "{B91FF338-E05D-4EF1-948B-A2376DB37ECA}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TestClients", "TestClients", "{B91FF338-E05D-4EF1-948B-A2376DB37ECA}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "MtApi5Bootstrapper", "MtApi5Bootstrapper\MtApi5Bootstrapper.wixproj", "{1497E285-C228-490B-9638-565E118548FB}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{A9ED070F-AB4D-4380-9DDE-5D931AC71333} = {A9ED070F-AB4D-4380-9DDE-5D931AC71333}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "MtApiBootstrapper", "MtApiBootstrapper\MtApiBootstrapper.wixproj", "{8E63046B-56E5-4623-8808-558AD72A8F2B}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{78B94552-DB17-40EC-B7C6-23D32DB85DC1} = {78B94552-DB17-40EC-B7C6-23D32DB85DC1}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -196,6 +206,32 @@ Global
|
|||||||
{10800F37-F71B-4818-8351-8CF744295F80}.Release|x64.ActiveCfg = Release|x86
|
{10800F37-F71B-4818-8351-8CF744295F80}.Release|x64.ActiveCfg = Release|x86
|
||||||
{10800F37-F71B-4818-8351-8CF744295F80}.Release|x86.ActiveCfg = Release|x86
|
{10800F37-F71B-4818-8351-8CF744295F80}.Release|x86.ActiveCfg = Release|x86
|
||||||
{10800F37-F71B-4818-8351-8CF744295F80}.Release|x86.Build.0 = Release|x86
|
{10800F37-F71B-4818-8351-8CF744295F80}.Release|x86.Build.0 = Release|x86
|
||||||
|
{1497E285-C228-490B-9638-565E118548FB}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||||
|
{1497E285-C228-490B-9638-565E118548FB}.Debug|Win32.ActiveCfg = Debug|x86
|
||||||
|
{1497E285-C228-490B-9638-565E118548FB}.Debug|Win32.Build.0 = Debug|x86
|
||||||
|
{1497E285-C228-490B-9638-565E118548FB}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{1497E285-C228-490B-9638-565E118548FB}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{1497E285-C228-490B-9638-565E118548FB}.Debug|x64.Deploy.0 = Debug|x64
|
||||||
|
{1497E285-C228-490B-9638-565E118548FB}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{1497E285-C228-490B-9638-565E118548FB}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{1497E285-C228-490B-9638-565E118548FB}.Release|Any CPU.ActiveCfg = Release|x86
|
||||||
|
{1497E285-C228-490B-9638-565E118548FB}.Release|Win32.ActiveCfg = Release|x86
|
||||||
|
{1497E285-C228-490B-9638-565E118548FB}.Release|Win32.Build.0 = Release|x86
|
||||||
|
{1497E285-C228-490B-9638-565E118548FB}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{1497E285-C228-490B-9638-565E118548FB}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{1497E285-C228-490B-9638-565E118548FB}.Release|x86.Build.0 = Release|x86
|
||||||
|
{8E63046B-56E5-4623-8808-558AD72A8F2B}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||||
|
{8E63046B-56E5-4623-8808-558AD72A8F2B}.Debug|Win32.ActiveCfg = Debug|x86
|
||||||
|
{8E63046B-56E5-4623-8808-558AD72A8F2B}.Debug|Win32.Build.0 = Debug|x86
|
||||||
|
{8E63046B-56E5-4623-8808-558AD72A8F2B}.Debug|x64.ActiveCfg = Debug|x86
|
||||||
|
{8E63046B-56E5-4623-8808-558AD72A8F2B}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{8E63046B-56E5-4623-8808-558AD72A8F2B}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{8E63046B-56E5-4623-8808-558AD72A8F2B}.Release|Any CPU.ActiveCfg = Release|x86
|
||||||
|
{8E63046B-56E5-4623-8808-558AD72A8F2B}.Release|Win32.ActiveCfg = Release|x86
|
||||||
|
{8E63046B-56E5-4623-8808-558AD72A8F2B}.Release|Win32.Build.0 = Release|x86
|
||||||
|
{8E63046B-56E5-4623-8808-558AD72A8F2B}.Release|x64.ActiveCfg = Release|x86
|
||||||
|
{8E63046B-56E5-4623-8808-558AD72A8F2B}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{8E63046B-56E5-4623-8808-558AD72A8F2B}.Release|x86.Build.0 = Release|x86
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
Executable
+10
@@ -0,0 +1,10 @@
|
|||||||
|
namespace MtApi
|
||||||
|
{
|
||||||
|
public enum EnumSeriesInfoInteger
|
||||||
|
{
|
||||||
|
SERIES_BARS_COUNT = 0,
|
||||||
|
SERIES_FIRSTDATE = 1,
|
||||||
|
SERIES_LASTBAR_DATE = 5,
|
||||||
|
SERIES_SERVER_FIRSTDATE = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
Executable
+46
@@ -0,0 +1,46 @@
|
|||||||
|
namespace MtApi
|
||||||
|
{
|
||||||
|
// https://docs.mql4.com/constants/environment_state/marketinfoconstants#enum_symbol_info_double
|
||||||
|
public enum EnumSymbolInfoDouble
|
||||||
|
{
|
||||||
|
SYMBOL_BID = 1, // Bid - best sell offer
|
||||||
|
SYMBOL_BIDHIGH = 2, // Not supported
|
||||||
|
SYMBOL_BIDLOW = 3, // Not supported
|
||||||
|
SYMBOL_ASK = 4, // Ask - best buy offer
|
||||||
|
SYMBOL_ASKHIGH = 5, // Not supported
|
||||||
|
SYMBOL_ASKLOW = 6, // Not supported
|
||||||
|
SYMBOL_LAST = 7, // Not supported
|
||||||
|
SYMBOL_LASTHIGH = 8, // Not supported
|
||||||
|
SYMBOL_LASTLOW = 9, // Not supported
|
||||||
|
SYMBOL_POINT = 16, // Symbol point value
|
||||||
|
SYMBOL_TRADE_TICK_VALUE = 26, // Value of SYMBOL_TRADE_TICK_VALUE_PROFIT
|
||||||
|
SYMBOL_TRADE_TICK_VALUE_PROFIT = 53, // Not supported
|
||||||
|
SYMBOL_TRADE_TICK_VALUE_LOSS = 54, // Not supported
|
||||||
|
SYMBOL_TRADE_TICK_SIZE = 27, // Minimal price change
|
||||||
|
SYMBOL_TRADE_CONTRACT_SIZE = 28, // Trade contract size
|
||||||
|
SYMBOL_VOLUME_MIN = 34, // Minimal volume for a deal
|
||||||
|
SYMBOL_VOLUME_MAX = 35, // Maximal volume for a deal
|
||||||
|
SYMBOL_VOLUME_STEP = 36, // Minimal volume change step for deal execution
|
||||||
|
SYMBOL_VOLUME_LIMIT = 55, // Not supported
|
||||||
|
SYMBOL_SWAP_LONG = 38, // Buy order swap value
|
||||||
|
SYMBOL_SWAP_SHORT = 39, // Sell order swap value
|
||||||
|
SYMBOL_MARGIN_INITIAL = 42, // Initial margin means the amount in the margin currency required for opening an order with the volume of one lot. It is used for checking a client's assets when he or she enters the market.
|
||||||
|
SYMBOL_MARGIN_MAINTENANCE = 43, // The maintenance margin. If it is set, it sets the margin amount in the margin currency of the symbol, charged from one lot. It is used for checking a client's assets when his/her account state changes. If the maintenance margin is equal to 0, the initial margin is used.
|
||||||
|
SYMBOL_MARGIN_LONG = 44, // Not supported
|
||||||
|
SYMBOL_MARGIN_SHORT = 45, // Not supported
|
||||||
|
SYMBOL_MARGIN_LIMIT = 46, // Not supported
|
||||||
|
SYMBOL_MARGIN_STOP = 47, // Not supported
|
||||||
|
SYMBOL_MARGIN_STOPLIMIT = 48, // Not supported
|
||||||
|
SYMBOL_SESSION_VOLUME = 57, // Not supported
|
||||||
|
SYMBOL_SESSION_TURNOVER = 58, // Not supported
|
||||||
|
SYMBOL_SESSION_INTEREST = 59, // Not supported
|
||||||
|
SYMBOL_SESSION_BUY_ORDERS_VOLUME = 61, // Not supported
|
||||||
|
SYMBOL_SESSION_SELL_ORDERS_VOLUME = 63, // Not supported
|
||||||
|
SYMBOL_SESSION_OPEN = 64, // Not supported
|
||||||
|
SYMBOL_SESSION_CLOSE = 65, // Not supported
|
||||||
|
SYMBOL_SESSION_AW = 66, // Not supported
|
||||||
|
SYMBOL_SESSION_PRICE_SETTLEMENT = 67, // Not supported
|
||||||
|
SYMBOL_SESSION_PRICE_LIMIT_MIN = 68, // Not supported
|
||||||
|
SYMBOL_SESSION_PRICE_LIMIT_MAX = 69, // Not supported
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
namespace MtApi
|
||||||
|
{
|
||||||
|
//MQL4: ENUM_SYMBOL_INFO_INTEGER
|
||||||
|
public enum EnumSymbolInfoInteger
|
||||||
|
{
|
||||||
|
SYMBOL_SELECT = 0,
|
||||||
|
SYMBOL_VISIBLE = 76,
|
||||||
|
SYMBOL_SESSION_DEALS = 56,
|
||||||
|
SYMBOL_SESSION_BUY_ORDERS = 60,
|
||||||
|
SYMBOL_SESSION_SELL_ORDERS = 62,
|
||||||
|
SYMBOL_VOLUME = 10,
|
||||||
|
SYMBOL_VOLUMEHIGH = 11,
|
||||||
|
SYMBOL_VOLUMELOW = 12,
|
||||||
|
SYMBOL_TIME = 15,
|
||||||
|
SYMBOL_DIGITS = 17,
|
||||||
|
SYMBOL_SPREAD = 18,
|
||||||
|
SYMBOL_SPREAD_FLOAT = 41,
|
||||||
|
SYMBOL_TRADE_CALC_MODE = 29,
|
||||||
|
SYMBOL_TRADE_MODE = 30,
|
||||||
|
SYMBOL_START_TIME = 51,
|
||||||
|
SYMBOL_EXPIRATION_TIME = 52,
|
||||||
|
SYMBOL_TRADE_STOPS_LEVEL = 31,
|
||||||
|
SYMBOL_TRADE_FREEZE_LEVEL = 32,
|
||||||
|
SYMBOL_TRADE_EXEMODE = 33,
|
||||||
|
SYMBOL_SWAP_MODE = 37,
|
||||||
|
SYMBOL_SWAP_ROLLOVER3DAYS = 40,
|
||||||
|
SYMBOL_EXPIRATION_MODE = 49,
|
||||||
|
SYMBOL_FILLING_MODE = 50,
|
||||||
|
SYMBOL_ORDER_MODE = 71
|
||||||
|
}
|
||||||
|
}
|
||||||
Executable
+8
@@ -0,0 +1,8 @@
|
|||||||
|
namespace MtApi
|
||||||
|
{
|
||||||
|
// https://docs.mql4.com/constants/environment_state/terminalstatus#enum_terminal_info_double
|
||||||
|
public enum EnumTerminalInfoDouble
|
||||||
|
{
|
||||||
|
TERMINAL_COMMUNITY_BALANCE = 25 // Balance in MQL5.community
|
||||||
|
}
|
||||||
|
}
|
||||||
Executable
+27
@@ -0,0 +1,27 @@
|
|||||||
|
namespace MtApi
|
||||||
|
{
|
||||||
|
// https://docs.mql4.com/constants/environment_state/terminalstatus#enum_terminal_info_integer
|
||||||
|
public enum EnumTerminalInfoInteger
|
||||||
|
{
|
||||||
|
TERMINAL_BUILD = 5, // The client terminal build number
|
||||||
|
TERMINAL_COMMUNITY_ACCOUNT = 23, // The flag indicates the presence of MQL5.community authorization data in the terminal
|
||||||
|
TERMINAL_COMMUNITY_CONNECTION = 24, // Connection to MQL5.community
|
||||||
|
TERMINAL_CONNECTED = 6, // Connection to a trade server
|
||||||
|
TERMINAL_DLLS_ALLOWED = 7, // Permission to use DLL
|
||||||
|
TERMINAL_TRADE_ALLOWED = 8, // Permission to trade
|
||||||
|
TERMINAL_EMAIL_ENABLED = 9, // Permission to send e-mails using SMTP-server and login, specified in the terminal settings
|
||||||
|
TERMINAL_FTP_ENABLED = 10, // Permission to send reports using FTP-server and login, specified in the terminal settings
|
||||||
|
TERMINAL_NOTIFICATIONS_ENABLED = 26, // Permission to send notifications to smartphone
|
||||||
|
TERMINAL_MAXBARS = 11, // The maximal bars count on the chart
|
||||||
|
TERMINAL_MQID = 22, // The flag indicates the presence of MetaQuotes ID data to send Push notifications
|
||||||
|
TERMINAL_CODEPAGE = 12, // Number of the code page of the language installed in the client terminal
|
||||||
|
TERMINAL_CPU_CORES = 21, // The number of CPU cores in the system
|
||||||
|
TERMINAL_DISK_SPACE = 20, // Free disk space for the MQL4\Files folder of the terminal, Mb
|
||||||
|
TERMINAL_MEMORY_PHYSICAL = 14, // Physical memory in the system, Mb
|
||||||
|
TERMINAL_MEMORY_TOTAL = 15, // Memory available to the process of the terminal , Mb
|
||||||
|
TERMINAL_MEMORY_AVAILABLE = 16, // Free memory of the terminal process, Mb
|
||||||
|
TERMINAL_MEMORY_USED = 17, // Memory used by the terminal , Mb
|
||||||
|
TERMINAL_SCREEN_DPI = 27, // The resolution of information display on the screen is measured as number of Dots in a line per Inch (DPI). Knowing the parameter value, you can set the size of graphical objects so that they look the same on monitors with different resolution characteristics.
|
||||||
|
TERMINAL_PING_LAST = 28 // The last known value of a ping to a trade server in microseconds. One second comprises of one million microseconds
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,4 @@
|
|||||||
using System;
|
namespace MtApi
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace MtApi
|
|
||||||
{
|
{
|
||||||
public enum MarketInfoModeType
|
public enum MarketInfoModeType
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ namespace MtApi.Monitors
|
|||||||
public class TimeframeTradeMonitor : TradeMonitor
|
public class TimeframeTradeMonitor : TradeMonitor
|
||||||
{
|
{
|
||||||
#region Fields
|
#region Fields
|
||||||
private volatile bool _isStarted = false;
|
private volatile bool _isStarted;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ctor
|
#region ctor
|
||||||
@@ -23,13 +23,8 @@ namespace MtApi.Monitors
|
|||||||
// Returns:
|
// Returns:
|
||||||
// true if PositionMonitor should check orders
|
// true if PositionMonitor should check orders
|
||||||
// otherwise, false.
|
// otherwise, false.
|
||||||
public override bool IsStarted
|
public override bool IsStarted => _isStarted;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _isStarted;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Protected Methods
|
#region Protected Methods
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace MtApi.Monitors
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ctor
|
#region ctor
|
||||||
public TradeMonitor(MtApiClient apiClient)
|
protected TradeMonitor(MtApiClient apiClient)
|
||||||
{
|
{
|
||||||
if (apiClient == null)
|
if (apiClient == null)
|
||||||
throw new ArgumentNullException(nameof(apiClient));
|
throw new ArgumentNullException(nameof(apiClient));
|
||||||
@@ -73,13 +73,7 @@ namespace MtApi.Monitors
|
|||||||
protected abstract void OnMtConnected();
|
protected abstract void OnMtConnected();
|
||||||
protected abstract void OnMtDisconnected();
|
protected abstract void OnMtDisconnected();
|
||||||
|
|
||||||
public bool IsMtConnected
|
public bool IsMtConnected => _apiClient.ConnectionState == MtConnectionState.Connected;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _apiClient.ConnectionState == MtConnectionState.Connected;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void Check()
|
protected void Check()
|
||||||
{
|
{
|
||||||
@@ -113,12 +107,12 @@ namespace MtApi.Monitors
|
|||||||
prevOrders = _prevOrders;
|
prevOrders = _prevOrders;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_prevOrders != null) //skip checking on first load orders
|
if (prevOrders != null) //skip checking on first load orders
|
||||||
{
|
{
|
||||||
//check open orders
|
//check open orders
|
||||||
foreach (var order in tradesOrders)
|
foreach (var order in tradesOrders)
|
||||||
{
|
{
|
||||||
if (_prevOrders.Find(a => a.Ticket == order.Ticket) == null)
|
if (prevOrders.Find(a => a.Ticket == order.Ticket) == null)
|
||||||
{
|
{
|
||||||
openedOrders.Add(order);
|
openedOrders.Add(order);
|
||||||
}
|
}
|
||||||
@@ -126,7 +120,7 @@ namespace MtApi.Monitors
|
|||||||
|
|
||||||
//check closed orders
|
//check closed orders
|
||||||
var closeOrdersTemp = new List<MtOrder>();
|
var closeOrdersTemp = new List<MtOrder>();
|
||||||
foreach (var order in _prevOrders)
|
foreach (var order in prevOrders)
|
||||||
{
|
{
|
||||||
if (tradesOrders.Find(a => a.Ticket == order.Ticket) == null)
|
if (tradesOrders.Find(a => a.Ticket == order.Ticket) == null)
|
||||||
{
|
{
|
||||||
@@ -180,10 +174,7 @@ namespace MtApi.Monitors
|
|||||||
_prevOrders = null;
|
_prevOrders = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Task.Factory.StartNew(() =>
|
Task.Factory.StartNew(Check);
|
||||||
{
|
|
||||||
Check();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-6
@@ -5,12 +5,7 @@ namespace MtApi
|
|||||||
public class MqlRates
|
public class MqlRates
|
||||||
{
|
{
|
||||||
public int MtTime { get; set; }
|
public int MtTime { get; set; }
|
||||||
|
public DateTime Time => MtApiTimeConverter.ConvertFromMtTime(MtTime);
|
||||||
public DateTime Time
|
|
||||||
{
|
|
||||||
get { return MtApiTimeConverter.ConvertFromMtTime(MtTime); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public double Open { get; set; }
|
public double Open { get; set; }
|
||||||
public double High { get; set; }
|
public double High { get; set; }
|
||||||
public double Low { get; set; }
|
public double Low { get; set; }
|
||||||
|
|||||||
Executable
+14
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace MtApi
|
||||||
|
{
|
||||||
|
public class MqlTick
|
||||||
|
{
|
||||||
|
public int MtTime { get; set; }
|
||||||
|
public DateTime Time => MtApiTimeConverter.ConvertFromMtTime(MtTime);
|
||||||
|
public double Bid { get; set; }
|
||||||
|
public double Ask { get; set; }
|
||||||
|
public double Last { get; set; }
|
||||||
|
public ulong Volume { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -59,9 +59,15 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="ChartPeriod.cs" />
|
<Compile Include="ChartPeriod.cs" />
|
||||||
|
<Compile Include="EnumSeriesInfoInteger.cs" />
|
||||||
|
<Compile Include="EnumSymbolInfoDouble.cs" />
|
||||||
|
<Compile Include="EnumSymbolInfoInteger.cs" />
|
||||||
|
<Compile Include="EnumTerminalInfoDouble.cs" />
|
||||||
|
<Compile Include="EnumTerminalInfoInteger.cs" />
|
||||||
<Compile Include="ExtensionMethods.cs" />
|
<Compile Include="ExtensionMethods.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="MtConnectionEventArgs.cs" />
|
<Compile Include="MtConnectionEventArgs.cs" />
|
||||||
<Compile Include="MtConnectionException.cs" />
|
<Compile Include="MtConnectionException.cs" />
|
||||||
<Compile Include="MtConnectionState.cs" />
|
<Compile Include="MtConnectionState.cs" />
|
||||||
@@ -72,6 +78,7 @@
|
|||||||
<Compile Include="MtOrder.cs" />
|
<Compile Include="MtOrder.cs" />
|
||||||
<Compile Include="MtQuote.cs" />
|
<Compile Include="MtQuote.cs" />
|
||||||
<Compile Include="MtQuoteEventArgs.cs" />
|
<Compile Include="MtQuoteEventArgs.cs" />
|
||||||
|
<Compile Include="MtSession.cs" />
|
||||||
<Compile Include="MtTimeBar.cs" />
|
<Compile Include="MtTimeBar.cs" />
|
||||||
<Compile Include="MtTypes.cs" />
|
<Compile Include="MtTypes.cs" />
|
||||||
<Compile Include="Monitors\TradeMonitor.cs" />
|
<Compile Include="Monitors\TradeMonitor.cs" />
|
||||||
@@ -90,14 +97,22 @@
|
|||||||
<Compile Include="Requests\OrderDeleteRequest.cs" />
|
<Compile Include="Requests\OrderDeleteRequest.cs" />
|
||||||
<Compile Include="Requests\OrderModifyRequest.cs" />
|
<Compile Include="Requests\OrderModifyRequest.cs" />
|
||||||
<Compile Include="Requests\OrderSendRequest.cs" />
|
<Compile Include="Requests\OrderSendRequest.cs" />
|
||||||
|
<Compile Include="Requests\SeriesInfoIntegerRequest.cs" />
|
||||||
|
<Compile Include="Requests\SessionRequest.cs" />
|
||||||
<Compile Include="Requests\RequestBase.cs" />
|
<Compile Include="Requests\RequestBase.cs" />
|
||||||
<Compile Include="Requests\RequestType.cs" />
|
<Compile Include="Requests\RequestType.cs" />
|
||||||
|
<Compile Include="Requests\SymbolInfoDoubleRequest.cs" />
|
||||||
|
<Compile Include="Requests\SymbolInfoTickRequest.cs" />
|
||||||
<Compile Include="Responses\CopyRatesResponse.cs" />
|
<Compile Include="Responses\CopyRatesResponse.cs" />
|
||||||
<Compile Include="Responses\GetOrderResponse.cs" />
|
<Compile Include="Responses\GetOrderResponse.cs" />
|
||||||
<Compile Include="Responses\GetOrdersResponse.cs" />
|
<Compile Include="Responses\GetOrdersResponse.cs" />
|
||||||
<Compile Include="Responses\ICustomResponse.cs" />
|
<Compile Include="Responses\ICustomResponse.cs" />
|
||||||
<Compile Include="Responses\OrderSendResponse.cs" />
|
<Compile Include="Responses\OrderSendResponse.cs" />
|
||||||
|
<Compile Include="Responses\SeriesInfoIntegerResponse.cs" />
|
||||||
|
<Compile Include="Responses\SessionResponse.cs" />
|
||||||
<Compile Include="Responses\ResponseBase.cs" />
|
<Compile Include="Responses\ResponseBase.cs" />
|
||||||
|
<Compile Include="Responses\SymbolInfoDoubleResponse.cs" />
|
||||||
|
<Compile Include="Responses\SymbolInfoTickResponse.cs" />
|
||||||
<Compile Include="SeriesIdentifier.cs" />
|
<Compile Include="SeriesIdentifier.cs" />
|
||||||
<Compile Include="TimeBarArgs.cs" />
|
<Compile Include="TimeBarArgs.cs" />
|
||||||
<Compile Include="Monitors\TimeframeTradeMonitor.cs" />
|
<Compile Include="Monitors\TimeframeTradeMonitor.cs" />
|
||||||
|
|||||||
+478
-202
File diff suppressed because it is too large
Load Diff
+15
-9
@@ -58,9 +58,15 @@ namespace MtApi
|
|||||||
IsVisualMode = 37,
|
IsVisualMode = 37,
|
||||||
UninitializeReason = 38,
|
UninitializeReason = 38,
|
||||||
ErrorDescription = 39,
|
ErrorDescription = 39,
|
||||||
|
TerminalCompany = 68,
|
||||||
|
TerminalName = 69,
|
||||||
|
TerminalPath = 70,
|
||||||
|
TerminalInfoString = 153,
|
||||||
|
TerminalInfoInteger = 204,
|
||||||
|
TerminalInfoDouble = 205,
|
||||||
|
|
||||||
//Account Information
|
//Account Information
|
||||||
AccountBalance = 40,
|
AccountBalance = 40,
|
||||||
AccountCredit = 41,
|
AccountCredit = 41,
|
||||||
AccountCompany = 42,
|
AccountCompany = 42,
|
||||||
AccountCurrency = 43,
|
AccountCurrency = 43,
|
||||||
@@ -91,11 +97,6 @@ namespace MtApi
|
|||||||
SendMail = 66,
|
SendMail = 66,
|
||||||
Sleep = 67,
|
Sleep = 67,
|
||||||
|
|
||||||
//Client Terminal
|
|
||||||
TerminalCompany = 68,
|
|
||||||
TerminalName = 69,
|
|
||||||
TerminalPath = 70,
|
|
||||||
|
|
||||||
//Date and Time
|
//Date and Time
|
||||||
Day = 71,
|
Day = 71,
|
||||||
DayOfWeek = 72,
|
DayOfWeek = 72,
|
||||||
@@ -188,13 +189,18 @@ namespace MtApi
|
|||||||
//
|
//
|
||||||
RefreshRates = 150,
|
RefreshRates = 150,
|
||||||
//
|
//
|
||||||
TerminalInfoString = 153,
|
|
||||||
SymbolInfoString = 154,
|
|
||||||
|
|
||||||
//Requests
|
//Requests
|
||||||
MtRequest = 155,
|
MtRequest = 155,
|
||||||
|
|
||||||
//Backtesting
|
//Backtesting
|
||||||
BacktestingReady = 156
|
BacktestingReady = 156,
|
||||||
|
|
||||||
|
//Market Info
|
||||||
|
SymbolInfoString = 154,
|
||||||
|
SymbolsTotal = 200,
|
||||||
|
SymbolName = 201,
|
||||||
|
SymbolSelect = 202,
|
||||||
|
SymbolInfoInteger = 203
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Regular → Executable
+85
-84
@@ -1,5 +1,6 @@
|
|||||||
namespace MtApi
|
namespace MtApi
|
||||||
{
|
{
|
||||||
|
// https://docs.mql4.com/constants/errorswarnings/errorcodes
|
||||||
public enum MtErrorCode
|
public enum MtErrorCode
|
||||||
{
|
{
|
||||||
MtApiCustomError = -1, // Error occurred in MtApi.
|
MtApiCustomError = -1, // Error occurred in MtApi.
|
||||||
@@ -10,91 +11,91 @@
|
|||||||
ServerBusy = 4, // Trade server is busy.
|
ServerBusy = 4, // Trade server is busy.
|
||||||
OldVersion = 5, // Old version of the client terminal.
|
OldVersion = 5, // Old version of the client terminal.
|
||||||
NoConnection = 6, // No connection with trade server.
|
NoConnection = 6, // No connection with trade server.
|
||||||
NotEnoughRights = 7, // Not enough rights.
|
NotEnoughRights = 7, // Not enough rights.
|
||||||
TooFrequentRequests = 8, // Too frequent requests.
|
TooFrequentRequests = 8, // Too frequent requests.
|
||||||
MalfunctionalTrade = 9, // Malfunctional trade operation.
|
MalfunctionalTrade = 9, // Malfunctional trade operation.
|
||||||
AccountDisabled = 64, // Account disabled.
|
AccountDisabled = 64, // Account disabled.
|
||||||
InvalidAccount = 65, // Invalid account.
|
InvalidAccount = 65, // Invalid account.
|
||||||
TradeTimeout = 128, // Trade timeout.
|
TradeTimeout = 128, // Trade timeout.
|
||||||
InvalidPrice = 129, // Invalid price.
|
InvalidPrice = 129, // Invalid price.
|
||||||
InvalidStops = 130, // Invalid stops.
|
InvalidStops = 130, // Invalid stops.
|
||||||
InvalidTradeVolume = 131, // Invalid trade volume.
|
InvalidTradeVolume = 131, // Invalid trade volume.
|
||||||
MarketClosed = 132, // Market is closed.
|
MarketClosed = 132, // Market is closed.
|
||||||
TradeDisabled = 133, // Trade is disabled.
|
TradeDisabled = 133, // Trade is disabled.
|
||||||
NotEnoughMoney = 134, // Not enough money.
|
NotEnoughMoney = 134, // Not enough money.
|
||||||
PriceChanged = 135, // Price changed.
|
PriceChanged = 135, // Price changed.
|
||||||
OffQuotes = 136, // Off quotes.
|
OffQuotes = 136, // Off quotes.
|
||||||
BrokerBusy = 137, // Broker is busy.
|
BrokerBusy = 137, // Broker is busy.
|
||||||
Requote = 138, // Requote.
|
Requote = 138, // Requote.
|
||||||
OrderLocked = 139, // Order is locked.
|
OrderLocked = 139, // Order is locked.
|
||||||
LongPositionsOnlyAllowed = 140, // Long positions only allowed.
|
LongPositionsOnlyAllowed = 140, // Long positions only allowed.
|
||||||
TooManyRequests = 141, // Too many requests.
|
TooManyRequests = 141, // Too many requests.
|
||||||
TradeModifyDenied = 145, // Modification denied because an order is too close to market.
|
TradeModifyDenied = 145, // Modification denied because an order is too close to market.
|
||||||
TradeContextBusy = 146, // Trade context is busy.
|
TradeContextBusy = 146, // Trade context is busy.
|
||||||
TradeExpirationDenied = 147, // Expirations are denied by broker.
|
TradeExpirationDenied = 147, // Expirations are denied by broker.
|
||||||
TradeTooManyOrders = 148, // The amount of opened and pending orders has reached the limit set by a broker.
|
TradeTooManyOrders = 148, // The amount of opened and pending orders has reached the limit set by a broker.
|
||||||
|
|
||||||
NoMqlerror = 4000, // No error.
|
NoMqlerror = 4000, // No error.
|
||||||
WrongFunctionPointer = 4001, // Wrong function pointer.
|
WrongFunctionPointer = 4001, // Wrong function pointer.
|
||||||
ArrayIndexOutOfRange = 4002, // Array index is out of range.
|
ArrayIndexOutOfRange = 4002, // Array index is out of range.
|
||||||
NoMemoryForFunctionCallStack = 4003, // No memory for function call stack.
|
NoMemoryForFunctionCallStack = 4003, // No memory for function call stack.
|
||||||
RecursiveStackOverflow = 4004, // Recursive stack overflow.
|
RecursiveStackOverflow = 4004, // Recursive stack overflow.
|
||||||
NotEnoughStackForParameter = 4005, // Not enough stack for parameter.
|
NotEnoughStackForParameter = 4005, // Not enough stack for parameter.
|
||||||
NoMemoryForParameterString = 4006, // No memory for parameter string.
|
NoMemoryForParameterString = 4006, // No memory for parameter string.
|
||||||
NoMemoryForTempString = 4007, // No memory for temp string.
|
NoMemoryForTempString = 4007, // No memory for temp string.
|
||||||
NotInitializedString = 4008, // Not initialized string.
|
NotInitializedString = 4008, // Not initialized string.
|
||||||
NotInitializedArraystring = 4009, // Not initialized string in an array.
|
NotInitializedArraystring = 4009, // Not initialized string in an array.
|
||||||
NoMemoryForArraystring = 4010, // No memory for an array string.
|
NoMemoryForArraystring = 4010, // No memory for an array string.
|
||||||
TooLongString = 4011, // Too long string.
|
TooLongString = 4011, // Too long string.
|
||||||
RemainderFromZeroDivide = 4012, // Remainder from zero divide.
|
RemainderFromZeroDivide = 4012, // Remainder from zero divide.
|
||||||
ZeroDivide = 4013, // Zero divide.
|
ZeroDivide = 4013, // Zero divide.
|
||||||
UnknownCommand = 4014, // Unknown command.
|
UnknownCommand = 4014, // Unknown command.
|
||||||
WrongJump = 4015, // Wrong jump.
|
WrongJump = 4015, // Wrong jump.
|
||||||
NotInitializedArray = 4016, // Not initialized array.
|
NotInitializedArray = 4016, // Not initialized array.
|
||||||
DllCallsNotAllowed = 4017, // DLL calls are not allowed.
|
DllCallsNotAllowed = 4017, // DLL calls are not allowed.
|
||||||
CannotLoadLibrary = 4018, // Cannot load library.
|
CannotLoadLibrary = 4018, // Cannot load library.
|
||||||
CannotCallFunction = 4019, // Cannot call function.
|
CannotCallFunction = 4019, // Cannot call function.
|
||||||
ExternalExpertCallsNotAllowed = 4020, // EA function calls are not allowed.
|
ExternalExpertCallsNotAllowed = 4020, // EA function calls are not allowed.
|
||||||
NotEnoughMemoryForReturnedString = 4021, // Not enough memory for a string returned from a function.
|
NotEnoughMemoryForReturnedString = 4021, // Not enough memory for a string returned from a function.
|
||||||
SystemBusy = 4022, // System is busy.
|
SystemBusy = 4022, // System is busy.
|
||||||
InvalidFunctionParametersCount = 4050, // Invalid function parameters count.
|
InvalidFunctionParametersCount = 4050, // Invalid function parameters count.
|
||||||
InvalidFunctionParameterValue = 4051, // Invalid function parameter value.
|
InvalidFunctionParameterValue = 4051, // Invalid function parameter value.
|
||||||
StringFunctionInternalError = 4052, // String function internal error.
|
StringFunctionInternalError = 4052, // String function internal error.
|
||||||
SomeArrayError = 4053, // Some array error.
|
SomeArrayError = 4053, // Some array error.
|
||||||
IncorrectSeriesArrayUsing = 4054, // Incorrect series array using.
|
IncorrectSeriesArrayUsing = 4054, // Incorrect series array using.
|
||||||
CustomIndicatorError = 4055, // Custom indicator error.
|
CustomIndicatorError = 4055, // Custom indicator error.
|
||||||
IncompatibleArrays = 4056, // Arrays are incompatible.
|
IncompatibleArrays = 4056, // Arrays are incompatible.
|
||||||
GlobalVariablesProcessingError = 4057, // Global variables processing error.
|
GlobalVariablesProcessingError = 4057, // Global variables processing error.
|
||||||
GlobalVariableNotFound = 4058, // Global variable not found.
|
GlobalVariableNotFound = 4058, // Global variable not found.
|
||||||
FunctionNotAllowedInTestingMode = 4059, // Function is not allowed in testing mode.
|
FunctionNotAllowedInTestingMode = 4059, // Function is not allowed in testing mode.
|
||||||
FunctionNotConfirmed = 4060, // Function is not confirmed.
|
FunctionNotConfirmed = 4060, // Function is not confirmed.
|
||||||
SendMailError = 4061, // Mail sending error.
|
SendMailError = 4061, // Mail sending error.
|
||||||
StringParameterExpected = 4062, // String parameter expected.
|
StringParameterExpected = 4062, // String parameter expected.
|
||||||
IntegerParameterExpected = 4063, // Integer parameter expected.
|
IntegerParameterExpected = 4063, // Integer parameter expected.
|
||||||
DoubleParameterExpected = 4064, // Double parameter expected.
|
DoubleParameterExpected = 4064, // Double parameter expected.
|
||||||
ArrayAsParameterExpected = 4065, // Array as parameter expected.
|
ArrayAsParameterExpected = 4065, // Array as parameter expected.
|
||||||
HistoryWillUpdated = 4066, // Requested history data in updating state.
|
HistoryWillUpdated = 4066, // Requested history data in updating state.
|
||||||
TradeError = 4067, // Some error in trade operation execution.
|
TradeError = 4067, // Some error in trade operation execution.
|
||||||
EndOfFile = 4099, // End of a file.
|
EndOfFile = 4099, // End of a file.
|
||||||
SomeFileError = 4100, // Some file error.
|
SomeFileError = 4100, // Some file error.
|
||||||
WrongFileName = 4101, // Wrong file name.
|
WrongFileName = 4101, // Wrong file name.
|
||||||
TooManyOpenedFiles = 4102, // Too many opened files.
|
TooManyOpenedFiles = 4102, // Too many opened files.
|
||||||
CannotOpenFile = 4103, // Cannot open file.
|
CannotOpenFile = 4103, // Cannot open file.
|
||||||
IncompatibleAccessToFile = 4104, // Incompatible access to a file.
|
IncompatibleAccessToFile = 4104, // Incompatible access to a file.
|
||||||
NoOrderSelected = 4105, // No order selected.
|
NoOrderSelected = 4105, // No order selected.
|
||||||
UnknownSymbol = 4106, // Unknown symbol.
|
UnknownSymbol = 4106, // Unknown symbol.
|
||||||
InvalidPriceParam = 4107, // Invalid price.
|
InvalidPriceParam = 4107, // Invalid price.
|
||||||
InvalidTicket = 4108, // Invalid ticket.
|
InvalidTicket = 4108, // Invalid ticket.
|
||||||
TradeNotAllowed = 4109, // Trade is not allowed.
|
TradeNotAllowed = 4109, // Trade is not allowed.
|
||||||
LongsNotAllowed = 4110, // Longs are not allowed.
|
LongsNotAllowed = 4110, // Longs are not allowed.
|
||||||
ShortsNotAllowed = 4111, // Shorts are not allowed.
|
ShortsNotAllowed = 4111, // Shorts are not allowed.
|
||||||
ObjectAlreadyExists = 4200, // Object already exists.
|
ObjectAlreadyExists = 4200, // Object already exists.
|
||||||
UnknownObjectProperty = 4201, // Unknown object property.
|
UnknownObjectProperty = 4201, // Unknown object property.
|
||||||
ObjectDoesNotExist = 4202, // Object does not exist.
|
ObjectDoesNotExist = 4202, // Object does not exist.
|
||||||
UnknownObjectType = 4203, // Unknown object type.
|
UnknownObjectType = 4203, // Unknown object type.
|
||||||
NoObjectName = 4204, // No object name.
|
NoObjectName = 4204, // No object name.
|
||||||
ObjectCoordinatesError = 4205, // Object coordinates error.
|
ObjectCoordinatesError = 4205, // Object coordinates error.
|
||||||
NoSpecifiedSubwindow = 4206, // No specified subwindow.
|
NoSpecifiedSubwindow = 4206, // No specified subwindow.
|
||||||
SomeObjectError = 4207 // Some error in object operation.
|
SomeObjectError = 4207 // Some error in object operation.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-6
@@ -1,9 +1,4 @@
|
|||||||
using System;
|
namespace MtApi
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace MtApi
|
|
||||||
{
|
{
|
||||||
public class MtQuote
|
public class MtQuote
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace MtApi
|
||||||
|
{
|
||||||
|
public class MtSession
|
||||||
|
{
|
||||||
|
public string Symbol { get; set; }
|
||||||
|
public DayOfWeek DayOfWeek { get; set; }
|
||||||
|
public uint Index { get; set; }
|
||||||
|
public int MtFromTime { get; set; }
|
||||||
|
public DateTime From => MtApiTimeConverter.ConvertFromMtTime(MtFromTime);
|
||||||
|
public int MtToTime { get; set; }
|
||||||
|
public DateTime To => MtApiTimeConverter.ConvertFromMtTime(MtToTime);
|
||||||
|
public bool HasData { get; set; }
|
||||||
|
public SessionType Type { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum SessionType
|
||||||
|
{
|
||||||
|
Quote,
|
||||||
|
Trade
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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.30.0")]
|
[assembly: AssemblyVersion("1.0.32.0")]
|
||||||
[assembly: AssemblyFileVersion("1.0.30.0")]
|
[assembly: AssemblyFileVersion("1.0.32.0")]
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
using System;
|
namespace MtApi.Requests
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace MtApi.Requests
|
|
||||||
{
|
{
|
||||||
public abstract class CopyRatesRequestBase : RequestBase
|
internal abstract class CopyRatesRequestBase : RequestBase
|
||||||
{
|
{
|
||||||
public enum CopyRatesTypeEnum
|
public enum CopyRatesTypeEnum
|
||||||
{
|
{
|
||||||
@@ -15,10 +9,7 @@ namespace MtApi.Requests
|
|||||||
CopyRates_3 = 3,
|
CopyRates_3 = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
public override RequestType RequestType
|
public override RequestType RequestType => RequestType.CopyRates;
|
||||||
{
|
|
||||||
get { return RequestType.CopyRates; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract CopyRatesTypeEnum CopyRatesType { get; }
|
public abstract CopyRatesTypeEnum CopyRatesType { get; }
|
||||||
|
|
||||||
@@ -26,34 +17,25 @@ namespace MtApi.Requests
|
|||||||
public ENUM_TIMEFRAMES Timeframe { get; set; }
|
public ENUM_TIMEFRAMES Timeframe { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CopyRates1Request : CopyRatesRequestBase
|
internal class CopyRates1Request : CopyRatesRequestBase
|
||||||
{
|
{
|
||||||
public override CopyRatesTypeEnum CopyRatesType
|
public override CopyRatesTypeEnum CopyRatesType => CopyRatesTypeEnum.CopyRates_1;
|
||||||
{
|
|
||||||
get { return CopyRatesTypeEnum.CopyRates_1; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public int StartPos { get; set; }
|
public int StartPos { get; set; }
|
||||||
public int Count { get; set; }
|
public int Count { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CopyRates2Request : CopyRatesRequestBase
|
internal class CopyRates2Request : CopyRatesRequestBase
|
||||||
{
|
{
|
||||||
public override CopyRatesTypeEnum CopyRatesType
|
public override CopyRatesTypeEnum CopyRatesType => CopyRatesTypeEnum.CopyRates_2;
|
||||||
{
|
|
||||||
get { return CopyRatesTypeEnum.CopyRates_2; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public int StartTime { get; set; }
|
public int StartTime { get; set; }
|
||||||
public int Count { get; set; }
|
public int Count { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CopyRates3Request : CopyRatesRequestBase
|
internal class CopyRates3Request : CopyRatesRequestBase
|
||||||
{
|
{
|
||||||
public override CopyRatesTypeEnum CopyRatesType
|
public override CopyRatesTypeEnum CopyRatesType => CopyRatesTypeEnum.CopyRates_3;
|
||||||
{
|
|
||||||
get { return CopyRatesTypeEnum.CopyRates_3; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public int StartTime { get; set; }
|
public int StartTime { get; set; }
|
||||||
public int StopTime { get; set; }
|
public int StopTime { get; set; }
|
||||||
|
|||||||
Regular → Executable
+2
-5
@@ -1,14 +1,11 @@
|
|||||||
namespace MtApi.Requests
|
namespace MtApi.Requests
|
||||||
{
|
{
|
||||||
public class GetOrderRequest: RequestBase
|
internal class GetOrderRequest: RequestBase
|
||||||
{
|
{
|
||||||
public int Index { get; set; }
|
public int Index { get; set; }
|
||||||
public int Select { get; set; }
|
public int Select { get; set; }
|
||||||
public int Pool { get; set; }
|
public int Pool { get; set; }
|
||||||
|
|
||||||
public override RequestType RequestType
|
public override RequestType RequestType => RequestType.GetOrder;
|
||||||
{
|
|
||||||
get { return RequestType.GetOrder; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Regular → Executable
+2
-5
@@ -1,12 +1,9 @@
|
|||||||
namespace MtApi.Requests
|
namespace MtApi.Requests
|
||||||
{
|
{
|
||||||
public class GetOrdersRequest: RequestBase
|
internal class GetOrdersRequest: RequestBase
|
||||||
{
|
{
|
||||||
public int Pool { get; set; }
|
public int Pool { get; set; }
|
||||||
|
|
||||||
public override RequestType RequestType
|
public override RequestType RequestType => RequestType.GetOrders;
|
||||||
{
|
|
||||||
get { return RequestType.GetOrders; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Regular → Executable
+3
-8
@@ -1,10 +1,8 @@
|
|||||||
|
using System.Collections;
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
|
|
||||||
namespace MtApi.Requests
|
namespace MtApi.Requests
|
||||||
{
|
{
|
||||||
public class ICustomRequest : RequestBase
|
internal class ICustomRequest : RequestBase
|
||||||
{
|
{
|
||||||
public enum ParametersType
|
public enum ParametersType
|
||||||
{
|
{
|
||||||
@@ -22,9 +20,6 @@ namespace MtApi.Requests
|
|||||||
public ArrayList Params { get; set; }
|
public ArrayList Params { get; set; }
|
||||||
public ParametersType ParamsType { get; set; }
|
public ParametersType ParamsType { get; set; }
|
||||||
|
|
||||||
public override RequestType RequestType
|
public override RequestType RequestType => RequestType.iCustom;
|
||||||
{
|
|
||||||
get { return RequestType.iCustom; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Regular → Executable
+2
-5
@@ -1,15 +1,12 @@
|
|||||||
namespace MtApi.Requests
|
namespace MtApi.Requests
|
||||||
{
|
{
|
||||||
public class OrderCloseByRequest: RequestBase
|
internal class OrderCloseByRequest: RequestBase
|
||||||
{
|
{
|
||||||
public int Ticket { get; set; }
|
public int Ticket { get; set; }
|
||||||
public int Opposite { get; set; }
|
public int Opposite { get; set; }
|
||||||
|
|
||||||
public int? ArrowColor { get; set; }
|
public int? ArrowColor { get; set; }
|
||||||
|
|
||||||
public override RequestType RequestType
|
public override RequestType RequestType => RequestType.OrderCloseBy;
|
||||||
{
|
|
||||||
get { return RequestType.OrderCloseBy; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Regular → Executable
+2
-5
@@ -1,6 +1,6 @@
|
|||||||
namespace MtApi.Requests
|
namespace MtApi.Requests
|
||||||
{
|
{
|
||||||
public class OrderCloseRequest: RequestBase
|
internal class OrderCloseRequest: RequestBase
|
||||||
{
|
{
|
||||||
public int Ticket { get; set; }
|
public int Ticket { get; set; }
|
||||||
|
|
||||||
@@ -9,9 +9,6 @@
|
|||||||
public int? Slippage { get; set; }
|
public int? Slippage { get; set; }
|
||||||
public int? ArrowColor { get; set; }
|
public int? ArrowColor { get; set; }
|
||||||
|
|
||||||
public override RequestType RequestType
|
public override RequestType RequestType => RequestType.OrderClose;
|
||||||
{
|
|
||||||
get { return RequestType.OrderClose; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Regular → Executable
+2
-5
@@ -1,14 +1,11 @@
|
|||||||
namespace MtApi.Requests
|
namespace MtApi.Requests
|
||||||
{
|
{
|
||||||
public class OrderDeleteRequest: RequestBase
|
internal class OrderDeleteRequest: RequestBase
|
||||||
{
|
{
|
||||||
public int Ticket { get; set; }
|
public int Ticket { get; set; }
|
||||||
|
|
||||||
public int? ArrowColor { get; set; }
|
public int? ArrowColor { get; set; }
|
||||||
|
|
||||||
public override RequestType RequestType
|
public override RequestType RequestType => RequestType.OrderDelete;
|
||||||
{
|
|
||||||
get { return RequestType.OrderDelete; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Regular → Executable
+2
-5
@@ -1,6 +1,6 @@
|
|||||||
namespace MtApi.Requests
|
namespace MtApi.Requests
|
||||||
{
|
{
|
||||||
public class OrderModifyRequest: RequestBase
|
internal class OrderModifyRequest: RequestBase
|
||||||
{
|
{
|
||||||
public int Ticket { get; set; }
|
public int Ticket { get; set; }
|
||||||
public double Price { get; set; }
|
public double Price { get; set; }
|
||||||
@@ -10,9 +10,6 @@
|
|||||||
|
|
||||||
public int? ArrowColor { get; set; }
|
public int? ArrowColor { get; set; }
|
||||||
|
|
||||||
public override RequestType RequestType
|
public override RequestType RequestType => RequestType.OrderModify;
|
||||||
{
|
|
||||||
get { return RequestType.OrderModify; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Regular → Executable
+2
-5
@@ -1,6 +1,6 @@
|
|||||||
namespace MtApi.Requests
|
namespace MtApi.Requests
|
||||||
{
|
{
|
||||||
public class OrderSendRequest: RequestBase
|
internal class OrderSendRequest: RequestBase
|
||||||
{
|
{
|
||||||
public string Symbol { get; set; }
|
public string Symbol { get; set; }
|
||||||
public int Cmd { get; set; }
|
public int Cmd { get; set; }
|
||||||
@@ -15,9 +15,6 @@
|
|||||||
public int? Expiration { get; set; }
|
public int? Expiration { get; set; }
|
||||||
public int? ArrowColor { get; set; }
|
public int? ArrowColor { get; set; }
|
||||||
|
|
||||||
public override RequestType RequestType
|
public override RequestType RequestType => RequestType.OrderSend;
|
||||||
{
|
|
||||||
get { return RequestType.OrderSend; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
using Newtonsoft.Json;
|
namespace MtApi.Requests
|
||||||
|
|
||||||
namespace MtApi.Requests
|
|
||||||
{
|
{
|
||||||
public abstract class RequestBase
|
internal abstract class RequestBase
|
||||||
{
|
{
|
||||||
public abstract RequestType RequestType { get; }
|
public abstract RequestType RequestType { get; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,20 @@
|
|||||||
namespace MtApi.Requests
|
namespace MtApi.Requests
|
||||||
{
|
{
|
||||||
public enum RequestType
|
internal enum RequestType
|
||||||
{
|
{
|
||||||
Unknown = 0,
|
Unknown = 0,
|
||||||
GetOrder = 1,
|
GetOrder = 1,
|
||||||
GetOrders = 2,
|
GetOrders = 2,
|
||||||
OrderSend = 3,
|
OrderSend = 3,
|
||||||
OrderClose = 4,
|
OrderClose = 4,
|
||||||
OrderCloseBy = 5,
|
OrderCloseBy = 5,
|
||||||
OrderDelete = 6,
|
OrderDelete = 6,
|
||||||
OrderModify = 7,
|
OrderModify = 7,
|
||||||
iCustom = 8,
|
iCustom = 8,
|
||||||
CopyRates = 9
|
CopyRates = 9,
|
||||||
|
Session = 10,
|
||||||
|
SeriesInfoInteger = 11,
|
||||||
|
SymbolInfoDouble = 12,
|
||||||
|
SymbolInfoTick = 13
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Executable
+11
@@ -0,0 +1,11 @@
|
|||||||
|
namespace MtApi.Requests
|
||||||
|
{
|
||||||
|
internal class SeriesInfoIntegerRequest: RequestBase
|
||||||
|
{
|
||||||
|
public override RequestType RequestType => RequestType.SeriesInfoInteger;
|
||||||
|
|
||||||
|
public string SymbolName { get; set; }
|
||||||
|
public int Timeframe { get; set; }
|
||||||
|
public int PropId { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace MtApi.Requests
|
||||||
|
{
|
||||||
|
internal class SessionRequest : RequestBase
|
||||||
|
{
|
||||||
|
public string Symbol { get; set; }
|
||||||
|
public DayOfWeek DayOfWeek { get; set; }
|
||||||
|
public int SessionIndex { get; set; }
|
||||||
|
public SessionType SessionType { get; set; }
|
||||||
|
|
||||||
|
public override RequestType RequestType => RequestType.Session;
|
||||||
|
}
|
||||||
|
}
|
||||||
Executable
+12
@@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace MtApi.Requests
|
||||||
|
{
|
||||||
|
internal class SymbolInfoDoubleRequest : RequestBase
|
||||||
|
{
|
||||||
|
public override RequestType RequestType => RequestType.SymbolInfoDouble;
|
||||||
|
|
||||||
|
public string SymbolName { get; set; }
|
||||||
|
public int PropId { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
Executable
+9
@@ -0,0 +1,9 @@
|
|||||||
|
namespace MtApi.Requests
|
||||||
|
{
|
||||||
|
internal class SymbolInfoTickRequest: RequestBase
|
||||||
|
{
|
||||||
|
public override RequestType RequestType => RequestType.SymbolInfoTick;
|
||||||
|
|
||||||
|
public string Symbol { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace MtApi.Responses
|
namespace MtApi.Responses
|
||||||
{
|
{
|
||||||
public class CopyRatesResponse: ResponseBase
|
internal class CopyRatesResponse: ResponseBase
|
||||||
{
|
{
|
||||||
public List<MqlRates> Rates { get; set; }
|
public List<MqlRates> Rates { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
Regular → Executable
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
namespace MtApi.Responses
|
namespace MtApi.Responses
|
||||||
{
|
{
|
||||||
public class GetOrderResponse: ResponseBase
|
internal class GetOrderResponse: ResponseBase
|
||||||
{
|
{
|
||||||
public MtOrder Order { get; set; }
|
public MtOrder Order { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
Regular → Executable
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace MtApi.Responses
|
namespace MtApi.Responses
|
||||||
{
|
{
|
||||||
public class GetOrdersResponse: ResponseBase
|
internal class GetOrdersResponse: ResponseBase
|
||||||
{
|
{
|
||||||
public List<MtOrder> Orders { get; set; }
|
public List<MtOrder> Orders { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
Regular → Executable
+2
-8
@@ -1,12 +1,6 @@
|
|||||||
using System;
|
namespace MtApi.Responses
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace MtApi.Responses
|
|
||||||
{
|
{
|
||||||
public class ICustomResponse: ResponseBase
|
internal class ICustomResponse: ResponseBase
|
||||||
{
|
{
|
||||||
public double Value { get; set; }
|
public double Value { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
Regular → Executable
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
namespace MtApi.Responses
|
namespace MtApi.Responses
|
||||||
{
|
{
|
||||||
public class OrderSendResponse: ResponseBase
|
internal class OrderSendResponse: ResponseBase
|
||||||
{
|
{
|
||||||
public int Ticket { get; set; }
|
public int Ticket { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
Regular → Executable
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
namespace MtApi.Responses
|
namespace MtApi.Responses
|
||||||
{
|
{
|
||||||
public class ResponseBase
|
internal class ResponseBase
|
||||||
{
|
{
|
||||||
public int ErrorCode { get; set; }
|
public int ErrorCode { get; set; }
|
||||||
public string ErrorMessage { get; set; }
|
public string ErrorMessage { get; set; }
|
||||||
|
|||||||
Executable
+7
@@ -0,0 +1,7 @@
|
|||||||
|
namespace MtApi.Responses
|
||||||
|
{
|
||||||
|
internal class SeriesInfoIntegerResponse: ResponseBase
|
||||||
|
{
|
||||||
|
public long Value { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace MtApi.Responses
|
||||||
|
{
|
||||||
|
internal class SessionResponse : ResponseBase
|
||||||
|
{
|
||||||
|
public MtSession Session { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
Executable
+7
@@ -0,0 +1,7 @@
|
|||||||
|
namespace MtApi.Responses
|
||||||
|
{
|
||||||
|
internal class SymbolInfoDoubleResponse: ResponseBase
|
||||||
|
{
|
||||||
|
public double Value { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
Executable
+7
@@ -0,0 +1,7 @@
|
|||||||
|
namespace MtApi.Responses
|
||||||
|
{
|
||||||
|
internal class SymbolInfoTickResponse: ResponseBase
|
||||||
|
{
|
||||||
|
public MqlTick Tick { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,4 @@
|
|||||||
using System;
|
namespace MtApi
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace MtApi
|
|
||||||
{
|
{
|
||||||
public enum TradeOperation
|
public enum TradeOperation
|
||||||
{
|
{
|
||||||
|
|||||||
Executable
+9
@@ -0,0 +1,9 @@
|
|||||||
|
namespace MtApi5
|
||||||
|
{
|
||||||
|
public enum CopyTicksFlag
|
||||||
|
{
|
||||||
|
Info = 1, // ticks with Bid and/or Ask changes
|
||||||
|
Trade = 2, // ticks with changes in Last and Volume
|
||||||
|
All = -1 // all ticks
|
||||||
|
}
|
||||||
|
}
|
||||||
Executable
+188
@@ -0,0 +1,188 @@
|
|||||||
|
namespace MtApi5
|
||||||
|
{
|
||||||
|
//Error codes from https://www.mql5.com/en/docs/constants/errorswarnings/errorcodes
|
||||||
|
|
||||||
|
public enum ErrorCode
|
||||||
|
{
|
||||||
|
ErrCustom = -1, // Error occurred in MtApi5.
|
||||||
|
ErrSuccess = 0, // The operation completed successfully
|
||||||
|
ErrInternalError = 4001, // Unexpected internal error
|
||||||
|
ErrWrongInternalParameter = 4002, // Wrong parameter in the inner call of the client terminal function
|
||||||
|
ErrInvalidParameter = 4003, // Wrong parameter when calling the system function
|
||||||
|
ErrNotEnoughMemory = 4004, // Not enough memory to perform the system function
|
||||||
|
ErrStructWithobjectsOrclass = 4005, // The structure contains objects of strings and/or dynamic arrays and/or structure of such objects and/or classes
|
||||||
|
ErrInvalidArray = 4006, // Array of a wrong type, wrong size, or a damaged object of a dynamic array
|
||||||
|
ErrArrayResizeError = 4007, // Not enough memory for the relocation of an array, or an attempt to change the size of a static array
|
||||||
|
ErrStringResizeError = 4008, // Not enough memory for the relocation of string
|
||||||
|
ErrNotinitializedString = 4009, // Not initialized string
|
||||||
|
ErrInvalidDatetime = 4010, // Invalid date and/or time
|
||||||
|
ErrArrayBadSize = 4011, // Requested array size exceeds 2 GB
|
||||||
|
ErrInvalidPointer = 4012, // Wrong pointer
|
||||||
|
ErrInvalidPointerType = 4013, // Wrong type of pointer
|
||||||
|
ErrFunctionNotAllowed = 4014, // Function is not allowed for call
|
||||||
|
ErrResourceNameDuplicated = 4015, // The names of the dynamic and the static resource match
|
||||||
|
ErrResourceNotFound = 4016, // Resource with this name has not been found in EX5
|
||||||
|
ErrResourceUnsuppotedType = 4017, // Unsupported resource type or its size exceeds 16 Mb
|
||||||
|
ErrResourceNameIsTooLong = 4018, // The resource name exceeds 63 characters
|
||||||
|
|
||||||
|
ErrChartWrongId = 4101, // Wrong chart ID
|
||||||
|
ErrChartNoReply = 4102, // Chart does not respond
|
||||||
|
ErrChartNotFound = 4103, // Chart not found
|
||||||
|
ErrChartNoExpert = 4104, // No Expert Advisor in the chart that could handle the event
|
||||||
|
ErrChartCannotOpen = 4105, // Chart opening error
|
||||||
|
ErrChartCannotChange = 4106, // Failed to change chart symbol and period
|
||||||
|
ErrChartWrongParameter = 4107, // Error value of the parameter for the function of working with charts
|
||||||
|
ErrChartCannotCreateTimer = 4108, // Failed to create timer
|
||||||
|
ErrChartWrongProperty = 4109, // Wrong chart property ID
|
||||||
|
ErrChartScreenshotFailed = 4110, // Error creating screenshots
|
||||||
|
ErrChartNavigateFailed = 4111, // Error navigating through chart
|
||||||
|
ErrChartTemplateFailed = 4112, // Error applying template
|
||||||
|
ErrChartWindowNotFound = 4113, // Subwindow containing the indicator was not found
|
||||||
|
ErrChartIndicatorCannotAdd = 4114, // Error adding an indicator to chart
|
||||||
|
ErrChartIndicatorCannotDel = 4115, // Error deleting an indicator from the chart
|
||||||
|
ErrChartIndicatorNotFound = 4116, // Indicator not found on the specified chart
|
||||||
|
|
||||||
|
ErrObjectError = 4201, // Error working with a graphical object
|
||||||
|
ErrObjectNotFound = 4202, // Graphical object was not found
|
||||||
|
ErrObjectWrongProperty = 4203, // Wrong ID of a graphical object property
|
||||||
|
ErrObjectGetdateFailed = 4204, // Unable to get date corresponding to the value
|
||||||
|
ErrObjectGetvalueFailed = 4205, // Unable to get value corresponding to the date
|
||||||
|
|
||||||
|
ErrMarketUnknownSymbol = 4301, // Unknown symbol
|
||||||
|
ErrMarketNotSelected = 4302, // Symbol is not selected in MarketWatch
|
||||||
|
ErrMarketWrongProperty = 4303, // Wrong identifier of a symbol property
|
||||||
|
ErrMarketLasttimeUnknown = 4304, // Time of the last tick is not known (no ticks)
|
||||||
|
ErrMarketSelectError = 4305, // Error adding or deleting a symbol in MarketWatch
|
||||||
|
|
||||||
|
ErrHistoryNotFound = 4401, // Requested history not found
|
||||||
|
ErrHistoryWrongProperty = 4402, // Wrong ID of the history property
|
||||||
|
|
||||||
|
ErrGlobalvariableNotFound = 4501, // Global variable of the client terminal is not found
|
||||||
|
ErrGlobalvariableExists = 4502, // Global variable of the client terminal with the same name already exists
|
||||||
|
ErrMailSendFailed = 4510, // Email sending failed
|
||||||
|
ErrPlaySoundFailed = 4511, // Sound playing failed
|
||||||
|
ErrMql5WrongProperty = 4512, // Wrong identifier of the program property
|
||||||
|
ErrTerminalWrongProperty = 4513, // Wrong identifier of the terminal property
|
||||||
|
ErrFtpSendFailed = 4514, // File sending via ftp failed
|
||||||
|
ErrNotificationSendFailed = 4515, // Failed to send a notification
|
||||||
|
ErrNotificationWrongParameter = 4516, // Invalid parameter for sending a notification — an empty string or NULL has been passed to the SendNotification() function
|
||||||
|
ErrNotificationWrongSettings = 4517, // Wrong settings of notifications in the terminal (ID is not specified or permission is not set)
|
||||||
|
ErrNotificationTooFrequent = 4518, // Too frequent sending of notifications
|
||||||
|
ErrFtpNoserver = 4519, // FTP server is not specified
|
||||||
|
ErrFtpNologin = 4520, // FTP login is not specified
|
||||||
|
ErrFtpFileError = 4521, // File not found in the MQL5\Files directory to send on FTP server
|
||||||
|
ErrFtpConnectFailed = 4522, // FTP connection failed
|
||||||
|
ErrFtpChangedir = 4523, // FTP path not found on server
|
||||||
|
ErrFtpClosed = 4524, // FTP connection closed
|
||||||
|
|
||||||
|
ErrBuffersNoMemory = 4601, // Not enough memory for the distribution of indicator buffers
|
||||||
|
ErrBuffersWrongIndex = 4602, // Wrong indicator buffer index
|
||||||
|
|
||||||
|
ErrCustomWrongProperty = 4603, // Wrong ID of the custom indicator property
|
||||||
|
|
||||||
|
ErrAccountWrongProperty = 4701, // Wrong account property ID
|
||||||
|
ErrTradeWrongProperty = 4751, // Wrong trade property ID
|
||||||
|
ErrTradeDisabled = 4752, // Trading by Expert Advisors prohibited
|
||||||
|
ErrTradePositionNotFound = 4753, // Position not found
|
||||||
|
ErrTradeOrderNotFound = 4754, // Order not found
|
||||||
|
ErrTradeDealNotFound = 4755, // Deal not found
|
||||||
|
ErrTradeSendFailed = 4756, // Trade request sending failed
|
||||||
|
|
||||||
|
ErrIndicatorUnknownSymbol = 4801, // Unknown symbol
|
||||||
|
ErrIndicatorCannotCreate = 4802, // Indicator cannot be created
|
||||||
|
ErrIndicatorNoMemory = 4803, // Not enough memory to add the indicator
|
||||||
|
ErrIndicatorCannotApply = 4804, // The indicator cannot be applied to another indicator
|
||||||
|
ErrIndicatorCannotAdd = 4805, // Error applying an indicator to chart
|
||||||
|
ErrIndicatorDataNotFound = 4806, // Requested data not found
|
||||||
|
ErrIndicatorWrongHandle = 4807, // Wrong indicator handle
|
||||||
|
ErrIndicatorWrongParameters = 4808, // Wrong number of parameters when creating an indicator
|
||||||
|
ErrIndicatorParametersMissing = 4809, // No parameters when creating an indicator
|
||||||
|
ErrIndicatorCustomName = 4810, // The first parameter in the array must be the name of the custom indicator
|
||||||
|
ErrIndicatorParameterType = 4811, // Invalid parameter type in the array when creating an indicator
|
||||||
|
ErrIndicatorWrongIndex = 4812, // Wrong index of the requested indicator buffer
|
||||||
|
|
||||||
|
ErrBooksCannotAdd = 4901, // Depth Of Market can not be added
|
||||||
|
ErrBooksCannotDelete = 4902, // Depth Of Market can not be removed
|
||||||
|
ErrBooksCannotGet = 4903, // The data from Depth Of Market can not be obtained
|
||||||
|
ErrBooksCannotSubscribe = 4904, // Error in subscribing to receive new data from Depth Of Market
|
||||||
|
|
||||||
|
ErrTooManyFiles = 5001, // More than 64 files cannot be opened at the same time
|
||||||
|
ErrWrongFilename = 5002, // Invalid file name
|
||||||
|
ErrTooLongFilename = 5003, // Too long file name
|
||||||
|
ErrCannotOpenFile = 5004, // File opening error
|
||||||
|
ErrFileCachebufferError = 5005, // Not enough memory for cache to read
|
||||||
|
ErrCannotDeleteFile = 5006, // File deleting error
|
||||||
|
ErrInvalidFilehandle = 5007, // A file with this handle was closed, or was not opening at all
|
||||||
|
ErrWrongFilehandle = 5008, // Wrong file handle
|
||||||
|
ErrFileNottowrite = 5009, // The file must be opened for writing
|
||||||
|
ErrFileNottoread = 5010, // The file must be opened for reading
|
||||||
|
ErrFileNotbin = 5011, // The file must be opened as a binary one
|
||||||
|
ErrFileNottxt = 5012, // The file must be opened as a text
|
||||||
|
ErrFileNottxtorcsv = 5013, // The file must be opened as a text or CSV
|
||||||
|
ErrFileNotcsv = 5014, // The file must be opened as CSV
|
||||||
|
ErrFileReaderror = 5015, // File reading error
|
||||||
|
ErrFileBinstringsize = 5016, // String size must be specified, because the file is opened as binary
|
||||||
|
ErrIncompatibleFile = 5017, // A text file must be for string arrays, for other arrays - binary
|
||||||
|
ErrFileIsDirectory = 5018, // This is not a file, this is a directory
|
||||||
|
ErrFileNotExist = 5019, // File does not exist
|
||||||
|
ErrFileCannotRewrite = 5020, // File can not be rewritten
|
||||||
|
ErrWrongDirectoryname = 5021, // Wrong directory name
|
||||||
|
ErrDirectoryNotExist = 5022, // Directory does not exist
|
||||||
|
ErrFileIsnotDirectory = 5023, // This is a file, not a directory
|
||||||
|
ErrCannotDeleteDirectory = 5024, // The directory cannot be removed
|
||||||
|
ErrCannotCleanDirectory = 5025, // Failed to clear the directory (probably one or more files are blocked and removal operation failed)
|
||||||
|
ErrFileWriteerror = 5026, // Failed to write a resource to a file
|
||||||
|
ErrFileEndoffile = 5027, // Unable to read the next piece of data from a CSV file (FileReadString, FileReadNumber, FileReadDatetime, FileReadBool), since the end of file is reached
|
||||||
|
|
||||||
|
ErrNoStringDate = 5030, // No date in the string
|
||||||
|
ErrWrongStringDate = 5031, // Wrong date in the string
|
||||||
|
ErrWrongStringTime = 5032, // Wrong time in the string
|
||||||
|
ErrStringTimeError = 5033, // Error converting string to date
|
||||||
|
ErrStringOutOfMemory = 5034, // Not enough memory for the string
|
||||||
|
ErrStringSmallLen = 5035, // The string length is less than expected
|
||||||
|
ErrStringTooBignumber = 5036, // Too large number, more than ULONG_MAX
|
||||||
|
ErrWrongFormatstring = 5037, // Invalid format string
|
||||||
|
ErrTooManyFormatters = 5038, // Amount of format specifiers more than the parameters
|
||||||
|
ErrTooManyParameters = 5039, // Amount of parameters more than the format specifiers
|
||||||
|
ErrWrongStringParameter = 5040, // Damaged parameter of string type
|
||||||
|
ErrStringposOutofrange = 5041, // Position outside the string
|
||||||
|
ErrStringZeroadded = 5042, // 0 added to the string end, a useless operation
|
||||||
|
ErrStringUnknowntype = 5043, // Unknown data type when converting to a string
|
||||||
|
ErrWrongStringObject = 5044, // Damaged string object
|
||||||
|
|
||||||
|
ErrIncompatibleArrays = 5050, // Copying incompatible arrays. String array can be copied only to a string array, and a numeric array - in numeric array only
|
||||||
|
ErrSmallAsseriesArray = 5051, // The receiving array is declared as AS_SERIES, and it is of insufficient size
|
||||||
|
ErrSmallArray = 5052, // Too small array, the starting position is outside the array
|
||||||
|
ErrZerosizeArray = 5053, // An array of zero length
|
||||||
|
ErrNumberArraysOnly = 5054, // Must be a numeric array
|
||||||
|
ErrOnedimArraysOnly = 5055, // Must be a one-dimensional array
|
||||||
|
ErrSeriesArray = 5056, // Timeseries cannot be used
|
||||||
|
ErrDoubleArrayOnly = 5057, // Must be an array of type double
|
||||||
|
ErrFloatArrayOnly = 5058, // Must be an array of type float
|
||||||
|
ErrLongArrayOnly = 5059, // Must be an array of type long
|
||||||
|
ErrIntArrayOnly = 5060, // Must be an array of type int
|
||||||
|
ErrShortArrayOnly = 5061, // Must be an array of type short
|
||||||
|
ErrCharArrayOnly = 5062, // Must be an array of type char
|
||||||
|
|
||||||
|
ErrOpenclNotSupported = 5100, // OpenCL functions are not supported on this computer
|
||||||
|
ErrOpenclInternal = 5101, // Internal error occurred when running OpenCL
|
||||||
|
ErrOpenclInvalidHandle = 5102, // Invalid OpenCL handle
|
||||||
|
ErrOpenclContextCreate = 5103, // Error creating the OpenCL context
|
||||||
|
ErrOpenclQueueCreate = 5104, // Failed to create a run queue in OpenCL
|
||||||
|
ErrOpenclProgramCreate = 5105, // Error occurred when compiling an OpenCL program
|
||||||
|
ErrOpenclTooLongKernelName = 5106, // Too long kernel name (OpenCL kernel)
|
||||||
|
ErrOpenclKernelCreate = 5107, // Error creating an OpenCL kernel
|
||||||
|
ErrOpenclSetKernelParameter = 5108, // Error occurred when setting parameters for the OpenCL kernel
|
||||||
|
ErrOpenclExecute = 5109, // OpenCL program runtime error
|
||||||
|
ErrOpenclWrongBufferSize = 5110, // Invalid size of the OpenCL buffer
|
||||||
|
ErrOpenclWrongBufferOffset = 5111, // Invalid offset in the OpenCL buffer
|
||||||
|
ErrOpenclBufferCreate = 5112, // Failed to create an OpenCL buffer
|
||||||
|
|
||||||
|
ErrWebrequestInvalidAddress = 5200, // Invalid URL
|
||||||
|
ErrWebrequestConnectFailed = 5201, // Failed to connect to specified URL
|
||||||
|
ErrWebrequestTimeout = 5202, // Timeout exceeded
|
||||||
|
ErrWebrequestRequestFailed = 5203, // HTTP request failed
|
||||||
|
|
||||||
|
ErrUserErrorFirst = 65536 // User defined errors start with this code
|
||||||
|
}
|
||||||
|
}
|
||||||
Executable
+15
@@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace MtApi5
|
||||||
|
{
|
||||||
|
public class ExecutionException: Exception
|
||||||
|
{
|
||||||
|
public ExecutionException(ErrorCode errorCode, string message)
|
||||||
|
:base(message)
|
||||||
|
{
|
||||||
|
ErrorCode = errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ErrorCode ErrorCode { get; private set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,28 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace MtApi5
|
namespace MtApi5
|
||||||
{
|
{
|
||||||
static class ExtensionMethods
|
internal static class ExtensionMethods
|
||||||
{
|
{
|
||||||
#region Event Methods
|
#region Event Methods
|
||||||
public static void FireEvent(this EventHandler eventHandler, object sender)
|
public static void FireEvent(this EventHandler eventHandler, object sender)
|
||||||
{
|
{
|
||||||
if (eventHandler != null)
|
eventHandler?.Invoke(sender, EventArgs.Empty);
|
||||||
{
|
|
||||||
eventHandler(sender, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void FireEvent<T>(this EventHandler<T> eventHandler, object sender, T e)
|
public static void FireEvent<T>(this EventHandler<T> eventHandler, object sender, T e)
|
||||||
where T : EventArgs
|
where T : EventArgs
|
||||||
{
|
{
|
||||||
if (eventHandler != null)
|
eventHandler?.Invoke(sender, e);
|
||||||
{
|
|
||||||
eventHandler(sender, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
+12
-11
@@ -1,7 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace MtApi5
|
namespace MtApi5
|
||||||
{
|
{
|
||||||
@@ -19,13 +16,17 @@ namespace MtApi5
|
|||||||
this.real_volume = real_volume;
|
this.real_volume = real_volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DateTime time { get; private set; } // Period start time
|
public MqlRates()
|
||||||
public double open { get; private set; } // Open price
|
{
|
||||||
public double high { get; private set; } // The highest price of the period
|
}
|
||||||
public double low { get; private set; } // The lowest price of the period
|
|
||||||
public double close { get; private set; } // Close price
|
public DateTime time { get; set; } // Period start time
|
||||||
public long tick_volume { get; private set; } // Tick volume
|
public double open { get; set; } // Open price
|
||||||
public int spread { get; private set; } // Spread
|
public double high { get; set; } // The highest price of the period
|
||||||
public long real_volume { get; private set; } // Trade volume
|
public double low { get; set; } // The lowest price of the period
|
||||||
|
public double close { get; set; } // Close price
|
||||||
|
public long tick_volume { get; set; } // Tick volume
|
||||||
|
public int spread { get; set; } // Spread
|
||||||
|
public long real_volume { get; set; } // Trade volume
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-9
@@ -1,7 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace MtApi5
|
namespace MtApi5
|
||||||
{
|
{
|
||||||
@@ -9,17 +6,24 @@ namespace MtApi5
|
|||||||
{
|
{
|
||||||
public MqlTick(DateTime time, double bid, double ask, double last, ulong volume)
|
public MqlTick(DateTime time, double bid, double ask, double last, ulong volume)
|
||||||
{
|
{
|
||||||
this.time = time;
|
MtTime = Mt5TimeConverter.ConvertToMtTime(time);
|
||||||
this.bid = bid;
|
this.bid = bid;
|
||||||
this.ask = ask;
|
this.ask = ask;
|
||||||
this.last = last;
|
this.last = last;
|
||||||
this.volume = volume;
|
this.volume = volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DateTime time { get; private set; } // Time of the last prices update
|
public MqlTick()
|
||||||
public double bid { get; private set; } // Current Bid price
|
{
|
||||||
public double ask { get; private set; } // Current Ask price
|
}
|
||||||
public double last { get; private set; } // Price of the last deal (Last)
|
|
||||||
public ulong volume { get; private set; } // Volume for the current Last price
|
public long MtTime { get; set; } // Time of the last prices update
|
||||||
|
|
||||||
|
public double bid { get; set; } // Current Bid price
|
||||||
|
public double ask { get; set; } // Current Ask price
|
||||||
|
public double last { get; set; } // Price of the last deal (Last)
|
||||||
|
public ulong volume { get; set; } // Volume for the current Last price
|
||||||
|
|
||||||
|
public DateTime time => Mt5TimeConverter.ConvertFromMtTime(MtTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace MtApi5
|
namespace MtApi5
|
||||||
{
|
{
|
||||||
@@ -8,7 +6,7 @@ namespace MtApi5
|
|||||||
{
|
{
|
||||||
public ENUM_TRADE_REQUEST_ACTIONS Action { get; set; } // Trade operation type
|
public ENUM_TRADE_REQUEST_ACTIONS Action { get; set; } // Trade operation type
|
||||||
public uint Magic { get; set; } // Expert Advisor ID (magic number)
|
public uint Magic { get; set; } // Expert Advisor ID (magic number)
|
||||||
public uint Order { get; set; } // Order ticket
|
public ulong Order { get; set; } // Order ticket
|
||||||
public string Symbol { get; set; } // Trade symbol
|
public string Symbol { get; set; } // Trade symbol
|
||||||
public double Volume { get; set; } // Requested volume for a deal in lots
|
public double Volume { get; set; } // Requested volume for a deal in lots
|
||||||
public double Price { get; set; } // Price
|
public double Price { get; set; } // Price
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using System.Text;
|
|||||||
|
|
||||||
namespace MtApi5
|
namespace MtApi5
|
||||||
{
|
{
|
||||||
enum Mt5CommandType
|
internal enum Mt5CommandType
|
||||||
{
|
{
|
||||||
//NoCommand = 0
|
//NoCommand = 0
|
||||||
|
|
||||||
@@ -101,6 +101,18 @@ namespace MtApi5
|
|||||||
MarketBookRelease = 61,
|
MarketBookRelease = 61,
|
||||||
MarketBookGet = 62,
|
MarketBookGet = 62,
|
||||||
OrderCloseAll = 63,
|
OrderCloseAll = 63,
|
||||||
PositionClose = 64
|
|
||||||
|
//CTrade
|
||||||
|
PositionClose = 64,
|
||||||
|
PositionOpen = 65,
|
||||||
|
|
||||||
|
//Backtesting
|
||||||
|
BacktestingReady = 66,
|
||||||
|
IsTesting = 67,
|
||||||
|
|
||||||
|
Print = 68,
|
||||||
|
|
||||||
|
//Requests
|
||||||
|
MtRequest = 155,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+17
-1
@@ -32,9 +32,14 @@
|
|||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Reference Include="Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Newtonsoft.Json.8.0.3\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Configuration.Install" />
|
<Reference Include="System.Configuration.Install" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.ServiceModel" />
|
||||||
<Reference Include="System.Xml.Linq" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
<Reference Include="System.Data.DataSetExtensions" />
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
@@ -42,6 +47,7 @@
|
|||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="CopyTicksFlag.cs" />
|
||||||
<Compile Include="MqlBookInfo.cs" />
|
<Compile Include="MqlBookInfo.cs" />
|
||||||
<Compile Include="MqlRates.cs" />
|
<Compile Include="MqlRates.cs" />
|
||||||
<Compile Include="MqlTick.cs" />
|
<Compile Include="MqlTick.cs" />
|
||||||
@@ -55,10 +61,17 @@
|
|||||||
<Compile Include="MqlTradeResult.cs" />
|
<Compile Include="MqlTradeResult.cs" />
|
||||||
<Compile Include="Mt5QuoteEventArgs.cs" />
|
<Compile Include="Mt5QuoteEventArgs.cs" />
|
||||||
<Compile Include="MtApi5Client.cs" />
|
<Compile Include="MtApi5Client.cs" />
|
||||||
<Compile Include="MtCommandType.cs" />
|
<Compile Include="Mt5CommandType.cs" />
|
||||||
<Compile Include="MtConverters.cs" />
|
<Compile Include="MtConverters.cs" />
|
||||||
|
<Compile Include="ErrorCode.cs" />
|
||||||
|
<Compile Include="ExecutionException.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Mt5Quote.cs" />
|
<Compile Include="Mt5Quote.cs" />
|
||||||
|
<Compile Include="Requests\CopyTicksRequest.cs" />
|
||||||
|
<Compile Include="Requests\RequestBase.cs" />
|
||||||
|
<Compile Include="Requests\RequestType.cs" />
|
||||||
|
<Compile Include="Responses\CopyTicksResponse.cs" />
|
||||||
|
<Compile Include="Responses\ResponseBase.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\MTApiService\MTApiService.csproj">
|
<ProjectReference Include="..\MTApiService\MTApiService.csproj">
|
||||||
@@ -66,6 +79,9 @@
|
|||||||
<Name>MTApiService</Name>
|
<Name>MTApiService</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="packages.config" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.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.
|
||||||
|
|||||||
+590
-489
File diff suppressed because it is too large
Load Diff
+30
-33
@@ -1,13 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using MTApiService;
|
using MTApiService;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
|
||||||
namespace MtApi5
|
namespace MtApi5
|
||||||
{
|
{
|
||||||
static class MtConverters
|
internal static class MtConverters
|
||||||
{
|
{
|
||||||
#region Values Converters
|
#region Values Converters
|
||||||
public static Mt5Quote Parse(this MtQuote quote)
|
public static Mt5Quote Parse(this MtQuote quote)
|
||||||
@@ -17,29 +14,29 @@ namespace MtApi5
|
|||||||
|
|
||||||
public static bool ParseResult(this string inputString, char separator, out MqlTradeResult result)
|
public static bool ParseResult(this string inputString, char separator, out MqlTradeResult result)
|
||||||
{
|
{
|
||||||
bool retVal = false;
|
var retVal = false;
|
||||||
result = null;
|
result = null;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(inputString) == false)
|
if (string.IsNullOrEmpty(inputString) == false)
|
||||||
{
|
{
|
||||||
string[] values = inputString.Split(separator);
|
var values = inputString.Split(separator);
|
||||||
if (values.Length == 10)
|
if (values.Length == 10)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
retVal = int.Parse(values[0]) != 0;
|
retVal = int.Parse(values[0]) != 0;
|
||||||
|
|
||||||
uint retcode = uint.Parse(values[1]);
|
var retcode = uint.Parse(values[1]);
|
||||||
ulong deal = ulong.Parse(values[2]);
|
var deal = ulong.Parse(values[2]);
|
||||||
ulong order = ulong.Parse(values[3]);
|
var order = ulong.Parse(values[3]);
|
||||||
double volume = double.Parse(values[4]);
|
var volume = double.Parse(values[4]);
|
||||||
double price = double.Parse(values[5]);
|
var price = double.Parse(values[5]);
|
||||||
double bid = double.Parse(values[6]);
|
var bid = double.Parse(values[6]);
|
||||||
double ask = double.Parse(values[7]);
|
var ask = double.Parse(values[7]);
|
||||||
string comment = values[8];
|
var comment = values[8];
|
||||||
uint request_id = uint.Parse(values[9]);
|
var requestId = uint.Parse(values[9]);
|
||||||
|
|
||||||
result = new MqlTradeResult(retcode, deal, order, volume, price, bid, ask, comment, request_id);
|
result = new MqlTradeResult(retcode, deal, order, volume, price, bid, ask, comment, requestId);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
@@ -52,28 +49,28 @@ namespace MtApi5
|
|||||||
|
|
||||||
public static bool ParseResult(this string inputString, char separator, out MqlTradeCheckResult result)
|
public static bool ParseResult(this string inputString, char separator, out MqlTradeCheckResult result)
|
||||||
{
|
{
|
||||||
bool retVal = false;
|
var retVal = false;
|
||||||
result = null;
|
result = null;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(inputString) == false)
|
if (string.IsNullOrEmpty(inputString) == false)
|
||||||
{
|
{
|
||||||
string[] values = inputString.Split(separator);
|
var values = inputString.Split(separator);
|
||||||
if (values.Length == 10)
|
if (values.Length == 10)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
retVal = int.Parse(values[0]) != 0;
|
retVal = int.Parse(values[0]) != 0;
|
||||||
|
|
||||||
uint retcode = uint.Parse(values[1]);
|
var retcode = uint.Parse(values[1]);
|
||||||
double balance = double.Parse(values[2]);
|
var balance = double.Parse(values[2]);
|
||||||
double equity = double.Parse(values[3]);
|
var equity = double.Parse(values[3]);
|
||||||
double profit = double.Parse(values[4]);
|
var profit = double.Parse(values[4]);
|
||||||
double margin = double.Parse(values[5]);
|
var margin = double.Parse(values[5]);
|
||||||
double margin_free = double.Parse(values[6]);
|
var marginFree = double.Parse(values[6]);
|
||||||
double margin_level = double.Parse(values[7]);
|
var marginLevel = double.Parse(values[7]);
|
||||||
string comment = values[8];
|
var comment = values[8];
|
||||||
|
|
||||||
result = new MqlTradeCheckResult(retcode, balance, equity, profit, margin, margin_free, margin_level, comment);
|
result = new MqlTradeCheckResult(retcode, balance, equity, profit, margin, marginFree, marginLevel, comment);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
@@ -87,7 +84,7 @@ namespace MtApi5
|
|||||||
|
|
||||||
public static bool ParseResult(this string inputString, char separator, out double result)
|
public static bool ParseResult(this string inputString, char separator, out double result)
|
||||||
{
|
{
|
||||||
bool retVal = false;
|
var retVal = false;
|
||||||
result = 0;
|
result = 0;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(inputString) == false)
|
if (string.IsNullOrEmpty(inputString) == false)
|
||||||
@@ -113,24 +110,24 @@ namespace MtApi5
|
|||||||
|
|
||||||
public static bool ParseResult(this string inputString, char separator, out DateTime from, out DateTime to)
|
public static bool ParseResult(this string inputString, char separator, out DateTime from, out DateTime to)
|
||||||
{
|
{
|
||||||
bool retVal = false;
|
var retVal = false;
|
||||||
|
|
||||||
from = new DateTime();
|
from = new DateTime();
|
||||||
to = new DateTime();
|
to = new DateTime();
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(inputString) == false)
|
if (string.IsNullOrEmpty(inputString) == false)
|
||||||
{
|
{
|
||||||
string[] values = inputString.Split(separator);
|
var values = inputString.Split(separator);
|
||||||
if (values.Length == 3)
|
if (values.Length == 3)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
retVal = int.Parse(values[0]) != 0;
|
retVal = int.Parse(values[0]) != 0;
|
||||||
|
|
||||||
int iFrom = int.Parse(values[1]);
|
var iFrom = int.Parse(values[1]);
|
||||||
from = Mt5TimeConverter.ConvertFromMtTime(iFrom);
|
from = Mt5TimeConverter.ConvertFromMtTime(iFrom);
|
||||||
|
|
||||||
int iTo= int.Parse(values[2]);
|
var iTo= int.Parse(values[2]);
|
||||||
to = Mt5TimeConverter.ConvertFromMtTime(iTo);
|
to = Mt5TimeConverter.ConvertFromMtTime(iTo);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
@@ -148,7 +145,7 @@ namespace MtApi5
|
|||||||
if (request == null)
|
if (request == null)
|
||||||
throw new ArgumentNullException();
|
throw new ArgumentNullException();
|
||||||
|
|
||||||
int exp = Mt5TimeConverter.ConvertToMtTime(request.Expiration);
|
var exp = Mt5TimeConverter.ConvertToMtTime(request.Expiration);
|
||||||
|
|
||||||
return new ArrayList { (int)request.Action, request.Magic, request.Order, request.Symbol, request.Volume
|
return new ArrayList { (int)request.Action, request.Magic, request.Order, request.Symbol, request.Volume
|
||||||
, request.Price, request.Stoplimit, request.Sl, request.Tp, request.Deviation, (int)request.Type
|
, request.Price, request.Stoplimit, request.Sl, request.Tp, request.Deviation, (int)request.Type
|
||||||
|
|||||||
@@ -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.9.0")]
|
[assembly: AssemblyVersion("1.0.11.0")]
|
||||||
[assembly: AssemblyFileVersion("1.0.9.0")]
|
[assembly: AssemblyFileVersion("1.0.11.0")]
|
||||||
|
|||||||
Executable
+12
@@ -0,0 +1,12 @@
|
|||||||
|
namespace MtApi5.Requests
|
||||||
|
{
|
||||||
|
internal class CopyTicksRequest: RequestBase
|
||||||
|
{
|
||||||
|
public override RequestType RequestType => RequestType.CopyTicks;
|
||||||
|
|
||||||
|
public string SymbolName { get; set; }
|
||||||
|
public int Flags { get; set; }
|
||||||
|
public ulong From { get; set; }
|
||||||
|
public uint Count { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
Executable
+7
@@ -0,0 +1,7 @@
|
|||||||
|
namespace MtApi5.Requests
|
||||||
|
{
|
||||||
|
internal abstract class RequestBase
|
||||||
|
{
|
||||||
|
public abstract RequestType RequestType { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
Executable
+8
@@ -0,0 +1,8 @@
|
|||||||
|
namespace MtApi5.Requests
|
||||||
|
{
|
||||||
|
internal enum RequestType
|
||||||
|
{
|
||||||
|
Unknown = 0,
|
||||||
|
CopyTicks = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
Executable
+9
@@ -0,0 +1,9 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MtApi5.Responses
|
||||||
|
{
|
||||||
|
internal class CopyTicksResponse: ResponseBase
|
||||||
|
{
|
||||||
|
public List<MqlTick> Ticks { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
Executable
+8
@@ -0,0 +1,8 @@
|
|||||||
|
namespace MtApi5.Responses
|
||||||
|
{
|
||||||
|
internal class ResponseBase
|
||||||
|
{
|
||||||
|
public int ErrorCode { get; set; }
|
||||||
|
public string ErrorMessage { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
Executable
+4
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<packages>
|
||||||
|
<package id="Newtonsoft.Json" version="8.0.3" targetFramework="net40" />
|
||||||
|
</packages>
|
||||||
Executable
+42
@@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:bal="http://schemas.microsoft.com/wix/BalExtension">
|
||||||
|
<?if $(var.Platform) = x64 ?>
|
||||||
|
<?define MsiSourceFileName="MtApi5Installer_x64.msi"?>
|
||||||
|
<?define VcRedistFileName="vc_redist.x64.exe"?>
|
||||||
|
<?else ?>
|
||||||
|
<?define MsiSourceFileName="MtApi5Installer_x86.msi"?>
|
||||||
|
<?define VcRedistFileName="vc_redist.x86.exe"?>
|
||||||
|
<?endif ?>
|
||||||
|
|
||||||
|
<?define ProductName="!(bind.packageName.MtApi5Msi)" ?>
|
||||||
|
<?define ProductVersion="!(bind.packageVersion.MtApi5Msi)" ?>
|
||||||
|
<?define Manufacturer="!(bind.packageManufacturer.MtApi5Msi)" ?>
|
||||||
|
|
||||||
|
<Bundle Name="$(var.ProductName) Bootstrapper"
|
||||||
|
Version="$(var.ProductVersion)"
|
||||||
|
Manufacturer="$(var.Manufacturer)"
|
||||||
|
UpgradeCode="1497e285-c228-490b-9638-565e118548fb">
|
||||||
|
|
||||||
|
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense">
|
||||||
|
<bal:WixStandardBootstrapperApplication LicenseFile="..\LICENSE.rtf"/>
|
||||||
|
</BootstrapperApplicationRef>
|
||||||
|
|
||||||
|
<Chain>
|
||||||
|
|
||||||
|
<ExePackage SourceFile="..\vcredist\$(var.VcRedistFileName)"
|
||||||
|
Name="Redist\$(var.VcRedistFileName)"
|
||||||
|
Cache="no"
|
||||||
|
Compressed="yes"
|
||||||
|
InstallCommand="/install /quiet /norestart">
|
||||||
|
<!-- Ignore "Newer version installed" error -->
|
||||||
|
<ExitCode Value="1638" Behavior="success"/>
|
||||||
|
</ExePackage>
|
||||||
|
|
||||||
|
<MsiPackage Id="MtApi5Msi"
|
||||||
|
SourceFile="..\build\installers\$(var.Configuration)\$(var.MsiSourceFileName)"
|
||||||
|
Visible="yes"
|
||||||
|
DisplayInternalUI="yes" />
|
||||||
|
|
||||||
|
</Chain>
|
||||||
|
</Bundle>
|
||||||
|
</Wix>
|
||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||||
|
<ProductVersion>3.10</ProductVersion>
|
||||||
|
<ProjectGuid>1497e285-c228-490b-9638-565e118548fb</ProjectGuid>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
<OutputName>MtApi5_Setup_$(Platform)</OutputName>
|
||||||
|
<OutputType>Bundle</OutputType>
|
||||||
|
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
|
||||||
|
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||||
|
<OutputPath>..\build\installers\$(Configuration)\</OutputPath>
|
||||||
|
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
|
||||||
|
<DefineConstants>Debug</DefineConstants>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||||
|
<OutputPath>..\build\installers\$(Configuration)\</OutputPath>
|
||||||
|
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
|
||||||
|
<DefineConstants>Debug</DefineConstants>
|
||||||
|
<OutputPath>..\build\installers\$(Configuration)\</OutputPath>
|
||||||
|
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)\</IntermediateOutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
|
||||||
|
<OutputPath>..\build\installers\$(Configuration)\</OutputPath>
|
||||||
|
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)\</IntermediateOutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Bundle.wxs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<WixExtension Include="WixBalExtension">
|
||||||
|
<HintPath>$(WixExtDir)\WixBalExtension.dll</HintPath>
|
||||||
|
<Name>WixBalExtension</Name>
|
||||||
|
</WixExtension>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(WixTargetsPath)" />
|
||||||
|
<!--
|
||||||
|
To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Wix.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
<ProductVersion>3.6</ProductVersion>
|
<ProductVersion>3.6</ProductVersion>
|
||||||
<ProjectGuid>{a9ed070f-ab4d-4380-9dde-5d931ac71333}</ProjectGuid>
|
<ProjectGuid>{a9ed070f-ab4d-4380-9dde-5d931ac71333}</ProjectGuid>
|
||||||
<SchemaVersion>2.0</SchemaVersion>
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
<OutputName>MtApi5Installer</OutputName>
|
<OutputName>MtApi5Installer_$(Platform)</OutputName>
|
||||||
<OutputType>Package</OutputType>
|
<OutputType>Package</OutputType>
|
||||||
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
|
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
|
||||||
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
|
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
|
||||||
@@ -22,11 +22,11 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
|
||||||
<DefineConstants>Debug</DefineConstants>
|
<DefineConstants>Debug</DefineConstants>
|
||||||
<OutputPath>..\build\installers\$(Configuration)\x64\</OutputPath>
|
<OutputPath>..\build\installers\$(Configuration)</OutputPath>
|
||||||
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)\</IntermediateOutputPath>
|
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)\</IntermediateOutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
|
||||||
<OutputPath>..\build\installers\$(Configuration)\x64\</OutputPath>
|
<OutputPath>..\build\installers\$(Configuration)\</OutputPath>
|
||||||
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)\</IntermediateOutputPath>
|
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)\</IntermediateOutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,30 +1,32 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||||
|
<?define ProductName="MtApi5" ?>
|
||||||
|
|
||||||
<?if $(var.Platform) = x64 ?>
|
<?if $(var.Platform) = x64 ?>
|
||||||
<?define ProductName="MtApi5_x64" ?>
|
|
||||||
<?define ProductPathNative="..\build\products\$(var.Configuration)\x64\"?>
|
<?define ProductPathNative="..\build\products\$(var.Configuration)\x64\"?>
|
||||||
<?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
|
<?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
|
||||||
<?define PlatformSystemFolder = "System64Folder" ?>
|
<?define PlatformSystemFolder = "System64Folder" ?>
|
||||||
<?else ?>
|
<?else ?>
|
||||||
<?define ProductName="MtApi5" ?>
|
|
||||||
<?define ProductPathNative="..\build\products\$(var.Configuration)\"?>
|
<?define ProductPathNative="..\build\products\$(var.Configuration)\"?>
|
||||||
<?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
|
<?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
|
||||||
<?define PlatformSystemFolder = "SystemFolder" ?>
|
<?define PlatformSystemFolder = "SystemFolder" ?>
|
||||||
<?endif ?>
|
<?endif ?>
|
||||||
|
|
||||||
<?define ProductVersion="1.0.9" ?>
|
<?define ProductVersion=!(bind.FileVersion.MtApi5.dll) ?>
|
||||||
<?define Manufacturer="DW"?>
|
<?define Manufacturer="DW"?>
|
||||||
<?define ProductPath="..\build\products\$(var.Configuration)\"?>
|
<?define ProductPath="..\build\products\$(var.Configuration)\"?>
|
||||||
|
|
||||||
<Product Id="*"
|
<Product Id="*"
|
||||||
Name="$(var.ProductName) $(var.ProductVersion)"
|
Name="$(var.ProductName) $(var.ProductVersion)"
|
||||||
Language="1033"
|
Language="1033"
|
||||||
Version="$(var.ProductVersion)"
|
Version="$(var.ProductVersion)"
|
||||||
Manufacturer="$(var.Manufacturer)"
|
Manufacturer="$(var.Manufacturer)"
|
||||||
UpgradeCode="d72d346e-e6f7-4c23-85c6-1c42b3175599">
|
UpgradeCode="d72d346e-e6f7-4c23-85c6-1c42b3175599">
|
||||||
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
|
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
|
||||||
|
|
||||||
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
|
<WixVariable Id="WixUILicenseRtf" Value="..\LICENSE.rtf" />
|
||||||
|
|
||||||
|
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
|
||||||
<MediaTemplate EmbedCab="yes" />
|
<MediaTemplate EmbedCab="yes" />
|
||||||
|
|
||||||
<Feature Id="MtApi5" Title="$(var.ProductName)" Level="1">
|
<Feature Id="MtApi5" Title="$(var.ProductName)" Level="1">
|
||||||
@@ -37,7 +39,7 @@
|
|||||||
|
|
||||||
<Property Id="WIXUI_INSTALLDIR">INSTALLFOLDER</Property>
|
<Property Id="WIXUI_INSTALLDIR">INSTALLFOLDER</Property>
|
||||||
<UIRef Id="WixUI_Mondo" />
|
<UIRef Id="WixUI_Mondo" />
|
||||||
</Product>
|
</Product>
|
||||||
|
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<Directory Id="TARGETDIR" Name="SourceDir">
|
<Directory Id="TARGETDIR" Name="SourceDir">
|
||||||
@@ -79,6 +81,11 @@
|
|||||||
|
|
||||||
</Component>
|
</Component>
|
||||||
|
|
||||||
|
<Component Id="NewtonsoftJsondll" Directory="INSTALLFOLDER">
|
||||||
|
<File Id="Newtonsoft.Json.dll" Name="Newtonsoft.Json.dll" KeyPath="yes"
|
||||||
|
src="$(var.ProductPath)Newtonsoft.Json.dll"/>
|
||||||
|
</Component>
|
||||||
|
|
||||||
<Component Id="MTApiServiceDll" Directory="INSTALLFOLDER">
|
<Component Id="MTApiServiceDll" Directory="INSTALLFOLDER">
|
||||||
<File Id="GAC_MTApiService.dll" Name="MTApiService.dll" KeyPath="yes"
|
<File Id="GAC_MTApiService.dll" Name="MTApiService.dll" KeyPath="yes"
|
||||||
src="$(var.ProductPath)MTApiService.dll"/>
|
src="$(var.ProductPath)MTApiService.dll"/>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user