Compare commits

..

28 Commits

Author SHA1 Message Date
DW 4a7bb6f2cb MtApi (MT5) ver. 1.0.11.1 HotFix 2016-11-29 10:20:55 +02:00
DW d63a53b8a9 MtApi (MT4) version 1.0.32.1 (HotFix) 2016-11-25 16:06:11 +02:00
DW 7e821fcade Issue #38: Removed MemoryAppender in LogConfigurator (MtApiService) 2016-11-25 15:50:56 +02:00
vdemydiuk 8e3f206c76 Issue #35: Implemented function TerminalInfoDouble in MtApi MT4 2016-11-15 11:06:43 +02:00
vdemydiuk 8e5dcbd2ee Issue #31: Implemented function TerminalInfoInteger in MtApi MT4 2016-11-15 10:02:30 +02:00
vdemydiuk 563a5a895b Issue #31: Implemented function SymbolInfoTick in MtApi MT4 2016-11-14 16:31:01 +02:00
vdemydiuk 32f6018858 Issue #31: Implemented function SymbolInfoDouble in MtApi MT4 2016-11-14 14:04:31 +02:00
vdemydiuk c64417474a Issue #33: Implemented function SeriesInfoInteger (MtApi MT4) 2016-11-13 23:24:38 +02:00
vdemydiuk 6d4b5f4c00 Issue #27: Created bootstrapper project for MtApi MT4 with vcredist package 2016-11-11 17:56:17 +02:00
vdemydiuk 601c95369e Recovered MtApi.ex4 2016-11-11 17:54:33 +02:00
vdemydiuk 0542dd3e71 Started MtApi (MT4) version 1.0.32 2016-11-11 17:53:43 +02:00
vdemydiuk 15068ca99c Issue #30: Added MtApi5 Bootstrapper project to merge installer and vcredist packages 2016-11-08 17:38:51 +02:00
vdemydiuk c3617549f8 Updated version of MtApiService to 1.0.23 2016-11-08 14:16:09 +02:00
vdemydiuk aa91196e31 Updated license text in MtApi5 installer 2016-11-07 13:45:18 +02:00
vdemydiuk ba7b50e241 Issue #29: Added process Id into name of log file 2016-11-07 13:05:36 +02:00
vdemydiuk ddcd6fa2d5 Issue #25: Implemented function CopyTicks. Used json request 2016-11-05 00:52:52 +02:00
vdemydiuk ad55740bc7 Started MtApi (MT5) version 1.0.11 2016-11-03 13:07:48 +02:00
vdemydiuk 26a3db9ae1 Small refactoring testing application (MT4) 2016-11-02 11:25:47 +02:00
DW 7d3af82e1f Updated testing application (MT4) to test functions: SymbolsTotal, SymbolName, SymbolSelect, SymbolInfoInteger 2016-11-01 18:43:49 +02:00
DW 09b72fc64d Added function SymbolInfoInteger into MtApi (MT4). Added function sendLongResponse into library MTConnector 2016-11-01 12:49:39 +02:00
DW 834b0af430 Started version 1.0.31 MtApi (MT4) 2016-11-01 10:32:29 +02:00
DW 5dd1e4831d Merge branch Add_sessions 2016-11-01 10:28:24 +02:00
DW 39f11bfc34 Merge branch Manage_symbols 2016-11-01 10:18:22 +02:00
vdemydiuk c6faaf0602 Issue #26: Use tick event function to perform MtApi commands in testing mode 2016-10-31 17:59:55 +02:00
Konstantin Ivanov 6b4adfaa97 Add method SymbolInfoSession() 2016-10-05 17:02:00 +03:00
Konstantin Ivanov db4bb44fb3 Add SymbolSelect() and use existing local variables 2016-09-29 17:13:41 +03:00
Konstantin Ivanov 68d5fa98af Add SymbolName() 2016-09-29 16:30:11 +03:00
Konstantin Ivanov dc28823ca9 add SymbolsTotal() 2016-09-29 16:14:53 +03:00
88 changed files with 4108 additions and 4044 deletions
Executable
BIN
View File
Binary file not shown.
+2 -5
View File
@@ -1,4 +1,5 @@
using System;
using System.Diagnostics;
using log4net;
using log4net.Appender;
using log4net.Core;
@@ -24,7 +25,7 @@ namespace MTApiService
};
patternLayout.ActivateOptions();
string filename = $"{DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss")}.{LogFileNameExtension}";
string filename = $"{DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss")}-{Process.GetCurrentProcess().Id}.{LogFileNameExtension}";
var roller = new RollingFileAppender
{
@@ -40,10 +41,6 @@ namespace MTApiService
roller.ActivateOptions();
hierarchy.Root.AddAppender(roller);
var memory = new MemoryAppender();
memory.ActivateOptions();
hierarchy.Root.AddAppender(memory);
#if (DEBUG)
hierarchy.Root.Level = Level.Debug;
#else
+2 -2
View File
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.22.0")]
[assembly: AssemblyFileVersion("1.0.22.0")]
[assembly: AssemblyVersion("1.0.24.0")]
[assembly: AssemblyFileVersion("1.0.24.0")]
+187 -158
View File
@@ -19,56 +19,56 @@ using namespace System::Diagnostics;
void convertSystemString(wchar_t* dest, String^ src)
{
pin_ptr<const wchar_t> wch = PtrToStringChars(src);
memcpy(dest, wch, wcslen(wch) * sizeof(wchar_t));
dest[wcslen(wch)] = '\0';
pin_ptr<const wchar_t> wch = PtrToStringChars(src);
memcpy(dest, wch, wcslen(wch) * sizeof(wchar_t));
dest[wcslen(wch)] = '\0';
}
int _stdcall initExpert(int expertHandle, int port, wchar_t* symbol, double bid, double ask, wchar_t* err)
{
try
{
MT4Handler^ mtHandler = gcnew MT4Handler();
try
{
MT4Handler^ mtHandler = gcnew MT4Handler();
MtServerInstance::GetInstance()->InitExpert(expertHandle, port, gcnew String(symbol), bid, ask, mtHandler);
}
catch (Exception^ e)
{
convertSystemString(err, e->Message);
Debug::WriteLine("[ERROR] MTConnector:initExpert(): " + e->Message);
return 0;
}
return 1;
MtServerInstance::GetInstance()->InitExpert(expertHandle, port, gcnew String(symbol), bid, ask, mtHandler);
}
catch (Exception^ e)
{
convertSystemString(err, e->Message);
Debug::WriteLine("[ERROR] MTConnector:initExpert(): " + e->Message);
return 0;
}
return 1;
}
int _stdcall deinitExpert(int expertHandle, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->DeinitExpert(expertHandle);
}
catch (Exception^ e)
{
convertSystemString(err, e->Message);
Debug::WriteLine("[ERROR] MTConnector:deinitExpert(): " + e->Message);
return 0;
}
return 1;
try
{
MtServerInstance::GetInstance()->DeinitExpert(expertHandle);
}
catch (Exception^ e)
{
convertSystemString(err, e->Message);
Debug::WriteLine("[ERROR] MTConnector:deinitExpert(): " + e->Message);
return 0;
}
return 1;
}
int _stdcall updateQuote(int expertHandle, wchar_t* symbol, double bid, double ask, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->SendQuote(expertHandle, gcnew String(symbol), bid, ask);
}
catch (Exception^ e)
{
convertSystemString(err, e->Message);
Debug::WriteLine("[ERROR] MTConnector:updateQuote(): " + e->Message);
return 0;
}
return 1;
try
{
MtServerInstance::GetInstance()->SendQuote(expertHandle, gcnew String(symbol), bid, ask);
}
catch (Exception^ e)
{
convertSystemString(err, e->Message);
Debug::WriteLine("[ERROR] MTConnector:updateQuote(): " + e->Message);
return 0;
}
return 1;
}
@@ -89,170 +89,199 @@ int _stdcall sendEvent(int expertHandle, int eventType, wchar_t* payload, wchar_
int _stdcall sendIntResponse(int expertHandle, int response)
{
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseInt(response));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendIntResponse(): " + e->Message);
return 0;
}
return 1;
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseInt(response));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendIntResponse(): " + e->Message);
return 0;
}
return 1;
}
int _stdcall sendBooleanResponse(int expertHandle, int response)
{
try
{
bool value = (response != 0) ? true : false;
try
{
bool value = (response != 0) ? true : false;
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseBool(value));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendBooleanResponse(): " + e->Message);
return 0;
}
return 1;
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseBool(value));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendBooleanResponse(): " + e->Message);
return 0;
}
return 1;
}
int _stdcall sendDoubleResponse(int expertHandle, double response)
{
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDouble(response));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendDoubleResponse(): " + e->Message);
return 0;
}
return 1;
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDouble(response));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendDoubleResponse(): " + e->Message);
return 0;
}
return 1;
}
int _stdcall sendStringResponse(int expertHandle, wchar_t* response)
{
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseString(gcnew String(response)));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendStringResponse(): " + e->Message);
return 0;
}
return 1;
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseString(gcnew String(response)));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendStringResponse(): " + e->Message);
return 0;
}
return 1;
}
int _stdcall sendVoidResponse(int expertHandle)
{
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, nullptr);
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendVoidResponse(): " + e->Message);
return 0;
}
return 1;
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, nullptr);
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendVoidResponse(): " + e->Message);
return 0;
}
return 1;
}
int _stdcall sendDoubleArrayResponse(int expertHandle, double* values, int size)
{
try
{
array<double>^ list = gcnew array<double>(size);
try
{
array<double>^ list = gcnew array<double>(size);
for(int i = 0; i < size; i++)
{
list[i] = values[i];
}
for(int i = 0; i < size; i++)
{
list[i] = values[i];
}
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDoubleArray(list));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendDoubleArrayResponse(): " + e->Message);
return 0;
}
return 1;
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDoubleArray(list));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendDoubleArrayResponse(): " + e->Message);
return 0;
}
return 1;
}
int _stdcall sendIntArrayResponse(int expertHandle, int* values, int size)
{
try
{
array<int>^ list = gcnew array<int>(size);
try
{
array<int>^ list = gcnew array<int>(size);
for(int i = 0; i < size; i++)
{
list[i] = values[i];
}
for(int i = 0; i < size; i++)
{
list[i] = values[i];
}
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseIntArray(list));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendIntArrayResponse(): " + e->Message);
return 0;
}
return 1;
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseIntArray(list));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendIntArrayResponse(): " + e->Message);
return 0;
}
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)
{
try
{
*res = MtServerInstance::GetInstance()->GetCommandType(expertHandle);
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:getCommandType(): " + e->Message);
return 0;
}
return 1;
try
{
*res = MtServerInstance::GetInstance()->GetCommandType(expertHandle);
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:getCommandType(): " + e->Message);
return 0;
}
return 1;
}
int _stdcall getIntValue(int expertHandle, int paramIndex, int* res)
{
try
{
*res = (int)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:getIntValue(): " + e->Message);
return 0;
}
return 1;
try
{
*res = (int)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:getIntValue(): " + e->Message);
return 0;
}
return 1;
}
int _stdcall getDoubleValue(int expertHandle, int paramIndex, double* res)
{
try
{
*res = (double)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:getDoubleValue(): " + e->Message);
return 0;
}
return 1;
try
{
*res = (double)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:getDoubleValue(): " + e->Message);
return 0;
}
return 1;
}
int _stdcall getStringValue(int expertHandle, int paramIndex, wchar_t* res)
{
try
{
convertSystemString(res, (String^)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:getStringValue(): " + e->Message);
return 0;
}
return 1;
try
{
convertSystemString(res, (String^)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:getStringValue(): " + e->Message);
return 0;
}
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
View File
@@ -3,15 +3,17 @@ LIBRARY MTConnector
EXPORTS initExpert
deinitExpert
updateQuote
sendEvent
sendIntResponse
sendBooleanResponse
sendDoubleResponse
sendStringResponse
sendVoidResponse
sendDoubleArrayResponse
sendIntArrayResponse
getCommandType
getIntValue
getDoubleValue
getStringValue
sendEvent
sendIntResponse
sendBooleanResponse
sendDoubleResponse
sendStringResponse
sendVoidResponse
sendDoubleArrayResponse
sendIntArrayResponse
sendLongResponse
getCommandType
getIntValue
getDoubleValue
getStringValue
getBooleanValue
+37 -1
View File
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25123.0
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestApiClientUI", "TestClients\TestApiClientUI\TestApiClientUI.csproj", "{663CC515-EAAE-47D4-8933-5008C2DA1160}"
EndProject
@@ -37,6 +37,16 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MtApiSetupActions", "MtApiS
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TestClients", "TestClients", "{B91FF338-E05D-4EF1-948B-A2376DB37ECA}"
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
GlobalSection(SolutionConfigurationPlatforms) = preSolution
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|x86.ActiveCfg = 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
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
+10
View File
@@ -0,0 +1,10 @@
namespace MtApi
{
public enum EnumSeriesInfoInteger
{
SERIES_BARS_COUNT = 0,
SERIES_FIRSTDATE = 1,
SERIES_LASTBAR_DATE = 5,
SERIES_SERVER_FIRSTDATE = 2
}
}
+46
View File
@@ -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
}
}
+31
View File
@@ -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
}
}
+8
View File
@@ -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
}
}
+27
View File
@@ -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 -6
View File
@@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MtApi
namespace MtApi
{
public enum MarketInfoModeType
{
+3 -8
View File
@@ -4,7 +4,7 @@ namespace MtApi.Monitors
public class TimeframeTradeMonitor : TradeMonitor
{
#region Fields
private volatile bool _isStarted = false;
private volatile bool _isStarted;
#endregion
#region ctor
@@ -23,13 +23,8 @@ namespace MtApi.Monitors
// Returns:
// true if PositionMonitor should check orders
// otherwise, false.
public override bool IsStarted
{
get
{
return _isStarted;
}
}
public override bool IsStarted => _isStarted;
#endregion
#region Protected Methods
+6 -15
View File
@@ -13,7 +13,7 @@ namespace MtApi.Monitors
#endregion
#region ctor
public TradeMonitor(MtApiClient apiClient)
protected TradeMonitor(MtApiClient apiClient)
{
if (apiClient == null)
throw new ArgumentNullException(nameof(apiClient));
@@ -73,13 +73,7 @@ namespace MtApi.Monitors
protected abstract void OnMtConnected();
protected abstract void OnMtDisconnected();
public bool IsMtConnected
{
get
{
return _apiClient.ConnectionState == MtConnectionState.Connected;
}
}
public bool IsMtConnected => _apiClient.ConnectionState == MtConnectionState.Connected;
protected void Check()
{
@@ -113,12 +107,12 @@ namespace MtApi.Monitors
prevOrders = _prevOrders;
}
if (_prevOrders != null) //skip checking on first load orders
if (prevOrders != null) //skip checking on first load orders
{
//check open orders
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);
}
@@ -126,7 +120,7 @@ namespace MtApi.Monitors
//check closed orders
var closeOrdersTemp = new List<MtOrder>();
foreach (var order in _prevOrders)
foreach (var order in prevOrders)
{
if (tradesOrders.Find(a => a.Ticket == order.Ticket) == null)
{
@@ -180,10 +174,7 @@ namespace MtApi.Monitors
_prevOrders = null;
}
Task.Factory.StartNew(() =>
{
Check();
});
Task.Factory.StartNew(Check);
}
#endregion
}
+1 -6
View File
@@ -5,12 +5,7 @@ namespace MtApi
public class MqlRates
{
public int MtTime { get; set; }
public DateTime Time
{
get { return MtApiTimeConverter.ConvertFromMtTime(MtTime); }
}
public DateTime Time => MtApiTimeConverter.ConvertFromMtTime(MtTime);
public double Open { get; set; }
public double High { get; set; }
public double Low { get; set; }
+14
View File
@@ -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; }
}
}
+15
View File
@@ -59,9 +59,15 @@
</ItemGroup>
<ItemGroup>
<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="Monitors\AvailabilityOrdersEventArgs.cs" />
<Compile Include="MqlRates.cs" />
<Compile Include="MqlTick.cs" />
<Compile Include="MtConnectionEventArgs.cs" />
<Compile Include="MtConnectionException.cs" />
<Compile Include="MtConnectionState.cs" />
@@ -72,6 +78,7 @@
<Compile Include="MtOrder.cs" />
<Compile Include="MtQuote.cs" />
<Compile Include="MtQuoteEventArgs.cs" />
<Compile Include="MtSession.cs" />
<Compile Include="MtTimeBar.cs" />
<Compile Include="MtTypes.cs" />
<Compile Include="Monitors\TradeMonitor.cs" />
@@ -90,14 +97,22 @@
<Compile Include="Requests\OrderDeleteRequest.cs" />
<Compile Include="Requests\OrderModifyRequest.cs" />
<Compile Include="Requests\OrderSendRequest.cs" />
<Compile Include="Requests\SeriesInfoIntegerRequest.cs" />
<Compile Include="Requests\SessionRequest.cs" />
<Compile Include="Requests\RequestBase.cs" />
<Compile Include="Requests\RequestType.cs" />
<Compile Include="Requests\SymbolInfoDoubleRequest.cs" />
<Compile Include="Requests\SymbolInfoTickRequest.cs" />
<Compile Include="Responses\CopyRatesResponse.cs" />
<Compile Include="Responses\GetOrderResponse.cs" />
<Compile Include="Responses\GetOrdersResponse.cs" />
<Compile Include="Responses\ICustomResponse.cs" />
<Compile Include="Responses\OrderSendResponse.cs" />
<Compile Include="Responses\SeriesInfoIntegerResponse.cs" />
<Compile Include="Responses\SessionResponse.cs" />
<Compile Include="Responses\ResponseBase.cs" />
<Compile Include="Responses\SymbolInfoDoubleResponse.cs" />
<Compile Include="Responses\SymbolInfoTickResponse.cs" />
<Compile Include="SeriesIdentifier.cs" />
<Compile Include="TimeBarArgs.cs" />
<Compile Include="Monitors\TimeframeTradeMonitor.cs" />
+313 -34
View File
@@ -498,83 +498,241 @@ namespace MtApi
}
#endregion
#region Check Status
#region Checkup
///<summary>
///Returns the contents of the system variable _LastError.
///After the function call, the contents of _LastError are reset.
///</summary>
///<returns>
///Returns the value of the last error that occurred during the execution of an mql4 program.
///</returns>
public int GetLastError()
{
return SendCommand<int>(MtCommandType.GetLastError, null);
}
///<summary>
///Checks connection between client terminal and server.
///</summary>
///<returns>
///It returns true if connection to the server was successfully established, otherwise, it returns false.
///</returns>
public bool IsConnected()
{
return SendCommand<bool>(MtCommandType.IsConnected, null);
}
///<summary>
///Checks if the Expert Advisor runs on a demo account.
///</summary>
///<returns>
///Returns true if the Expert Advisor runs on a demo account, otherwise returns false.
///</returns>
public bool IsDemo()
{
return SendCommand<bool>(MtCommandType.IsDemo, null);
}
///<summary>
///Checks if the DLL function call is allowed for the Expert Advisor.
///</summary>
///<returns>
///Returns true if the DLL function call is allowed for the Expert Advisor, otherwise returns false.
///</returns>
public bool IsDllsAllowed()
{
return SendCommand<bool>(MtCommandType.IsDllsAllowed, null);
}
///<summary>
///Checks if Expert Advisors are enabled for running.
///</summary>
///<returns>
///Returns true if Expert Advisors are enabled for running, otherwise returns false.
///</returns>
public bool IsExpertEnabled()
{
return SendCommand<bool>(MtCommandType.IsExpertEnabled, null);
}
///<summary>
///Checks if the Expert Advisor can call library function.
///</summary>
///<returns>
///Returns true if the Expert Advisor can call library function, otherwise returns false.
///</returns>
public bool IsLibrariesAllowed()
{
return SendCommand<bool>(MtCommandType.IsLibrariesAllowed, null);
}
///<summary>
///Checks if Expert Advisor runs in the Strategy Tester optimization mode.
///</summary>
///<returns>
///Returns true if Expert Advisor runs in the Strategy Tester optimization mode, otherwise returns false.
///</returns>
public bool IsOptimization()
{
return SendCommand<bool>(MtCommandType.IsOptimization, null);
}
///<summary>
///Checks the forced shutdown of an mql4 program.
///</summary>
///<returns>
///Returns true, if the _StopFlag system variable contains a value other than 0.
///A nonzero value is written into _StopFlag, if a mql4 program has been commanded to complete its operation.
///In this case, you must immediately terminate the program, otherwise the program will be completed
///forcibly from the outside after 3 seconds.
///</returns>
public bool IsStopped()
{
return SendCommand<bool>(MtCommandType.IsStopped, null);
}
///<summary>
///Checks if the Expert Advisor runs in the testing mode.
///</summary>
///<returns>
///Returns true if the Expert Advisor runs in the testing mode, otherwise returns false.
///</returns>
public bool IsTesting()
{
return SendCommand<bool>(MtCommandType.IsTesting, null);
}
///<summary>
///Checks if the Expert Advisor is allowed to trade and trading context is not busy.
///</summary>
///<returns>
///Returns true if the Expert Advisor is allowed to trade and trading context is not busy, otherwise returns false.
///</returns>
public bool IsTradeAllowed()
{
return SendCommand<bool>(MtCommandType.IsTradeAllowed, null);
}
///<summary>
///Returns the information about trade context.
///</summary>
///<returns>
///Returns true if a thread for trading is occupied by another Expert Advisor, otherwise returns false.
///</returns>
public bool IsTradeContextBusy()
{
return SendCommand<bool>(MtCommandType.IsTradeContextBusy, null);
}
///<summary>
///Checks if the Expert Advisor is tested in visual mode.
///</summary>
///<returns>
///Returns true if the Expert Advisor is tested with checked "Visual Mode" button, otherwise returns false.
///</returns>
public bool IsVisualMode()
{
return SendCommand<bool>(MtCommandType.IsVisualMode, null);
}
///<summary>
///Returns the code of a reason for deinitialization.
///</summary>
///<returns>
///Returns the value of _UninitReason which is formed before OnDeinit() is called.
///Value depends on the reasons that led to deinitialization.
///</returns>
public int UninitializeReason()
{
return SendCommand<int>(MtCommandType.UninitializeReason, null);
}
///<summary>
///Print the error description.
///</summary>
public string ErrorDescription(int errorCode)
{
var commandParameters = new ArrayList { errorCode };
return SendCommand<string>(MtCommandType.ErrorDescription, commandParameters);
}
///<summary>
///Returns the value of a corresponding property of the mql4 program environment.
///</summary>
///<param name="propertyId">Identifier of a property. Can be one of the values of the ENUM_TERMINAL_INFO_STRING enumeration.</param>
///<returns>
///Value of string type.
///</returns>
public string TerminalInfoString(ENUM_TERMINAL_INFO_STRING propertyId)
{
var commandParameters = new ArrayList { (int)propertyId };
return SendCommand<string>(MtCommandType.TerminalInfoString, commandParameters);
}
///<summary>
///Returns the value of a corresponding property of the mql4 program environment.
///</summary>
///<param name="propertyId">Identifier of a property. Can be one of the values of the ENUM_TERMINAL_INFO_INTEGER enumeration.</param>
///<returns>
///Value of int type.
///</returns>
public int TerminalInfoInteger(EnumTerminalInfoInteger propertyId)
{
var commandParameters = new ArrayList { (int)propertyId };
return SendCommand<int>(MtCommandType.TerminalInfoInteger, commandParameters);
}
///<summary>
///Returns the value of a corresponding property of the mql4 program environment.
///</summary>
///<param name="propertyId">Identifier of a property. Can be one of the values of the ENUM_TERMINAL_INFO_DOUBLE enumeration.</param>
///<returns>
///Value of double type.
///</returns>
public double TerminalInfoDouble(EnumTerminalInfoDouble propertyId)
{
var commandParameters = new ArrayList { (int)propertyId };
return SendCommand<double>(MtCommandType.TerminalInfoDouble, commandParameters);
}
///<summary>
///Returns the name of company owning the client terminal.
///</summary>
///<returns>
///The name of company owning the client terminal.
///</returns>
public string TerminalCompany()
{
return SendCommand<string>(MtCommandType.TerminalCompany, null);
}
///<summary>
///Returns client terminal name.
///</summary>
///<returns>
///Client terminal name.
///</returns>
public string TerminalName()
{
return SendCommand<string>(MtCommandType.TerminalName, null);
}
///<summary>
///Returns the directory, from which the client terminal was launched.
///</summary>
///<returns>
///The directory, from which the client terminal was launched.
///</returns>
public string TerminalPath()
{
return SendCommand<string>(MtCommandType.TerminalPath, null);
}
#endregion
#region Account Information
public double AccountBalance()
{
return SendCommand<double>(MtCommandType.AccountBalance, null);
@@ -677,12 +835,6 @@ namespace MtApi
return SendCommand<int>(MtCommandType.GetTickCount, null);
}
public double MarketInfo(string symbol, MarketInfoModeType type)
{
var commandParameters = new ArrayList { symbol, (int)type };
return SendCommand<double>(MtCommandType.MarketInfo, commandParameters);
}
public int MessageBox(string text, string caption, int flag)
{
var commandParameters = new ArrayList { text, caption, flag };
@@ -738,25 +890,6 @@ namespace MtApi
#endregion
#region Client Terminal Functions
public string TerminalCompany()
{
return SendCommand<string>(MtCommandType.TerminalCompany, null);
}
public string TerminalName()
{
return SendCommand<string>(MtCommandType.TerminalName, null);
}
public string TerminalPath()
{
return SendCommand<string>(MtCommandType.TerminalPath, null);
}
#endregion
#region Date and Time Functions
public int Day()
@@ -1409,19 +1542,165 @@ namespace MtApi
return response?.Rates;
}
#endregion
#region Checkup
public string TerminalInfoString(ENUM_TERMINAL_INFO_STRING propertyId)
///<summary>
///Returns information about the state of historical data.
///</summary>
///<param name="symbolName">Symbol name.</param>
///<param name="timeframe">Period.</param>
///<param name="propId">Identifier of the requested property, value of the ENUM_SERIES_INFO_INTEGER enumeration.</param>
///<returns>
///Returns value of the long type.
///</returns>
public long SeriesInfoInteger(string symbolName, ENUM_TIMEFRAMES timeframe, EnumSeriesInfoInteger propId)
{
var commandParameters = new ArrayList { (int)propertyId };
return SendCommand<string>(MtCommandType.TerminalInfoString, commandParameters);
var response = SendRequest<SeriesInfoIntegerResponse>(new SeriesInfoIntegerRequest
{
SymbolName = symbolName,
Timeframe = (int)timeframe,
PropId = (int)propId
});
return response?.Value ?? 0;
}
#endregion
#region Market Info
///<summary>
///Returns various data about securities listed in the "Market Watch" window.
///</summary>
///<param name="symbol">Symbol name.</param>
///<param name="type">Request identifier that defines the type of information to be returned. Can be any of values of request identifiers.</param>
///<returns>
///Returns various data about securities listed in the "Market Watch" window.
///</returns>
public double MarketInfo(string symbol, MarketInfoModeType type)
{
var commandParameters = new ArrayList { symbol, (int)type };
return SendCommand<double>(MtCommandType.MarketInfo, commandParameters);
}
///<summary>
///Returns the number of available (selected in Market Watch or all) symbols.
///</summary>
///<param name="selected">Request mode. Can be true or false.</param>
///<returns>
///If the 'selected' parameter is true, the function returns the number of symbols selected in MarketWatch. If the value is false, it returns the total number of all symbols.
///</returns>
public int SymbolsTotal(bool selected)
{
var commandParameters = new ArrayList { selected };
return SendCommand<int>(MtCommandType.SymbolsTotal, commandParameters);
}
///<summary>
///Returns the name of a symbol.
///</summary>
///<param name="pos">Order number of a symbol.</param>
///<param name="selected">Request mode. If the value is true, the symbol is taken from the list of symbols selected in MarketWatch. If the value is false, the symbol is taken from the general list.</param>
///<returns>
///Value of string type with the symbol name.
///</returns>
public string SymbolName(int pos, bool selected)
{
var commandParameters = new ArrayList { pos, selected };
return SendCommand<string>(MtCommandType.SymbolName, commandParameters);
}
///<summary>
///Selects a symbol in the Market Watch window or removes a symbol from the window.
///</summary>
///<param name="name">Symbol name</param>
///<param name="select">Switch. If the value is false, a symbol should be removed from MarketWatch, otherwise a symbol should be selected in this window. A symbol can't be removed if the symbol chart is open, or there are open orders for this symbol.</param>
///<returns>
///In case of failure returns false.
///</returns>
public bool SymbolSelect(string name, bool select)
{
var commandParameters = new ArrayList { name, select };
return SendCommand<bool>(MtCommandType.SymbolSelect, commandParameters);
}
///<summary>
///Returns the corresponding property of a specified symbol.
///</summary>
///<param name="name">Symbol name</param>
///<param name="propId">Identifier of a symbol property. The value can be one of the values of the EnumSymbolInfoInteger enumeration</param>
///<returns>
///The value of long type.
///</returns>
public long SymbolInfoInteger(string name, EnumSymbolInfoInteger propId)
{
var commandParameters = new ArrayList { name, (int)propId };
return SendCommand<long>(MtCommandType.SymbolInfoInteger, commandParameters);
}
///<summary>
///Returns the corresponding property of a specified symbol.
///</summary>
///<param name="name">Symbol name</param>
///<param name="propId">Identifier of a symbol property. The value can be one of the values of the ENUM_SYMBOL_INFO_STRING enumeration.</param>
///<returns>
///The value of string type.
///</returns>
public string SymbolInfoString(string name, ENUM_SYMBOL_INFO_STRING propId)
{
var commandParameters = new ArrayList { name, (int)propId };
return SendCommand<string>(MtCommandType.SymbolInfoString, commandParameters); ;
return SendCommand<string>(MtCommandType.SymbolInfoString, commandParameters);
}
///<summary>
///Allows receiving time of beginning and end of the specified quoting/trading sessions for a specified symbol and day of week.
///
///</summary>
///<param name="symbol">Symbol name.</param>
///<param name="dayOfWeek">Day of the week.</param>
///<param name="index">Ordinal number of a session, whose beginning and end time we want to receive. Indexing of sessions starts with 0.</param>
///<param name="type">Session type: Quote, Trade</param>
///<returns>
///The value session.
///</returns>
public MtSession SymbolInfoSession(string symbol, DayOfWeek dayOfWeek, uint index, SessionType type)
{
var responce = SendRequest<SessionResponse>(new SessionRequest { Symbol = symbol, DayOfWeek = dayOfWeek, SessionIndex = (int)index, SessionType = type });
return responce?.Session;
}
///<summary>
///Returns the corresponding property of a specified symbol.
///</summary>
///<param name="symbolName">Symbol name.</param>
///<param name="propId">Identifier of a symbol property. The value can be one of the values of the ENUM_SYMBOL_INFO_DOUBLE enumeration.</param>
/// <returns>
/// The value of double type.
/// </returns>
public double SymbolInfoDouble(string symbolName, EnumSymbolInfoDouble propId)
{
var response = SendRequest<SymbolInfoDoubleResponse>(new SymbolInfoDoubleRequest
{
SymbolName = symbolName,
PropId = (int)propId
});
return response?.Value ?? 0;
}
///<summary>
///Returns the corresponding property of a specified symbol.
///</summary>
///<param name="symbol">Symbol name.</param>
/// <returns>
/// MqlTick object, to which the current prices and time of the last price update will be placed.
/// </returns>
public MqlTick SymbolInfoTick(string symbol)
{
var response = SendRequest<SymbolInfoTickResponse>(new SymbolInfoTickRequest
{
Symbol = symbol
});
return response?.Tick;
}
#endregion
+15 -9
View File
@@ -58,9 +58,15 @@ namespace MtApi
IsVisualMode = 37,
UninitializeReason = 38,
ErrorDescription = 39,
TerminalCompany = 68,
TerminalName = 69,
TerminalPath = 70,
TerminalInfoString = 153,
TerminalInfoInteger = 204,
TerminalInfoDouble = 205,
//Account Information
AccountBalance = 40,
AccountBalance = 40,
AccountCredit = 41,
AccountCompany = 42,
AccountCurrency = 43,
@@ -91,11 +97,6 @@ namespace MtApi
SendMail = 66,
Sleep = 67,
//Client Terminal
TerminalCompany = 68,
TerminalName = 69,
TerminalPath = 70,
//Date and Time
Day = 71,
DayOfWeek = 72,
@@ -188,13 +189,18 @@ namespace MtApi
//
RefreshRates = 150,
//
TerminalInfoString = 153,
SymbolInfoString = 154,
//Requests
MtRequest = 155,
//Backtesting
BacktestingReady = 156
BacktestingReady = 156,
//Market Info
SymbolInfoString = 154,
SymbolsTotal = 200,
SymbolName = 201,
SymbolSelect = 202,
SymbolInfoInteger = 203
}
}
Regular → Executable
+85 -84
View File
@@ -1,5 +1,6 @@
namespace MtApi
{
// https://docs.mql4.com/constants/errorswarnings/errorcodes
public enum MtErrorCode
{
MtApiCustomError = -1, // Error occurred in MtApi.
@@ -10,91 +11,91 @@
ServerBusy = 4, // Trade server is busy.
OldVersion = 5, // Old version of the client terminal.
NoConnection = 6, // No connection with trade server.
NotEnoughRights = 7, // Not enough rights.
TooFrequentRequests = 8, // Too frequent requests.
MalfunctionalTrade = 9, // Malfunctional trade operation.
NotEnoughRights = 7, // Not enough rights.
TooFrequentRequests = 8, // Too frequent requests.
MalfunctionalTrade = 9, // Malfunctional trade operation.
AccountDisabled = 64, // Account disabled.
InvalidAccount = 65, // Invalid account.
TradeTimeout = 128, // Trade timeout.
InvalidPrice = 129, // Invalid price.
InvalidStops = 130, // Invalid stops.
InvalidTradeVolume = 131, // Invalid trade volume.
MarketClosed = 132, // Market is closed.
TradeDisabled = 133, // Trade is disabled.
NotEnoughMoney = 134, // Not enough money.
PriceChanged = 135, // Price changed.
OffQuotes = 136, // Off quotes.
BrokerBusy = 137, // Broker is busy.
Requote = 138, // Requote.
OrderLocked = 139, // Order is locked.
LongPositionsOnlyAllowed = 140, // Long positions only allowed.
TooManyRequests = 141, // Too many requests.
TradeModifyDenied = 145, // Modification denied because an order is too close to market.
TradeContextBusy = 146, // Trade context is busy.
TradeExpirationDenied = 147, // Expirations are denied by broker.
TradeTooManyOrders = 148, // The amount of opened and pending orders has reached the limit set by a broker.
InvalidAccount = 65, // Invalid account.
TradeTimeout = 128, // Trade timeout.
InvalidPrice = 129, // Invalid price.
InvalidStops = 130, // Invalid stops.
InvalidTradeVolume = 131, // Invalid trade volume.
MarketClosed = 132, // Market is closed.
TradeDisabled = 133, // Trade is disabled.
NotEnoughMoney = 134, // Not enough money.
PriceChanged = 135, // Price changed.
OffQuotes = 136, // Off quotes.
BrokerBusy = 137, // Broker is busy.
Requote = 138, // Requote.
OrderLocked = 139, // Order is locked.
LongPositionsOnlyAllowed = 140, // Long positions only allowed.
TooManyRequests = 141, // Too many requests.
TradeModifyDenied = 145, // Modification denied because an order is too close to market.
TradeContextBusy = 146, // Trade context is busy.
TradeExpirationDenied = 147, // Expirations are denied by broker.
TradeTooManyOrders = 148, // The amount of opened and pending orders has reached the limit set by a broker.
NoMqlerror = 4000, // No error.
WrongFunctionPointer = 4001, // Wrong function pointer.
ArrayIndexOutOfRange = 4002, // Array index is out of range.
NoMemoryForFunctionCallStack = 4003, // No memory for function call stack.
RecursiveStackOverflow = 4004, // Recursive stack overflow.
NotEnoughStackForParameter = 4005, // Not enough stack for parameter.
NoMemoryForParameterString = 4006, // No memory for parameter string.
NoMemoryForTempString = 4007, // No memory for temp string.
NotInitializedString = 4008, // Not initialized string.
NotInitializedArraystring = 4009, // Not initialized string in an array.
NoMemoryForArraystring = 4010, // No memory for an array string.
TooLongString = 4011, // Too long string.
RemainderFromZeroDivide = 4012, // Remainder from zero divide.
ZeroDivide = 4013, // Zero divide.
UnknownCommand = 4014, // Unknown command.
WrongJump = 4015, // Wrong jump.
NotInitializedArray = 4016, // Not initialized array.
DllCallsNotAllowed = 4017, // DLL calls are not allowed.
CannotLoadLibrary = 4018, // Cannot load library.
CannotCallFunction = 4019, // Cannot call function.
ExternalExpertCallsNotAllowed = 4020, // EA function calls are not allowed.
NotEnoughMemoryForReturnedString = 4021, // Not enough memory for a string returned from a function.
SystemBusy = 4022, // System is busy.
InvalidFunctionParametersCount = 4050, // Invalid function parameters count.
InvalidFunctionParameterValue = 4051, // Invalid function parameter value.
StringFunctionInternalError = 4052, // String function internal error.
SomeArrayError = 4053, // Some array error.
IncorrectSeriesArrayUsing = 4054, // Incorrect series array using.
CustomIndicatorError = 4055, // Custom indicator error.
IncompatibleArrays = 4056, // Arrays are incompatible.
GlobalVariablesProcessingError = 4057, // Global variables processing error.
GlobalVariableNotFound = 4058, // Global variable not found.
FunctionNotAllowedInTestingMode = 4059, // Function is not allowed in testing mode.
FunctionNotConfirmed = 4060, // Function is not confirmed.
SendMailError = 4061, // Mail sending error.
StringParameterExpected = 4062, // String parameter expected.
IntegerParameterExpected = 4063, // Integer parameter expected.
DoubleParameterExpected = 4064, // Double parameter expected.
ArrayAsParameterExpected = 4065, // Array as parameter expected.
HistoryWillUpdated = 4066, // Requested history data in updating state.
TradeError = 4067, // Some error in trade operation execution.
EndOfFile = 4099, // End of a file.
SomeFileError = 4100, // Some file error.
WrongFileName = 4101, // Wrong file name.
TooManyOpenedFiles = 4102, // Too many opened files.
CannotOpenFile = 4103, // Cannot open file.
IncompatibleAccessToFile = 4104, // Incompatible access to a file.
NoOrderSelected = 4105, // No order selected.
UnknownSymbol = 4106, // Unknown symbol.
InvalidPriceParam = 4107, // Invalid price.
InvalidTicket = 4108, // Invalid ticket.
TradeNotAllowed = 4109, // Trade is not allowed.
LongsNotAllowed = 4110, // Longs are not allowed.
ShortsNotAllowed = 4111, // Shorts are not allowed.
ObjectAlreadyExists = 4200, // Object already exists.
UnknownObjectProperty = 4201, // Unknown object property.
ObjectDoesNotExist = 4202, // Object does not exist.
UnknownObjectType = 4203, // Unknown object type.
NoObjectName = 4204, // No object name.
ObjectCoordinatesError = 4205, // Object coordinates error.
NoSpecifiedSubwindow = 4206, // No specified subwindow.
SomeObjectError = 4207 // Some error in object operation.
NoMqlerror = 4000, // No error.
WrongFunctionPointer = 4001, // Wrong function pointer.
ArrayIndexOutOfRange = 4002, // Array index is out of range.
NoMemoryForFunctionCallStack = 4003, // No memory for function call stack.
RecursiveStackOverflow = 4004, // Recursive stack overflow.
NotEnoughStackForParameter = 4005, // Not enough stack for parameter.
NoMemoryForParameterString = 4006, // No memory for parameter string.
NoMemoryForTempString = 4007, // No memory for temp string.
NotInitializedString = 4008, // Not initialized string.
NotInitializedArraystring = 4009, // Not initialized string in an array.
NoMemoryForArraystring = 4010, // No memory for an array string.
TooLongString = 4011, // Too long string.
RemainderFromZeroDivide = 4012, // Remainder from zero divide.
ZeroDivide = 4013, // Zero divide.
UnknownCommand = 4014, // Unknown command.
WrongJump = 4015, // Wrong jump.
NotInitializedArray = 4016, // Not initialized array.
DllCallsNotAllowed = 4017, // DLL calls are not allowed.
CannotLoadLibrary = 4018, // Cannot load library.
CannotCallFunction = 4019, // Cannot call function.
ExternalExpertCallsNotAllowed = 4020, // EA function calls are not allowed.
NotEnoughMemoryForReturnedString = 4021, // Not enough memory for a string returned from a function.
SystemBusy = 4022, // System is busy.
InvalidFunctionParametersCount = 4050, // Invalid function parameters count.
InvalidFunctionParameterValue = 4051, // Invalid function parameter value.
StringFunctionInternalError = 4052, // String function internal error.
SomeArrayError = 4053, // Some array error.
IncorrectSeriesArrayUsing = 4054, // Incorrect series array using.
CustomIndicatorError = 4055, // Custom indicator error.
IncompatibleArrays = 4056, // Arrays are incompatible.
GlobalVariablesProcessingError = 4057, // Global variables processing error.
GlobalVariableNotFound = 4058, // Global variable not found.
FunctionNotAllowedInTestingMode = 4059, // Function is not allowed in testing mode.
FunctionNotConfirmed = 4060, // Function is not confirmed.
SendMailError = 4061, // Mail sending error.
StringParameterExpected = 4062, // String parameter expected.
IntegerParameterExpected = 4063, // Integer parameter expected.
DoubleParameterExpected = 4064, // Double parameter expected.
ArrayAsParameterExpected = 4065, // Array as parameter expected.
HistoryWillUpdated = 4066, // Requested history data in updating state.
TradeError = 4067, // Some error in trade operation execution.
EndOfFile = 4099, // End of a file.
SomeFileError = 4100, // Some file error.
WrongFileName = 4101, // Wrong file name.
TooManyOpenedFiles = 4102, // Too many opened files.
CannotOpenFile = 4103, // Cannot open file.
IncompatibleAccessToFile = 4104, // Incompatible access to a file.
NoOrderSelected = 4105, // No order selected.
UnknownSymbol = 4106, // Unknown symbol.
InvalidPriceParam = 4107, // Invalid price.
InvalidTicket = 4108, // Invalid ticket.
TradeNotAllowed = 4109, // Trade is not allowed.
LongsNotAllowed = 4110, // Longs are not allowed.
ShortsNotAllowed = 4111, // Shorts are not allowed.
ObjectAlreadyExists = 4200, // Object already exists.
UnknownObjectProperty = 4201, // Unknown object property.
ObjectDoesNotExist = 4202, // Object does not exist.
UnknownObjectType = 4203, // Unknown object type.
NoObjectName = 4204, // No object name.
ObjectCoordinatesError = 4205, // Object coordinates error.
NoSpecifiedSubwindow = 4206, // No specified subwindow.
SomeObjectError = 4207 // Some error in object operation.
}
}
+1 -6
View File
@@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MtApi
namespace MtApi
{
public class MtQuote
{
+23
View File
@@ -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
}
}
+2 -2
View File
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.30.0")]
[assembly: AssemblyFileVersion("1.0.30.0")]
[assembly: AssemblyVersion("1.0.32.1")]
[assembly: AssemblyFileVersion("1.0.32.1")]
+9 -27
View File
@@ -1,12 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MtApi.Requests
namespace MtApi.Requests
{
public abstract class CopyRatesRequestBase : RequestBase
internal abstract class CopyRatesRequestBase : RequestBase
{
public enum CopyRatesTypeEnum
{
@@ -15,10 +9,7 @@ namespace MtApi.Requests
CopyRates_3 = 3,
}
public override RequestType RequestType
{
get { return RequestType.CopyRates; }
}
public override RequestType RequestType => RequestType.CopyRates;
public abstract CopyRatesTypeEnum CopyRatesType { get; }
@@ -26,34 +17,25 @@ namespace MtApi.Requests
public ENUM_TIMEFRAMES Timeframe { get; set; }
}
public class CopyRates1Request : CopyRatesRequestBase
internal class CopyRates1Request : CopyRatesRequestBase
{
public override CopyRatesTypeEnum CopyRatesType
{
get { return CopyRatesTypeEnum.CopyRates_1; }
}
public override CopyRatesTypeEnum CopyRatesType => CopyRatesTypeEnum.CopyRates_1;
public int StartPos { get; set; }
public int Count { get; set; }
}
public class CopyRates2Request : CopyRatesRequestBase
internal class CopyRates2Request : CopyRatesRequestBase
{
public override CopyRatesTypeEnum CopyRatesType
{
get { return CopyRatesTypeEnum.CopyRates_2; }
}
public override CopyRatesTypeEnum CopyRatesType => CopyRatesTypeEnum.CopyRates_2;
public int StartTime { get; set; }
public int Count { get; set; }
}
public class CopyRates3Request : CopyRatesRequestBase
internal class CopyRates3Request : CopyRatesRequestBase
{
public override CopyRatesTypeEnum CopyRatesType
{
get { return CopyRatesTypeEnum.CopyRates_3; }
}
public override CopyRatesTypeEnum CopyRatesType => CopyRatesTypeEnum.CopyRates_3;
public int StartTime { get; set; }
public int StopTime { get; set; }
+2 -5
View File
@@ -1,14 +1,11 @@
namespace MtApi.Requests
{
public class GetOrderRequest: RequestBase
internal class GetOrderRequest: RequestBase
{
public int Index { get; set; }
public int Select { get; set; }
public int Pool { get; set; }
public override RequestType RequestType
{
get { return RequestType.GetOrder; }
}
public override RequestType RequestType => RequestType.GetOrder;
}
}
+2 -5
View File
@@ -1,12 +1,9 @@
namespace MtApi.Requests
{
public class GetOrdersRequest: RequestBase
internal class GetOrdersRequest: RequestBase
{
public int Pool { get; set; }
public override RequestType RequestType
{
get { return RequestType.GetOrders; }
}
public override RequestType RequestType => RequestType.GetOrders;
}
}
Regular → Executable
+3 -8
View File
@@ -1,10 +1,8 @@
using System;
using System.Collections;
using System.Collections;
namespace MtApi.Requests
{
public class ICustomRequest : RequestBase
internal class ICustomRequest : RequestBase
{
public enum ParametersType
{
@@ -22,9 +20,6 @@ namespace MtApi.Requests
public ArrayList Params { get; set; }
public ParametersType ParamsType { get; set; }
public override RequestType RequestType
{
get { return RequestType.iCustom; }
}
public override RequestType RequestType => RequestType.iCustom;
}
}
+2 -5
View File
@@ -1,15 +1,12 @@
namespace MtApi.Requests
{
public class OrderCloseByRequest: RequestBase
internal class OrderCloseByRequest: RequestBase
{
public int Ticket { get; set; }
public int Opposite { get; set; }
public int? ArrowColor { get; set; }
public override RequestType RequestType
{
get { return RequestType.OrderCloseBy; }
}
public override RequestType RequestType => RequestType.OrderCloseBy;
}
}
+2 -5
View File
@@ -1,6 +1,6 @@
namespace MtApi.Requests
{
public class OrderCloseRequest: RequestBase
internal class OrderCloseRequest: RequestBase
{
public int Ticket { get; set; }
@@ -9,9 +9,6 @@
public int? Slippage { get; set; }
public int? ArrowColor { get; set; }
public override RequestType RequestType
{
get { return RequestType.OrderClose; }
}
public override RequestType RequestType => RequestType.OrderClose;
}
}
+2 -5
View File
@@ -1,14 +1,11 @@
namespace MtApi.Requests
{
public class OrderDeleteRequest: RequestBase
internal class OrderDeleteRequest: RequestBase
{
public int Ticket { get; set; }
public int? ArrowColor { get; set; }
public override RequestType RequestType
{
get { return RequestType.OrderDelete; }
}
public override RequestType RequestType => RequestType.OrderDelete;
}
}
+2 -5
View File
@@ -1,6 +1,6 @@
namespace MtApi.Requests
{
public class OrderModifyRequest: RequestBase
internal class OrderModifyRequest: RequestBase
{
public int Ticket { get; set; }
public double Price { get; set; }
@@ -10,9 +10,6 @@
public int? ArrowColor { get; set; }
public override RequestType RequestType
{
get { return RequestType.OrderModify; }
}
public override RequestType RequestType => RequestType.OrderModify;
}
}
+2 -5
View File
@@ -1,6 +1,6 @@
namespace MtApi.Requests
{
public class OrderSendRequest: RequestBase
internal class OrderSendRequest: RequestBase
{
public string Symbol { get; set; }
public int Cmd { get; set; }
@@ -15,9 +15,6 @@
public int? Expiration { get; set; }
public int? ArrowColor { get; set; }
public override RequestType RequestType
{
get { return RequestType.OrderSend; }
}
public override RequestType RequestType => RequestType.OrderSend;
}
}
+6 -8
View File
@@ -1,9 +1,7 @@
using Newtonsoft.Json;
namespace MtApi.Requests
{
public abstract class RequestBase
namespace MtApi.Requests
{
internal abstract class RequestBase
{
public abstract RequestType RequestType { get; }
}
}
public abstract RequestType RequestType { get; }
}
}
+15 -11
View File
@@ -1,16 +1,20 @@
namespace MtApi.Requests
{
public enum RequestType
internal enum RequestType
{
Unknown = 0,
GetOrder = 1,
GetOrders = 2,
OrderSend = 3,
OrderClose = 4,
OrderCloseBy = 5,
OrderDelete = 6,
OrderModify = 7,
iCustom = 8,
CopyRates = 9
Unknown = 0,
GetOrder = 1,
GetOrders = 2,
OrderSend = 3,
OrderClose = 4,
OrderCloseBy = 5,
OrderDelete = 6,
OrderModify = 7,
iCustom = 8,
CopyRates = 9,
Session = 10,
SeriesInfoInteger = 11,
SymbolInfoDouble = 12,
SymbolInfoTick = 13
}
}
+11
View File
@@ -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; }
}
}
+14
View File
@@ -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;
}
}
+12
View File
@@ -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; }
}
}
+9
View File
@@ -0,0 +1,9 @@
namespace MtApi.Requests
{
internal class SymbolInfoTickRequest: RequestBase
{
public override RequestType RequestType => RequestType.SymbolInfoTick;
public string Symbol { get; set; }
}
}
+1 -1
View File
@@ -2,7 +2,7 @@
namespace MtApi.Responses
{
public class CopyRatesResponse: ResponseBase
internal class CopyRatesResponse: ResponseBase
{
public List<MqlRates> Rates { get; set; }
}
+1 -1
View File
@@ -1,6 +1,6 @@
namespace MtApi.Responses
{
public class GetOrderResponse: ResponseBase
internal class GetOrderResponse: ResponseBase
{
public MtOrder Order { get; set; }
}
+1 -1
View File
@@ -2,7 +2,7 @@
namespace MtApi.Responses
{
public class GetOrdersResponse: ResponseBase
internal class GetOrdersResponse: ResponseBase
{
public List<MtOrder> Orders { get; set; }
}
+2 -8
View File
@@ -1,12 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MtApi.Responses
namespace MtApi.Responses
{
public class ICustomResponse: ResponseBase
internal class ICustomResponse: ResponseBase
{
public double Value { get; set; }
}
+1 -1
View File
@@ -1,6 +1,6 @@
namespace MtApi.Responses
{
public class OrderSendResponse: ResponseBase
internal class OrderSendResponse: ResponseBase
{
public int Ticket { get; set; }
}
Regular → Executable
+1 -1
View File
@@ -1,6 +1,6 @@
namespace MtApi.Responses
{
public class ResponseBase
internal class ResponseBase
{
public int ErrorCode { get; set; }
public string ErrorMessage { get; set; }
+7
View File
@@ -0,0 +1,7 @@
namespace MtApi.Responses
{
internal class SeriesInfoIntegerResponse: ResponseBase
{
public long Value { get; set; }
}
}
+7
View File
@@ -0,0 +1,7 @@
namespace MtApi.Responses
{
internal class SessionResponse : ResponseBase
{
public MtSession Session { get; set; }
}
}
+7
View File
@@ -0,0 +1,7 @@
namespace MtApi.Responses
{
internal class SymbolInfoDoubleResponse: ResponseBase
{
public double Value { get; set; }
}
}
+7
View File
@@ -0,0 +1,7 @@
namespace MtApi.Responses
{
internal class SymbolInfoTickResponse: ResponseBase
{
public MqlTick Tick { get; set; }
}
}
+1 -6
View File
@@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MtApi
namespace MtApi
{
public enum TradeOperation
{
+9
View File
@@ -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
}
}
+188
View File
@@ -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
}
}
+15
View File
@@ -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; }
}
}
+13 -9
View File
@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MtApi5
{
@@ -9,17 +6,24 @@ namespace MtApi5
{
public MqlTick(DateTime time, double bid, double ask, double last, ulong volume)
{
this.time = time;
MtTime = Mt5TimeConverter.ConvertToMtTime(time);
this.bid = bid;
this.ask = ask;
this.last = last;
this.volume = volume;
}
public DateTime time { get; private set; } // Time of the last prices update
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 MqlTick()
{
}
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);
}
}
+4 -1
View File
@@ -110,6 +110,9 @@ namespace MtApi5
BacktestingReady = 66,
IsTesting = 67,
Print = 68
Print = 68,
//Requests
MtRequest = 155,
}
}
+15
View File
@@ -32,6 +32,10 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<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.Configuration.Install" />
<Reference Include="System.Core" />
@@ -43,6 +47,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CopyTicksFlag.cs" />
<Compile Include="MqlBookInfo.cs" />
<Compile Include="MqlRates.cs" />
<Compile Include="MqlTick.cs" />
@@ -58,8 +63,15 @@
<Compile Include="MtApi5Client.cs" />
<Compile Include="Mt5CommandType.cs" />
<Compile Include="MtConverters.cs" />
<Compile Include="ErrorCode.cs" />
<Compile Include="ExecutionException.cs" />
<Compile Include="Properties\AssemblyInfo.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>
<ProjectReference Include="..\MTApiService\MTApiService.csproj">
@@ -67,6 +79,9 @@
<Name>MTApiService</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
+62 -1
View File
@@ -4,6 +4,9 @@ using System.Linq;
using MTApiService;
using System.Collections;
using System.ServiceModel;
using MtApi5.Requests;
using MtApi5.Responses;
using Newtonsoft.Json;
namespace MtApi5
{
@@ -1200,6 +1203,24 @@ namespace MtApi5
return spreadArray?.Length ?? 0;
}
///<summary>
///The function receives ticks in the MqlTick format into ticks_array. In this case, ticks are indexed from the past to the present, i.e. the 0 indexed tick is the oldest one in the array. For tick analysis, check the flags field, which shows what exactly has changed in the tick.
///</summary>
///<param name="symbolName">Symbol name.</param>
///<param name="flags">The flag that determines the type of received ticks.</param>
///<param name="from">The date from which you want to request ticks. In milliseconds since 1970.01.01. If from=0, the last count ticks will be returned.</param>
///<param name="count">The number of ticks that you want to receive. If the 'from' and 'count' parameters are not specified, all available recent ticks (but not more than 2000) will be written to result.</param>
///<see href="https://www.mql5.com/en/docs/series/copyticks"/>
public List<MqlTick> CopyTicks(string symbolName, CopyTicksFlag flags = CopyTicksFlag.All, ulong from = 0, uint count = 0)
{
var response = SendRequest<CopyTicksResponse>(new CopyTicksRequest
{
SymbolName = symbolName, Flags = (int)flags, From = from, Count = count
});
return response.Ticks;
}
#endregion
#region Market Info
@@ -1302,7 +1323,7 @@ namespace MtApi5
tick = null;
if (retVal != null)
{
tick = new MqlTick(Mt5TimeConverter.ConvertFromMtTime(retVal.time), retVal.bid, retVal.ask, retVal.last, retVal.volume);
tick = new MqlTick { MtTime = retVal.time, ask = retVal.ask, bid = retVal.bid, last = retVal.last, volume = retVal.volume };
}
return tick != null;
@@ -1512,6 +1533,46 @@ namespace MtApi5
return responseValue != null ? (T) responseValue : default(T);
}
private T SendRequest<T>(RequestBase request) where T : ResponseBase, new()
{
if (request == null)
return default(T);
var serializer = JsonConvert.SerializeObject(request, Formatting.None,
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
});
var commandParameters = new ArrayList { serializer };
MtResponseString res;
try
{
lock (_client)
{
res = (MtResponseString)_client.SendCommand((int)Mt5CommandType.MtRequest, commandParameters);
}
}
catch (CommunicationException ex)
{
throw new Exception(ex.Message, ex);
}
if (res == null)
{
throw new ExecutionException(ErrorCode.ErrCustom, "Response from MetaTrader is null");
}
var response = JsonConvert.DeserializeObject<T>(res.Value);
if (response.ErrorCode != 0)
{
throw new ExecutionException((ErrorCode)response.ErrorCode, response.ErrorMessage);
}
return response;
}
private void mClient_QuoteUpdated(MtQuote quote)
{
if (quote != null)
+2 -2
View File
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.10.0")]
[assembly: AssemblyFileVersion("1.0.10.0")]
[assembly: AssemblyVersion("1.0.11.1")]
[assembly: AssemblyFileVersion("1.0.11.1")]
+12
View File
@@ -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; }
}
}
+7
View File
@@ -0,0 +1,7 @@
namespace MtApi5.Requests
{
internal abstract class RequestBase
{
public abstract RequestType RequestType { get; }
}
}
+8
View File
@@ -0,0 +1,8 @@
namespace MtApi5.Requests
{
internal enum RequestType
{
Unknown = 0,
CopyTicks = 1
}
}
+9
View File
@@ -0,0 +1,9 @@
using System.Collections.Generic;
namespace MtApi5.Responses
{
internal class CopyTicksResponse: ResponseBase
{
public List<MqlTick> Ticks { get; set; }
}
}
+8
View File
@@ -0,0 +1,8 @@
namespace MtApi5.Responses
{
internal class ResponseBase
{
public int ErrorCode { get; set; }
public string ErrorMessage { get; set; }
}
}
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="8.0.3" targetFramework="net40" />
</packages>
+42
View File
@@ -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
View File
@@ -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>
+3 -3
View File
@@ -6,7 +6,7 @@
<ProductVersion>3.6</ProductVersion>
<ProjectGuid>{a9ed070f-ab4d-4380-9dde-5d931ac71333}</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion>
<OutputName>MtApi5Installer</OutputName>
<OutputName>MtApi5Installer_$(Platform)</OutputName>
<OutputType>Package</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>
@@ -22,11 +22,11 @@
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
<DefineConstants>Debug</DefineConstants>
<OutputPath>..\build\installers\$(Configuration)\x64\</OutputPath>
<OutputPath>..\build\installers\$(Configuration)</OutputPath>
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)\</IntermediateOutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
<OutputPath>..\build\installers\$(Configuration)\x64\</OutputPath>
<OutputPath>..\build\installers\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)\</IntermediateOutputPath>
</PropertyGroup>
<ItemGroup>
+14 -7
View File
@@ -1,30 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?define ProductName="MtApi5" ?>
<?if $(var.Platform) = x64 ?>
<?define ProductName="MtApi5_x64" ?>
<?define ProductPathNative="..\build\products\$(var.Configuration)\x64\"?>
<?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
<?define PlatformSystemFolder = "System64Folder" ?>
<?else ?>
<?define ProductName="MtApi5" ?>
<?define ProductPathNative="..\build\products\$(var.Configuration)\"?>
<?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
<?define PlatformSystemFolder = "SystemFolder" ?>
<?endif ?>
<?define ProductVersion="1.0.10" ?>
<?define ProductVersion=!(bind.FileVersion.MtApi5.dll) ?>
<?define Manufacturer="DW"?>
<?define ProductPath="..\build\products\$(var.Configuration)\"?>
<Product Id="*"
<Product Id="*"
Name="$(var.ProductName) $(var.ProductVersion)"
Language="1033"
Version="$(var.ProductVersion)"
Manufacturer="$(var.Manufacturer)"
UpgradeCode="d72d346e-e6f7-4c23-85c6-1c42b3175599">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<WixVariable Id="WixUILicenseRtf" Value="..\LICENSE.rtf" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes" />
<Feature Id="MtApi5" Title="$(var.ProductName)" Level="1">
@@ -37,7 +39,7 @@
<Property Id="WIXUI_INSTALLDIR">INSTALLFOLDER</Property>
<UIRef Id="WixUI_Mondo" />
</Product>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
@@ -78,6 +80,11 @@
</RegistryKey>
</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">
<File Id="GAC_MTApiService.dll" Name="MTApiService.dll" KeyPath="yes"
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+41
View File
@@ -0,0 +1,41 @@
<?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 VcRedistFileName="vc_redist.x64.exe"?>
<?else ?>
<?define VcRedistFileName="vc_redist.x86.exe"?>
<?endif ?>
<?define MsiSourceFileName="MtApiInstaller.msi"?>
<?define ProductName="!(bind.packageName.MtApiMsi)" ?>
<?define ProductVersion="!(bind.packageVersion.MtApiMsi)" ?>
<?define Manufacturer="!(bind.packageManufacturer.MtApiMsi)" ?>
<Bundle Name="$(var.ProductName) Bootstrapper"
Version="$(var.ProductVersion)"
Manufacturer="$(var.Manufacturer)"
UpgradeCode="8e63046b-56e5-4623-8808-558ad72a8f2b">
<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="MtApiMsi"
SourceFile="..\build\installers\$(var.Configuration)\$(var.MsiSourceFileName)"
Visible="yes"
DisplayInternalUI="yes" />
</Chain>
</Bundle>
</Wix>
+41
View File
@@ -0,0 +1,41 @@
<?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>8e63046b-56e5-4623-8808-558ad72a8f2b</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion>
<OutputName>MtApi_Setup</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>
<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>
+1 -1
View File
@@ -6,7 +6,7 @@
<ProductVersion>3.6</ProductVersion>
<ProjectGuid>{78b94552-db17-40ec-b7c6-23d32db85dc1}</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion>
<OutputName>MtApiSetup</OutputName>
<OutputName>MtApiInstaller</OutputName>
<OutputType>Package</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>
+18 -16
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?define ProductName="MtApi" ?>
<?define ProductVersion="1.0.30" ?>
<?define ProductVersion=!(bind.FileVersion.MtApi.dll) ?>
<?define Manufacturer="DW"?>
<?define ProductPath="..\build\products\$(var.Configuration)\"?>
@@ -11,15 +11,17 @@
Version="$(var.ProductVersion)"
Manufacturer="$(var.Manufacturer)"
UpgradeCode="4107F5F4-7300-4B45-88CE-63929AF228FA">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes" />
<WixVariable Id="WixUILicenseRtf" Value="..\LICENSE.rtf" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes" />
<Feature Id="MtApi" Title="$(var.ProductName)" Level="1">
<ComponentGroupRef Id="MtApiComponents"/>
</Feature>
<Feature Id="MTConnector" Title="MT Connector" Level="1">
<ComponentGroupRef Id="MTConnectorComponents"/>
</Feature>
@@ -35,18 +37,18 @@
</InstallExecuteSequence>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="$(var.ProductName)">
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="$(var.ProductName)">
<Directory Id="ExpertFolder" Name="Experts">
<Directory Id="ExpertFolder" Name="Experts">
</Directory>
<Directory Id="GAC" Name="GAC">
</Directory>
</Directory>
</Directory>
</Directory>
<Directory Id="SystemFolder">
@@ -57,7 +59,7 @@
</Directory>
</Directory>
</Directory>
</Directory>
</Fragment>
<Fragment>
@@ -66,7 +68,7 @@
<Component Id="MtApiDll" Directory="INSTALLFOLDER">
<File Id="MtApi.dll" Name="MtApi.dll" KeyPath="yes"
Source="$(var.ProductPath)MtApi.dll" />
<RegistryKey Root="HKLM"
Key="Software\Microsoft\.NetFramework\v4.0.30319\AssemblyFoldersEx\$(var.ProductName)"
Action="createAndRemoveOnUninstall">
@@ -78,7 +80,7 @@
<File Id="GAC_MTApiService.dll" Name="MTApiService.dll" KeyPath="yes"
src="$(var.ProductPath)MTApiService.dll"/>
</Component>-->
<Component Id="NewtonsoftJsondll" Directory="INSTALLFOLDER">
<File Id="Newtonsoft.Json.dll" Name="Newtonsoft.Json.dll" KeyPath="yes"
src="$(var.ProductPath)Newtonsoft.Json.dll"/>
@@ -87,7 +89,7 @@
<Component Id="MtApiExpert" Directory="ExpertFolder">
<File Id="MtApi.ex4" Name="MtApi.ex4" KeyPath="yes"
Source="..\mq4\MtApi.ex4" />
</Component>
</Component>
<Component Id="AppShortcutConnMgr" Guid="*" Directory="ApplicationProgramsFolder">
<RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
-1
View File
@@ -1 +0,0 @@
regsvr32 ole32.dll
File diff suppressed because it is too large Load Diff
+15 -13
View File
@@ -334,9 +334,9 @@
</Grid.ColumnDefinitions>
<TextBox Grid.Row="0" Text="symbolName"/>
<TextBox Grid.Row="1" Text="timeframe"/>
<TextBox Grid.Row="2" Text="startPos"/>
<TextBox Grid.Row="3" Text="count"/>
<TextBox Grid.Row="1" Grid.Column="0" Text="timeframe"/>
<TextBox Grid.Row="2" Grid.Column="0" Text="startPos"/>
<TextBox Grid.Row="3" Grid.Column="0" Text="count"/>
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding TimeSeriesValues.SymbolValue}"/>
<ComboBox Grid.Row="1" Grid.Column="1"
ItemsSource="{Binding Source={StaticResource ENUM_TIMEFRAMES_Key}}"
@@ -344,25 +344,27 @@
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding TimeSeriesValues.StartPos}"/>
<TextBox Grid.Row="3" Grid.Column="1" Text="{Binding TimeSeriesValues.Count}"/>
<WrapPanel Grid.Row="4" Grid.ColumnSpan="2" Margin="10">
<Button Command="{Binding CopyRatesCommand}"
<WrapPanel Grid.Row="4" Grid.ColumnSpan="2" Grid.Column="0" Margin="10">
<Button Command="{Binding CopyRatesCommand}" Margin="1"
Content="CopyRates" HorizontalAlignment="Left" />
<Button Command="{Binding CopyTimesCommand}"
<Button Command="{Binding CopyTimesCommand}" Margin="1"
Content="CopyTimes" HorizontalAlignment="Left" />
<Button Command="{Binding CopyOpenCommand}"
<Button Command="{Binding CopyOpenCommand}" Margin="1"
Content="CopyOpen" HorizontalAlignment="Left" />
<Button Command="{Binding CopyHighCommand}"
<Button Command="{Binding CopyHighCommand}" Margin="1"
Content="CopyHigh" HorizontalAlignment="Left" />
<Button Command="{Binding CopyLowCommand}"
<Button Command="{Binding CopyLowCommand}" Margin="1"
Content="CopyLow" HorizontalAlignment="Left" />
<Button Command="{Binding CopyCloseCommand}"
<Button Command="{Binding CopyCloseCommand}" Margin="1"
Content="CopyClose" HorizontalAlignment="Left" />
<Button Command="{Binding CopyTickVolumeCommand}"
<Button Command="{Binding CopyTickVolumeCommand}" Margin="1"
Content="CopyTickVolume" HorizontalAlignment="Left" />
<Button Command="{Binding CopyRealVolumeCommand}"
<Button Command="{Binding CopyRealVolumeCommand}" Margin="1"
Content="CopyRealVolume" HorizontalAlignment="Left" />
<Button Command="{Binding CopySpreadCommand}"
<Button Command="{Binding CopySpreadCommand}" Margin="1"
Content="CopySpread" HorizontalAlignment="Left" />
<Button Command="{Binding CopyTicksCommand}" Margin="1"
Content="CopyTicks" HorizontalAlignment="Left" />
</WrapPanel>
</Grid>
+29 -1
View File
@@ -31,6 +31,7 @@ namespace MtApi5TestClient
public DelegateCommand CopyTickVolumeCommand { get; private set; }
public DelegateCommand CopyRealVolumeCommand { get; private set; }
public DelegateCommand CopySpreadCommand { get; private set; }
public DelegateCommand CopyTicksCommand { get; private set; }
public DelegateCommand SymbolsTotalCommand { get; private set; }
public DelegateCommand SymbolNameCommand { get; private set; }
@@ -207,7 +208,8 @@ namespace MtApi5TestClient
CopyTickVolumeCommand = new DelegateCommand(ExecuteCopyTickVolume);
CopyRealVolumeCommand = new DelegateCommand(ExecuteCopyRealVolume);
CopySpreadCommand = new DelegateCommand(ExecuteCopySpread);
CopyTicksCommand = new DelegateCommand(ExecuteCopyTicks);
SymbolsTotalCommand = new DelegateCommand(ExecuteSymbolsTotal);
SymbolNameCommand = new DelegateCommand(ExecuteSymbolName);
SymbolSelectCommand = new DelegateCommand(ExecuteSymbolSelect);
@@ -569,6 +571,32 @@ namespace MtApi5TestClient
AddLog("CopySpread: success");
}
private async void ExecuteCopyTicks(object o)
{
if (string.IsNullOrEmpty(TimeSeriesValues?.SymbolValue)) return;
TimeSeriesResults.Clear();
var result = await Execute(() => _mtApiClient.CopyTicks(TimeSeriesValues.SymbolValue));
if (result == null)
{
AddLog("CopyTicks: result is null");
return;
}
AddLog("CopyTicks: success.");
RunOnUiThread(() =>
{
foreach (var v in result)
{
var tickStr = $"time = {v.time}, bid = {v.bid}, ask = {v.ask}, last = {v.last}, volume = {v.volume}";
TimeSeriesResults.Add(tickStr);
}
});
}
private async void ExecuteSymbolsTotal(object o)
{
var selectedCount = await Execute(() => _mtApiClient.SymbolsTotal(true));
+313 -65
View File
@@ -110,9 +110,12 @@
this.listBoxAccountInfo = new System.Windows.Forms.ListBox();
this.button4 = new System.Windows.Forms.Button();
this.tabPage4 = new System.Windows.Forms.TabPage();
this.comboBox6 = new System.Windows.Forms.ComboBox();
this.label29 = new System.Windows.Forms.Label();
this.comboBox5 = new System.Windows.Forms.ComboBox();
this.button31 = new System.Windows.Forms.Button();
this.txtMarketInfoSymbol = new System.Windows.Forms.TextBox();
this.button5 = new System.Windows.Forms.Button();
this.listBoxMarketInfo = new System.Windows.Forms.ListBox();
this.tabPage5 = new System.Windows.Forms.TabPage();
this.dateTimePicker2 = new System.Windows.Forms.DateTimePicker();
this.dateTimePicker1 = new System.Windows.Forms.DateTimePicker();
@@ -139,13 +142,30 @@
this.button6 = new System.Windows.Forms.Button();
this.listBoxProceHistory = new System.Windows.Forms.ListBox();
this.tabPage6 = new System.Windows.Forms.TabPage();
this.textBoxPrint = new System.Windows.Forms.TextBox();
this.button27 = new System.Windows.Forms.Button();
this.button14 = new System.Windows.Forms.Button();
this.button13 = new System.Windows.Forms.Button();
this.tabPage7 = new System.Windows.Forms.TabPage();
this.button23 = new System.Windows.Forms.Button();
this.iCustomBtn = new System.Windows.Forms.Button();
this.button27 = new System.Windows.Forms.Button();
this.textBoxPrint = new System.Windows.Forms.TextBox();
this.tabPage8 = new System.Windows.Forms.TabPage();
this.comboBox4 = new System.Windows.Forms.ComboBox();
this.button32 = new System.Windows.Forms.Button();
this.button30 = new System.Windows.Forms.Button();
this.button29 = new System.Windows.Forms.Button();
this.button28 = new System.Windows.Forms.Button();
this.label28 = new System.Windows.Forms.Label();
this.textBox1 = new System.Windows.Forms.TextBox();
this.comboBox7 = new System.Windows.Forms.ComboBox();
this.button33 = new System.Windows.Forms.Button();
this.label30 = new System.Windows.Forms.Label();
this.comboBox8 = new System.Windows.Forms.ComboBox();
this.button34 = new System.Windows.Forms.Button();
this.button35 = new System.Windows.Forms.Button();
this.comboBox9 = new System.Windows.Forms.ComboBox();
this.comboBox10 = new System.Windows.Forms.ComboBox();
this.button36 = new System.Windows.Forms.Button();
this.groupBox1.SuspendLayout();
this.statusStrip1.SuspendLayout();
this.groupBox2.SuspendLayout();
@@ -161,6 +181,7 @@
((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();
this.tabPage6.SuspendLayout();
this.tabPage7.SuspendLayout();
this.tabPage8.SuspendLayout();
this.SuspendLayout();
//
// textBoxServerName
@@ -323,6 +344,7 @@
this.tabControl1.Controls.Add(this.tabPage5);
this.tabControl1.Controls.Add(this.tabPage6);
this.tabControl1.Controls.Add(this.tabPage7);
this.tabControl1.Controls.Add(this.tabPage8);
this.tabControl1.Location = new System.Drawing.Point(12, 147);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
@@ -1026,9 +1048,21 @@
//
// tabPage4
//
this.tabPage4.Controls.Add(this.button36);
this.tabPage4.Controls.Add(this.comboBox10);
this.tabPage4.Controls.Add(this.comboBox9);
this.tabPage4.Controls.Add(this.button35);
this.tabPage4.Controls.Add(this.button34);
this.tabPage4.Controls.Add(this.comboBox8);
this.tabPage4.Controls.Add(this.label30);
this.tabPage4.Controls.Add(this.button33);
this.tabPage4.Controls.Add(this.comboBox7);
this.tabPage4.Controls.Add(this.comboBox6);
this.tabPage4.Controls.Add(this.label29);
this.tabPage4.Controls.Add(this.comboBox5);
this.tabPage4.Controls.Add(this.button31);
this.tabPage4.Controls.Add(this.txtMarketInfoSymbol);
this.tabPage4.Controls.Add(this.button5);
this.tabPage4.Controls.Add(this.listBoxMarketInfo);
this.tabPage4.Location = new System.Drawing.Point(4, 22);
this.tabPage4.Name = "tabPage4";
this.tabPage4.Padding = new System.Windows.Forms.Padding(3);
@@ -1037,66 +1071,65 @@
this.tabPage4.Text = "MarketInfo";
this.tabPage4.UseVisualStyleBackColor = true;
//
// comboBox6
//
this.comboBox6.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBox6.FormattingEnabled = true;
this.comboBox6.Location = new System.Drawing.Point(229, 10);
this.comboBox6.Name = "comboBox6";
this.comboBox6.Size = new System.Drawing.Size(121, 21);
this.comboBox6.TabIndex = 27;
//
// label29
//
this.label29.AutoSize = true;
this.label29.Location = new System.Drawing.Point(164, 13);
this.label29.Name = "label29";
this.label29.Size = new System.Drawing.Size(59, 13);
this.label29.TabIndex = 26;
this.label29.Text = "TimeFrame";
//
// comboBox5
//
this.comboBox5.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBox5.FormattingEnabled = true;
this.comboBox5.Items.AddRange(new object[] {
"SERIES_BARS_COUNT",
"SERIES_FIRSTDATE",
"SERIES_LASTBAR_DATE",
"SERIES_SERVER_FIRSTDATE"});
this.comboBox5.Location = new System.Drawing.Point(13, 74);
this.comboBox5.Name = "comboBox5";
this.comboBox5.Size = new System.Drawing.Size(186, 21);
this.comboBox5.TabIndex = 25;
//
// button31
//
this.button31.Location = new System.Drawing.Point(208, 74);
this.button31.Name = "button31";
this.button31.Size = new System.Drawing.Size(111, 23);
this.button31.TabIndex = 24;
this.button31.Text = "SeriesInfoInteger";
this.button31.UseVisualStyleBackColor = true;
this.button31.Click += new System.EventHandler(this.button31_Click);
//
// txtMarketInfoSymbol
//
this.txtMarketInfoSymbol.Location = new System.Drawing.Point(208, 6);
this.txtMarketInfoSymbol.Location = new System.Drawing.Point(57, 10);
this.txtMarketInfoSymbol.Name = "txtMarketInfoSymbol";
this.txtMarketInfoSymbol.Size = new System.Drawing.Size(100, 20);
this.txtMarketInfoSymbol.TabIndex = 7;
//
// button5
//
this.button5.Location = new System.Drawing.Point(16, 328);
this.button5.Location = new System.Drawing.Point(208, 45);
this.button5.Name = "button5";
this.button5.Size = new System.Drawing.Size(186, 23);
this.button5.Size = new System.Drawing.Size(111, 23);
this.button5.TabIndex = 6;
this.button5.Text = "Execute";
this.button5.Text = "MarketInfo";
this.button5.UseVisualStyleBackColor = true;
this.button5.Click += new System.EventHandler(this.button5_Click);
//
// listBoxMarketInfo
//
this.listBoxMarketInfo.FormattingEnabled = true;
this.listBoxMarketInfo.Items.AddRange(new object[] {
"",
"MODE_LOW",
"MODE_HIGH",
"",
"",
"MODE_TIME",
"",
"",
"",
"MODE_BID",
"MODE_ASK",
"MODE_POINT",
"MODE_DIGITS",
"MODE_SPREAD",
"MODE_STOPLEVEL",
"MODE_LOTSIZE",
"MODE_TICKVALUE",
"MODE_TICKSIZE",
"MODE_SWAPLONG",
"MODE_SWAPSHORT",
"MODE_STARTING",
"MODE_EXPIRATION",
"MODE_TRADEALLOWED",
"MODE_MINLOT",
"MODE_LOTSTEP",
"MODE_MAXLOT",
"MODE_SWAPTYPE",
"MODE_PROFITCALCMODE",
"MODE_MARGINCALCMODE",
"MODE_MARGININIT",
"MODE_MARGINMAINTENANCE",
"MODE_MARGINHEDGED",
"MODE_MARGINREQUIRED",
"MODE_FREEZELEVEL"});
this.listBoxMarketInfo.Location = new System.Drawing.Point(16, 6);
this.listBoxMarketInfo.Name = "listBoxMarketInfo";
this.listBoxMarketInfo.Size = new System.Drawing.Size(186, 316);
this.listBoxMarketInfo.TabIndex = 5;
//
// tabPage5
//
this.tabPage5.Controls.Add(this.dateTimePicker2);
@@ -1359,6 +1392,23 @@
this.tabPage6.Text = "Client Terminal";
this.tabPage6.UseVisualStyleBackColor = true;
//
// textBoxPrint
//
this.textBoxPrint.Location = new System.Drawing.Point(209, 16);
this.textBoxPrint.Name = "textBoxPrint";
this.textBoxPrint.Size = new System.Drawing.Size(386, 20);
this.textBoxPrint.TabIndex = 3;
//
// button27
//
this.button27.Location = new System.Drawing.Point(601, 16);
this.button27.Name = "button27";
this.button27.Size = new System.Drawing.Size(75, 23);
this.button27.TabIndex = 2;
this.button27.Text = "Print";
this.button27.UseVisualStyleBackColor = true;
this.button27.Click += new System.EventHandler(this.button27_Click);
//
// button14
//
this.button14.Location = new System.Drawing.Point(13, 45);
@@ -1411,22 +1461,198 @@
this.iCustomBtn.UseVisualStyleBackColor = true;
this.iCustomBtn.Click += new System.EventHandler(this.iCustomBtn_Click);
//
// button27
// tabPage8
//
this.button27.Location = new System.Drawing.Point(601, 16);
this.button27.Name = "button27";
this.button27.Size = new System.Drawing.Size(75, 23);
this.button27.TabIndex = 2;
this.button27.Text = "Print";
this.button27.UseVisualStyleBackColor = true;
this.button27.Click += new System.EventHandler(this.button27_Click);
this.tabPage8.Controls.Add(this.comboBox4);
this.tabPage8.Controls.Add(this.button32);
this.tabPage8.Controls.Add(this.button30);
this.tabPage8.Controls.Add(this.button29);
this.tabPage8.Controls.Add(this.button28);
this.tabPage8.Controls.Add(this.label28);
this.tabPage8.Controls.Add(this.textBox1);
this.tabPage8.Location = new System.Drawing.Point(4, 22);
this.tabPage8.Name = "tabPage8";
this.tabPage8.Padding = new System.Windows.Forms.Padding(3);
this.tabPage8.Size = new System.Drawing.Size(682, 377);
this.tabPage8.TabIndex = 8;
this.tabPage8.Text = "Symbols";
this.tabPage8.UseVisualStyleBackColor = true;
//
// textBoxPrint
// comboBox4
//
this.textBoxPrint.Location = new System.Drawing.Point(209, 16);
this.textBoxPrint.Name = "textBoxPrint";
this.textBoxPrint.Size = new System.Drawing.Size(386, 20);
this.textBoxPrint.TabIndex = 3;
this.comboBox4.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBox4.FormattingEnabled = true;
this.comboBox4.Items.AddRange(new object[] {
"SYMBOL_SELECT",
"SYMBOL_VISIBLE",
"SYMBOL_SESSION_DEALS",
"SYMBOL_SESSION_BUY_ORDERS",
"SYMBOL_SESSION_SELL_ORDERS",
"SYMBOL_VOLUME",
"SYMBOL_VOLUMEHIGH",
"SYMBOL_VOLUMELOW",
"SYMBOL_TIME",
"SYMBOL_DIGITS",
"SYMBOL_SPREAD",
"SYMBOL_SPREAD_FLOAT",
"SYMBOL_TRADE_CALC_MODE",
"SYMBOL_TRADE_MODE",
"SYMBOL_START_TIME",
"SYMBOL_EXPIRATION_TIME",
"SYMBOL_TRADE_STOPS_LEVEL",
"SYMBOL_TRADE_FREEZE_LEVEL",
"SYMBOL_TRADE_EXEMODE",
"SYMBOL_SWAP_MODE",
"SYMBOL_SWAP_ROLLOVER3DAYS",
"SYMBOL_EXPIRATION_MODE",
"SYMBOL_FILLING_MODE",
"SYMBOL_ORDER_MODE"});
this.comboBox4.Location = new System.Drawing.Point(10, 87);
this.comboBox4.Name = "comboBox4";
this.comboBox4.Size = new System.Drawing.Size(174, 21);
this.comboBox4.TabIndex = 3;
//
// button32
//
this.button32.Location = new System.Drawing.Point(190, 87);
this.button32.Name = "button32";
this.button32.Size = new System.Drawing.Size(108, 23);
this.button32.TabIndex = 2;
this.button32.Text = "SymbolInfoInteger";
this.button32.UseVisualStyleBackColor = true;
this.button32.Click += new System.EventHandler(this.button32_Click);
//
// button30
//
this.button30.Location = new System.Drawing.Point(206, 56);
this.button30.Name = "button30";
this.button30.Size = new System.Drawing.Size(92, 23);
this.button30.TabIndex = 2;
this.button30.Text = "SymbolSelect";
this.button30.UseVisualStyleBackColor = true;
this.button30.Click += new System.EventHandler(this.button30_Click);
//
// button29
//
this.button29.Location = new System.Drawing.Point(108, 56);
this.button29.Name = "button29";
this.button29.Size = new System.Drawing.Size(92, 23);
this.button29.TabIndex = 2;
this.button29.Text = "SymbolName";
this.button29.UseVisualStyleBackColor = true;
this.button29.Click += new System.EventHandler(this.button29_Click);
//
// button28
//
this.button28.Location = new System.Drawing.Point(10, 56);
this.button28.Name = "button28";
this.button28.Size = new System.Drawing.Size(92, 23);
this.button28.TabIndex = 2;
this.button28.Text = "SymbolsTotal";
this.button28.UseVisualStyleBackColor = true;
this.button28.Click += new System.EventHandler(this.button28_Click);
//
// label28
//
this.label28.AutoSize = true;
this.label28.Location = new System.Drawing.Point(7, 20);
this.label28.Name = "label28";
this.label28.Size = new System.Drawing.Size(41, 13);
this.label28.TabIndex = 1;
this.label28.Text = "Symbol";
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(54, 17);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(100, 20);
this.textBox1.TabIndex = 0;
this.textBox1.Text = "EURUSD";
//
// comboBox7
//
this.comboBox7.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBox7.FormattingEnabled = true;
this.comboBox7.Location = new System.Drawing.Point(13, 101);
this.comboBox7.Name = "comboBox7";
this.comboBox7.Size = new System.Drawing.Size(186, 21);
this.comboBox7.TabIndex = 28;
//
// button33
//
this.button33.Location = new System.Drawing.Point(208, 99);
this.button33.Name = "button33";
this.button33.Size = new System.Drawing.Size(111, 23);
this.button33.TabIndex = 29;
this.button33.Text = "SymbolInfoDouble";
this.button33.UseVisualStyleBackColor = true;
this.button33.Click += new System.EventHandler(this.button33_Click);
//
// label30
//
this.label30.AutoSize = true;
this.label30.Location = new System.Drawing.Point(10, 13);
this.label30.Name = "label30";
this.label30.Size = new System.Drawing.Size(41, 13);
this.label30.TabIndex = 30;
this.label30.Text = "Symbol";
//
// comboBox8
//
this.comboBox8.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBox8.FormattingEnabled = true;
this.comboBox8.Location = new System.Drawing.Point(13, 47);
this.comboBox8.Name = "comboBox8";
this.comboBox8.Size = new System.Drawing.Size(186, 21);
this.comboBox8.TabIndex = 31;
//
// button34
//
this.button34.Location = new System.Drawing.Point(387, 47);
this.button34.Name = "button34";
this.button34.Size = new System.Drawing.Size(112, 23);
this.button34.TabIndex = 32;
this.button34.Text = "SymbolInfoTick";
this.button34.UseVisualStyleBackColor = true;
this.button34.Click += new System.EventHandler(this.button34_Click);
//
// button35
//
this.button35.Location = new System.Drawing.Point(208, 128);
this.button35.Name = "button35";
this.button35.Size = new System.Drawing.Size(111, 23);
this.button35.TabIndex = 33;
this.button35.Text = "TerminalInfoInteger";
this.button35.UseVisualStyleBackColor = true;
this.button35.Click += new System.EventHandler(this.button35_Click);
//
// comboBox9
//
this.comboBox9.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBox9.FormattingEnabled = true;
this.comboBox9.Location = new System.Drawing.Point(13, 130);
this.comboBox9.Name = "comboBox9";
this.comboBox9.Size = new System.Drawing.Size(186, 21);
this.comboBox9.TabIndex = 34;
//
// comboBox10
//
this.comboBox10.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBox10.FormattingEnabled = true;
this.comboBox10.Location = new System.Drawing.Point(13, 157);
this.comboBox10.Name = "comboBox10";
this.comboBox10.Size = new System.Drawing.Size(186, 21);
this.comboBox10.TabIndex = 35;
//
// button36
//
this.button36.Location = new System.Drawing.Point(208, 157);
this.button36.Name = "button36";
this.button36.Size = new System.Drawing.Size(111, 23);
this.button36.TabIndex = 36;
this.button36.Text = "TerminalInfoDouble";
this.button36.UseVisualStyleBackColor = true;
this.button36.Click += new System.EventHandler(this.button36_Click);
//
// Form1
//
@@ -1466,6 +1692,8 @@
this.tabPage6.ResumeLayout(false);
this.tabPage6.PerformLayout();
this.tabPage7.ResumeLayout(false);
this.tabPage8.ResumeLayout(false);
this.tabPage8.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
@@ -1539,7 +1767,6 @@
private System.Windows.Forms.Label label24;
private System.Windows.Forms.TabPage tabPage4;
private System.Windows.Forms.Button button5;
private System.Windows.Forms.ListBox listBoxMarketInfo;
private System.Windows.Forms.TextBox txtMarketInfoSymbol;
private System.Windows.Forms.TabPage tabPage5;
private System.Windows.Forms.Button button6;
@@ -1590,6 +1817,27 @@
private System.Windows.Forms.Button button25;
private System.Windows.Forms.Button button27;
private System.Windows.Forms.TextBox textBoxPrint;
private System.Windows.Forms.TabPage tabPage8;
private System.Windows.Forms.Label label28;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Button button28;
private System.Windows.Forms.Button button29;
private System.Windows.Forms.Button button30;
private System.Windows.Forms.Button button32;
private System.Windows.Forms.ComboBox comboBox4;
private System.Windows.Forms.ComboBox comboBox5;
private System.Windows.Forms.Button button31;
private System.Windows.Forms.ComboBox comboBox6;
private System.Windows.Forms.Label label29;
private System.Windows.Forms.ComboBox comboBox7;
private System.Windows.Forms.Button button33;
private System.Windows.Forms.Label label30;
private System.Windows.Forms.ComboBox comboBox8;
private System.Windows.Forms.Button button34;
private System.Windows.Forms.Button button35;
private System.Windows.Forms.ComboBox comboBox9;
private System.Windows.Forms.Button button36;
private System.Windows.Forms.ComboBox comboBox10;
}
}
File diff suppressed because it is too large Load Diff
View File
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+133
View File
@@ -1,6 +1,7 @@
#property copyright "Vyacheslav Demidyuk"
#property link ""
#include <json.mqh>
#include <Trade\SymbolInfo.mqh>
#include <trade/trade.mqh>
#property version "1.1"
@@ -47,6 +48,7 @@ bool IsRemoteReadyForTesting = false;
string symbolValue;
string commentValue;
string requestValue;
string PARAM_SEPARATOR = ";";
@@ -77,6 +79,7 @@ int preinit()
StringInit(message, 1000, 0);
StringInit(symbolValue, 1000, 0);
StringInit(commentValue, 1000, 0);
StringInit(requestValue, 1000, 0);
return (0);
}
@@ -231,6 +234,25 @@ int executeCommand()
case 0:
//NoCommand
break;
case 155: //Request
{
if (!getStringValue(ExpertHandle, 0, requestValue))
{
PrintParamError("Request");
}
string response = "";
if (requestValue != "")
{
Print("executeCommand: incoming request = ", requestValue);
response = OnRequest(requestValue);
}
sendStringResponse(ExpertHandle, response);
}
break;
case 1: // OrderSend
{
@@ -1830,3 +1852,114 @@ bool OrderCloseAll()
}
return true;
}
string OnRequest(string json)
{
string response = "";
JSONParser *parser = new JSONParser();
JSONValue *jv = parser.parse(json);
if(jv == NULL)
{
PrintFormat("OnRequest [ERROR]: %d - %s", (string)parser.getErrorCode(), parser.getErrorMessage());
}
else
{
if(jv.isObject())
{
JSONObject *jo = jv;
int requestType = jo.getInt("RequestType");
switch(requestType)
{
case 1: //CopyTicks
response = ExecuteRequest_CopyTicks(jo);
break;
default:
PrintFormat("OnRequest [WARNING]: Unknown request type %d", requestType);
response = CreateErrorResponse(-1, "Unknown request type");
break;
}
}
delete jv;
}
delete parser;
return response;
}
string CreateErrorResponse(int code, string message)
{
JSONValue* jsonError;
if (code == 0)
jsonError = new JSONString("0");
else
jsonError = new JSONNumber((long)code);
JSONObject *joResponse = new JSONObject();
joResponse.put("ErrorCode", jsonError);
joResponse.put("ErrorMessage", new JSONString(message));
string result = joResponse.toString();
delete joResponse;
return result;
}
string CreateSuccessResponse(string responseName, JSONValue* responseBody)
{
JSONObject *joResponse = new JSONObject();
joResponse.put("ErrorCode", new JSONString("0"));
if (responseBody != NULL)
{
joResponse.put(responseName, responseBody);
}
string result = joResponse.toString();
delete joResponse;
return result;
}
JSONObject* Serialize(MqlTick& tick)
{
JSONObject *jo = new JSONObject();
jo.put("MtTime", new JSONNumber(tick.time));
jo.put("bid", new JSONNumber(tick.bid));
jo.put("ask", new JSONNumber(tick.ask));
jo.put("last", new JSONNumber(tick.last));
jo.put("volume", new JSONNumber(tick.volume));
return jo;
}
string ExecuteRequest_CopyTicks(JSONObject *jo)
{
if (jo.getValue("SymbolName") == NULL)
return CreateErrorResponse(-1, "Undefinded mandatory parameter SymbolName");
if (jo.getValue("Flags") == NULL)
return CreateErrorResponse(-1, "Undefinded mandatory parameter Flags");
if (jo.getValue("From") == NULL)
return CreateErrorResponse(-1, "Undefinded mandatory parameter From");
if (jo.getValue("Count") == NULL)
return CreateErrorResponse(-1, "Undefinded mandatory parameter Count");
string symbol = jo.getString("SymbolName");
uint flags = jo.getInt("Flags");
int from = jo.getInt("From");
int count = jo.getInt("Count");
MqlTick ticks[];
int received = CopyTicks(symbol, ticks, flags, from, count);
if(received == -1)
return CreateErrorResponse(GetLastError(), "CopyTicks failed");
JSONArray* jaTicks = new JSONArray();
for(int i = 0; i < received; i++)
{
jaTicks.put(i, Serialize(ticks[i]));
}
return CreateSuccessResponse("Ticks", jaTicks);;
}
Executable
+672
View File
@@ -0,0 +1,672 @@
// $Id: hash.mqh 125 2014-03-03 08:38:32Z ydrol $
#ifndef YDROL_HASH_MQH
#define YDROL_HASH_MQH
//#property strict
/*
This is losely ported from a C version I have which was in turn modified from hashtable.c by Christopher Clark.
Copyright (C) 2014, Andrew Lord (NICKNAME=lordy) <forex@NICKNAME.org.uk>
Copyright (C) 2002, 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk>
2014/02/21 - Readded PrimeNumber sizes and auto rehashing when load factor hit.
*/
/// Any value stored in a Hash must be a subclass of HashValue
class HashValue {
};
/// Linked list of values - there will be one list for each hash value
class HashEntry {
public:
string _key;
HashValue * _val;
HashEntry *_next;
HashEntry() {
_key=NULL;
_val=NULL;
_next=NULL;
}
HashEntry(string key,HashValue* val) {
_key=key;
_val=val;
_next=NULL;
}
~HashEntry() {
}
};
/// Convenience class for storing strings as hash values.
class HashString : public HashValue {
private:
string val;
public:
HashString(string v) { val=v;}
string getVal() { return val; }
};
/// Convenience class for storing doubles as hash values.
class HashDouble : public HashValue {
private:
double val;
public:
HashDouble(double v) { val=v;}
double getVal() { return val; }
};
/// Convenience class for storing ints as hash values.
class HashInt : public HashValue {
private:
int val;
public:
HashInt(int v) { val=v;}
int getVal() { return val; }
};
/// Convenience class for storing longs as hash values.
class HashLong : public HashValue {
private:
long val;
public:
HashLong(datetime v) { val=v;}
long getVal() { return val; }
};
/// Convenience class for storing datetimes as hash values.
class HashDatetime : public HashValue {
private:
datetime val;
public:
HashDatetime(datetime v) { val=v;}
datetime getVal() { return val; }
};
///
/// Hash class allows objects to be stored in a table index by strings.
/// the stored Objects must be a sub class of the HashValue class.
///
/// There are some convenience classes to hold atomic types as values HashString,HashDouble,HashInt
///
///EXAMPLE:
///
/// <pre>
/// class myClass: public HashValue {
/// public: int v;
/// myClass(int a) { v = a;}
/// };
///
/// // Create the objects as needed
///
/// myClass *a = new myClass(1);
/// myClass *b = new myClass(2);
/// myClass *c = new myClass(3);
///
/// // Then to insert into hash etc.
///
/// Hash* h = new Hash(193,true);
/// // 'true' means when the hash will adopt the values and delete them when they are removed from the hash or when the hash is deleted.
///
/// h.hPut("a",a);
/// h.hPut("b",b);
/// h.hPut("c",c);
///
/// myClass *d = h.hGet("b");
///
/// etc.
///
/// // Iterate over hash
/// HashLoop *l
/// for (l = new HashLoop(h) ; l.hasNext() ; l.next() ) {
/// string key = l.key();
/// MyClass *c = l.val();
/// }
/// delete l;
///
/// // Delete from hash - This will also delete 'a' because we set the 'adopt' flag on the hash.
/// h.hDel("a");
///
/// //Delete the hash - this will also delete 'b' and 'c' because of the adopt flag.
/// delete h;
/// </pre>
class Hash : public HashValue {
private:
/// Number of slots in the hashtable.
/// this should be approx number of elements to store. Depending on hash algorithm
/// it may optimally be a prime or a power of two etc. but probably not important
/// for MQL4 performance. A future optimisation might be to move the hashcode function to a DLL??
uint _hashSlots;
/// Number of elements at which hash will get resized.
int _resizeThreshold;
/// number of things in the hash
int _hashEntryCount;
/// an array of linked lists (HashEntry). one for each hash value.
/// To store an object against a string(key) - get the string hashcode, then insert pair (key,val) into the linked list for that hashcode.
/// To fetch an object against a string(key) - get the string hashcode, get linked-list at that hashcode index, then search for the key and return the val.
HashEntry* _buckets[];
/// If true the hash will free(delete) values as they are removed, or at cleanup.
bool _adoptValues;
int _errCode;
string _errText;
void init(uint size,bool adoptValues)
{
_hashSlots = 0;
_hashEntryCount = 0;
clearError();
setAdoptValues(adoptValues);
rehash(size);
}
// Hash table distribution is better when size is prime, eg if hash function procduces numbers
// that are multiples of x, then there may be grouping occuring around gcd(x,slots) gcd(2x,slots) etc
// using a prime size helps spread the distribution.
uint size2prime(uint size) {
int pmax=ArraySize(_primes);
for(int p=0 ; p<pmax; p++ ) {
if (_primes[p] >= size) {
return _primes[p];
}
}
return size;
}
/// Primes that approx double in size, used for hash table sizes to avoid gcd causing bunching
static uint _primes[];
/// After reviewing quite a few hash functions I settled on the one below.
/// http://www.cse.yorku.ca/~oz/hash.html
/// this is the bottleneck function. Shame mql hash no default hash method for objects.
uint hash(string s)
{
uchar c[];
uint h = 0;
if (s != NULL) {
h = 5381;
int n = StringToCharArray(s,c);
for(int i = 0 ; i < n ; i++ ) {
h = ((h << 5 ) + h ) + c[i];
}
}
return h % _hashSlots;
}
void clearError() {
setError(0,"");
}
void setError(int e,string m) {
_errCode = e;
_errText = m;
//error((string)e,m);
}
public:
/// Constructor: Create a Hash Object
Hash() {
init(17,true);
}
/// Constructor: Create a Hash Object
/// @param adoptValues : If true the hash destructor will <b>delete</b> all dynamically allocated hash values.
Hash(bool adoptValues) {
init(17,adoptValues);
}
/// Constructor: Create a Hash Object
/// @param size : Approximate size (actual size will be a larger prime number close to a power of 2)
/// @param adoptValues : If true the hash destructor will <b>delete</b> all dynamically allocated hash values.
Hash(int size,bool adoptValues) {
init(size,adoptValues);
}
~Hash() {
// Free entries.
for(uint i = 0 ; i< _hashSlots ; i++) {
HashEntry *nextEntry = NULL;
for(HashEntry *entry = _buckets[i] ; entry!= NULL ; entry = nextEntry )
{
nextEntry = entry._next;
if (_adoptValues && entry._val != NULL && CheckPointer(entry._val) == POINTER_DYNAMIC ) {
delete entry._val;
}
delete entry;
}
_buckets[i] = NULL;
}
}
/// Return any error that has occured. This should be used when
/// retriving values in a Hash that may contain NULLs. hGet()
/// methods can return NULL if not found, in which case getErrorCode
/// will be set.
int getErrCode() {
return _errCode;
}
/// Return text of the error message.
string getErrText() {
return _errText;
}
/// If true the hash destructor will <b>delete</b> all dynamically allocated hash values.
void setAdoptValues(bool v) {
_adoptValues = v;
}
/// True if the hash destructor will <b>delete</b> all dynamically allocated hash values.
bool getAdoptValues() {
return _adoptValues;
}
private:
uint _foundIndex; // After find() is called is set to hashindex for name whether found or not.
HashEntry* _foundEntry; // After find() is called is set to the HashEntry that contains the key.
HashEntry* _foundPrev; // After find() is called is set to the HashEntry before the entry
// (could use double linked list but requires more memory).
/// Look for the required entry for key 'name' true if found.
bool find(string keyName) {
//Alert("finding");
bool found = false;
// Get the index using the hashcode of the string
_foundIndex = hash(keyName);
if (_foundIndex>_hashSlots ) {
setError(1,"hGet: bad hashIndex="+(string)_foundIndex+" size "+(string)_hashSlots);
} else {
// Search the linked list determined by the index.
for(HashEntry *e = _buckets[_foundIndex] ; e != NULL ; e = e._next ) {
if (e._key == keyName) {
_foundEntry = e;
found=true;
break;
}
// Track the item before the target item in case deleting from single linked list.
_foundPrev = e;
}
}
return found;
}
public:
/// This is used by the HashLoop class to get start of LinkedList at bucket[i]
HashEntry*getEntry(int i) {
return _buckets[i];
}
/// Return the number of slots/buckets (not number of elements)
uint getSlots() {
return _hashSlots;
}
/// Return the number of elements in the Hash
int getCount() {
return _hashEntryCount;
}
/// Change the hash size and re-allocate values to new buckets.
bool rehash(uint newSize) {
bool ret = false;
HashEntry* oldTable[];
uint oldSize = _hashSlots;
newSize = size2prime(newSize);
//info("rehashing from "+(string)_hashSlots+" to "+(string)newSize+" "+(string)GetTickCount());
if (newSize <= getSlots()) {
setError(2,"rehash "+(string)newSize+" <= "+(string)_hashSlots);
} else if (ArrayResize(_buckets,newSize) != newSize) {
setError(3,"unable to resize ");
} else if (ArrayResize(oldTable,oldSize) != oldSize) {
setError(4,"unable to resize old copy ");
} else {
//Copy old table.
uint i;
for(i = 0 ; i < oldSize ; i++ ) oldTable[i] = _buckets[i];
// Init new entries - not sure if MQL does this anyway
for(i = 0 ; i<newSize ; i++ ) _buckets[i] = NULL;
// Move entries to new slots
_hashSlots = newSize;
_resizeThreshold = (int)_hashSlots / 4 * 3; // Just use the default load factor value of Javas HashTable
// Look through all slots
for(uint oldHashCode = 0 ; oldHashCode<oldSize ; oldHashCode++ ) {
HashEntry *next = NULL;
// Walk linked list
for(HashEntry *e = oldTable[oldHashCode] ; e != NULL ; e = next ) {
next = e._next;
uint newHashCode = hash(e._key);
// Insert at head of new list.
e._next = _buckets[newHashCode];
_buckets[newHashCode] = e;
}
oldTable[oldHashCode] = NULL;
}
ret = true;
}
return ret;
}
/// Check if the hash contains the given key
/// @param keyName : The key
/// @return: true if found otherwise false
bool hContainsKey(string keyName) {
return find(keyName);
}
/// Fetch a value using string key
/// @return :HashValue associated with the key (or NULL if none found)
/// If the Hashtable contains legitimate NULL values then also check errCode()
/// Examples:
/// If not storing nulls use
/// obj = hash.hGet(x); if (obj != NULL) OK
///
/// If storing nulls use
/// obj = hash.hGet(x); if (obj != NULL || hash.errCode() == 0 ) OK
HashValue* hGet(string keyName) {
HashValue *obj = NULL;
clearError();
bool found=false;
if (find(keyName)) {
obj = _foundEntry._val;
} else {
//If Hash contains nulls then also check the errorCode=0 when retrieving
if (!found) {
setError(1,"not found");
}
}
return obj;
}
/// Convenience method for getting values from a HashString value (see hPutString())
string hGetString(string keyName) {
string ret = NULL;
HashString *v = hGet(keyName);
if (v != NULL) {
ret = v.getVal();
}
return ret;
}
/// Convenience method for getting values from a HashDouble value (see hPutDouble())
double hGetDouble(string keyName) {
double ret = NULL;
HashDouble *v = hGet(keyName);
if (v != NULL) {
ret = v.getVal();
}
return ret;
}
/// Convenience method for getting values from a HashInt value (see hPutInt())
int hGetInt(string keyName) {
int ret = NULL;
HashInt *v = hGet(keyName);
if (v != NULL) {
ret = v.getVal();
}
return ret;
}
/// Convenience method for getting values from a HashLong ( see hPutLong())
long hGetLong(string keyName) {
long ret = NULL;
HashLong *v = hGet(keyName);
if (v != NULL) {
ret = v.getVal();
}
return ret;
}
/// Convenience method for getting values from a HashDatetime ( see hPutDatetime())
datetime hGetDatetime(string keyName) {
datetime ret = NULL;
HashDatetime *v = hGet(keyName);
if (v != NULL) {
ret = v.getVal();
}
return ret;
}
/// Store a hash value against the <b>keyName</b> key. This will overwrite any existing
/// value. It adoptValues is set, it will also free the value if applicable.
/// @param keyName : key name
/// @param obj : Value to store
/// @return the previous value of the key or NULL if there wasnt one
HashValue *hPut(string keyName,HashValue *obj) {
HashValue *ret = NULL;
clearError();
if (find(keyName)) {
// Return revious value
ret = _foundEntry._val;
/*
// Replace entry contents
if (_adoptValues && _foundEntry._val != NULL && CheckPointer(_foundEntry._val) == POINTER_DYNAMIC ) {
delete _foundEntry._val;
}
*/
_foundEntry._val = obj;
} else {
// Insert new entry at head of list
HashEntry* e = new HashEntry(keyName,obj);
HashEntry* first = _buckets[_foundIndex];
e._next = first;
_buckets[_foundIndex] = e;
_hashEntryCount++;
//info((string)_hashEntryCount+" vs. "+(string)_resizeThreshold);
// Auto Resize if number of entries hits _resizeThreshold
if (_hashEntryCount > _resizeThreshold ) {
rehash(_hashSlots/2*3); // this will snap to the next prime
}
}
return ret;
}
/// Store a string as hash value (HashString)
/// @return the previous value of the key or NULL if there wasnt one
HashValue* hPutString(string keyName,string s) {
HashString *v = new HashString(s);
return hPut(keyName,v);
}
/// Store a double as hash value (HashDouble)
/// @return the previous value of the key or NULL if there wasnt one
HashValue* hPutDouble(string keyName,double d) {
HashDouble *v = new HashDouble(d);
return hPut(keyName,v);
}
/// Store an int as hash value (HashInt)
/// @return the previous value of the key or NULL if there wasnt one
HashValue* hPutInt(string keyName,int i) {
HashInt *v = new HashInt(i);
return hPut(keyName,v);
}
/// Store a datetime as hash value (HashLong)
/// @return the previous value of the key or NULL if there wasnt one
HashValue* hPutLong(string keyName,long i) {
HashLong *v = new HashLong(i);
return hPut(keyName,v);
}
/// Store a datetime as hash value (HashDatetime)
/// @return the previous value of the key or NULL if there wasnt one
HashValue* hPutDatetime(string keyName,datetime i) {
HashDatetime *v = new HashDatetime(i);
return hPut(keyName,v);
}
/// Delete an entry from the hash.
bool hDel(string keyName) {
bool found = false;
clearError();
if (find(keyName)) {
HashEntry *next = _foundEntry._next;
if (_foundPrev != NULL) {
//Remove entry from the middle of the list.
_foundPrev._next = next;
} else {
// remove from head of list
_buckets[_foundIndex] = next;
}
if (_adoptValues && _foundEntry._val != NULL&& CheckPointer(_foundEntry._val) == POINTER_DYNAMIC) {
delete _foundEntry._val;
}
delete _foundEntry;
_hashEntryCount--;
found=true;
}
return found;
}
};
uint Hash::_primes[] = {
17, 53, 97, 193, 389,
769, 1543, 3079, 6151,
12289, 24593, 49157, 98317,
196613, 393241, 786433, 1572869,
3145739, 6291469, 12582917, 25165843,
50331653, 100663319, 201326611, 402653189,
805306457, 1610612741};
/// Class to iterate over a Hash using ...
/// <pre>
/// HashLoop *l
/// for (l = new HashLoop(h) ; l.hasNext() ; l.next() ) {
/// string key = l.key();
/// MyClass *c = l.val();
/// }
/// delete l;
/// </pre>
class HashLoop {
private:
uint _index;
HashEntry *_currentEntry;
Hash *_hash;
public:
/// Create iterator for a hash - move to first item
HashLoop(Hash *h) {
setHash(h);
}
~HashLoop() {};
/// Clear current state and move to first item (if any).
void reset() {
_index=0;
_currentEntry = _hash.getEntry(_index);
// Move to first item
if (_currentEntry == NULL) {
next();
}
}
/// Change the hash over which to iterate.
void setHash(Hash *h) {
_hash = h;
reset();
}
/// Check if more items.
bool hasNext() {
bool ret = ( _currentEntry != NULL);
//config("hasNext=",ret);
return ret;
}
/// Move to next item.
void next() {
//config("next : index = ",_index);
// Advance
if (_currentEntry != NULL) {
_currentEntry = _currentEntry._next;
}
// Keep advancing if _currentEntry is null
while (_currentEntry==NULL) {
_index++;
if (_index >= _hash.getSlots() ) return ;
_currentEntry = _hash.getEntry(_index);
}
}
/// Return the key name of the current item.
string key() {
if (_currentEntry != NULL) {
return _currentEntry._key;
} else {
return NULL;
}
}
/// Return the value.
HashValue *val() {
if (_currentEntry != NULL) {
return _currentEntry._val;
} else {
return NULL;
}
}
/// Convenience functions for retriving int from a current HashInt entry
int valInt() {
return ((HashInt *)val()).getVal();
}
/// Convenience functions for retriving int from a current HashString entry
string valString() {
return ((HashString *)val()).getVal();
}
/// Convenience functions for retriving int from a current HashDouble entry
double valDouble() {
return ((HashDouble *)val()).getVal();
}
/// Convenience functions for retriving int from a current HashLong entry
long valLong() {
return ((HashLong *)val()).getVal();
}
/// Convenience functions for retriving int from a current HashDatetime entry
datetime valDatetime() {
return ((HashDatetime *)val()).getVal();
}
};
#endif
Executable
+1033
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.