Compare commits

..

153 Commits

Author SHA1 Message Date
vdemydiuk 52ca4fae1e MtApi5.ex5: Update version to 1.5. Disable debug logging 2018-03-27 11:25:22 +03:00
vdemydiuk 6b327e017a Removed unnecessary Windows Operations from MtApi5 code (MT5) 2018-03-27 11:11:33 +03:00
vdemydiuk 10a758bd93 Updated test application (MT5) to perform testing functions ChartIndicatorAdd, ChartIndicatorGet 2018-03-27 10:22:16 +03:00
vdemydiuk 4a9642b60c Issue #109: Fixed typo 'Magic' to 'Order' in MQL function JsonToMqlTradeRequest 2018-03-26 18:06:39 +03:00
vdemydiuk 6ba6496e46 Implemented functions ChartIndicatorAdd and ChartIndicatorGet 2018-03-24 21:45:35 +02:00
vdemydiuk 1ffbba5ee3 Updated test application (MT5) to perform testing functions ChartNavigate, ChartIndicatorDelete, ChartIndicatorName, ChartIndicatorsTotal, ChartWindowOnDropped, ChartPriceOnDropped, ChartTimeOnDropped, ChartXOnDropped, ChartYOnDropped, ChartSetSymbolPeriod, ChartScreenShot 2018-03-24 19:08:40 +02:00
vdemydiuk 8cdfd6fb91 Updated test application (MT5) to perform testing function ChartGetDouble and ChartGetInteger 2018-03-19 19:10:51 +02:00
vdemydiuk 7c3ddbabac Updated test application (MT5) to perform testing function ChartSetInteger and ChartSetString 2018-03-19 18:58:12 +02:00
vdemydiuk 83e0145a3a Updated test application (MT5) to perform testing function ChartPeriod and ChartSetDouble 2018-03-19 18:39:15 +02:00
vdemydiuk f17c7cd554 Updated test application (MT5) to perform testing function ChartWindowFind and ChartClose 2018-03-19 17:23:16 +02:00
vdemydiuk 4aefdd554b Updated test application (MT5) to perform testing function ChartId and ChartRedraw 2018-03-19 16:23:55 +02:00
vdemydiuk 820ed9a631 Refactored UI test client (MT5) 2018-03-19 15:10:09 +02:00
vdemydiuk 95c55e90be Added field ExpertHandle into class Mt5Quote 2018-03-19 15:09:02 +02:00
vdemydiuk 486a1979a6 Implemented functions ChartIndicatorName, ChartIndicatorsTotal, ChartWindowOnDropped, ChartPriceOnDropped, ChartTimeOnDropped, ChartXOnDropped, ChartYOnDropped, ChartSetSymbolPeriod, ChartScreenShot (MT5) 2018-03-15 17:44:53 +02:00
vdemydiuk faef5f7d18 Implemented function ChartIndicatorDelete (MT5) 2018-03-15 13:15:50 +02:00
vdemydiuk bd45c45fa1 Implemented function ChartNavigate (MT5) 2018-03-15 12:55:46 +02:00
vdemydiuk 29be184136 Implemented functions ChartGetDouble, ChartGetInteger (MT5) 2018-03-15 11:20:20 +02:00
vdemydiuk 9bfda95cf7 Implemented functions ChartSetDouble, ChartSetInteger, ChartSetString (MT5) 2018-03-14 19:53:53 +02:00
vdemydiuk 24b881d8a0 Implemented function ChartPeriod (MT5) 2018-03-14 19:16:29 +02:00
vdemydiuk 07dd83f890 Implemented functions ChartId, ChartRedraw, ChartWindowFind, ChartClose (MT5) 2018-03-14 18:10:44 +02:00
vdemydiuk 9afd30e463 Implemented function Alert (MT5) 2018-03-13 18:24:40 +02:00
vdemydiuk 16f454ca61 Implemented functions ChartTimePriceToXY, ChartXYToTimePrice (MT5) 2018-03-13 17:28:21 +02:00
vdemydiuk f3a3a582fd Issue #100: update test application for testing function SymbolInfoString (MT5) 2018-03-13 11:40:16 +02:00
vdemydiuk 93aaae86ed Issue #100: implemented second function SymbolInfoString (MT5) 2018-03-13 11:20:55 +02:00
Vyacheslav Demidyuk bce68fd168 Merge pull request #104 from Janderson/master
TerminalInfo Commands and ChartTemplate Commands
2018-03-13 10:54:16 +02:00
Janderson 0812229538 Chart Commands:
- ChartSaveTemplate Implemented
2018-03-12 23:08:04 -03:00
Janderson d0fa4af1d0 - Bug fix - when click in chartApplyTemplateButton, store template file in right place 2018-03-12 22:44:08 -03:00
Janderson 8eb4bcfabe Commands to handle with Terminal:
- TerminalInfoDoublePropertyId
- TerminalInfoIntegerPropertyId
- TerminalInfoStringPropertyId
2018-03-12 22:37:06 -03:00
Vyacheslav Demidyuk 9ea58354be Merge pull request #103 from Janderson/master
Missing function to mql5
2018-03-12 16:49:21 +02:00
Janderson FFerreira 02774d7328 Merge branch 'mt5_1_0_18' into master 2018-03-12 11:34:00 -03:00
Janderson FFerreira cbff71f8d0 - Correction of Test Client
- Missing codes in mtapi5.mq5
2018-03-12 11:17:12 -03:00
Janderson FFerreira 951a91976c - missing mql5 file 2018-03-11 19:56:28 -03:00
Janderson FFerreira 6a37826486 - Add some commands to handle with Chart to MT5 api
- Add some commands to handle with windows to MT5 api
2018-03-11 19:26:25 -03:00
vdemydiuk cab2de6d24 Issue #100: implemented functions GetLastError, ResetLastError() in MtApi (MT5) 2018-03-09 19:18:54 +02:00
vdemydiuk ec6c71607b Issue #96: Implemented function PositionGetTicket in MtApi (MT5) 2018-03-08 17:45:22 +02:00
vdemydiuk 0a39b69b15 Issue #95: Added default constructors to classes MqlBookInfo, MqlTradeCheckResult 2018-03-08 16:22:37 +02:00
vdemydiuk fe94ec21de Issue #102: fixed long type of result in function SeriesInfoInteger 2018-03-08 15:31:02 +02:00
vdemydiuk 34c78c73c0 Started version 1.0.18 (MT5) 2018-03-08 15:26:29 +02:00
vdemydiuk d7b8ef894c Issue #93: Fixed typo Cction (Action) in MtApi5.mq5 2018-03-02 13:22:40 +02:00
vdemydiuk 7f33cebce1 MtApi5: Set version 1.0.17 2018-03-02 12:21:54 +02:00
vdemydiuk 84740787d5 Issue #94: Added event handler OnBookEvent (MT5). 2018-03-02 11:43:03 +02:00
vdemydiuk ad6bad5187 Issue #93: Added event OnTradeTransaction. Udpated json.mqh to fix JSONNumber for correct serialization zero integer value". 2018-03-01 11:20:25 +02:00
vdemydiuk 0086b02bc8 Issue #92: Updated test application (MT5) to use functions IndicatorCreate and IndicatorRelease 2018-02-27 18:26:37 +02:00
vdemydiuk f7e06c1570 Issue #92: Added functions IndicatorCreate and IndicatorRelease 2018-02-27 09:49:26 +02:00
vdemydiuk c86a3a3752 Issue #91: Added MarketBookGetRequest to perform function MarketBookGet (MT5) 2018-02-21 14:43:25 +02:00
vdemydiuk be8a17c0fd Issue #88: Activate execute commands in tester mode (MT5) 2018-02-19 19:21:29 +02:00
vdemydiuk 5c6751de9b Issue #90: Added time functions: TimeCurrent, TimeTradeServer, TimeLocal, TimeGMT 2018-02-19 18:48:31 +02:00
vdemydiuk 83776f8b7a Minor refactoring to remote redundant code 2018-02-19 17:12:26 +02:00
vdemydiuk f1c1df1e00 Issue #89: Changed function OrderCheck to use json request/response 2018-02-19 17:02:19 +02:00
vdemydiuk d6640300f5 Issue #89: Changed function PositionOpen to use json request/response 2018-02-19 15:54:03 +02:00
vdemydiuk c9c188f697 Minor refactoring to remove code syle warnings 2018-02-19 13:37:43 +02:00
vdemydiuk 3a4f561836 Issue #87: Added event QuoteUpdate to MtApi5Client (MT5) for compatibility with MATLAB 2018-02-19 11:49:52 +02:00
vdemydiuk bdb30edee3 Issue #82: Responsed moved to Request folder 2018-02-19 11:27:07 +02:00
vdemydiuk 29f501b055 Issue #82: Refactored request responses (MtAp5). Added iCustom functions with string and boolean parameters. Added button iCustom in test application (MT5). 2018-02-19 11:07:37 +02:00
vdemydiuk 521d7ea2c0 Issue #82: Disabled debug mode in MtApi5.ex5. Updated test client to send order with values Expiration and Comment 2018-02-18 20:24:27 +02:00
DW 0e5bb40a6f Issue #82: Refactored MQL5 expert to use json in function OrderSend 2018-02-17 00:10:10 +02:00
vdemydiuk 14079dc3c1 Issue #82: Added stub class OrderSendRequest 2018-02-15 20:32:22 +02:00
vdemydiuk 3600a86971 MtApiService version 1.0.29. Added log wrapper class MtLog 2018-02-15 17:37:08 +02:00
vdemydiuk 83e62fbff7 Started version 1.0.16 (MT5) 2018-02-15 17:33:02 +02:00
vdemydiuk 5c96aeb2fd Issue #81: Added function TimeGMT into MtApi (MT4) 2018-02-13 19:02:08 +02:00
vdemydiuk a238e5eb36 Issue #80: Fixed wrong condition on fetch first parameter in function Execute_TerminalInfoString 2018-02-13 18:35:40 +02:00
vdemydiuk 11fd5b7527 Started version 1.0.40 (MT4) 2018-02-13 18:33:11 +02:00
vdemydiuk cbe75cfbf6 Issue #83: Added command button HistoryDealMethods to check functions related to the issue 2018-02-08 18:04:15 +02:00
vdemydiuk 9581431a9f Issue #84: Fixed bug in function HistoryOrderGetInteger, there was wrong return value type 2018-02-04 14:39:09 +02:00
vdemydiuk acf0c12531 MT5: started version 1.0.15 2018-02-04 14:02:41 +02:00
DW 1eccda9b2c Version MtApi4 1.0.39 2018-01-16 16:11:33 +02:00
DW fd4aac7c32 Issie #73: added wrapped function getBooleanValueW into MtApi.mq4. Issue #76: added precompiled value __DEBUG_LOG__ into MtApi.mq4 to disable logging in release verion 2018-01-16 16:06:21 +02:00
DW 36c90c8481 Updated test application (MT5): added test functions HistoryDealGetDouble, HistoryDealGetInteger, HistoryDealGetString 2018-01-11 15:28:57 +02:00
DW fefa451371 Issue #39: Added indicator functions on MQL side (MtApi MT5) 2018-01-10 19:13:31 +02:00
DW 1c57f88cb1 Issue #72: Fixed bug with serialization of parameters in functions HistoryDealGetInteger, HistoryDealGetString, HistoryDealGetDouble 2017-11-27 18:16:35 +02:00
DW 08ba45c65f Issue #39: Added indicator functions on C# side (MtApi MT5) 2017-11-27 18:09:54 +02:00
DW b8314e9ed7 MtApi5: add waiting incoming connection on MT5 side in backtesting mode 2017-11-15 18:16:23 +02:00
DW 9587b10c8c MtApi5 version 1.0.14 2017-11-15 18:15:34 +02:00
DW b838084ba2 Issue #14: Updated test application for using function PositionOpen with MqlTradeResult 2017-09-29 19:05:06 +03:00
DW cd24891022 Issue #14: Added function PositionOpen which returns MqlTradeResult 2017-09-29 18:27:36 +03:00
DW add69a4c03 Issue #41: Complete object functions on MQL side 2017-09-29 17:39:18 +03:00
DW 5a3407e47c Issue #41: Refactored MtApi5.mq5 - removed unnecessary variables 2017-09-29 15:48:46 +03:00
DW ce8cfbbb70 Issue #41: Refactored MtApi5.mq5 2017-09-29 15:34:35 +03:00
DW 8470bbd5cc Issue #41: Complete object functions in client side (MT5) 2017-09-27 18:36:26 +03:00
DW 5c7ae748a5 Issue #41: Added Object Properties enums: ENUM_OBJECT_PROPERTY_INTEGER, ENUM_OBJECT_PROPERTY_STRING, ENUM_BORDER_TYPE, ENUM_ALIGN_MODE 2017-09-27 17:45:09 +03:00
DW 7abb4d3b5e Issue #41: Partialy implemented object functions on client side 2017-09-27 15:38:54 +03:00
DW 486c42685a Issue #41: Added Object Types enum 2017-09-26 18:37:50 +03:00
DW f41ab37b6f Set version 1.0.13 of MtApi (MT5) 2017-09-26 17:27:06 +03:00
Vyacheslav Demidyuk 9e129fb6e2 Merge pull request #64 from Tr4Dr/master
Fixes for the OrderSend function [MT5]
2017-09-25 12:41:35 +03:00
Tr4Dr f7b00a8d88 Added null check to convertSystemString [MT5]
Whithout this fix, the OrderSend method crashing if we doesn't set the "request.Comment" property.
2017-09-18 14:55:03 +02:00
Tr4Dr a7cb14de25 Updated MqlTradeRequest [MT5] 2017-09-18 02:05:22 +02:00
Tr4Dr f50925c8d3 Changed wcslen to wcsnlen [MT5]
Maximum character length set to 1000 based on preinit() MQL5 function. This value must be kept synchronized with MQL side.
2017-09-17 22:35:26 +02:00
Tr4Dr e29a11de68 Changed type of '\0' literal to wchar_t [MT5] 2017-09-17 22:19:09 +02:00
Tr4Dr 12141775f3 Fixed type casting to __int64 [MT5]
long long type should be an alternative.
2017-09-17 22:05:56 +02:00
Tr4Dr b6d24b8aa9 Merge pull request #2 from vdemydiuk/master
Update from original
2017-09-16 22:01:19 +02:00
DW 7175fae18c Fixed WIX error: ICE Internal Error 100. API Returned: 1615. 2017-09-08 17:07:53 +03:00
DW 3c4d8d52ca Revert version mtapi (MT5) to 1.0.12 2017-09-08 16:30:39 +03:00
DW 6873363d41 Fixed build of MT5 test client 2017-09-08 16:07:41 +03:00
DW 947599327a MtApi5 version 1.0.13 2017-09-08 13:05:01 +03:00
DW 5645902a48 Merge branch 'master' into mt5_1_0_13 2017-09-08 12:45:31 +03:00
DW c82787473f Issue #16: Added Mt5Expert into MTApiService. Refactored MT5Connector 2017-09-08 12:44:14 +03:00
Vyacheslav Demidyuk c213fb709a Merge pull request #62 from Tr4Dr/master
Fixed the type of Deviation property in MqlTradeRequest (MT5)
2017-09-08 12:38:29 +03:00
Tr4Dr 2ac29dc871 Fixed the type of Deviation property in MqlTradeRequest (MT5) 2017-09-07 20:08:01 +02:00
DW 1f72b2b790 Refactored MTApiService and connectors projects 2017-09-07 17:46:25 +03:00
Vyacheslav Demidyuk 3a62ff56d7 Merge pull request #61 from Tr4Dr/master
Updated PositionClose function and a fixed warning (MT5)
2017-09-07 12:23:34 +03:00
Unknown d25fe529b4 Fixed warning in function CreateErrorResponse (MT5)
Declaration of 'message' hides global declaration in MtApi5.mq5
2017-09-07 00:21:12 +02:00
Unknown 15538e81f4 Updated PositionClose function (MT5)
Type of the ticket argument changed to ulong, added optional argument: deviation
2017-09-07 00:06:59 +02:00
Tr4Dr a33be3c764 Merge pull request #1 from vdemydiuk/master
Bringing fork up to date
2017-09-06 23:48:13 +02:00
DW 023fe8c7c9 Disable code to print event payload in MQL code (MT4) 2017-09-06 11:47:45 +03:00
DW b77516e324 Issue #59: Added event OnChartEvent into MtApi (MT4) 2017-09-05 18:34:26 +03:00
DW 4b48423c3f Issue #57: Added function PositionSelectByTicket into MQL code 2017-09-04 13:08:30 +03:00
DW 9800177b08 Issue #57: Added function PositionSelectByTicket into C# code 2017-08-29 17:40:23 +03:00
Vyacheslav Demidyuk a33d4a4594 Merge pull request #58 from Tr4Dr/master
Refactored and updated enumerations
2017-08-28 13:56:44 +03:00
Unknown 29722f362d Added Position and PositionBy properties to MqlTradeRequest 2017-08-25 15:32:24 +02:00
Unknown e072343fe1 Missing break after PositionGetSymbol 2017-08-25 15:12:41 +02:00
Unknown acb0c20ca8 Missing break after PositionGetDouble 2017-08-25 15:00:24 +02:00
Unknown 83543fee88 Refactored and updated enumerations 2017-08-25 01:31:57 +02:00
DW 3ce6b042de Added files into MtApi.proj 2017-08-21 15:56:21 +03:00
DW 9dd770e768 Fixed small errors in MQL part of chart operations 2017-08-21 15:42:10 +03:00
DW abb8b8afaa Added enums for chart properties. Fixed some mistakes in C# code of Chart Operations 2017-08-21 13:57:38 +03:00
DW 1d6569caa8 Issue #53: Complete add chart operation functions in expert (MQL part) 2017-08-18 18:56:00 +03:00
DW 441a3cb8de Merge with branch auth 2017-08-15 16:42:51 +03:00
DW 443f5c982c Issue #53: Complete chart operation functions into MtApi (client side) 2017-08-15 14:34:41 +03:00
DW 515a12ab15 Added function ChangeAccount 2017-08-12 01:31:36 +03:00
DW 84b00b605a Issue #53: Added some chart operation functions into MtApi (client side) 2017-08-11 23:33:30 +03:00
DW 10e267d031 Fixed bug in function iBarShift 2017-07-20 17:55:29 +03:00
DW abcd489367 Started version 1.0.37 2017-06-21 17:41:10 +03:00
DW d630e61e3c Issue #52: Updated functions OrderSend to use request stucture 2017-05-11 17:26:46 +03:00
DW 280bab7faf Started version 1.0.36 2017-05-11 10:44:30 +03:00
DW 26d270422b Revert version mtapi (MT4) to 1.0.35 2017-05-06 23:34:30 +03:00
DW 9cd2e3b18f Updated test application: added button on function UnlockTicks 2017-05-05 15:51:34 +03:00
DW 50013c0c29 Added command to UnlockTick in backtesting mode that will be locked on each candle. It allows to perform big tasks and send commands to MT4 in time of candle. 2017-05-05 14:16:15 +03:00
DW ca49d23017 Started version 1.0.36 2017-05-05 14:01:29 +03:00
DW 0346836d35 Issue #51: Add support localhost (127.0.0.1) host name 2017-05-05 13:57:43 +03:00
DW 2cc41df01a MtApi (MT4) version 1.0.34. Fixed issue #45 in MtApi.ex4 2017-02-22 17:17:00 +02:00
DW f05ade2cbf Set AppendToFile to True in LogConfigurator 2017-01-12 16:47:41 +02:00
DW d34524d77f Issue #44: Fixed MT5Connector project for using MtAdapter 2017-01-08 14:47:08 +02:00
DW d06cc67a5d MtApi MT5: started version 1.0.12 2017-01-08 14:45:03 +02:00
DW 5b76bf0547 Merge master fixed conflict. 2017-01-05 21:36:55 +02:00
DW 1c269f7339 Issue #32: Added function ObjectName into test client 2017-01-05 02:14:13 +02:00
DW 21fb790d8c Issue #32: Fixed small bugs in EA MtApi.mq4 2017-01-05 01:02:55 +02:00
DW 7c9a0aa8cc Issue #32: Implement object functions in EA MtApi.mq4 2017-01-03 21:29:41 +02:00
DW 18ddf3df1c Issue #32: Added c# implementations of most object functions in MtApi client 2016-12-30 17:16:48 +02:00
DW a8832b79ba Issue #32: Added function ObjectCreate in MtApi (MT4) 2016-12-27 17:41:11 +02:00
vdemydiuk 39146d68b2 Starting work on Object Functions 2016-12-26 17:49:06 +02:00
DW 5b03f01e9b Clear unnecessary witespaces in MtApi.mq4 2016-12-21 14:26:37 +02:00
vdemydiuk 8f5a1c8222 Refactored MtApi.mq4 2016-12-21 12:01:15 +02:00
vdemydiuk f5f13a13cc Issue #32: Added function ChartRedraw 2016-12-12 17:29:52 +02:00
vdemydiuk 9ef970cf1e Refactoring TestApiUiClient (Account Information tab) 2016-11-30 10:57:33 +02:00
vdemydiuk b5878ccb62 Refactoring TestApiUiClient (Check Status tab) 2016-11-29 19:08:53 +02:00
DW 4a7bb6f2cb MtApi (MT5) ver. 1.0.11.1 HotFix 2016-11-29 10:20:55 +02:00
vdemydiuk 5abfeebc90 Issue #32: Added function ChartId 2016-11-28 16:03:40 +02:00
vdemydiuk e333164552 Issue #32: Added ExecutorHandle property to determine which expert will be used for execution command 2016-11-28 14:45:33 +02:00
vdemydiuk 9a6968f618 Refactoring MtApi 2016-11-26 19:27:09 +02:00
DW 88e2d22abe Issue #38: Removed MemoryAppender in LogConfigurator (MtApiService) 2016-11-23 13:09:47 +02:00
DW fcfd741e5b Issue #37: Used ConcurrencyMode.Multiple for server and client side to avoid deadlocks and freezes of MtApiService 2016-11-23 10:51:50 +02:00
DW c722511c03 Refactored MtApiService (ver. 1.0.24): Added ExpertHandle to MtQuote and MtEvent. Added event QuoteUpdate to MtApiClient. 2016-11-18 15:47:55 +02:00
DW 39599436ab Started version 1.0.33 of MtApi MT4 2016-11-18 12:13:00 +02:00
120 changed files with 15235 additions and 4256 deletions
+1 -3
View File
@@ -35,6 +35,4 @@ using namespace System::Security::Permissions;
[assembly:ComVisible(false)];
[assembly:CLSCompliantAttribute(true)];
[assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)];
[assembly:CLSCompliantAttribute(true)];
+157 -344
View File
@@ -6,14 +6,15 @@
#include "MT5Handler.h"
#include "Windows.h"
#include < vcclr.h >
#include <vcclr.h>
#include <functional>
using namespace System;
using namespace MTApiService;
using namespace System::Runtime::InteropServices;
using namespace System::Reflection;
using namespace System::Text;
using namespace System::Collections::Generic;
using namespace System::Collections::Generic;
using namespace System::Diagnostics;
using namespace System::Security::Cryptography;
using namespace System::Security;
@@ -50,277 +51,162 @@ public struct CMqlBookInfo
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';
if (src != nullptr) {
pin_ptr<const wchar_t> wch = PtrToStringChars(src);
memcpy(dest, wch, wcsnlen(wch, 1000) * sizeof(wchar_t));
dest[wcsnlen(wch, 1000)] = L'\0';
}
else
{
dest[0] = L'\0';
}
}
bool VerifySignature(System::String^ inputData, System::String^ signature, System::String^ publicKey)
{
bool verifyResult = false;
#define _DLLAPI extern "C" __declspec(dllexport)
template <typename T> T Execute(std::function<T()> func, wchar_t* err, T default_value)
{
T result = default_value;
try
{
DSACryptoServiceProvider^ dsa = gcnew DSACryptoServiceProvider();
dsa->FromXmlString(publicKey);
array<System::Byte>^ data = UTF8Encoding::ASCII->GetBytes(inputData);
array<System::Byte>^ signatureData = Convert::FromBase64String(signature);
verifyResult = dsa->VerifyData(data, signatureData);
}
catch(Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:VerifySignature(): failed. " + e->Message);
verifyResult = false;
}
return verifyResult;
}
bool g_IsVerified = true;
void _stdcall verify(int isDemo, wchar_t* accountName, long accountNumber)
{
if (isDemo != 0)
{
g_IsVerified = true;
return;
}
System::String^ signature = MtRegistryManager::ReadSignatureKey(gcnew String(accountName), accountNumber.ToString());
Resources::ResourceManager^ rm = gcnew Resources::ResourceManager(L"MT5Connector.cl", Assembly::GetExecutingAssembly());
System::String^ inputData = gcnew System::String(accountName);
inputData += accountNumber.ToString();
System::String^ publicKey = rm->GetString(L"cl");
g_IsVerified = VerifySignature(inputData, gcnew System::String(signature), publicKey);
}
int _stdcall initExpert(int expertHandle, int port, wchar_t* symbol, double bid, double ask, wchar_t* err)
{
if (g_IsVerified == false)
{
System::String^ errorVerified = "Verification is failed!\nPlease contact with support.";
convertSystemString(err, errorVerified);
Debug::WriteLine("[ERROR] MT5Connector:initExpert(): not verified");
return 0;
}
try
{
MT5Handler^ mtHander = gcnew MT5Handler();
MtServerInstance::GetInstance()->InitExpert(expertHandle, port, gcnew String(symbol), bid, ask, mtHander);
result = func();
}
catch (Exception^ e)
{
convertSystemString(err, e->Message);
Debug::WriteLine("[ERROR] MT5Connector:initExpert(): " + e->Message);
return 0;
}
return 1;
return result;
}
int _stdcall deinitExpert(int expertHandle, wchar_t* err)
_DLLAPI int _stdcall initExpert(int expertHandle, int port, wchar_t* symbol, double bid, double ask, int isTestMode, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->DeinitExpert(expertHandle);
}
catch (Exception^ e)
{
convertSystemString(err, e->Message);
Debug::WriteLine("[ERROR] MT5Connector:deinitExpert(): " + e->Message);
return 0;
}
return 1;
return Execute<int>([&expertHandle, &port, symbol, &bid, &ask, &isTestMode]() {
bool isTesting = (isTestMode != 0) ? true : false;
auto expert = gcnew Mt5Expert(expertHandle, gcnew String(symbol), bid, ask, gcnew MT5Handler(), isTesting);
MtAdapter::GetInstance()->AddExpert(port, expert);
return 1;
}, err, 0);
}
int _stdcall updateQuote(int expertHandle, wchar_t* symbol, double bid, double ask, wchar_t* err)
_DLLAPI int _stdcall deinitExpert(int expertHandle, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->SendQuote(expertHandle, gcnew String(symbol), bid, ask);
}
catch (Exception^ e)
{
convertSystemString(err, e->Message);
Debug::WriteLine("[ERROR] MT5Connector:updateQuote(): " + e->Message);
return 0;
}
return 1;
return Execute<int>([&expertHandle]() {
MtAdapter::GetInstance()->RemoveExpert(expertHandle);
return 1;
}, err, 0);
}
int _stdcall sendIntResponse(int expertHandle, int response)
_DLLAPI int _stdcall updateQuote(int expertHandle, wchar_t* symbol, double bid, double ask, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseInt(response));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:sendIntResponse(): " + e->Message);
return 0;
}
return 1;
return Execute<int>([&expertHandle, symbol, &bid, &ask]() {
MtAdapter::GetInstance()->SendQuote(expertHandle, gcnew String(symbol), bid, ask);
return 1;
}, err, 0);
}
int _stdcall sendLongResponse(int expertHandle, __int64 response)
_DLLAPI bool _stdcall sendEvent(int expertHandle, int eventType, wchar_t* payload, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLong(response));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:sendLongResponse(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, &eventType, payload]() {
MtAdapter::GetInstance()->SendEvent(expertHandle, eventType, gcnew String(payload));
return true;
}, err, false);
}
int _stdcall sendULongResponse(int expertHandle, unsigned __int64 response)
_DLLAPI int _stdcall sendIntResponse(int expertHandle, int response, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseULong(response));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:sendLongResponse(): " + e->Message);
return 0;
}
return 1;
return Execute<int>([&expertHandle, &response]() {
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseInt(response));
return 1;
}, err, 0);
}
int _stdcall sendBooleanResponse(int expertHandle, int response)
_DLLAPI int _stdcall sendLongResponse(int expertHandle, __int64 response, wchar_t* err)
{
try
{
return Execute<int>([&expertHandle, &response]() {
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLong(response));
return 1;
}, err, 0);
}
_DLLAPI int _stdcall sendULongResponse(int expertHandle, unsigned __int64 response, wchar_t* err)
{
return Execute<int>([&expertHandle, &response]() {
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseULong(response));
return 1;
}, err, 0);
}
_DLLAPI int _stdcall sendBooleanResponse(int expertHandle, int response, wchar_t* err)
{
return Execute<int>([&expertHandle, &response]() {
bool value = (response != 0) ? true : false;
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseBool(value));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:sendBooleanResponse(): " + e->Message);
return 0;
}
return 1;
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseBool(value));
return 1;
}, err, 0);
}
int _stdcall sendDoubleResponse(int expertHandle, double response)
_DLLAPI int _stdcall sendDoubleResponse(int expertHandle, double response, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDouble(response));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:sendDoubleResponse(): " + e->Message);
return 0;
}
return 1;
return Execute<int>([&expertHandle, &response]() {
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDouble(response));
return 1;
}, err, 0);
}
int _stdcall sendStringResponse(int expertHandle, wchar_t* response)
_DLLAPI int _stdcall sendStringResponse(int expertHandle, wchar_t* response, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseString(gcnew String(response)));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:sendStringResponse(): " + e->Message);
return 0;
}
return 1;
return Execute<int>([&expertHandle, response]() {
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseString(gcnew String(response)));
return 1;
}, err, 0);
}
int _stdcall sendVoidResponse(int expertHandle)
_DLLAPI int _stdcall sendVoidResponse(int expertHandle, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, nullptr);
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:sendVoidResponse(): " + e->Message);
return 0;
}
return 1;
return Execute<int>([&expertHandle]() {
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseObject(nullptr));
return 1;
}, err, 0);
}
int _stdcall sendDoubleArrayResponse(int expertHandle, double* values, int size)
_DLLAPI int _stdcall sendDoubleArrayResponse(int expertHandle, double* values, int size, wchar_t* err)
{
try
{
return Execute<int>([&expertHandle, values, &size]() {
array<double>^ list = gcnew array<double>(size);
for(int i = 0; i < size; i++)
{
for (int i = 0; i < size; i++)
list[i] = values[i];
}
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDoubleArray(list));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:sendDoubleArrayResponse(): " + e->Message);
return 0;
}
return 1;
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDoubleArray(list));
return 1;
}, err, 0);
}
int _stdcall sendIntArrayResponse(int expertHandle, int* values, int size)
_DLLAPI int _stdcall sendIntArrayResponse(int expertHandle, int* values, int size, wchar_t* err)
{
try
{
return Execute<int>([&expertHandle, values, &size]() {
array<int>^ list = gcnew array<int>(size);
for(int i = 0; i < size; i++)
{
for (int i = 0; i < size; i++)
list[i] = values[i];
}
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseIntArray(list));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:sendIntArrayResponse(): " + e->Message);
return 0;
}
return 1;
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseIntArray(list));
return 1;
}, err, 0);
}
int _stdcall sendLongArrayResponse(int expertHandle, __int64* values, int size)
_DLLAPI int _stdcall sendLongArrayResponse(int expertHandle, __int64* values, int size, wchar_t* err)
{
try
{
return Execute<int>([&expertHandle, values, &size]() {
array<System::Int64>^ list = gcnew array<System::Int64>(size);
for(int i = 0; i < size; i++)
{
for (int i = 0; i < size; i++)
list[i] = values[i];
}
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLongArray(list));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:sendLongArrayResponse(): " + e->Message);
return 0;
}
return 1;
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLongArray(list));
return 1;
}, err, 0);
}
int _stdcall sendMqlRatesArrayResponse(int expertHandle, CMqlRates values[], int size)
_DLLAPI int _stdcall sendMqlRatesArrayResponse(int expertHandle, CMqlRates values[], int size, wchar_t* err)
{
try
{
return Execute<int>([&expertHandle, values, &size]() {
array<MtMqlRates^>^ list = gcnew array<MtMqlRates^>(size);
for(int i = 0; i < size; i++)
for (int i = 0; i < size; i++)
{
MtMqlRates^ rates = gcnew MtMqlRates();
rates->time = values[i].time;
@@ -331,180 +217,107 @@ int _stdcall sendMqlRatesArrayResponse(int expertHandle, CMqlRates values[], int
rates->tick_volume = values[i].tick_volume;
rates->spread = values[i].spread;
rates->real_volume = values[i].real_volume;
list[i] = rates;
}
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlRatesArray(list));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:sendMqlRatesArrayResponse(): " + e->Message);
return 0;
}
return 1;
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlRatesArray(list));
return 1;
}, err, 0);
}
int _stdcall sendMqlTickResponse(int expertHandle, CMqlTick* response, int size)
_DLLAPI int _stdcall sendMqlTickResponse(int expertHandle, CMqlTick* response, wchar_t* err)
{
try
{
return Execute<int>([&expertHandle, response]() {
MtMqlTick^ mtResponse = gcnew MtMqlTick();
mtResponse->time = response->time;
mtResponse->bid = response->bid;
mtResponse->ask = response->ask;
mtResponse->last = response->last;
mtResponse->volume = response->volume;
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlTick(mtResponse));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:sendMqlTickResponse(): " + e->Message);
return 0;
}
return 1;
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlTick(mtResponse));
return 1;
}, err, 0);
}
int _stdcall sendMqlBookInfoArrayResponse(int expertHandle, CMqlBookInfo values[], int size)
_DLLAPI int _stdcall sendMqlBookInfoArrayResponse(int expertHandle, CMqlBookInfo values[], int size, wchar_t* err)
{
try
{
return Execute<int>([&expertHandle, values, &size]() {
array<MtMqlBookInfo^>^ list = gcnew array<MtMqlBookInfo^>(size);
for(int i = 0; i < size; i++)
for (int i = 0; i < size; i++)
{
MtMqlBookInfo^ info = gcnew MtMqlBookInfo();
info->type = values[i].type;
info->price = values[i].price;
info->volume = values[i].volume;
list[i] = info;
}
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlBookInfoArray(list));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:sendMqlRatesArrayResponse(): " + e->Message);
return 0;
}
return 1;
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlBookInfoArray(list));
return 1;
}, err, 0);
}
//----------- get values -------------------------------
int _stdcall getCommandType(int expertHandle, int* res)
_DLLAPI int _stdcall getCommandType(int expertHandle, int* res, wchar_t* err)
{
try
{
*res = MtServerInstance::GetInstance()->GetCommandType(expertHandle);
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:getCommandType(): " + e->Message);
return 0;
}
return 1;
return Execute<int>([&expertHandle, res]() {
*res = MtAdapter::GetInstance()->GetCommandType(expertHandle);
return 1;
}, err, 0);
}
int _stdcall getIntValue(int expertHandle, int paramIndex, int* res)
_DLLAPI int _stdcall getIntValue(int expertHandle, int paramIndex, int* res, wchar_t* err)
{
try
{
*res = (int)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:getIntValue(): " + e->Message);
return 0;
}
return 1;
return Execute<int>([&expertHandle, &paramIndex, res]() {
*res = (int)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
return 1;
}, err, 0);
}
int _stdcall getDoubleValue(int expertHandle, int paramIndex, double* res)
_DLLAPI int _stdcall getDoubleValue(int expertHandle, int paramIndex, double* res, wchar_t* err)
{
try
{
*res = (double)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:getDoubleValue(): " + e->Message);
return 0;
}
return 1;
return Execute<int>([&expertHandle, &paramIndex, res]() {
*res = (double)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
return 1;
}, err, 0);
}
int _stdcall getStringValue(int expertHandle, int paramIndex, wchar_t* res)
_DLLAPI int _stdcall getStringValue(int expertHandle, int paramIndex, wchar_t* res, wchar_t* err)
{
try
{
convertSystemString(res, (String^)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:getStringValue(): " + e->Message);
return 0;
}
return 1;
return Execute<int>([&expertHandle, &paramIndex, res]() {
convertSystemString(res, (String^)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex));
return 1;
}, err, 0);
}
int _stdcall getULongValue(int expertHandle, int paramIndex, unsigned __int64* res)
_DLLAPI int _stdcall getULongValue(int expertHandle, int paramIndex, unsigned __int64* res, wchar_t* err)
{
try
{
*res = (unsigned long)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:getULongValue(): " + e->Message);
return 0;
}
return 1;
return Execute<int>([&expertHandle, &paramIndex, res]() {
*res = (unsigned __int64)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
return 1;
}, err, 0);
}
int _stdcall getLongValue(int expertHandle, int paramIndex, __int64* res)
_DLLAPI int _stdcall getLongValue(int expertHandle, int paramIndex, __int64* res, wchar_t* err)
{
try
{
*res = (long)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:getLongValue(): " + e->Message);
return 0;
}
return 1;
return Execute<int>([&expertHandle, &paramIndex, res]() {
*res = (__int64)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
return 1;
}, err, 0);
}
int _stdcall getBooleanValue(int expertHandle, int paramIndex, int* res)
_DLLAPI int _stdcall getBooleanValue(int expertHandle, int paramIndex, int* res, wchar_t* err)
{
try
{
bool val = (bool)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
return Execute<int>([&expertHandle, &paramIndex, res]() {
bool val = (bool)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
*res = val == true ? 1 : 0;
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:getBooleanValue(): " + e->Message);
return 0;
}
return 1;
return 1;
}, err, 0);
}
int _stdcall getUIntValue(int expertHandle, int paramIndex, unsigned int* res)
_DLLAPI int _stdcall getUIntValue(int expertHandle, int paramIndex, unsigned int* res, wchar_t* err)
{
try
{
*res = (unsigned int)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:getUIntValue(): " + e->Message);
return 0;
}
return 1;
}
return Execute<int>([&expertHandle, &paramIndex, res]() {
*res = (unsigned int)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
return 1;
}, err, 0);
}
-27
View File
@@ -1,27 +0,0 @@
LIBRARY MT5Connector
EXPORTS initExpert
deinitExpert
updateQuote
sendIntResponse
sendBooleanResponse
sendDoubleResponse
sendStringResponse
sendVoidResponse
sendDoubleArrayResponse
sendIntArrayResponse
sendLongArrayResponse
sendMqlRatesArrayResponse
sendLongResponse
sendULongResponse
sendMqlTickResponse
sendMqlBookInfoArrayResponse
getCommandType
getIntValue
getUIntValue
getDoubleValue
getStringValue
getLongValue
getULongValue
getBooleanValue
verify
-5
View File
@@ -95,7 +95,6 @@
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>user32.lib</AdditionalDependencies>
<ModuleDefinitionFile>.\MT5Connector.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -108,7 +107,6 @@
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>.\MT5Connector.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -120,7 +118,6 @@
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>.\MT5Connector.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -132,7 +129,6 @@
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>.\MT5Connector.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
@@ -157,7 +153,6 @@
</ItemGroup>
<ItemGroup>
<None Include="app.ico" />
<None Include="MT5Connector.def" />
<None Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
@@ -44,9 +44,6 @@
<None Include="app.ico">
<Filter>Resource Files</Filter>
</None>
<None Include="MT5Connector.def">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="app.rc">
+2 -3
View File
@@ -1,8 +1,7 @@
namespace MTApiService
{
public interface ICommandManager
internal interface ICommandManager
{
void EnqueueCommandTask(MtCommandTask task);
MtCommandTask DequeueCommandTask();
MtCommandTask SendCommand(MtCommand task);
}
}
+1 -6
View File
@@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MTApiService
namespace MTApiService
{
public interface IMetaTraderHandler
{
+9
View File
@@ -0,0 +1,9 @@
namespace MTApiService
{
internal interface ITaskExecutor
{
void Execute(MtCommandTask task);
int Handle { get; }
}
}
+53 -1
View File
@@ -8,6 +8,50 @@ using log4net.Repository.Hierarchy;
namespace MTApiService
{
public class MtLog
{
#region ctor
internal MtLog(Type type)
{
_log = LogManager.GetLogger(type);
}
#endregion
#region Public
public void Debug(object message)
{
_log.Debug(message);
}
public void Error(object message)
{
_log.Error(message);
}
public void Fatal(object message)
{
_log.Fatal(message);
}
public void Info(object message)
{
_log.Info(message);
}
public void Warn(object message)
{
_log.Warn(message);
}
#endregion
#region Private
private readonly ILog _log;
#endregion
}
public class LogConfigurator
{
private const string LogFileNameExtension = "txt";
@@ -29,7 +73,7 @@ namespace MTApiService
var roller = new RollingFileAppender
{
AppendToFile = false,
AppendToFile = true,
File = $@"{System.IO.Path.GetTempPath()}{profileName}\Logs\{filename}",
Layout = patternLayout,
PreserveLogFileNameExtension = true,
@@ -48,5 +92,13 @@ namespace MTApiService
#endif
hierarchy.Configured = true;
}
public static MtLog GetLogger(Type type)
{
if (type == null)
throw new ArgumentNullException(nameof(type));
return new MtLog(type);
}
}
}
+4 -2
View File
@@ -62,7 +62,9 @@
<ItemGroup>
<Compile Include="ICommandManager.cs" />
<Compile Include="IMetaTraderHandler.cs" />
<Compile Include="ITaskExecutor.cs" />
<Compile Include="LogConfigurator.cs" />
<Compile Include="Mt5Expert.cs" />
<Compile Include="MtCommandEventArgs.cs" />
<Compile Include="IDisposableChannel.cs" />
<Compile Include="IMtApiServer.cs" />
@@ -78,11 +80,11 @@
<Compile Include="MtConnectionProfile.cs" />
<Compile Include="MtExecutorManager.cs" />
<Compile Include="MtExpert.cs" />
<Compile Include="MtInstrument.cs" />
<Compile Include="MtQuote.cs" />
<Compile Include="MtResponse.cs" />
<Compile Include="MtServer.cs" />
<Compile Include="MtCommand.cs" />
<Compile Include="MtServerInstance.cs" />
<Compile Include="MtAdapter.cs" />
<Compile Include="MtService.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
+48
View File
@@ -0,0 +1,48 @@
using log4net;
namespace MTApiService
{
public class Mt5Expert : MtExpert
{
private static readonly ILog Log = LogManager.GetLogger(typeof(MtExpert));
private const int StopExpertInterval = 2000; // 2 sec for testing mode
private readonly System.Timers.Timer _stopTimer = new System.Timers.Timer();
public Mt5Expert(int handle, string symbol, double bid, double ask, IMetaTraderHandler mtHandler, bool isTestMode) :
base(handle, symbol, bid, ask, mtHandler)
{
IsTestMode = isTestMode;
_stopTimer.Interval = StopExpertInterval;
_stopTimer.Elapsed += _stopTimer_Elapsed;
}
public bool IsTestMode { get; }
public override void UpdateQuote(MtQuote quote)
{
Log.Debug("UpdateQuote: begin.");
base.UpdateQuote(quote);
if (IsTestMode)
{
//reset timer
_stopTimer.Stop();
_stopTimer.Start();
}
Log.Debug("UpdateQuote: end.");
}
private void _stopTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Log.Debug("_stopTimer_Elapsed: begin.");
Log.Warn("Mt5Expert has received new tick during 2 sec in testing mode. The possible cause: user has stopped the tester manually in MetaTrader 5.");
Deinit();
Log.Debug("_stopTimer_Elapsed: end.");
}
}
}
+64 -22
View File
@@ -4,13 +4,13 @@ using log4net;
namespace MTApiService
{
public class MtServerInstance
public class MtAdapter
{
#region Fields
private const string LogProfileName = "MtApiService";
private static readonly ILog Log = LogManager.GetLogger(typeof(MtServerInstance));
private static readonly MtServerInstance Instance = new MtServerInstance();
private static readonly ILog Log = LogManager.GetLogger(typeof(MtAdapter));
private static readonly MtAdapter Instance = new MtAdapter();
private readonly Dictionary<int, MtServer> _servers = new Dictionary<int, MtServer>();
private readonly Dictionary<int, MtExpert> _experts = new Dictionary<int, MtExpert>();
@@ -18,16 +18,16 @@ namespace MTApiService
#region Init Instance
private MtServerInstance()
private MtAdapter()
{
LogConfigurator.Setup(LogProfileName);
}
static MtServerInstance()
static MtAdapter()
{
}
public static MtServerInstance GetInstance()
public static MtAdapter GetInstance()
{
return Instance;
}
@@ -36,12 +36,12 @@ namespace MTApiService
#region Public Methods
public void InitExpert(int expertHandle, int port, string symbol, double bid, double ask, IMetaTraderHandler mtHandler)
public void AddExpert(int port, MtExpert expert)
{
if (mtHandler == null)
throw new ArgumentNullException(nameof(mtHandler));
if (expert == null)
throw new ArgumentNullException(nameof(expert));
Log.InfoFormat("InitExpert: begin. symbol = {0}, expertHandle = {1}, port = {2}", symbol, expertHandle, port);
Log.InfoFormat("AddExpert: begin. expert = {0}", expert);
MtServer server;
lock (_servers)
@@ -60,8 +60,6 @@ namespace MTApiService
}
}
var expert = new MtExpert(expertHandle, new MtQuote(symbol, bid, ask), mtHandler);
lock (_experts)
{
_experts[expert.Handle] = expert;
@@ -69,12 +67,12 @@ namespace MTApiService
server.AddExpert(expert);
Log.Info("InitExpert: end");
Log.Info("AddExpert: end");
}
public void DeinitExpert(int expertHandle)
public void RemoveExpert(int expertHandle)
{
Log.InfoFormat("DeinitExpert: begin. expertHandle = {0}", expertHandle);
Log.InfoFormat("RemoveExpert: begin. expertHandle = {0}", expertHandle);
MtExpert expert = null;
@@ -93,15 +91,15 @@ namespace MTApiService
}
else
{
Log.WarnFormat("DeinitExpert: expert with id {0} has not been found.", expertHandle);
Log.WarnFormat("RemoveExpert: expert with id {0} has not been found.", expertHandle);
}
Log.Info("DeinitExpert: end");
Log.Info("RemoveExpert: end");
}
public void SendQuote(int expertHandle, string symbol, double bid, double ask)
{
Log.DebugFormat("SendQuote: begin. symbol = {0}, bid = {1}, ask = {2}", symbol, bid, ask);
Log.DebugFormat("UpdateQuote: begin. symbol = {0}, bid = {1}, ask = {2}", symbol, bid, ask);
MtExpert expert;
lock (_experts)
@@ -111,14 +109,14 @@ namespace MTApiService
if (expert != null)
{
expert.Quote = new MtQuote(symbol, bid, ask);
expert.UpdateQuote(new MtQuote { Instrument = symbol, Bid = bid, Ask = ask, ExpertHandle = expertHandle });
}
else
{
Log.WarnFormat("SendQuote: expert with id {0} has not been found.", expertHandle);
Log.WarnFormat("UpdateQuote: expert with id {0} has not been found.", expertHandle);
}
Log.Debug("SendQuote: end");
Log.Debug("UpdateQuote: end");
}
public void SendEvent(int expertHandle, int eventType, string payload)
@@ -133,7 +131,7 @@ namespace MTApiService
if (expert != null)
{
expert.SendEvent(new MtEvent(eventType, payload));
expert.SendEvent(new MtEvent { EventType = eventType, Payload = payload, ExpertHandle = expertHandle });
}
else
{
@@ -208,6 +206,50 @@ namespace MTApiService
return retval;
}
public object GetNamedParameter(int expertHandle, string name)
{
Log.DebugFormat("GetNamedParameter: begin. expertHandle = {0}, name = {1}", expertHandle, name);
MtExpert expert;
lock (_experts)
{
expert = _experts[expertHandle];
}
if (expert == null)
{
Log.WarnFormat("GetNamedParameter: expert with id {0} has not been found.", expertHandle);
}
var retval = expert?.GetNamedParameter(name);
Log.DebugFormat("GetNamedParameter: end. retval = {0}", retval);
return retval;
}
public bool ContainsNamedParameter(int expertHandle, string name)
{
Log.DebugFormat("ContainsNamedParameter: begin. expertHandle = {0}, name = {1}", expertHandle, name);
MtExpert expert;
lock (_experts)
{
expert = _experts[expertHandle];
}
if (expert == null)
{
Log.WarnFormat("ContainsNamedParameter: expert with id {0} has not been found.", expertHandle);
}
bool retval = expert != null ? expert.ContainsNamedParameter(name) : false;
Log.DebugFormat("ContainsNamedParameter: end. retval = {0}", retval);
return retval;
}
#endregion
#region Private Methods
+1 -1
View File
@@ -11,13 +11,13 @@ namespace MTApiService
: base(callbackContext, binding, remoteAddress)
{
InnerDuplexChannel.Faulted += InnerDuplexChannel_Faulted;
InnerDuplexChannel.Open();
}
#region IMtApi Members
public bool Connect()
{
InnerDuplexChannel.Open();
return Channel.Connect();
}
+42 -90
View File
@@ -6,38 +6,33 @@ using log4net;
namespace MTApiService
{
[CallbackBehavior(UseSynchronizationContext = false)]
public class MtClient: IMtApiCallback, IDisposable
[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)]
public class MtClient : IMtApiCallback, IDisposable
{
private const string ServiceName = "MtApiService";
public delegate void MtQuoteHandler(MtQuote quote);
public delegate void MtEventHandler(MtEvent e);
#region Fields
private static readonly ILog Log = LogManager.GetLogger(typeof(MtClient));
private MtApiProxy _proxy;
private bool _isConnected;
private readonly MtApiProxy _proxy;
#endregion
#region Public Methods
public void Open(string host, int port)
#region ctor
public MtClient(string host, int port)
{
Log.DebugFormat("Open: begin. host = {0}, port = {1}", host, port);
if (string.IsNullOrEmpty(host))
throw new ArgumentNullException(nameof(host), "host is null or empty");
if (port < 0 || port > 65536)
throw new ArgumentOutOfRangeException(nameof(port), "port value is invalid");
var urlService = $"net.tcp://{host}:{port}/{ServiceName}";
Host = host;
Port = port;
if (_proxy != null)
{
Log.Warn("Open: end. _proxy is not null.");
return;
}
var urlService = $"net.tcp://{host}:{port}/{ServiceName}";
var bind = new NetTcpBinding(SecurityMode.None)
{
@@ -55,28 +50,19 @@ namespace MTApiService
MaxNameTableCharCount = 2147483647
}
};
// Commented next statement since it is not required
_proxy = new MtApiProxy(new InstanceContext(this), bind, new EndpointAddress(urlService));
_proxy.Faulted += ProxyFaulted;
Log.Debug("Open: end.");
}
public void Open(int port)
public MtClient(int port)
{
Log.DebugFormat("Open: begin. port = {0}", port);
if (port < 0 || port > 65536)
throw new ArgumentOutOfRangeException(nameof(port), "port value is invalid");
var urlService = $"net.pipe://localhost/{ServiceName}_{port}";
Port = port;
if (_proxy != null)
{
Log.Warn("Open: end. _proxy is not null.");
return;
}
var urlService = $"net.pipe://localhost/{ServiceName}_{port}";
var bind = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
{
@@ -94,61 +80,40 @@ namespace MTApiService
MaxNameTableCharCount = 2147483647
}
};
// Commented next statement since it is not required
_proxy = new MtApiProxy(new InstanceContext(this), bind, new EndpointAddress(urlService));
_proxy.Faulted += ProxyFaulted;
Log.Debug("Open: end.");
}
public void Close()
{
Log.Debug("Close: begin.");
if (_proxy != null)
{
_proxy.Faulted -= ProxyFaulted;
_proxy.Dispose();
_proxy = null;
}
_isConnected = false;
Log.Debug("Close: end.");
}
#endregion
#region Public Methods
/// <exception cref="CommunicationException">Thrown when connection failed</exception>
public void Connect()
{
Log.Debug("Connect: begin.");
if (_proxy == null)
if (_proxy.State != CommunicationState.Created)
{
Log.Error("Connect: _proxy is not defined.");
throw new CommunicationException("Connection failed to service. Proxy is not defined (needs to call Open)");
}
if (_isConnected)
{
Log.Warn("Connected: end. Client is already connected.");
Log.ErrorFormat("Connected: end. Client has invalid state {0}", _proxy.State);
return;
}
bool coonected;
try
{
_isConnected = _proxy.Connect();
coonected = _proxy.Connect();
}
catch (Exception ex)
{
Log.ErrorFormat("Connect: Exception - {0}", ex.Message);
Close();
throw new CommunicationException($"Connection failed to service. {ex.Message}");
}
if (_isConnected == false)
if (coonected == false)
{
Log.Error("Connect: end. Connection failed.");
throw new CommunicationException("Connection failed");
@@ -163,72 +128,60 @@ namespace MTApiService
try
{
_isConnected = false;
_proxy?.Disconnect();
_proxy.Disconnect();
}
catch (Exception ex)
{
Log.ErrorFormat("Disconnect: Exception - {0}", ex.Message);
Close();
}
Log.Debug("Disconnect: end.");
}
/// <exception cref="CommunicationException">Thrown when connection failed</exception>
public MtResponse SendCommand(int commandType, ArrayList parameters)
public MtResponse SendCommand(int commandType, ArrayList parameters, Dictionary<string, object> namedParams, int expertHandle)
{
Log.DebugFormat("SendCommand: begin. commandType = {0}, parameters count = {1}", commandType, parameters?.Count);
MtResponse result;
if (_isConnected == false)
if (IsConnected == false)
{
Log.Error("SendCommand: Client is not connected.");
throw new CommunicationException("Client is not connected.");
}
if (_proxy == null)
{
Log.Error("SendCommand: Proxy is not defined.");
throw new CommunicationException("Proxy is not defined.");
}
MtResponse result;
try
{
result = _proxy.SendCommand(new MtCommand(commandType, parameters));
result = _proxy.SendCommand(new MtCommand {
CommandType = commandType,
Parameters = parameters,
NamedParams = namedParams,
ExpertHandle = expertHandle});
}
catch (Exception ex)
{
Log.ErrorFormat("SendCommand: Exception - {0}", ex.Message);
Close();
throw new CommunicationException("Service connection failed! " + ex.Message);
}
Log.DebugFormat("SendCommand: end. result = {0}", result);
return result;
}
/// <exception cref="CommunicationException">Thrown when connection failed</exception>
public IEnumerable<MtQuote> GetQuotes()
public List<MtQuote> GetQuotes()
{
Log.Debug("GetQuotes: begin.");
if (_isConnected == false)
if (IsConnected == false)
{
Log.Warn("GetQuotes: end. Client is not connected.");
return null;
}
if (_proxy == null)
{
Log.Warn("GetQuotes: end. _proxy is not defined.");
return null;
}
List<MtQuote> result;
try
@@ -239,8 +192,6 @@ namespace MTApiService
{
Log.ErrorFormat("GetQuotes: Exception - {0}", ex.Message);
Close();
throw new CommunicationException($"Service connection failed! {ex.Message}");
}
@@ -286,18 +237,17 @@ namespace MTApiService
{
Log.Debug("OnServerStopped: begin.");
Close();
ServerDisconnected?.Invoke(this, EventArgs.Empty);
Log.Debug("OnServerStopped: end.");
}
public void OnMtEvent(MtEvent mtEvent)
public void OnMtEvent(MtEvent e)
{
Log.DebugFormat("OnMtEvent: begin. event = {0}", mtEvent);
Log.DebugFormat("OnMtEvent: begin. event = {0}", e);
MtEventReceived?.Invoke(this, new MtEventArgs(mtEvent));
MtEventReceived?.Invoke(e);
Log.Debug("OnMtEvent: end.");
}
@@ -305,7 +255,10 @@ namespace MTApiService
#endregion
#region Properties
public bool IsConnected => _proxy.State == CommunicationState.Opened && _isConnected;
public string Host { get; private set; }
public int Port { get; private set; }
private bool IsConnected => _proxy.State == CommunicationState.Opened;
#endregion
@@ -315,7 +268,6 @@ namespace MTApiService
{
Log.Debug("ProxyFaulted: begin.");
Close();
ServerFailed?.Invoke(this, EventArgs.Empty);
Log.Debug("ProxyFaulted: end.");
@@ -329,7 +281,7 @@ namespace MTApiService
{
Log.Debug("Dispose: begin.");
Close();
_proxy.Dispose();
Log.Debug("Dispose: end.");
}
@@ -342,7 +294,7 @@ namespace MTApiService
public event MtQuoteHandler QuoteUpdated;
public event EventHandler ServerDisconnected;
public event EventHandler ServerFailed;
public event EventHandler<MtEventArgs> MtEventReceived;
public event MtEventHandler MtEventReceived;
#endregion
}
}
+9 -8
View File
@@ -1,26 +1,27 @@
using System.Runtime.Serialization;
using System.Collections;
using System.Collections.Generic;
namespace MTApiService
{
[DataContract]
public class MtCommand
{
public MtCommand(int commandType, ArrayList parameters)
{
CommandType = commandType;
Parameters = parameters;
}
[DataMember]
public int CommandType { get; set; }
[DataMember]
public int CommandType { get; private set; }
public ArrayList Parameters { get; set; }
[DataMember]
public ArrayList Parameters { get; private set; }
public Dictionary<string, object> NamedParams { get; set; }
[DataMember]
public int ExpertHandle { get; set; }
public override string ToString()
{
return $"CommandType = {CommandType}";
return $"CommandType = {CommandType}; ExpertHandle = {ExpertHandle}";
}
}
}
+1 -1
View File
@@ -17,7 +17,7 @@ namespace MTApiService
Command = command;
}
public MtCommand Command { get; private set; }
public MtCommand Command { get; }
public MtResponse WaitResult(int time)
{
+5 -18
View File
@@ -7,30 +7,17 @@ namespace MTApiService
public class MtEvent
{
[DataMember]
public int EventType { get; private set; }
public int EventType { get; internal set; }
[DataMember]
public string Payload { get; private set; }
public string Payload { get; internal set; }
public MtEvent(int eventType, string payload)
{
EventType = eventType;
Payload = payload;
}
[DataMember]
public int ExpertHandle { get; internal set; }
public override string ToString()
{
return "MtEvent = " + EventType + ", Payload = " + Payload;
return $"EventType = {EventType}; Payload = {Payload}; ExpertHandle = {ExpertHandle}";
}
}
public class MtEventArgs: EventArgs
{
public MtEventArgs(MtEvent e)
{
Event = e;
}
public MtEvent Event { get; private set; }
}
}
+55 -111
View File
@@ -4,14 +4,13 @@ using log4net;
namespace MTApiService
{
internal class MtCommandExecutorManager : ICommandManager
internal class MtExecutorManager : ICommandManager
{
#region Private Fields
private static readonly ILog Log = LogManager.GetLogger(typeof(MtCommandExecutorManager));
private readonly List<MtExpert> _commandExecutors = new List<MtExpert>();
private readonly Queue<MtCommandTask> _commandTasks = new Queue<MtCommandTask>();
private static readonly ILog Log = LogManager.GetLogger(typeof(MtExecutorManager));
private readonly List<ITaskExecutor> _executorList = new List<ITaskExecutor>();
private readonly Dictionary<int, ITaskExecutor> _executorMap = new Dictionary<int, ITaskExecutor>();
private readonly object _locker = new object();
#endregion
@@ -23,149 +22,94 @@ namespace MTApiService
lock (_locker)
{
_commandExecutors.Clear();
_commandTasks.Clear();
_executorList.Clear();
_executorMap.Clear();
}
Log.Debug("Stop: end.");
}
public void AddCommandExecutor(MtExpert commandExecutor)
public void AddExecutor(ITaskExecutor executor)
{
if (commandExecutor == null)
throw new ArgumentNullException(nameof(commandExecutor));
if (executor == null)
throw new ArgumentNullException(nameof(executor));
Log.DebugFormat("AddCommandExecutor: begin. commandExecutor = {0}", commandExecutor);
Log.DebugFormat("AddExecutor: begin. executor = {0}", executor);
var notify = false;
lock (_locker)
{
if (_commandExecutors.Contains(commandExecutor))
if (_executorList.Contains(executor))
{
Log.Warn("AddCommandExecutor: end. Command executor already exist.");
Log.Warn("AddExecutor: end. Executor already exist.");
return;
}
_commandExecutors.Add(commandExecutor);
if (_commandTasks.Count > 0)
{
notify = true;
}
}
commandExecutor.CommandExecuted += CommandExecutor_CommandExecuted;
commandExecutor.CommandManager = this;
if (notify)
{
NotifyCommandReady();
_executorList.Add(executor);
_executorMap[executor.Handle] = executor;
}
Log.Debug("AddCommandExecutor: end.");
}
public void RemoveCommandExecutor(MtExpert commandExecutor)
public void RemoveExecutor(ITaskExecutor executor)
{
if (commandExecutor == null)
throw new ArgumentNullException(nameof(commandExecutor));
if (executor == null)
throw new ArgumentNullException(nameof(executor));
Log.DebugFormat("RemoveCommandExecutor: begin. commandExecutor = {0}", commandExecutor);
Log.DebugFormat("RemoveExecutor: begin. executor = {0}", executor);
var notify = false;
lock (_locker)
{
if (_commandExecutors.Contains(commandExecutor) == false)
if (_executorList.Contains(executor) == false)
{
Log.Warn("RemoveCommandExecutor: end. Command executor is not exist in collection.");
Log.Warn("RemoveExecutor: end. Executor is not exist in collection.");
return;
}
_commandExecutors.Remove(commandExecutor);
if (_commandTasks.Count > 0)
_executorList.Remove(executor);
_executorMap.Remove(executor.Handle);
}
Log.Debug("RemoveExecutor: end.");
}
public MtCommandTask SendCommand(MtCommand command)
{
if (command == null)
throw new ArgumentNullException(nameof(command));
var task = new MtCommandTask(command);
Log.DebugFormat("SendTask: begin. command = {0}", command);
ITaskExecutor executor;
lock (_locker)
{
if (_executorMap.ContainsKey(command.ExpertHandle))
{
notify = true;
executor = _executorMap[command.ExpertHandle];
}
else
{
executor = _executorList.Count > 0 ? _executorList[0] : null;
}
}
commandExecutor.CommandExecuted -= CommandExecutor_CommandExecuted;
commandExecutor.CommandManager = null;
if (notify)
if (executor == null)
{
NotifyCommandReady();
Log.Error("SendTask: Executor is null!");
}
else
{
executor.Execute(task);
}
Log.Debug("RemoveCommandExecutor: end.");
Log.Debug("SendTask: end.");
return task;
}
public void EnqueueCommandTask(MtCommandTask task)
{
if (task == null)
throw new ArgumentNullException(nameof(task));
Log.DebugFormat("EnqueueCommandTask: begin. task = {0}", task);
lock (_locker)
{
_commandTasks.Enqueue(task);
}
NotifyCommandReady();
Log.Debug("EnqueueCommandTask: end.");
}
public MtCommandTask DequeueCommandTask()
{
Log.Debug("DequeueCommandTask: called.");
lock (_locker)
{
return _commandTasks.Count > 0 ? _commandTasks.Dequeue() : null;
}
}
#endregion
#region Private Methods
private void NotifyCommandReady()
{
Log.Debug("NotifyCommandReady: begin.");
var commandExecutors = new List<MtExpert>();
lock (_locker)
{
commandExecutors.AddRange(_commandExecutors);
}
foreach (var executor in commandExecutors)
{
executor.NotifyCommandReady();
}
Log.DebugFormat("NotifyCommandReady: end. Notified executor count = {0}", commandExecutors.Count);
}
private void CommandExecutor_CommandExecuted(object sender, EventArgs e)
{
Log.Debug("CommandExecutor_CommandExecuted: begin.");
var notify = false;
lock (_locker)
{
if (_commandTasks.Count > 0)
{
notify = true;
}
}
if (notify)
{
NotifyCommandReady();
}
Log.Debug("CommandExecutor_CommandExecuted: end.");
}
#endregion
}
}
+105 -78
View File
@@ -1,37 +1,38 @@
using System;
using log4net;
using System.Collections.Generic;
namespace MTApiService
{
public class MtExpert
public class MtExpert: ITaskExecutor
{
public delegate void MtQuoteHandler(MtExpert expert, MtQuote quote);
public delegate void MtEventHandler(MtExpert expert, MtEvent e);
#region Private Fields
private static readonly ILog Log = LogManager.GetLogger(typeof(MtExpert));
private readonly IMetaTraderHandler _mtHadler;
private MtCommandTask _commandTask;
private ICommandManager _commandManager;
private MtCommandTask _currentTask;
private readonly Queue<MtCommandTask> _taskQueue = new Queue<MtCommandTask>();
private readonly object _locker = new object();
#endregion
#region Public Methods
public MtExpert(int handle, MtQuote quote, IMetaTraderHandler mtHandler)
public MtExpert(int handle, string symbol, double bid, double ask, IMetaTraderHandler mtHandler)
{
if (mtHandler == null)
throw new ArgumentNullException(nameof(mtHandler));
Quote = quote;
_quote = new MtQuote { ExpertHandle = handle, Instrument = symbol, Bid = bid, Ask = ask};
Handle = handle;
_mtHadler = mtHandler;
}
public void Deinit()
public virtual void Deinit()
{
Log.Debug("Deinit: begin.");
IsEnable = false;
FireOnDeinited();
Log.Debug("Deinit: end.");
@@ -41,9 +42,8 @@ namespace MTApiService
{
Log.DebugFormat("SendResponse: begin. response = {0}", response);
_commandTask.SetResult(response);
_commandTask = null;
FireOnCommandExecuted();
_currentTask.SetResult(response);
_currentTask = null;
Log.Debug("SendResponse: end.");
}
@@ -52,20 +52,16 @@ namespace MTApiService
{
Log.Debug("GetCommandType: called.");
var commandManager = CommandManager;
if (commandManager != null)
{
_commandTask = commandManager.DequeueCommandTask();
}
_currentTask = DequeueTask();
return _commandTask?.Command?.CommandType ?? 0;
return _currentTask?.Command?.CommandType ?? 0;
}
public object GetCommandParameter(int index)
{
Log.DebugFormat("GetCommandType: called. index = {0}", index);
Log.DebugFormat("GetCommandParameter: called. index = {0}", index);
var command = _commandTask?.Command;
var command = _currentTask?.Command;
if (command?.Parameters != null && index >= 0 && index < command.Parameters.Count)
{
return command.Parameters[index];
@@ -74,6 +70,46 @@ namespace MTApiService
return null;
}
public object GetNamedParameter(string name)
{
Log.DebugFormat("GetNamedParameter: called. name = {0}", name);
var command = _currentTask?.Command;
if (command == null)
{
Log.Warn("GetNamedParameter: command is not defined in task.");
return null;
}
if (command.NamedParams == null)
{
Log.Warn("GetNamedParameter: NamedParams is not defined in command.");
return null;
}
return command.NamedParams[name];
}
public bool ContainsNamedParameter(string name)
{
Log.DebugFormat("ContainsNamedParameter: called. name = {0}", name);
var command = _currentTask?.Command;
if (command == null)
{
Log.Warn("ContainsNamedParameter: command is not defined in task.");
return false;
}
if (command.NamedParams == null)
{
Log.Warn("ContainsNamedParameter: NamedParams is not defined in command.");
return false;
}
return command.NamedParams.ContainsKey(name);
}
public void SendEvent(MtEvent mtEvent)
{
Log.DebugFormat("SendEvent: begin. event = {0}", mtEvent);
@@ -83,14 +119,38 @@ namespace MTApiService
Log.Debug("SendEvent: end.");
}
public virtual void UpdateQuote(MtQuote quote)
{
Log.DebugFormat("UpdateQuote: begin. quote = {0}", quote);
Quote = quote;
Log.Debug("UpdateQuote: end.");
}
public override string ToString()
{
return $"ExpertHandle = {Handle}";
return $"ExpertHandle = {Handle}, Quote = {Quote}";
}
#endregion
#region ITaskExecutor
public void Execute(MtCommandTask task)
{
lock (_taskQueue)
{
_taskQueue.Enqueue(task);
}
NotifyCommandReady();
}
#endregion
#region Properties
private MtQuote _quote;
public MtQuote Quote
{
@@ -101,7 +161,7 @@ namespace MTApiService
return _quote;
}
}
set
private set
{
lock (_locker)
{
@@ -113,61 +173,34 @@ namespace MTApiService
}
public int Handle { get; }
private bool _isEnable = true;
public bool IsEnable
{
get
{
lock (_locker)
{
return _isEnable;
}
}
private set
{
lock (_locker)
{
_isEnable = value;
}
}
}
public ICommandManager CommandManager
{
private get
{
lock (_locker)
{
return _commandManager;
}
}
set
{
lock (_locker)
{
_commandManager = value;
}
}
}
#endregion
#region IMtCommandExecutor
public void NotifyCommandReady()
{
Log.Debug("NotifyCommandReady: begin.");
SendTickToMetaTrader();
Log.Debug("NotifyCommandReady: end.");
}
#endregion
#region Private Methods
private void SendTickToMetaTrader()
private MtCommandTask DequeueTask()
{
Log.Debug("DequeueTask: called.");
MtCommandTask task;
int count;
lock (_locker)
{
count = _taskQueue.Count;
task = _taskQueue.Count > 0 ? _taskQueue.Dequeue() : null;
}
Log.DebugFormat("DequeueTask: end. left task count = {0}.", count);
return task;
}
private void NotifyCommandReady()
{
Log.Debug("NotifyCommandReady: begin.");
_mtHadler.SendTickToMetaTrader(Handle);
Log.Debug("NotifyCommandReady: end.");
}
private void FireOnQuoteChanged(MtQuote quote)
@@ -180,22 +213,16 @@ namespace MTApiService
Deinited?.Invoke(this, EventArgs.Empty);
}
private void FireOnCommandExecuted()
{
CommandExecuted?.Invoke(this, EventArgs.Empty);
}
private void FireOnMtEvent(MtEvent mtEvent)
{
OnMtEvent?.Invoke(this, new MtEventArgs(mtEvent));
OnMtEvent?.Invoke(this, mtEvent);
}
#endregion
#region Events
public event EventHandler Deinited;
public event MtQuoteHandler QuoteChanged;
public event EventHandler CommandExecuted;
public event EventHandler<MtEventArgs> OnMtEvent;
public event MtEventHandler OnMtEvent;
#endregion
}
}
-29
View File
@@ -1,29 +0,0 @@
using System.Runtime.Serialization;
namespace MTApiService
{
[DataContract]
public class MtQuote
{
[DataMember]
public string Instrument { get; private set; }
[DataMember]
public double Bid { get; private set; }
[DataMember]
public double Ask { get; private set; }
public MtQuote(string instrument, double bid, double ask)
{
Instrument = instrument;
Bid = bid;
Ask = ask;
}
public override string ToString()
{
return "Instrument = " + Instrument + ", Bid = " + Bid + ", Ask = " + Ask;
}
}
}
+7 -3
View File
@@ -9,9 +9,9 @@ namespace MTApiService
[DataMember]
public int Action { get; set; }
[DataMember]
public uint Magic { get; set; }
public ulong Magic { get; set; }
[DataMember]
public uint Order { get; set; }
public ulong Order { get; set; }
[DataMember]
public string Symbol { get; set; }
[DataMember]
@@ -25,7 +25,7 @@ namespace MTApiService
[DataMember]
public double Tp { get; set; }
[DataMember]
public uint Deviation { get; set; }
public ulong Deviation { get; set; }
[DataMember]
public int Type { get; set; }
[DataMember]
@@ -36,5 +36,9 @@ namespace MTApiService
public DateTime Expiration { get; set; }
[DataMember]
public string Comment { get; set; }
[DataMember]
public ulong Position { get; set; }
[DataMember]
public ulong PositionBy { get; set; }
}
}
+25
View File
@@ -0,0 +1,25 @@
using System.Runtime.Serialization;
namespace MTApiService
{
[DataContract]
public class MtQuote
{
[DataMember]
public string Instrument { get; internal set; }
[DataMember]
public double Bid { get; internal set; }
[DataMember]
public double Ask { get; internal set; }
[DataMember]
public int ExpertHandle { get; internal set; }
public override string ToString()
{
return $"Instrument = {Instrument}; Bid = {Bid}; Ask = {Ask}; ExpertHandle = {ExpertHandle}";
}
}
}
+24 -1
View File
@@ -12,7 +12,8 @@ namespace MTApiService
{
static IEnumerable<Type> GetKnownTypes()
{
return new Type[] { typeof(MtResponseInt), typeof(MtResponseDouble),
return new Type[] { typeof(MtResponseObject),
typeof(MtResponseInt), typeof(MtResponseDouble),
typeof(MtResponseString), typeof(MtResponseBool),
typeof(MtResponseLong), typeof(MtResponseULong),
typeof(MtResponseDoubleArray), typeof(MtResponseIntArray),
@@ -22,6 +23,28 @@ namespace MTApiService
}
public abstract object GetValue();
[DataMember]
public int ErrorCode { get; set; }
}
[DataContract]
public class MtResponseObject : MtResponse
{
public MtResponseObject(object value)
{
Value = value;
}
[DataMember]
public object Value { get; private set; }
public override object GetValue() { return Value; }
public override string ToString()
{
return Value?.ToString() ?? string.Empty;
}
}
[DataContract]
+29 -17
View File
@@ -21,7 +21,7 @@ namespace MTApiService
private readonly MtService _service;
private readonly List<ServiceHost> _hosts = new List<ServiceHost>();
private readonly MtCommandExecutorManager _executorManager = new MtCommandExecutorManager();
private readonly MtExecutorManager _executorManager = new MtExecutorManager();
private readonly List<MtExpert> _experts = new List<MtExpert>();
#endregion
@@ -62,21 +62,24 @@ namespace MTApiService
}
//init local pipe host
var localUrl = CreateConnectionAddress(null, port, true);
var localServiceHost = CreateServiceHost(localUrl, true);
var localPipeUrl = CreateConnectionAddress(null, port, true);
var localPipeServiceHost = CreateServiceHost(localPipeUrl, true);
if (localPipeServiceHost != null)
{
_hosts.Add(localPipeServiceHost);
}
//init localhost
var localUrl = CreateConnectionAddress("localhost", port, false);
var localServiceHost = CreateServiceHost(localUrl, false);
if (localServiceHost != null)
{
_hosts.Add(localServiceHost);
}
//init network hosts
var dnsHostName = Dns.GetHostName();
var ips = Dns.GetHostEntry(dnsHostName);
if (ips == null)
{
Log.WarnFormat("InitHosts: end. Dns.GetHostEntry has returned null for DNS Host Name {0}", dnsHostName);
return false;
}
foreach (var ipAddress in ips.AddressList)
{
@@ -149,7 +152,7 @@ namespace MTApiService
_experts.Add(expert);
}
_executorManager.AddCommandExecutor(expert);
_executorManager.AddExecutor(expert);
_service.OnQuoteAdded(expert.Quote);
@@ -170,11 +173,20 @@ namespace MTApiService
return null;
}
var task = new MtCommandTask(command);
_executorManager.EnqueueCommandTask(task);
var task = _executorManager.SendCommand(command);
//wait for execute command in MetaTrader
var response = task.WaitResult(WaitResponseTime);
MtResponse response = null;
try
{
response = task.WaitResult(WaitResponseTime);
}
catch (Exception ex)
{
Log.WarnFormat("SendCommand: Exception - {0}", ex.Message);
}
Log.DebugFormat("SendCommand: end. response = {0}", response);
return response;
}
@@ -371,7 +383,7 @@ namespace MTApiService
expertsCount = _experts.Count;
}
_executorManager.RemoveCommandExecutor(expert);
_executorManager.RemoveExecutor(expert);
expert.Deinited -= expert_Deinited;
expert.QuoteChanged -= expert_QuoteChanged;
@@ -398,11 +410,11 @@ namespace MTApiService
Log.Debug("expert_QuoteChanged: end.");
}
private void Expert_OnMtEvent(object sender, MtEventArgs e)
private void Expert_OnMtEvent(MtExpert expert, MtEvent e)
{
Log.DebugFormat("Expert_OnMtEvent: begin. event = {0}", e.Event);
Log.DebugFormat("Expert_OnMtEvent: begin. expert = {0}, event = {1}", expert, e);
_service.OnMtEvent(e.Event);
_service.OnMtEvent(e);
Log.Debug("Expert_OnMtEvent: end.");
}
+7 -7
View File
@@ -66,7 +66,7 @@ namespace MTApiService
if (callback == null)
{
Log.Warn("Connect: end. Callback is not definded.");
Log.Warn("Connect: end. Callback is not defined.");
return false;
}
@@ -158,7 +158,7 @@ namespace MTApiService
public void QuoteUpdate(MtQuote quote)
{
Log.Debug("QuoteUpdate: begin.");
Log.DebugFormat("QuoteUpdate: begin. quote = {0}", quote);
ExecuteCallbackAction(a => a.OnQuoteUpdate(quote));
@@ -167,7 +167,7 @@ namespace MTApiService
public void OnQuoteAdded(MtQuote quote)
{
Log.Debug("OnQuoteAdded: begin.");
Log.DebugFormat("OnQuoteAdded: begin. quote = {0}", quote);
ExecuteCallbackAction(a => a.OnQuoteAdded(quote));
@@ -176,18 +176,18 @@ namespace MTApiService
public void OnQuoteRemoved(MtQuote quote)
{
Log.Debug("OnQuoteRemoved: begin.");
Log.DebugFormat("OnQuoteRemoved: begin. quote = {0}", quote);
ExecuteCallbackAction(a => a.OnQuoteRemoved(quote));
Log.Debug("OnQuoteRemoved: end.");
}
public void OnMtEvent(MtEvent mtEvent)
public void OnMtEvent(MtEvent e)
{
Log.Debug("OnMtEvent: begin.");
Log.DebugFormat("OnMtEvent: begin.quote = {0}", e);
ExecuteCallbackAction(a => a.OnMtEvent(mtEvent));
ExecuteCallbackAction(a => a.OnMtEvent(e));
Log.Debug("OnMtEvent: end.");
}
+2 -2
View File
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.24.0")]
[assembly: AssemblyFileVersion("1.0.24.0")]
[assembly: AssemblyVersion("1.0.29.0")]
[assembly: AssemblyFileVersion("1.0.29.0")]
+175 -196
View File
@@ -4,7 +4,8 @@
#include "MT4Handler.h"
#include "Windows.h"
#include < vcclr.h >
#include <vcclr.h>
#include <functional>
using namespace System;
using namespace MTApiService;
@@ -17,6 +18,8 @@ using namespace System::IO;
using namespace System::Collections::Generic;
using namespace System::Diagnostics;
#define _DLLAPI extern "C" __declspec(dllexport)
void convertSystemString(wchar_t* dest, String^ src)
{
pin_ptr<const wchar_t> wch = PtrToStringChars(src);
@@ -24,264 +27,240 @@ void convertSystemString(wchar_t* dest, String^ src)
dest[wcslen(wch)] = '\0';
}
int _stdcall initExpert(int expertHandle, int port, wchar_t* symbol, double bid, double ask, wchar_t* err)
template <typename T> T Execute(std::function<T()> func, wchar_t* err, T default_value)
{
T result = default_value;
try
{
MT4Handler^ mtHandler = gcnew MT4Handler();
MtServerInstance::GetInstance()->InitExpert(expertHandle, port, gcnew String(symbol), bid, ask, mtHandler);
result = func();
}
catch (Exception^ e)
{
convertSystemString(err, e->Message);
Debug::WriteLine("[ERROR] MTConnector:initExpert(): " + e->Message);
return 0;
}
return 1;
return result;
}
int _stdcall deinitExpert(int expertHandle, wchar_t* err)
_DLLAPI bool _stdcall initExpert(int expertHandle, int port, wchar_t* symbol, double bid, double ask, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->DeinitExpert(expertHandle);
}
catch (Exception^ e)
{
convertSystemString(err, e->Message);
Debug::WriteLine("[ERROR] MTConnector:deinitExpert(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, &port, symbol, &bid, &ask]() {
auto expert = gcnew MtExpert(expertHandle, gcnew String(symbol), bid, ask, gcnew MT4Handler());
MtAdapter::GetInstance()->AddExpert(port, expert);
return true;
}, err, false);
}
int _stdcall updateQuote(int expertHandle, wchar_t* symbol, double bid, double ask, wchar_t* err)
_DLLAPI bool _stdcall deinitExpert(int expertHandle, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->SendQuote(expertHandle, gcnew String(symbol), bid, ask);
}
catch (Exception^ e)
{
convertSystemString(err, e->Message);
Debug::WriteLine("[ERROR] MTConnector:updateQuote(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle]() {
MtAdapter::GetInstance()->RemoveExpert(expertHandle);
return true;
}, err, false);
}
_DLLAPI bool _stdcall updateQuote(int expertHandle, wchar_t* symbol, double bid, double ask, wchar_t* err)
{
return Execute<bool>([&expertHandle, symbol, &bid, &ask]() {
MtAdapter::GetInstance()->SendQuote(expertHandle, gcnew String(symbol), bid, ask);
return true;
}, err, false);
}
int _stdcall sendEvent(int expertHandle, int eventType, wchar_t* payload, wchar_t* err)
_DLLAPI bool _stdcall sendEvent(int expertHandle, int eventType, wchar_t* payload, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->SendEvent(expertHandle, eventType, gcnew String(payload));
}
catch (Exception^ e)
{
convertSystemString(err, e->Message);
Debug::WriteLine("[ERROR] MTConnector:updateTimeBar(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, &eventType, payload]() {
MtAdapter::GetInstance()->SendEvent(expertHandle, eventType, gcnew String(payload));
return true;
}, err, false);
}
int _stdcall sendIntResponse(int expertHandle, int response)
_DLLAPI bool _stdcall sendIntResponse(int expertHandle, int response, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseInt(response));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendIntResponse(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, &response]() {
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseInt(response));
return true;
}, err, false);
}
int _stdcall sendBooleanResponse(int expertHandle, int response)
_DLLAPI bool _stdcall sendBooleanResponse(int expertHandle, bool response, wchar_t* err)
{
try
{
bool value = (response != 0) ? true : false;
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseBool(value));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendBooleanResponse(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, &response]() {
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseBool(response));
return true;
}, err, false);
}
int _stdcall sendDoubleResponse(int expertHandle, double response)
_DLLAPI bool _stdcall sendDoubleResponse(int expertHandle, double response, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDouble(response));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendDoubleResponse(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, &response]() {
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDouble(response));
return true;
}, err, false);
}
int _stdcall sendStringResponse(int expertHandle, wchar_t* response)
_DLLAPI bool _stdcall sendStringResponse(int expertHandle, wchar_t* response, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseString(gcnew String(response)));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendStringResponse(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, response]() {
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseString(gcnew String(response)));
return true;
}, err, false);
}
int _stdcall sendVoidResponse(int expertHandle)
_DLLAPI bool _stdcall sendErrorResponse(int expertHandle, int code, wchar_t* message, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, nullptr);
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendVoidResponse(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, &code, message]() {
MtResponseString^ res = gcnew MtResponseString(gcnew String(message));
res->ErrorCode = code;
MtAdapter::GetInstance()->SendResponse(expertHandle, res);
return true;
}, err, false);
}
int _stdcall sendDoubleArrayResponse(int expertHandle, double* values, int size)
_DLLAPI bool _stdcall sendVoidResponse(int expertHandle, wchar_t* err)
{
try
{
return Execute<bool>([&expertHandle]() {
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseObject(nullptr));
return true;
}, err, false);
}
_DLLAPI bool _stdcall sendDoubleArrayResponse(int expertHandle, double* values, int size, wchar_t* err)
{
return Execute<bool>([&expertHandle, values, &size]() {
array<double>^ list = gcnew array<double>(size);
for(int i = 0; i < size; i++)
for (int i = 0; i < size; i++)
{
list[i] = values[i];
}
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDoubleArray(list));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendDoubleArrayResponse(): " + e->Message);
return 0;
}
return 1;
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDoubleArray(list));
return true;
}, err, false);
}
int _stdcall sendIntArrayResponse(int expertHandle, int* values, int size)
_DLLAPI bool _stdcall sendIntArrayResponse(int expertHandle, int* values, int size, wchar_t* err)
{
try
{
return Execute<bool>([&expertHandle, values, &size]() {
array<int>^ list = gcnew array<int>(size);
for(int i = 0; i < size; i++)
for (int i = 0; i < size; i++)
{
list[i] = values[i];
}
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseIntArray(list));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendIntArrayResponse(): " + e->Message);
return 0;
}
return 1;
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseIntArray(list));
return true;
}, err, false);
}
int _stdcall sendLongResponse(int expertHandle, __int64 response)
_DLLAPI bool _stdcall sendLongResponse(int expertHandle, __int64 response, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLong(response));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendLongResponse(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, &response]() {
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLong(response));
return true;
}, err, false);
}
int _stdcall getCommandType(int expertHandle, int* res)
_DLLAPI bool _stdcall getCommandType(int expertHandle, int* res, wchar_t* err)
{
try
{
*res = MtServerInstance::GetInstance()->GetCommandType(expertHandle);
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:getCommandType(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, res]() {
*res = MtAdapter::GetInstance()->GetCommandType(expertHandle);
return true;
}, err, false);
}
int _stdcall getIntValue(int expertHandle, int paramIndex, int* res)
_DLLAPI bool _stdcall getIntValue(int expertHandle, int paramIndex, int* res, wchar_t* err)
{
try
{
*res = (int)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:getIntValue(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, &paramIndex, res]() {
*res = (int)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
return true;
}, err, false);
}
int _stdcall getDoubleValue(int expertHandle, int paramIndex, double* res)
// --- index parameters
_DLLAPI bool _stdcall getDoubleValue(int expertHandle, int paramIndex, double* res, wchar_t* err)
{
try
{
*res = (double)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:getDoubleValue(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, &paramIndex, res]() {
*res = (double)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
return true;
}, err, false);
}
int _stdcall getStringValue(int expertHandle, int paramIndex, wchar_t* res)
_DLLAPI bool _stdcall getStringValue(int expertHandle, int paramIndex, wchar_t* res, wchar_t* err)
{
try
{
convertSystemString(res, (String^)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:getStringValue(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, &paramIndex, res]() {
convertSystemString(res, (String^)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex));
return true;
}, err, false);
}
int _stdcall getBooleanValue(int expertHandle, int paramIndex, int* res)
_DLLAPI bool _stdcall getBooleanValue(int expertHandle, int paramIndex, int* res, wchar_t* err)
{
try
{
bool val = (bool)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
*res = val == true ? 1 : 0;
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:getBooleanValue(): " + e->Message);
return 0;
}
return 1;
return Execute<bool>([&expertHandle, &paramIndex, res]() {
*res = (bool)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
return true;
}, err, false);
}
_DLLAPI bool _stdcall getLongValue(int expertHandle, int paramIndex, __int64* res, wchar_t* err)
{
return Execute<bool>([&expertHandle, &paramIndex, res]() {
*res = (__int64)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
return true;
}, err, false);
}
// --- named parameters
_DLLAPI bool _stdcall containsNamedValue(int expertHandle, wchar_t* paramName)
{
wchar_t err[1000];
return Execute<bool>([&expertHandle, paramName]() {
return MtAdapter::GetInstance()->ContainsNamedParameter(expertHandle, gcnew String(paramName));
}, err, false);
}
_DLLAPI bool _stdcall getNamedIntValue(int expertHandle, wchar_t* paramName, int* res, wchar_t* err)
{
return Execute<bool>([&expertHandle, paramName, res]() {
System::Object^ obj = MtAdapter::GetInstance()->GetNamedParameter(expertHandle, gcnew String(paramName));
*res = (int)obj;
return true;
}, err, false);
}
_DLLAPI bool _stdcall getNamedDoubleValue(int expertHandle, wchar_t* paramName, double* res, wchar_t* err)
{
return Execute<bool>([&expertHandle, paramName, res]() {
System::Object^ obj = MtAdapter::GetInstance()->GetNamedParameter(expertHandle, gcnew String(paramName));
*res = (double)obj;
return true;
}, err, false);
}
_DLLAPI bool _stdcall getNamedStringValue(int expertHandle, wchar_t* paramName, wchar_t* res, wchar_t* err)
{
return Execute<bool>([&expertHandle, paramName, res]() {
System::Object^ obj = MtAdapter::GetInstance()->GetNamedParameter(expertHandle, gcnew String(paramName));
convertSystemString(res, (String^)obj);
return true;
}, err, false);
}
_DLLAPI bool _stdcall getNamedBooleanValue(int expertHandle, wchar_t* paramName, int* res, wchar_t* err)
{
return Execute<bool>([&expertHandle, paramName, res]() {
System::Object^ obj = MtAdapter::GetInstance()->GetNamedParameter(expertHandle, gcnew String(paramName));
*res = (bool)obj;
return true;
}, err, false);
}
_DLLAPI bool _stdcall getNamedLongValue(int expertHandle, wchar_t* paramName, __int64* res, wchar_t* err)
{
return Execute<bool>([&expertHandle, paramName, res]() {
System::Object^ obj = MtAdapter::GetInstance()->GetNamedParameter(expertHandle, gcnew String(paramName));
if (obj != nullptr)
*res = (__int64)obj;
return true;
}, err, false);
}
-19
View File
@@ -1,19 +0,0 @@
LIBRARY MTConnector
EXPORTS initExpert
deinitExpert
updateQuote
sendEvent
sendIntResponse
sendBooleanResponse
sendDoubleResponse
sendStringResponse
sendVoidResponse
sendDoubleArrayResponse
sendIntArrayResponse
sendLongResponse
getCommandType
getIntValue
getDoubleValue
getStringValue
getBooleanValue
-5
View File
@@ -96,7 +96,6 @@
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>.\MTConnector.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -109,7 +108,6 @@
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>.\MTConnector.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -121,7 +119,6 @@
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>.\MTConnector.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -133,7 +130,6 @@
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>.\MTConnector.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
@@ -154,7 +150,6 @@
</ItemGroup>
<ItemGroup>
<None Include="app.ico" />
<None Include="MTConnector.def" />
<None Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
-3
View File
@@ -44,9 +44,6 @@
<None Include="app.ico">
<Filter>Resource Files</Filter>
</None>
<None Include="MTConnector.def">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="app.rc">
+24
View File
@@ -0,0 +1,24 @@
using System;
namespace MtApi
{
public class ChartEventArgs : EventArgs
{
internal ChartEventArgs(int expertHandle, MtChartEvent chartEvent)
{
ExpertHandle = expertHandle;
ChartId = chartEvent.ChartId;
EventId = chartEvent.EventId;
Lparam = chartEvent.Lparam;
Dparam = chartEvent.Dparam;
Sparam = chartEvent.Sparam;
}
public int ExpertHandle { get; }
public long ChartId { get; }
public int EventId { get; }
public long Lparam { get; }
public double Dparam { get; }
public string Sparam { get; }
}
}
+9
View File
@@ -0,0 +1,9 @@
namespace MtApi
{
public enum EnumAlignMode
{
ALIGN_LEFT = 1,
ALIGN_CENTER = 2,
ALIGN_RIGHT = 0
}
}
+18
View File
@@ -0,0 +1,18 @@
namespace MtApi
{
public enum EnumChartEvent
{
CHARTEVENT_KEYDOWN = 0,
CHARTEVENT_MOUSE_MOVE = 10,
CHARTEVENT_OBJECT_CREATE = 7,
CHARTEVENT_OBJECT_CHANGE = 8,
CHARTEVENT_OBJECT_DELETE = 6,
CHARTEVENT_CLICK = 4,
CHARTEVENT_OBJECT_CLICK = 1,
CHARTEVENT_OBJECT_DRAG = 2,
CHARTEVENT_OBJECT_ENDEDIT = 3,
CHARTEVENT_CHART_CHANGE = 9,
CHARTEVENT_CUSTOM = 1000,
CHARTEVENT_CUSTOM_LAST = 66534
}
}
+13
View File
@@ -0,0 +1,13 @@
namespace MtApi
{
public enum EnumChartPropertyDouble
{
CHART_SHIFT_SIZE = 3,
CHART_FIXED_POSITION = 41,
CHART_FIXED_MAX = 8,
CHART_FIXED_MIN = 9,
CHART_POINTS_PER_BAR = 11,
CHART_PRICE_MIN = 108,
CHART_PRICE_MAX = 109
}
}
+55
View File
@@ -0,0 +1,55 @@
namespace MtApi
{
public enum EnumChartPropertyInteger
{
CHART_BRING_TO_TOP = 35,
CHART_MOUSE_SCROLL = 42,
CHART_EVENT_MOUSE_MOVE = 40,
CHART_EVENT_OBJECT_CREATE = 38,
CHART_EVENT_OBJECT_DELETE = 39,
CHART_MODE = 0,
CHART_FOREGROUND = 1,
CHART_SHIFT = 2,
CHART_AUTOSCROLL = 4,
CHART_QUICK_NAVIGATION = 45,
CHART_SCALE = 5,
CHART_SCALEFIX = 6,
CHART_SCALEFIX_11 = 7,
CHART_SCALE_PT_PER_BAR = 10,
CHART_SHOW_OHLC = 12,
CHART_SHOW_BID_LINE = 13,
CHART_SHOW_ASK_LINE = 14,
CHART_SHOW_LAST_LINE = 15,
CHART_SHOW_PERIOD_SEP = 16,
CHART_SHOW_GRID = 17,
CHART_SHOW_VOLUMES = 18,
CHART_SHOW_OBJECT_DESCR = 19,
CHART_VISIBLE_BARS = 100,
CHART_WINDOWS_TOTAL = 101,
CHART_WINDOW_IS_VISIBLE = 102,
CHART_WINDOW_HANDLE = 103,
CHART_WINDOW_YDISTANCE = 110,
CHART_FIRST_VISIBLE_BAR = 104,
CHART_WIDTH_IN_BARS = 105,
CHART_WIDTH_IN_PIXELS = 106,
CHART_HEIGHT_IN_PIXELS = 107,
CHART_COLOR_BACKGROUND = 21,
CHART_COLOR_FOREGROUND = 22,
CHART_COLOR_GRID = 23,
CHART_COLOR_VOLUME = 24,
CHART_COLOR_CHART_UP = 25,
CHART_COLOR_CHART_DOWN = 26,
CHART_COLOR_CHART_LINE = 27,
CHART_COLOR_CANDLE_BULL = 28,
CHART_COLOR_CANDLE_BEAR = 29,
CHART_COLOR_BID = 30,
CHART_COLOR_ASK = 31,
CHART_COLOR_LAST = 32,
CHART_COLOR_STOP_LEVEL = 33,
CHART_SHOW_TRADE_LEVELS = 34,
CHART_DRAG_TRADE_LEVELS = 43,
CHART_SHOW_DATE_SCALE = 36,
CHART_SHOW_PRICE_SCALE = 37,
CHART_IS_OFFLINE = 112
}
}
+7
View File
@@ -0,0 +1,7 @@
namespace MtApi
{
public enum EnumChartPropertyString
{
CHART_COMMENT = 20
}
}
+9
View File
@@ -0,0 +1,9 @@
namespace MtApi
{
enum EnumColorFormat
{
COLOR_FORMAT_XRGB_NOALPHA = 0, //The component of the alpha channel is ignored
COLOR_FORMAT_ARGB_RAW = 1, //Color components are not handled by the terminal (must be correctly set by the user)
COLOR_FORMAT_ARGB_NORMALIZE = 2 //Color components are handled by the terminal
}
}
+46
View File
@@ -0,0 +1,46 @@
namespace MtApi
{
public enum EnumObject
{
OBJ_VLINE = 0, //Vertical Line
OBJ_HLINE = 1, //Horizontal Line
OBJ_TREND = 2, //Trend Line
BJ_TRENDBYANGLE = 3, //Trend Line By Angle
OBJ_CYCLES = 20, //Cycle Lines
OBJ_CHANNEL = 5, //Equidistant Channel
OBJ_STDDEVCHANNEL = 6, //Standard Deviation Channel
OBJ_REGRESSION = 4, //Linear Regression Channel
OBJ_PITCHFORK = 19, //Andrews’ Pitchfork
OBJ_GANNLINE = 7, //Gann Line
OBJ_GANNFAN = 8, //Gann Fan
OBJ_GANNGRID = 9, //Gann Grid
OBJ_FIBO = 10, //Fibonacci Retracement
OBJ_FIBOTIMES = 11, //Fibonacci Time Zones
OBJ_FIBOFAN = 12, //Fibonacci Fan
OBJ_FIBOARC = 13, //Fibonacci Arcs
OBJ_FIBOCHANNEL = 15, //Fibonacci Channel
OBJ_EXPANSION = 14, //Fibonacci Expansion
OBJ_RECTANGLE = 16, //Rectangle
OBJ_TRIANGLE = 17, //Triangle
OBJ_ELLIPSE = 18, //Ellipse
OBJ_ARROW_THUMB_UP = 29, //Thumbs Up
OBJ_ARROW_THUMB_DOWN = 30, //Thumbs Down
OBJ_ARROW_UP = 31, //Arrow Up
OBJ_ARROW_DOWN = 32, //Arrow Down
OBJ_ARROW_STOP = 33, //Stop Sign
OBJ_ARROW_CHECK = 34, //Check Sign
OBJ_ARROW_LEFT_PRICE = 35, //Left Price Label
OBJ_ARROW_RIGHT_PRICE = 36, //Right Price Label
OBJ_ARROW_BUY = 37, //Buy Sign
OBJ_ARROW_SELL = 38, //Sell Sign
OBJ_ARROW = 22, //Arrow
OBJ_TEXT = 21, //Text
OBJ_LABEL = 23, //Label
OBJ_BUTTON = 25, //Button
OBJ_BITMAP = 26, //Bitmap
OBJ_BITMAP_LABEL = 24, //Bitmap Label
OBJ_EDIT = 27, //Edit
OBJ_EVENT = 42, //The "Event" object corresponding to an event in the economic calendar
OBJ_RECTANGLE_LABEL = 28 //The "Rectangle label" object for creating and designing the custom graphical interface.
}
}
+11
View File
@@ -0,0 +1,11 @@
namespace MtApi
{
public enum EnumObjectPropertyDouble
{
OBJPROP_PRICE = 20, // Price coordinate
OBJPROP_LEVELVALUE = 204, // Level value
OBJPROP_SCALE = 12, // Scale (properties of Gann objects, Fibonacci Arcs and Ellipse)
OBJPROP_ANGLE = 13, // Angle. For the objects with no angle specified, created from a program, the value is equal to EMPTY_VALUE
OBJPROP_DEVIATION = 16, // Deviation for the Standard Deviation Channel
}
}
+40
View File
@@ -0,0 +1,40 @@
namespace MtApi
{
public enum EnumObjectPropertyInteger
{
OBJPROP_COLOR = 6,
OBJPROP_STYLE = 7,
OBJPROP_WIDTH = 8,
OBJPROP_BACK = 9,
OBJPROP_ZORDER = 207,
OBJPROP_HIDDEN = 208,
OBJPROP_SELECTED = 17,
OBJPROP_READONLY = 1028,
OBJPROP_TYPE = 18,
OBJPROP_TIME = 19,
OBJPROP_SELECTABLE = 1000,
OBJPROP_CREATETIME = 998,
OBJPROP_LEVELS = 200,
OBJPROP_LEVELCOLOR = 201,
OBJPROP_LEVELSTYLE = 202,
OBJPROP_LEVELWIDTH = 203,
OBJPROP_ALIGN = 1036,
OBJPROP_FONTSIZE = 100,
OBJPROP_RAY_RIGHT = 1004,
OBJPROP_ELLIPSE = 11,
OBJPROP_ARROWCODE = 14,
OBJPROP_TIMEFRAMES = 15,
OBJPROP_ANCHOR = 1011,
OBJPROP_XDISTANCE = 102,
OBJPROP_YDISTANCE = 103,
OBJPROP_STATE = 1018,
OBJPROP_XSIZE = 1019,
OBJPROP_YSIZE = 1020,
OBJPROP_XOFFSET = 1033,
OBJPROP_YOFFSET = 1034,
OBJPROP_BGCOLOR = 1025,
OBJPROP_CORNER = 101,
OBJPROP_BORDER_TYPE = 1029,
OBJPROP_BORDER_COLOR = 1035
}
}
+13
View File
@@ -0,0 +1,13 @@
namespace MtApi
{
public enum EnumObjectPropertyString
{
OBJPROP_NAME = 1037,
OBJPROP_TEXT = 999,
OBJPROP_TOOLTIP = 206,
OBJPROP_LEVELTEXT = 205,
OBJPROP_FONT = 1001,
OBJPROP_BMPFILE = 1017,
OBJPROP_SYMBOL = 1021
}
}
-42
View File
@@ -1,42 +0,0 @@
using System;
using System.Threading.Tasks;
namespace MtApi
{
static class ExtensionMethods
{
#region Event Methods
public static Task FireEventAsync(this MtApiQuoteHandler evenHandler, object sender, string symbol, double bid, double ask)
{
return Task.Factory.StartNew(() =>
{
evenHandler?.Invoke(sender, symbol, bid, ask);
});
}
public static Task FireEventAsync(this EventHandler eventHandler, object sender)
{
return Task.Factory.StartNew(() =>
{
eventHandler?.Invoke(sender, EventArgs.Empty);
});
}
public static Task FireEventAsync<T>(this EventHandler<T> eventHandler, object sender, T e)
where T : EventArgs
{
return Task.Factory.StartNew(() =>
{
eventHandler?.Invoke(sender, e);
});
}
#endregion
public static MtQuote Convert(this MTApiService.MtQuote quote)
{
return (quote != null) ? new MtQuote(quote.Instrument, quote.Bid, quote.Ask) : null;
}
}
}
+30
View File
@@ -0,0 +1,30 @@
using System;
namespace MtApi
{
[Flags]
public enum FlagFontStyle
{
//Flags for specifying font style
FONT_ITALIC = -2147483648,
FONT_UNDERLINE = 1073741824,
FONT_STRIKEOUT = 536870912,
//Flags for specifying font width
FW_DONTCARE = 0,
FW_THIN = 1,
FW_EXTRALIGHT = 2,
FW_ULTRALIGHT = 3,
FW_LIGHT = 4,
FW_NORMAL = 5,
FW_REGULAR = 6,
FW_MEDIUM = 7,
FW_SEMIBOLD = 8,
FW_DEMIBOLD = 9,
FW_BOLD = 10,
FW_EXTRABOLD = 11,
FW_ULTRABOLD = 12,
FW_HEAVY = 13,
FW_BLACK = 14
}
}
+12 -1
View File
@@ -58,16 +58,27 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ChartEventArgs.cs" />
<Compile Include="ChartPeriod.cs" />
<Compile Include="EnumAlignMode.cs" />
<Compile Include="EnumChartPropertyDouble.cs" />
<Compile Include="EnumChartPropertyInteger.cs" />
<Compile Include="EnumChartPropertyString.cs" />
<Compile Include="EnumColorFormat.cs" />
<Compile Include="EnumObject.cs" />
<Compile Include="EnumObjectPropertyDouble.cs" />
<Compile Include="EnumObjectPropertyInteger.cs" />
<Compile Include="EnumObjectPropertyString.cs" />
<Compile Include="EnumSeriesInfoInteger.cs" />
<Compile Include="EnumSymbolInfoDouble.cs" />
<Compile Include="EnumSymbolInfoInteger.cs" />
<Compile Include="EnumTerminalInfoDouble.cs" />
<Compile Include="EnumTerminalInfoInteger.cs" />
<Compile Include="ExtensionMethods.cs" />
<Compile Include="FlagFontStyle.cs" />
<Compile Include="Monitors\AvailabilityOrdersEventArgs.cs" />
<Compile Include="MqlRates.cs" />
<Compile Include="MqlTick.cs" />
<Compile Include="MtChartEvent.cs" />
<Compile Include="MtConnectionEventArgs.cs" />
<Compile Include="MtConnectionException.cs" />
<Compile Include="MtConnectionState.cs" />
+1320 -121
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -13,9 +13,9 @@ namespace MtApi
return Color.FromArgb((byte)(color), (byte)(color >> 8), (byte)(color >> 16));
}
public static int ConvertToMtColor(Color color)
public static int ConvertToMtColor(Color? color)
{
return color == Color.Empty ? 0xffffff : (Color.FromArgb(color.B, color.G, color.R).ToArgb() & 0xffffff);
return color == null || color == Color.Empty ? 0xffffff : (Color.FromArgb(color.Value.B, color.Value.G, color.Value.R).ToArgb() & 0xffffff);
}
}
}
+3 -3
View File
@@ -13,13 +13,13 @@ namespace MtApi
return new DateTime(tmpTime.Ticks + (time * 0x989680L));
}
public static int ConvertToMtTime(DateTime time)
public static int ConvertToMtTime(DateTime? time)
{
int result = 0;
if (time != DateTime.MinValue)
if (time != null && time != DateTime.MinValue)
{
DateTime tmpTime = new DateTime(1970, 1, 1);
result = (int)((time.Ticks - tmpTime.Ticks) / 0x989680L);
result = (int)((time.Value.Ticks - tmpTime.Ticks) / 0x989680L);
}
return result;
}
+11
View File
@@ -0,0 +1,11 @@
namespace MtApi
{
internal class MtChartEvent
{
public long ChartId { get; set; }
public int EventId { get; set; }
public long Lparam { get; set; }
public double Dparam { get; set; }
public string Sparam { get; set; }
}
}
Executable → Regular
+86 -9
View File
@@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MtApi
namespace MtApi
{
enum MtCommandType
{
@@ -116,6 +111,7 @@ namespace MtApi
TimeSeconds = 86,
TimeYear = 87,
Year = 88,
TimeGMT = 281,
//Global Variables
GlobalVariableCheck = 89,
@@ -140,8 +136,8 @@ namespace MtApi
iBullsPower = 106,
iCCI = 107,
iCCIOnArray = 108,
iCustom = 109,
iCustom_d = 10109,
//iCustom = 109,
//iCustom_d = 10109,
iDeMarker = 110,
iEnvelopes = 111,
iEnvelopesOnArray = 112,
@@ -201,6 +197,87 @@ namespace MtApi
SymbolsTotal = 200,
SymbolName = 201,
SymbolSelect = 202,
SymbolInfoInteger = 203
SymbolInfoInteger = 203,
//Object Functions
ObjectCreate = 208,
ObjectName = 209,
ObjectDelete = 210,
ObjectsDeleteAll = 211,
ObjectFind = 212,
ObjectGetTimeByValue = 213,
ObjectGetValueByTime = 214,
ObjectMove = 215,
ObjectsTotal = 216,
ObjectGetDouble = 217,
ObjectGetInteger = 218,
ObjectGetString = 219,
ObjectSetDouble = 220,
ObjectSetInteger = 221,
ObjectSetString = 222,
TextSetFont = 223,
TextOut = 224,
TextGetSize = 225,
ObjectDescription = 226,
ObjectGet = 227,
ObjectGetFiboDescription = 228,
ObjectGetShiftByValue = 229,
ObjectGetValueByShift = 230,
ObjectSet = 231,
ObjectSetFiboDescription = 232,
ObjectSetText = 233,
ObjectType = 234,
UnlockTicks = 235,
//Chart Operations
ChartId = 206,
ChartRedraw = 207,
ChartApplyTemplate = 236,
ChartSaveTemplate = 237,
ChartWindowFind = 238,
ChartTimePriceToXY = 239,
ChartXYToTimePrice = 240,
ChartOpen = 241,
ChartFirst = 242,
ChartNext = 243,
ChartClose = 244,
ChartSymbol = 245,
ChartPeriod = 246,
ChartSetDouble = 247,
ChartSetInteger = 248,
ChartSetString = 249,
ChartGetDouble = 250,
ChartGetInteger = 251,
ChartGetString = 252,
ChartNavigate = 253,
ChartIndicatorDelete = 254,
ChartIndicatorName = 255,
ChartIndicatorsTotal = 256,
ChartWindowOnDropped = 257,
ChartPriceOnDropped = 258,
ChartTimeOnDropped = 259,
ChartXOnDropped = 260,
ChartYOnDropped = 261,
ChartSetSymbolPeriod = 262,
ChartScreenShot = 263,
WindowBarsPerChart = 264,
WindowExpertName = 265,
WindowFind = 266,
WindowFirstVisibleBar = 267,
WindowHandle = 268,
WindowIsVisible = 269,
WindowOnDropped = 270,
WindowPriceMax = 271,
WindowPriceMin = 272,
WindowPriceOnDropped = 273,
WindowRedraw = 274,
WindowScreenShot = 275,
WindowTimeOnDropped = 276,
WindowsTotal = 277,
WindowXOnDropped = 278,
WindowYOnDropped = 279,
ChangeAccount = 280
}
}
+1 -4
View File
@@ -1,14 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MtApi
{
public class MtConnectionEventArgs: EventArgs
{
public MtConnectionState Status { get; private set; }
public String ConnectionMessage { get; private set; }
public string ConnectionMessage { get; private set; }
public MtConnectionEventArgs(MtConnectionState status, string message)
{
+2 -1
View File
@@ -2,6 +2,7 @@
{
public enum MtEventTypes
{
LastTimeBar = 1
LastTimeBar = 1,
ChartEvent = 2
}
}
+9
View File
@@ -5,6 +5,7 @@
public string Instrument { get; private set; }
public double Bid { get; private set; }
public double Ask { get; private set; }
public int ExpertHandle { get; private set; }
public MtQuote(string instrument, double bid, double ask)
{
@@ -12,5 +13,13 @@
Bid = bid;
Ask = ask;
}
internal MtQuote(MTApiService.MtQuote quote)
{
Instrument = quote.Instrument;
Bid = quote.Bid;
Ask = quote.Ask;
ExpertHandle = quote.ExpertHandle;
}
}
}
-3
View File
@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MtApi
{
+2 -11
View File
@@ -11,16 +11,7 @@ namespace MtApi
public double Close { get; set; }
public double High { get; set; }
public double Low { get; set; }
public DateTime OpenTime
{
get { return MtApiTimeConverter.ConvertFromMtTime(MtOpenTime); }
}
public DateTime CloseTime
{
get { return MtApiTimeConverter.ConvertFromMtTime(MtCloseTime); }
}
public DateTime OpenTime => MtApiTimeConverter.ConvertFromMtTime(MtOpenTime);
public DateTime CloseTime => MtApiTimeConverter.ConvertFromMtTime(MtCloseTime);
}
}
+3 -1
View File
@@ -1,4 +1,6 @@
namespace MtApi
// ReSharper disable InconsistentNaming
namespace MtApi
{
public enum ENUM_TERMINAL_INFO_STRING
{
Executable → Regular
+2 -2
View File
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.32.1")]
[assembly: AssemblyFileVersion("1.0.32.1")]
[assembly: AssemblyVersion("1.0.40.0")]
[assembly: AssemblyFileVersion("1.0.40.0")]
+8 -5
View File
@@ -1,18 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MtApi
{
public class TimeBarArgs: EventArgs
{
internal TimeBarArgs(int expertHandle, MtTimeBar timeBar)
: this(timeBar)
{
ExpertHandle = expertHandle;
}
public TimeBarArgs(MtTimeBar timeBar)
{
TimeBar = timeBar;
}
public MtTimeBar TimeBar { get; private set; }
public int ExpertHandle { get; }
public MtTimeBar TimeBar { get; }
}
}
+8
View File
@@ -0,0 +1,8 @@
namespace MtApi5.Events
{
internal enum Mt5EventTypes
{
OnTradeTransaction = 1,
OnBookEvent = 2
}
}
+7
View File
@@ -0,0 +1,7 @@
namespace MtApi5.Events
{
internal class OnBookEvent
{
public string Symbol { get; set; }
}
}
+9
View File
@@ -0,0 +1,9 @@
namespace MtApi5.Events
{
internal class OnTradeTransactionEvent
{
public MqlTradeTransaction Trans { get; set; }
public MqlTradeRequest Request { get; set; }
public MqlTradeResult Result { get; set; }
}
}
-21
View File
@@ -1,21 +0,0 @@
using System;
namespace MtApi5
{
internal static class ExtensionMethods
{
#region Event Methods
public static void FireEvent(this EventHandler eventHandler, object sender)
{
eventHandler?.Invoke(sender, EventArgs.Empty);
}
public static void FireEvent<T>(this EventHandler<T> eventHandler, object sender, T e)
where T : EventArgs
{
eventHandler?.Invoke(sender, e);
}
#endregion
}
}
+12 -8
View File
@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
// ReSharper disable InconsistentNaming
namespace MtApi5
{
public class MqlBookInfo
@@ -14,8 +10,16 @@ namespace MtApi5
this.volume = volume;
}
public ENUM_BOOK_TYPE type { get; private set; } // Order type from ENUM_BOOK_TYPE enumeration
public double price { get; private set; } // Price
public long volume { get; private set; } // Volume
public MqlBookInfo()
{ }
public ENUM_BOOK_TYPE type { get; set; } // Order type from ENUM_BOOK_TYPE enumeration
public double price { get; set; } // Price
public long volume { get; set; } // Volume
public override string ToString()
{
return $"type = {type}; price = {price}; volume = {volume}";
}
}
}
+10
View File
@@ -0,0 +1,10 @@
namespace MtApi5
{
public class MqlParam
{
public ENUM_DATATYPE DataType { get; set; }
public long? IntegerValue { get; set; }
public double? DoubleValue { get; set; }
public string StringValue { get; set; }
}
}
+2 -1
View File
@@ -1,4 +1,5 @@
using System;
// ReSharper disable InconsistentNaming
using System;
namespace MtApi5
{
+2 -1
View File
@@ -1,4 +1,5 @@
using System;
// ReSharper disable InconsistentNaming
using System;
namespace MtApi5
{
+17 -12
View File
@@ -1,20 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
// ReSharper disable InconsistentNaming
namespace MtApi5
{
public class MqlTradeCheckResult
{
public uint Retcode { get; private set; } // Reply code
public double Balance { get; private set; } // Balance after the execution of the deal
public double Equity { get; private set; } // Equity after the execution of the deal
public double Profit { get; private set; } // Floating profit
public double Margin { get; private set; } // Margin requirements
public double Margin_free { get; private set; } // Free margin
public double Margin_level { get; private set; } // Margin level
public string Comment { get; private set; } // Comment to the reply code (description of the error)
public uint Retcode { get; set; } // Reply code
public double Balance { get; set; } // Balance after the execution of the deal
public double Equity { get; set; } // Equity after the execution of the deal
public double Profit { get; set; } // Floating profit
public double Margin { get; set; } // Margin requirements
public double Margin_free { get; set; } // Free margin
public double Margin_level { get; set; } // Margin level
public string Comment { get; set; } // Comment to the reply code (description of the error)
public MqlTradeCheckResult(uint retcode
, double balance
@@ -34,5 +31,13 @@ namespace MtApi5
Margin_level = margin_level;
Comment = comment;
}
public MqlTradeCheckResult()
{ }
public override string ToString()
{
return $"Retcode={Retcode}; Comment={Comment}; Balance={Balance}; Equity={Equity}; Profit={Profit}; Margin={Margin}; Margin_free={Margin_free}; Margin_level={Margin_level}";
}
}
}
+22 -4
View File
@@ -1,11 +1,13 @@
using System;
// ReSharper disable InconsistentNaming
using System;
using Newtonsoft.Json;
namespace MtApi5
{
public class MqlTradeRequest
{
public ENUM_TRADE_REQUEST_ACTIONS Action { get; set; } // Trade operation type
public uint Magic { get; set; } // Expert Advisor ID (magic number)
public ulong Magic { get; set; } // Expert Advisor ID (magic number)
public ulong Order { get; set; } // Order ticket
public string Symbol { get; set; } // Trade symbol
public double Volume { get; set; } // Requested volume for a deal in lots
@@ -13,11 +15,27 @@ namespace MtApi5
public double Stoplimit { get; set; } // StopLimit level of the order
public double Sl { get; set; } // Stop Loss level of the order
public double Tp { get; set; } // Take Profit level of the order
public uint Deviation { get; set; } // Maximal possible deviation from the requested price
public ulong Deviation { get; set; } // Maximal possible deviation from the requested price
public ENUM_ORDER_TYPE Type { get; set; } // Order type
public ENUM_ORDER_TYPE_FILLING Type_filling { get; set; } // Order execution type
public ENUM_ORDER_TYPE_TIME Type_time { get; set; } // Order expiration type
public DateTime Expiration { get; set; } // Order expiration time (for the orders of ORDER_TIME_SPECIFIED type)
[JsonIgnore]
public DateTime Expiration // Order expiration time (for the orders of ORDER_TIME_SPECIFIED type)
{
get { return Mt5TimeConverter.ConvertFromMtTime(MtExpiration); }
set { MtExpiration = Mt5TimeConverter.ConvertToMtTime(value); }
}
public string Comment { get; set; } // Order comment
public ulong Position { get; set; } // Position ticket
public ulong PositionBy { get; set; } // The ticket of an opposite position
public int MtExpiration { get; private set; }
public override string ToString()
{
return $"Action={Action}; Magic={Magic}; Order={Order}; Symbol={Symbol}; Volume={Volume}; Price={Price}; Stoplimit={Stoplimit}; Sl={Sl}; Tp={Tp}; Deviation={Deviation}; Type={Type}; Type_filling={Type_filling}; Type_time={Type_time}; Expiration={Expiration}; Comment={Comment}; Position={Position}; PositionBy={PositionBy}";
}
}
}
+28 -12
View File
@@ -1,6 +1,4 @@
using System;
using System.Linq;
using System.Text;
// ReSharper disable InconsistentNaming
namespace MtApi5
{
@@ -19,14 +17,32 @@ namespace MtApi5
Request_id = request_id;
}
public uint Retcode { get; private set; } // Operation return code
public ulong Deal { get; private set; } // Deal ticket, if it is performed
public ulong Order { get; private set; } // Order ticket, if it is placed
public double Volume { get; private set; } // Deal volume, confirmed by broker
public double Price { get; private set; } // Deal price, confirmed by broker
public double Bid { get; private set; } // Current Bid price
public double Ask { get; private set; } // Current Ask price
public string Comment { get; private set; } // Broker comment to operation (by default it is filled by the operation description)
public uint Request_id { get; private set; } // Request ID set by the terminal during the dispatch
internal MqlTradeResult(MqlTradeResult o)
{
Retcode = o.Retcode;
Deal = o.Deal;
Order = o.Order;
Volume = o.Volume;
Price = o.Price;
Bid = o.Bid;
Ask = o.Ask;
Comment = o.Comment;
Request_id = o.Request_id;
}
public uint Retcode { get; } // Operation return code
public ulong Deal { get; } // Deal ticket, if it is performed
public ulong Order { get; } // Order ticket, if it is placed
public double Volume { get; } // Deal volume, confirmed by broker
public double Price { get; } // Deal price, confirmed by broker
public double Bid { get; } // Current Bid price
public double Ask { get; } // Current Ask price
public string Comment { get; } // Broker comment to operation (by default it is filled by the operation description)
public uint Request_id { get; } // Request ID set by the terminal during the dispatch
public override string ToString()
{
return $"Retcode={Retcode}; Comment={Comment}; Deal={Deal}; Order={Order}; Volume={Volume}; Price={Price}; Bid={Bid}; Ask={Ask}; Request_id={Request_id}";
}
}
}
+39
View File
@@ -0,0 +1,39 @@
using System;
using Newtonsoft.Json;
namespace MtApi5
{
public class MqlTradeTransaction
{
public ulong Deal { get; set; } // Deal ticket
public ulong Order { get; set; } // Order ticket
public string Symbol { get; set; } // Trade symbol name
public ENUM_TRADE_TRANSACTION_TYPE Type { get; set; } // Trade transaction type
public ENUM_ORDER_TYPE OrderType { get; set; } // Order type
public ENUM_ORDER_STATE OrderState { get; set; } // Order state
public ENUM_DEAL_TYPE DealType { get; set; } // Deal type
public ENUM_ORDER_TYPE_TIME TimeType { get; set; } // Order type by action period
[JsonIgnore]
public DateTime TimeExpiration // Order expiration time
{
get { return Mt5TimeConverter.ConvertFromMtTime(MtTimeExpiration); }
set { MtTimeExpiration = Mt5TimeConverter.ConvertToMtTime(value); }
}
public double Price { get; set; } // Price
public double PriceTrigger { get; set; } // Stop limit order activation price
public double PriceSl { get; set; } // Stop Loss level
public double PriceTp { get; set; } // Take Profit level
public double Volume { get; set; } // Volume in lots
public ulong Position { get; set; } // Position ticket
public ulong PositionBy { get; set; } // Ticket of an opposite position
public int MtTimeExpiration { get; private set; }
public override string ToString()
{
return $"Deal={Deal}; Order={Order}; Symbol={Symbol}; Type={Type}; OrderType={OrderType}; OrderState={OrderState}; DealType={DealType}; TimeType={TimeType}; TimeExpiration={TimeExpiration}; Price={Price}; PriceTrigger{PriceTrigger}; PriceSl={PriceSl}; PriceTp={PriceTp}; Volume={Volume}; Position={Position}; PositionBy={PositionBy}";
}
}
}
+10
View File
@@ -0,0 +1,10 @@
using System;
namespace MtApi5
{
public class Mt5BookEventArgs : EventArgs
{
public int ExpertHandle { get; set; }
public string Symbol { get; set; } //Symbol of OnBookEvent event.
}
}
+132 -10
View File
@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
// ReSharper disable InconsistentNaming
namespace MtApi5
{
internal enum Mt5CommandType
@@ -10,10 +6,9 @@ namespace MtApi5
//NoCommand = 0
//trade operations
OrderSend = 1,
//OrderSend = 1,
OrderCalcMargin = 2,
OrderCalcProfit = 3,
OrderCheck = 4,
//OrderSendAsync = 5,
PositionsTotal = 6,
PositionGetSymbol = 7,
@@ -21,6 +16,7 @@ namespace MtApi5
PositionGetDouble = 9,
PositionGetInteger = 10,
PositionGetString = 11,
PositionGetTicket = 4,
OrdersTotal = 12,
OrderGetTicket = 13,
OrderSelect = 14,
@@ -99,20 +95,146 @@ namespace MtApi5
SymbolInfoSessionTrade = 59,
MarketBookAdd = 60,
MarketBookRelease = 61,
MarketBookGet = 62,
//MarketBookGet = 62,
OrderCloseAll = 63,
//CTrade
PositionClose = 64,
PositionOpen = 65,
//PositionOpenWithResult = 1065,
//Backtesting
BacktestingReady = 66,
IsTesting = 67,
Print = 68,
//Requests
MtRequest = 155,
PositionSelectByTicket = 69,
ObjectCreate = 70,
ObjectName = 71,
ObjectDelete = 72,
ObjectsDeleteAll = 73,
ObjectFind = 74,
ObjectGetTimeByValue = 75,
ObjectGetValueByTime = 76,
ObjectMove = 77,
ObjectsTotal = 78,
ObjectGetDouble = 79,
ObjectGetInteger = 80,
ObjectGetString = 81,
ObjectSetDouble = 82,
ObjectSetInteger = 83,
ObjectSetString = 84,
//TextSetFont = 85,
//TextOut = 86,
//TextGetSize = 87,
iAC = 88,
iAD = 89,
iADX = 90,
iADXWilder = 91,
iAlligator = 92,
iAMA = 93,
iAO = 94,
iATR = 95,
iBearsPower = 96,
iBands = 97,
iBullsPower = 98,
iCCI = 99,
iChaikin = 100,
//iCustom = 101,
iDEMA = 102,
iDeMarker = 103,
iEnvelopes = 104,
iForce = 105,
iFractals = 106,
iFrAMA = 107,
iGator = 108,
iIchimoku = 109,
iBWMFI = 110,
iMomentum = 111,
iMFI = 112,
iMA = 113,
iOsMA = 114,
iMACD = 115,
iOBV = 116,
iSAR = 117,
iRSI = 118,
iRVI = 119,
iStdDev = 120,
iStochastic = 121,
iTEMA = 122,
iTriX = 123,
iWPR = 124,
iVIDyA = 125,
iVolumes = 126,
//Date and Time
TimeCurrent = 127,
TimeTradeServer = 128,
TimeLocal = 129,
TimeGMT = 130,
IndicatorRelease = 131,
//Chart Operations
ChartId = 206,
ChartRedraw = 207,
ChartApplyTemplate = 236,
ChartSaveTemplate = 237,
ChartWindowFind = 238,
//ChartTimePriceToXY = 239,
//ChartXYToTimePrice = 240,
ChartOpen = 241,
ChartFirst = 242,
ChartNext = 243,
ChartClose = 244,
ChartSymbol = 245,
ChartPeriod = 246,
ChartSetDouble = 247,
ChartSetInteger = 248,
ChartSetString = 249,
ChartGetDouble = 250,
ChartGetInteger = 251,
ChartGetString = 252,
ChartNavigate = 253,
ChartIndicatorDelete = 254,
ChartIndicatorName = 255,
ChartIndicatorsTotal = 256,
ChartWindowOnDropped = 257,
ChartPriceOnDropped = 258,
ChartTimeOnDropped = 259,
ChartXOnDropped = 260,
ChartYOnDropped = 261,
ChartSetSymbolPeriod = 262,
ChartScreenShot = 263,
ChartIndicatorAdd = 280,
ChartIndicatorGet = 281,
// Terminal Operations
TerminalCompany = 68,
TerminalName = 69,
TerminalPath = 70,
//Checkup
GetLastError = 132,
TerminalInfoString = 153,
TerminalInfoInteger = 204,
TerminalInfoDouble = 205,
//Common Functions
Alert = 136,
Comment = 137, //TODO
GetTickCount = 138, //TODO
GetMicrosecondCount = 139, //TODO
MessageBox = 140, //TODO
PeriodSeconds = 141, //TODO
PlaySound = 142, //TODO
Print = 68,
ResetLastError = 143,
SendNotification = 144, //TODO
SendMail = 145 //TODO
}
}
+2 -5
View File
@@ -1,14 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MtApi5
{
public class Mt5ConnectionEventArgs: EventArgs
{
public Mt5ConnectionState Status { get; private set; }
public String ConnectionMessage { get; private set; }
public Mt5ConnectionState Status { get; }
public string ConnectionMessage { get; }
public Mt5ConnectionEventArgs(Mt5ConnectionState status, string message)
{
+820 -212
View File
File diff suppressed because it is too large Load Diff
+12 -8
View File
@@ -1,21 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MTApiService;
namespace MtApi5
{
public class Mt5Quote
{
public string Instrument { get; private set; }
public double Bid { get; private set; }
public double Ask { get; private set; }
public string Instrument { get; }
public double Bid { get; }
public double Ask { get; }
public int ExpertHandle { get; set; }
public Mt5Quote(string instrument, double bid, double ask)
private Mt5Quote(string instrument, double bid, double ask)
{
Instrument = instrument;
Bid = bid;
Ask = ask;
}
internal Mt5Quote(MtQuote quote)
:this(quote.Instrument, quote.Bid, quote.Ask)
{
ExpertHandle = quote.ExpertHandle;
}
}
}
+1 -4
View File
@@ -1,13 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MtApi5
{
public class Mt5QuoteEventArgs: EventArgs
{
public Mt5Quote Quote { get; private set; }
public Mt5Quote Quote { get; }
public Mt5QuoteEventArgs(Mt5Quote quote)
{
+9 -13
View File
@@ -1,32 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MtApi5
{
class Mt5TimeConverter
internal class Mt5TimeConverter
{
public static DateTime ConvertFromMtTime(int time)
{
DateTime tmpTime = new DateTime(1970, 1, 1);
var tmpTime = new DateTime(1970, 1, 1);
return new DateTime(tmpTime.Ticks + (time * 0x989680L));
}
public static DateTime ConvertFromMtTime(long time)
{
DateTime tmpTime = new DateTime(1970, 1, 1);
var tmpTime = new DateTime(1970, 1, 1);
return new DateTime(tmpTime.Ticks + (time * 0x989680L));
}
public static int ConvertToMtTime(DateTime time)
public static int ConvertToMtTime(DateTime? time)
{
int result = 0;
if (time != DateTime.MinValue)
{
DateTime tmpTime = new DateTime(1970, 1, 1);
result = (int)((time.Ticks - tmpTime.Ticks) / 0x989680L);
}
var result = 0;
if (time == null || time == DateTime.MinValue)
return result;
var tmpTime = new DateTime(1970, 1, 1);
result = (int)((time.Value.Ticks - tmpTime.Ticks) / 0x989680L);
return result;
}
}
+12
View File
@@ -0,0 +1,12 @@
using System;
namespace MtApi5
{
public class Mt5TradeTransactionEventArgs : EventArgs
{
public int ExpertHandle { get; set; }
public MqlTradeTransaction Trans { get; set; } // trade transaction structure
public MqlTradeRequest Request { get; set; } // request structure
public MqlTradeResult Result { get; set; } // result structure
}
}
+23 -3
View File
@@ -48,30 +48,49 @@
</ItemGroup>
<ItemGroup>
<Compile Include="CopyTicksFlag.cs" />
<Compile Include="Events\OnBookEvent.cs" />
<Compile Include="Events\OnTradeTransactionEvent.cs" />
<Compile Include="MqlBookInfo.cs" />
<Compile Include="MqlParam.cs" />
<Compile Include="MqlRates.cs" />
<Compile Include="MqlTick.cs" />
<Compile Include="MqlTradeCheckResult.cs" />
<Compile Include="MqlTradeTransaction.cs" />
<Compile Include="Mt5BookEventArgs.cs" />
<Compile Include="Mt5TimeConverter.cs" />
<Compile Include="Mt5Enums.cs" />
<Compile Include="Mt5ConnectionEventArgs.cs" />
<Compile Include="Mt5ConnectionState.cs" />
<Compile Include="ExtensionMethods.cs" />
<Compile Include="MqlTradeRequest.cs" />
<Compile Include="MqlTradeResult.cs" />
<Compile Include="Mt5QuoteEventArgs.cs" />
<Compile Include="Mt5TradeTransactionEventArgs.cs" />
<Compile Include="MtApi5Client.cs" />
<Compile Include="Mt5CommandType.cs" />
<Compile Include="MtConverters.cs" />
<Compile Include="ErrorCode.cs" />
<Compile Include="ExecutionException.cs" />
<Compile Include="Events\Mt5EventTypes.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Mt5Quote.cs" />
<Compile Include="Requests\ChartTimePriceToXyRequest.cs" />
<Compile Include="Requests\ChartTimePriceToXyResult.cs" />
<Compile Include="Requests\ChartXyToTimePriceRequest.cs" />
<Compile Include="Requests\ChartXyToTimePriceResult.cs" />
<Compile Include="Requests\CopyTicksRequest.cs" />
<Compile Include="Requests\ICustomRequest.cs" />
<Compile Include="Requests\IndicatorCreateRequest.cs" />
<Compile Include="Requests\MarketBookGetRequest.cs" />
<Compile Include="Requests\OrderCheckRequest.cs" />
<Compile Include="Requests\OrderCheckResult.cs" />
<Compile Include="Requests\OrderSendRequest.cs" />
<Compile Include="Requests\PositionOpenRequest.cs" />
<Compile Include="Requests\RequestBase.cs" />
<Compile Include="Requests\RequestType.cs" />
<Compile Include="Responses\CopyTicksResponse.cs" />
<Compile Include="Responses\ResponseBase.cs" />
<Compile Include="Requests\OrderSendResult.cs" />
<Compile Include="Requests\Response.cs" />
<Compile Include="Requests\SymbolInfoStringRequest.cs" />
<Compile Include="Requests\SymbolInfoStringResult.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MTApiService\MTApiService.csproj">
@@ -82,6 +101,7 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<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.
+1748 -170
View File
File diff suppressed because it is too large Load Diff
+19 -77
View File
@@ -6,84 +6,14 @@ namespace MtApi5
{
internal static class MtConverters
{
private static readonly MtLog Log = LogConfigurator.GetLogger(typeof(MtConverters));
#region Values Converters
public static Mt5Quote Parse(this MtQuote quote)
{
return (quote != null) ? new Mt5Quote(quote.Instrument, quote.Bid, quote.Ask) : null;
}
public static bool ParseResult(this string inputString, char separator, out MqlTradeResult result)
{
var retVal = false;
result = null;
if (string.IsNullOrEmpty(inputString) == false)
{
var values = inputString.Split(separator);
if (values.Length == 10)
{
try
{
retVal = int.Parse(values[0]) != 0;
var retcode = uint.Parse(values[1]);
var deal = ulong.Parse(values[2]);
var order = ulong.Parse(values[3]);
var volume = double.Parse(values[4]);
var price = double.Parse(values[5]);
var bid = double.Parse(values[6]);
var ask = double.Parse(values[7]);
var comment = values[8];
var requestId = uint.Parse(values[9]);
result = new MqlTradeResult(retcode, deal, order, volume, price, bid, ask, comment, requestId);
}
catch (Exception)
{
}
}
}
return retVal;
}
public static bool ParseResult(this string inputString, char separator, out MqlTradeCheckResult result)
{
var retVal = false;
result = null;
if (string.IsNullOrEmpty(inputString) == false)
{
var values = inputString.Split(separator);
if (values.Length == 10)
{
try
{
retVal = int.Parse(values[0]) != 0;
var retcode = uint.Parse(values[1]);
var balance = double.Parse(values[2]);
var equity = double.Parse(values[3]);
var profit = double.Parse(values[4]);
var margin = double.Parse(values[5]);
var marginFree = double.Parse(values[6]);
var marginLevel = double.Parse(values[7]);
var comment = values[8];
result = new MqlTradeCheckResult(retcode, balance, equity, profit, margin, marginFree, marginLevel, comment);
}
catch (Exception)
{
retVal = false;
}
}
}
return retVal;
}
public static bool ParseResult(this string inputString, char separator, out double result)
{
Log.Debug($"ParseResult: inputString = {inputString}, separator = {separator}");
var retVal = false;
result = 0;
@@ -98,18 +28,25 @@ namespace MtApi5
result = double.Parse(values[1]);
}
catch (Exception)
catch (Exception ex)
{
retVal = false;
Log.Error($"ParseResult: {ex.Message}");
}
}
}
else
{
Log.Warn("ParseResult: input srting is null or empty!");
}
return retVal;
}
public static bool ParseResult(this string inputString, char separator, out DateTime from, out DateTime to)
{
Log.Debug($"ParseResult: inputString = {inputString}, separator = {separator}");
var retVal = false;
from = new DateTime();
@@ -130,12 +67,17 @@ namespace MtApi5
var iTo= int.Parse(values[2]);
to = Mt5TimeConverter.ConvertFromMtTime(iTo);
}
catch (Exception)
catch (Exception ex)
{
retVal = false;
Log.Error($"ParseResult: {ex.Message}");
}
}
}
else
{
Log.Warn("ParseResult: input srting is null or empty!");
}
return retVal;
}
@@ -149,7 +91,7 @@ namespace MtApi5
return new ArrayList { (int)request.Action, request.Magic, request.Order, request.Symbol, request.Volume
, request.Price, request.Stoplimit, request.Sl, request.Tp, request.Deviation, (int)request.Type
, (int)request.Type_filling, (int)request.Type_time, exp, request.Comment };
, (int)request.Type_filling, (int)request.Type_time, exp, request.Comment, request.Position, request.PositionBy };
}
#endregion
+2 -2
View File
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.11.0")]
[assembly: AssemblyFileVersion("1.0.11.0")]
[assembly: AssemblyVersion("1.0.18")]
[assembly: AssemblyFileVersion("1.0.18")]
@@ -0,0 +1,16 @@
using System;
namespace MtApi5.Requests
{
internal class ChartTimePriceToXyRequest : RequestBase
{
public override RequestType RequestType => RequestType.ChartTimePriceToXY;
public long ChartId { get; set; }
public int SubWindow { get; set; }
public DateTime? Time { get; set; }
public double Price { get; set; }
public int MtTime => Mt5TimeConverter.ConvertToMtTime(Time);
}
}
@@ -0,0 +1,9 @@
namespace MtApi5.Requests
{
internal class ChartTimePriceToXyResult
{
public bool RetVal { get; set; }
public int X { get; set; }
public int Y { get; set; }
}
}
@@ -0,0 +1,13 @@
using System;
namespace MtApi5.Requests
{
internal class ChartXyToTimePriceRequest : RequestBase
{
public override RequestType RequestType => RequestType.ChartXYToTimePrice;
public long ChartId { get; set; }
public int X { get; set; }
public int Y { get; set; }
}
}
@@ -0,0 +1,14 @@
using System;
namespace MtApi5.Requests
{
internal class ChartXyToTimePriceResult
{
public bool RetVal { get; set; }
public int SubWindow { get; set; }
public DateTime? Time => Mt5TimeConverter.ConvertFromMtTime(MtTime);
public double Price { get; set; }
public int MtTime { get; set; }
}
}
+23
View File
@@ -0,0 +1,23 @@
using System.Collections;
namespace MtApi5.Requests
{
internal class ICustomRequest : RequestBase
{
public enum ParametersType
{
Int = 0,
Double = 1,
String = 2,
Boolean = 3
}
public string Symbol { get; set; }
public int Timeframe { get; set; }
public string Name { get; set; }
public ArrayList Params { get; set; }
public ParametersType ParamsType { get; set; }
public override RequestType RequestType => RequestType.iCustom;
}
}
+14
View File
@@ -0,0 +1,14 @@
using System.Collections.Generic;
namespace MtApi5.Requests
{
internal class IndicatorCreateRequest: RequestBase
{
public override RequestType RequestType => RequestType.IndicatorCreate;
public string Symbol { get; set; }
public ENUM_TIMEFRAMES Period { get; set; }
public ENUM_INDICATOR IndicatorType { get; set; }
public List<MqlParam> Parameters { get; set; }
}
}
+9
View File
@@ -0,0 +1,9 @@
namespace MtApi5.Requests
{
internal class MarketBookGetRequest: RequestBase
{
public override RequestType RequestType => RequestType.MarketBookGet;
public string Symbol { get; set; }
}
}
+10
View File
@@ -0,0 +1,10 @@
namespace MtApi5.Requests
{
internal class OrderCheckRequest: RequestBase
{
public override RequestType RequestType => RequestType.OrderCheck;
public MqlTradeRequest TradeRequest { get; set; }
}
}
+8
View File
@@ -0,0 +1,8 @@
namespace MtApi5.Requests
{
public class OrderCheckResult
{
public bool RetVal { get; set; }
public MqlTradeCheckResult TradeCheckResult { get; set; }
}
}
+9
View File
@@ -0,0 +1,9 @@
namespace MtApi5.Requests
{
internal class OrderSendRequest: RequestBase
{
public override RequestType RequestType => RequestType.OrderSend;
public MqlTradeRequest TradeRequest { get; set; }
}
}
+8
View File
@@ -0,0 +1,8 @@
namespace MtApi5.Requests
{
internal class OrderSendResult
{
public bool RetVal { get; set; }
public MqlTradeResult TradeResult { get; set; }
}
}
+15
View File
@@ -0,0 +1,15 @@
namespace MtApi5.Requests
{
internal class PositionOpenRequest: RequestBase
{
public override RequestType RequestType => RequestType.PositionOpen;
public string Symbol { get; set; }
public ENUM_ORDER_TYPE OrderType { get; set; }
public double Volume { get; set; }
public double Price { get; set; }
public double Sl { get; set; }
public double Tp { get; set; }
public string Comment { get; set; }
}
}
+14 -3
View File
@@ -1,8 +1,19 @@
namespace MtApi5.Requests
// ReSharper disable InconsistentNaming
namespace MtApi5.Requests
{
internal enum RequestType
{
Unknown = 0,
CopyTicks = 1
Unknown = 0,
CopyTicks = 1,
iCustom = 2,
OrderSend = 3,
PositionOpen = 4,
OrderCheck = 5,
MarketBookGet = 6,
IndicatorCreate = 7,
SymbolInfoString = 8,
ChartTimePriceToXY = 9,
ChartXYToTimePrice = 10
}
}
+4 -2
View File
@@ -1,8 +1,10 @@
namespace MtApi5.Responses
namespace MtApi5.Requests
{
internal class ResponseBase
internal class Response<T>
{
public int ErrorCode { get; set; }
public string ErrorMessage { get; set; }
public T Value { get; set; }
}
}
@@ -0,0 +1,10 @@
namespace MtApi5.Requests
{
internal class SymbolInfoStringRequest : RequestBase
{
public override RequestType RequestType => RequestType.SymbolInfoString;
public string SymbolName { get; set; }
public ENUM_SYMBOL_INFO_STRING PropId { get; set; }
}
}
@@ -0,0 +1,8 @@
namespace MtApi5.Requests
{
internal class SymbolInfoStringResult
{
public bool RetVal { get; set; }
public string StringVar { get; set; }
}
}
-9
View File
@@ -1,9 +0,0 @@
using System.Collections.Generic;
namespace MtApi5.Responses
{
internal class CopyTicksResponse: ResponseBase
{
public List<MqlTick> Ticks { get; set; }
}
}
+1
View File
@@ -10,6 +10,7 @@
<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>
<RunWixToolsOutOfProc>true</RunWixToolsOutOfProc>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<OutputPath>..\build\installers\$(Configuration)\</OutputPath>
+470 -269
View File
@@ -4,7 +4,7 @@
xmlns:mtapi5="clr-namespace:MtApi5;assembly=MtApi5"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:mtApi5TestClient="clr-namespace:MtApi5TestClient"
Title="MainWindow" Height="700" Width="650"
Title="MainWindow" Height="700" Width="900"
Closing="Window_Closing">
<Window.Resources>
<DataTemplate x:Key="ConnectionTextBlockTemplate" DataType="{x:Type mtapi5:Mt5ConnectionState}">
@@ -78,19 +78,48 @@
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<ObjectDataProvider x:Key="ENUM_TERMINAL_INFO_INTEGER_Key" MethodName="GetValues"
ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="mtapi5:ENUM_TERMINAL_INFO_INTEGER"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<ObjectDataProvider x:Key="ENUM_TERMINAL_INFO_STRING_Key" MethodName="GetValues"
ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="mtapi5:ENUM_TERMINAL_INFO_STRING"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<ObjectDataProvider x:Key="ENUM_TERMINAL_INFO_DOUBLE_Key" MethodName="GetValues"
ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="mtapi5:ENUM_TERMINAL_INFO_DOUBLE"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<ObjectDataProvider x:Key="ENUM_TIMEFRAMES_Key" MethodName="GetValues"
ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="mtapi5:ENUM_TIMEFRAMES"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<ObjectDataProvider x:Key="ENUM_INDICATOR_Key" MethodName="GetValues"
ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="mtapi5:ENUM_INDICATOR"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
<Grid x:Name="_MainLayout">
<Grid.RowDefinitions>
<RowDefinition Height="0.65*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="0.35*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
@@ -100,308 +129,480 @@
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Expander ExpandDirection="Right" IsExpanded="True"
Grid.Row="0" Grid.Column="0" Margin="5">
<Expander.Header>
<TextBlock Text="Connection" RenderTransformOrigin="0.5,0.5" Margin="0,0,0,0" Width="Auto">
<TextBlock.LayoutTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
<SkewTransform AngleX="0" AngleY="0"/>
<RotateTransform Angle="-90"/>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</TextBlock.LayoutTransform>
<TextBlock.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
<SkewTransform AngleX="0" AngleY="0"/>
<RotateTransform Angle="0"/>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</TextBlock.RenderTransform>
</TextBlock>
</Expander.Header>
<Expander.Content>
<Grid Margin="10">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" Margin="2" Visibility="Visible" BorderThickness="1" BorderBrush="DarkBlue">
<StackPanel>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Host" Margin="5,2,2,2" VerticalAlignment="Center"/>
<TextBox Grid.Row="0" Grid.Column="1" Margin="2" Text="{Binding Host, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="Port" Margin="5,2,2,2" VerticalAlignment="Center"/>
<TextBox Grid.Row="1" Grid.Column="1" Margin="2" Width="70" HorizontalAlignment="Left" Text="{Binding Port, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="30,5,0,10" >
<Button Content="Connect" Width="70" Command="{Binding ConnectCommand}" />
<Button Margin="10,0,0,0" Width="70" Content="Disconnect" Command="{Binding DisconnectCommand}" />
</StackPanel>
</StackPanel>
</Border>
<Border Grid.Row="3" Margin="2" Visibility="Visible" BorderThickness="1" BorderBrush="DarkBlue">
<Grid Margin="3">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="150"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Host"/>
<TextBox Grid.Row="0" Grid.Column="1"
Margin="5,0,0,0"
Text="{Binding Host, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="Port"/>
<TextBox Grid.Row="1" Grid.Column="1"
Margin="5,0,0,0"
Text="{Binding Port, UpdateSourceTrigger=PropertyChanged}"/>
<StackPanel Grid.Row="2" Grid.ColumnSpan="2" Margin="5" Orientation="Horizontal">
<Button Content="Connect" Width="70" Command="{Binding ConnectCommand}" />
<Button Margin="5,0,0,0" Width="70" Content="Disconnect" Command="{Binding DisconnectCommand}" />
</StackPanel>
<Label Grid.Row="0" Content="Quotes" Background="LightYellow" />
<ListView Grid.Row="1" Margin="2"
ItemsSource="{Binding Quotes}"
SelectedItem="{Binding SelectedQuote}"
SelectionMode="Single">
<ListView.View>
<GridView>
<GridViewColumn Width="100" Header="Instrument" DisplayMemberBinding="{Binding Instrument}" />
<GridViewColumn Width="70" Header="Bid" DisplayMemberBinding="{Binding Bid}" />
<GridViewColumn Width="70" Header="Ask" DisplayMemberBinding="{Binding Ask}" />
<GridViewColumn Width="80" Header="ExpertHandle" DisplayMemberBinding="{Binding ExpertHandle}" />
</GridView>
</ListView.View>
</ListView>
</Grid>
</Expander.Content>
</Expander>
</Border>
</Grid>
<ListView Grid.Row="0" Grid.Column="1"
ItemsSource="{Binding Quotes}"
SelectedItem="{Binding SelectedQuote}"
SelectionMode="Single">
<ListView.View>
<GridView>
<GridViewColumn Width="140" Header="Instrument" DisplayMemberBinding="{Binding Instrument}" />
<GridViewColumn Width="80" Header="Bid" DisplayMemberBinding="{Binding Bid}" />
<GridViewColumn Width="80" Header="Ask" DisplayMemberBinding="{Binding Ask}" />
<GridViewColumn Width="80" Header="Feeds Count" DisplayMemberBinding="{Binding FeedCount}" />
</GridView>
</ListView.View>
</ListView>
</Grid>
<TabControl Grid.Column="1" Margin="2">
<TabItem Header="Trade Functions">
<ScrollViewer>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TabControl Grid.Row="1" >
<TabItem Header="Trade Functions">
<ScrollViewer>
<Expander Header="MqlTradeRequest" Margin="10" IsExpanded="True">
<Grid Margin="0,10,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Text="Action"/>
<ComboBox Grid.Column="1" Grid.Row="0" ItemsSource="{Binding Source={StaticResource ENUM_TRADE_REQUEST_ACTIONS_Key}}"
SelectedItem="{Binding TradeRequest.Action}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="2" Grid.Row="0" Text="Magic" Margin="10,0,0,0"/>
<TextBox Grid.Column="3" Grid.Row="0" Text="{Binding TradeRequest.Magic}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="0" Grid.Row="1" Text="Order"/>
<TextBox Grid.Column="1" Grid.Row="1" Text="{Binding TradeRequest.Order}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="2" Grid.Row="1" Text="Symbol" Margin="10,0,0,0"/>
<TextBox Grid.Column="3" Grid.Row="1" Text="{Binding TradeRequest.Symbol}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="0" Grid.Row="2" Text="Volume"/>
<TextBox Grid.Column="1" Grid.Row="2" Text="{Binding TradeRequest.Volume}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="2" Grid.Row="2" Text="Price" Margin="10,0,0,0"/>
<TextBox Grid.Column="3" Grid.Row="2" Text="{Binding TradeRequest.Price}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="0" Grid.Row="3" Text="Stoplimit"/>
<TextBox Grid.Column="1" Grid.Row="3" Text="{Binding TradeRequest.Stoplimit}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="2" Grid.Row="3" Text="Sl" Margin="10,0,0,0"/>
<TextBox Grid.Column="3" Grid.Row="3" Text="{Binding TradeRequest.Sl}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="0" Grid.Row="4" Text="Tp"/>
<TextBox Grid.Column="1" Grid.Row="4" Text="{Binding TradeRequest.Tp}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="2" Grid.Row="4" Text="Deviation" Margin="10,0,0,0"/>
<TextBox Grid.Column="3" Grid.Row="4" Text="{Binding TradeRequest.Deviation}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="0" Grid.Row="5" Text="Type"/>
<ComboBox Grid.Column="1" Grid.Row="5" ItemsSource="{Binding Source={StaticResource ENUM_ORDER_TYPE_Key}}"
SelectedItem="{Binding TradeRequest.Type}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="2" Grid.Row="5" Text="Type_filling" Margin="10,0,0,0"/>
<ComboBox Grid.Column="3" Grid.Row="5" ItemsSource="{Binding Source={StaticResource ENUM_ORDER_TYPE_FILLING_Key}}"
SelectedItem="{Binding TradeRequest.Type_filling}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="0" Grid.Row="6" Text="Type_time"/>
<ComboBox Grid.Column="1" Grid.Row="6" ItemsSource="{Binding Source={StaticResource ENUM_ORDER_TYPE_TIME_Key}}"
SelectedItem="{Binding TradeRequest.Type_time}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="2" Grid.Row="6" Text="Expiration" Margin="10,0,0,0"/>
<TextBox Grid.Column="3" Grid.Row="6" Text="{Binding TradeRequest.Expiration}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="0" Grid.Row="7" Text="Comment"/>
<TextBox Grid.Column="1" Grid.Row="7" Grid.ColumnSpan="3" Text="{Binding TradeRequest.Comment}" Margin="5,0,0,0"/>
</Grid>
</Expander>
<StackPanel Grid.Row="1" Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Button Content="OrderSend" Command="{Binding OrderSendCommand}" Width="100" Height="25" HorizontalAlignment="Left" Margin="4"/>
<Button Content="OrderCheck" Command="{Binding OrderCheckCommand}" Width="100" Height="25" HorizontalAlignment="Left" Margin="4"/>
<Button Content="PositionGetTicket" Command="{Binding PositionGetTicketCommand}" Width="100" Height="25" HorizontalAlignment="Left" Margin="4"/>
</StackPanel>
<WrapPanel>
<Button Content="HistoryDealGetDouble" Command="{Binding HistoryDealGetDoubleCommand}" Height="25" HorizontalAlignment="Left" Margin="4"/>
<Button Content="HistoryDealGetInteger" Command="{Binding HistoryDealGetIntegerCommand}" Height="25" HorizontalAlignment="Left" Margin="4"/>
<Button Content="HistoryDealGetString" Command="{Binding HistoryDealGetStringCommand}" Height="25" HorizontalAlignment="Left" Margin="4"/>
<Button Content="HistoryOrderGetInteger" Command="{Binding HistoryOrderGetIntegerCommand}" Height="25" HorizontalAlignment="Left" Margin="4"/>
<Button Content="HistoryDealMethods" Command="{Binding HistoryDealMethodsCommand}" Height="25" HorizontalAlignment="Left" Margin="4"/>
</WrapPanel>
</StackPanel>
</Grid>
</ScrollViewer>
</TabItem>
<TabItem Header="Account Information">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.4*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Expander Header="MqlTradeRequest" Margin="10">
<Grid Margin="0,10,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ComboBox Grid.Column="0" Grid.Row="0"
SelectedItem="{Binding AccountInfoDoublePropertyId}"
ItemsSource="{Binding Source={StaticResource ENUM_ACCOUNT_INFO_DOUBLE_Key}}"/>
<Button Grid.Column="1" Grid.Row="0" Margin="10,0,0,0"
Command="{Binding AccountInfoDoubleCommand}"
Content="AccountInfoDouble" HorizontalAlignment="Left" />
<ComboBox Grid.Column="0" Grid.Row="1"
SelectedItem="{Binding AccountInfoIntegerPropertyId}"
ItemsSource="{Binding Source={StaticResource ENUM_ACCOUNT_INFO_INTEGER_Key}}"/>
<Button Grid.Column="1" Grid.Row="1" Margin="10,0,0,0"
Command="{Binding AccountInfoIntegerCommand}"
Content="AccountInfoInteger" HorizontalAlignment="Left" />
<ComboBox Grid.Column="0" Grid.Row="2"
SelectedItem="{Binding AccountInfoStringPropertyId}"
ItemsSource="{Binding Source={StaticResource ENUM_ACCOUNT_INFO_STRING_Key}}"/>
<Button Grid.Column="1" Grid.Row="2" Margin="10,0,0,0"
Command="{Binding AccountInfoStringCommand}"
Content="AccountInfoString" HorizontalAlignment="Left" />
</Grid>
</Grid>
</TabItem>
<TabItem Header="Terminal Information">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.4*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ComboBox Grid.Column="0" Grid.Row="0"
SelectedItem="{Binding TerminalInfoDoublePropertyId}"
ItemsSource="{Binding Source={StaticResource ENUM_TERMINAL_INFO_DOUBLE_Key}}"/>
<Button Grid.Column="1" Grid.Row="0" Margin="10,0,0,0"
Command="{Binding TerminalInfoDoubleCommand}"
Content="TerminalInfoDouble" HorizontalAlignment="Left" />
<ComboBox Grid.Column="0" Grid.Row="1"
SelectedItem="{Binding TerminalInfoIntegerPropertyId}"
ItemsSource="{Binding Source={StaticResource ENUM_TERMINAL_INFO_INTEGER_Key}}"/>
<Button Grid.Column="1" Grid.Row="1" Margin="10,0,0,0"
Command="{Binding TerminalInfoIntegerCommand}"
Content="TerminalInfoInteger" HorizontalAlignment="Left" />
<ComboBox Grid.Column="0" Grid.Row="2"
SelectedItem="{Binding TerminalInfoStringPropertyId}"
ItemsSource="{Binding Source={StaticResource ENUM_TERMINAL_INFO_STRING_Key}}"/>
<Button Grid.Column="1" Grid.Row="2" Margin="10,0,0,0"
Command="{Binding TerminalInfoStringCommand}"
Content="TerminalInfoString" HorizontalAlignment="Left" />
</Grid>
</Grid>
</TabItem>
<TabItem Header="Timeseries and Indicators Access">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="1" Margin="2">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Text="Symbol Name" Margin="1"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="TimeFrame" Margin="1" HorizontalAlignment="Right"/>
<TextBlock Grid.Row="2" Grid.Column="0" Text="StartPos" Margin="1" HorizontalAlignment="Right"/>
<TextBlock Grid.Row="3" Grid.Column="0" Text="Count" Margin="1" HorizontalAlignment="Right"/>
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding TimeSeriesValues.SymbolValue}" Margin="1"/>
<ComboBox Grid.Row="1" Grid.Column="1" Margin="1"
ItemsSource="{Binding Source={StaticResource ENUM_TIMEFRAMES_Key}}"
SelectedItem="{Binding TimeSeriesValues.TimeFrame}"/>
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding TimeSeriesValues.StartPos}" Margin="1"/>
<TextBox Grid.Row="3" Grid.Column="1" Text="{Binding TimeSeriesValues.Count}" Margin="1"/>
</Grid>
<WrapPanel Grid.Row="1" Grid.Column="0" Margin="5">
<Button Command="{Binding CopyRatesCommand}" Margin="1"
Content="CopyRates" HorizontalAlignment="Left" />
<Button Command="{Binding CopyTimesCommand}" Margin="1"
Content="CopyTimes" HorizontalAlignment="Left" />
<Button Command="{Binding CopyOpenCommand}" Margin="1"
Content="CopyOpen" HorizontalAlignment="Left" />
<Button Command="{Binding CopyHighCommand}" Margin="1"
Content="CopyHigh" HorizontalAlignment="Left" />
<Button Command="{Binding CopyLowCommand}" Margin="1"
Content="CopyLow" HorizontalAlignment="Left" />
<Button Command="{Binding CopyCloseCommand}" Margin="1"
Content="CopyClose" HorizontalAlignment="Left" />
<Button Command="{Binding CopyTickVolumeCommand}" Margin="1"
Content="CopyTickVolume" HorizontalAlignment="Left" />
<Button Command="{Binding CopyRealVolumeCommand}" Margin="1"
Content="CopyRealVolume" HorizontalAlignment="Left" />
<Button Command="{Binding CopySpreadCommand}" Margin="1"
Content="CopySpread" HorizontalAlignment="Left" />
<Button Command="{Binding CopyTicksCommand}" Margin="1"
Content="CopyTicks" HorizontalAlignment="Left" />
</WrapPanel>
<Grid Grid.Row="2">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Text="Action"/>
<ComboBox Grid.Column="1" Grid.Row="0" ItemsSource="{Binding Source={StaticResource ENUM_TRADE_REQUEST_ACTIONS_Key}}"
SelectedItem="{Binding TradeRequest.Action}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="2" Grid.Row="0" Text="Magic" Margin="10,0,0,0"/>
<TextBox Grid.Column="3" Grid.Row="0" Text="{Binding TradeRequest.Magic}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="0" Grid.Row="1" Text="Order"/>
<TextBox Grid.Column="1" Grid.Row="1" Text="{Binding TradeRequest.Order}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="2" Grid.Row="1" Text="Symbol" Margin="10,0,0,0"/>
<TextBox Grid.Column="3" Grid.Row="1" Text="{Binding TradeRequest.Symbol}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="0" Grid.Row="2" Text="Volume"/>
<TextBox Grid.Column="1" Grid.Row="2" Text="{Binding TradeRequest.Volume}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="2" Grid.Row="2" Text="Price" Margin="10,0,0,0"/>
<TextBox Grid.Column="3" Grid.Row="2" Text="{Binding TradeRequest.Price}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="0" Grid.Row="3" Text="Stoplimit"/>
<TextBox Grid.Column="1" Grid.Row="3" Text="{Binding TradeRequest.Stoplimit}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="2" Grid.Row="3" Text="Sl" Margin="10,0,0,0"/>
<TextBox Grid.Column="3" Grid.Row="3" Text="{Binding TradeRequest.Sl}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="0" Grid.Row="4" Text="Tp"/>
<TextBox Grid.Column="1" Grid.Row="4" Text="{Binding TradeRequest.Tp}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="2" Grid.Row="4" Text="Deviation" Margin="10,0,0,0"/>
<TextBox Grid.Column="3" Grid.Row="4" Text="{Binding TradeRequest.Deviation}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="0" Grid.Row="5" Text="Type"/>
<ComboBox Grid.Column="1" Grid.Row="5" ItemsSource="{Binding Source={StaticResource ENUM_ORDER_TYPE_Key}}"
SelectedItem="{Binding TradeRequest.Type}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="2" Grid.Row="5" Text="Type_filling" Margin="10,0,0,0"/>
<ComboBox Grid.Column="3" Grid.Row="5" ItemsSource="{Binding Source={StaticResource ENUM_ORDER_TYPE_FILLING_Key}}"
SelectedItem="{Binding TradeRequest.Type_filling}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="0" Grid.Row="6" Text="Type_time"/>
<ComboBox Grid.Column="1" Grid.Row="6" ItemsSource="{Binding Source={StaticResource ENUM_ORDER_TYPE_TIME_Key}}"
SelectedItem="{Binding TradeRequest.Type_time}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="2" Grid.Row="6" Text="Expiration" Margin="10,0,0,0"/>
<TextBox Grid.Column="3" Grid.Row="6" Text="{Binding TradeRequest}" Margin="5,0,0,0"/>
<TextBlock Grid.Column="0" Grid.Row="7" Text="Comment"/>
<TextBox Grid.Column="1" Grid.Row="7" Grid.ColumnSpan="3" Text="{Binding TradeRequest}" Margin="5,0,0,0"/>
<DockPanel Grid.Row="0" LastChildFill="True">
<Button DockPanel.Dock="Right" Command="{Binding IndicatorCreateCommand}" Margin="2"
Content="IndicatorCreate" HorizontalAlignment="Left" />
<ComboBox Margin="2"
ItemsSource="{Binding Source={StaticResource ENUM_INDICATOR_Key}}"
SelectedItem="{Binding TimeSeriesValues.IndicatorType}"/>
</DockPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<Label Content="Indicator handle:" Margin="2"/>
<TextBox Margin="2" Width="60" PreviewTextInput="NumberValidationTextBox" Text="{Binding TimeSeriesValues.IndicatorHandle}"/>
<Button Command="{Binding IndicatorReleaseCommand}" Margin="2"
Content="IndicatorRelease" HorizontalAlignment="Left" />
</StackPanel>
</Grid>
</Expander>
</Grid>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<Button Content="OrderSend" Command="{Binding OrderSendCommand}" Width="100" Height="25"/>
<ListBox Grid.Column="0" ItemsSource="{Binding TimeSeriesResults}" />
</Grid>
</TabItem>
<TabItem Header="Market Info">
<WrapPanel VerticalAlignment="Top" Margin="5">
<Button Command="{Binding SymbolsTotalCommand}" Content="SymbolsTotal" Margin="2"/>
<Button Command="{Binding SymbolNameCommand}" Content="SymbolName" Margin="2"/>
<Button Command="{Binding SymbolSelectCommand}" Content="SymbolSelect" Margin="2"/>
<Button Command="{Binding SymbolIsSynchronizedCommand}" Content="SymbolIsSynchronized" Margin="2"/>
<Button Command="{Binding SymbolInfoDoubleCommand}" Content="SymbolInfoDouble" Margin="2"/>
<Button Command="{Binding SymbolInfoIntegerCommand}" Content="SymbolInfoInteger" Margin="2"/>
<Button Command="{Binding SymbolInfoStringCommand}" Content="SymbolInfoString" Margin="2"/>
<Button Command="{Binding SymbolInfoString2Command}" Content="SymbolInfoString-2" Margin="2"/>
<Button Command="{Binding SymbolInfoTickCommand}" Content="SymbolInfoTick" Margin="2"/>
<Button Command="{Binding SymbolInfoSessionQuoteCommand}" Content="SymbolInfoSessionQuote" Margin="2"/>
<Button Command="{Binding SymbolInfoSessionTradeCommand}" Content="SymbolInfoSessionTrade" Margin="2"/>
<Button Command="{Binding MarketBookAddCommand}" Content="MarketBookAdd" Margin="2"/>
<Button Command="{Binding MarketBookReleaseCommand}" Content="MarketBookRelease" Margin="2"/>
<Button Command="{Binding MarketBookGetCommand}" Content="MarketBookGet" Margin="2"/>
</WrapPanel>
</TabItem>
<TabItem Header="CTrade">
<WrapPanel VerticalAlignment="Top" Margin="5">
<Button Command="{Binding PositionOpenCommand}" Content="PositionOpen" Margin="2"/>
</WrapPanel>
</TabItem>
<TabItem Header="Indicators">
<WrapPanel VerticalAlignment="Top" Margin="5">
<Button Command="{Binding iCustomCommand}" Content="iCustom" Margin="2"/>
</WrapPanel>
</TabItem>
<TabItem Header="Chart Functions">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="5">
<TextBlock Text="Symbol" VerticalAlignment="Center" Margin="2"/>
<TextBox Width="100" Text="{Binding ChartFunctionsSymbolValue}" Margin="2"/>
</StackPanel>
</Grid>
</ScrollViewer>
</TabItem>
<TabItem Header="Account Information">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.4*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<WrapPanel Grid.Row="1" Orientation="Horizontal" Margin="5">
<Button Command="{Binding ChartOpenCommand}" Content="ChartOpen" Margin="2"/>
<Button Command="{Binding ChartTimePriceToXYCommand}" Content="ChartTimePriceToXY" Margin="2"/>
<Button Command="{Binding ChartXYToTimePriceCommand}" Content="ChartXYToTimePrice" Margin="2"/>
</WrapPanel>
<ComboBox Grid.Column="0" Grid.Row="0"
SelectedItem="{Binding AccountInfoDoublePropertyId}"
ItemsSource="{Binding Source={StaticResource ENUM_ACCOUNT_INFO_DOUBLE_Key}}"/>
<Button Grid.Column="1" Grid.Row="0" Margin="10,0,0,0"
Command="{Binding AccountInfoDoubleCommand}"
Content="AccountInfoDouble" HorizontalAlignment="Left" />
<WrapPanel Grid.Row="3" VerticalAlignment="Top" Margin="5">
<Button Command="{Binding ChartApplyTemplateCommand}" Content="ChartApplyTemplate" Margin="2"/>
<Button Command="{Binding ChartSaveTemplateCommand}" Content="ChartSaveTemplate" Margin="2"/>
</WrapPanel>
<ComboBox Grid.Column="0" Grid.Row="1"
SelectedItem="{Binding AccountInfoIntegerPropertyId}"
ItemsSource="{Binding Source={StaticResource ENUM_ACCOUNT_INFO_INTEGER_Key}}"/>
<Button Grid.Column="1" Grid.Row="1" Margin="10,0,0,0"
Command="{Binding AccountInfoIntegerCommand}"
Content="AccountInfoInteger" HorizontalAlignment="Left" />
<ComboBox Grid.Column="0" Grid.Row="2"
SelectedItem="{Binding AccountInfoStringPropertyId}"
ItemsSource="{Binding Source={StaticResource ENUM_ACCOUNT_INFO_STRING_Key}}"/>
<Button Grid.Column="1" Grid.Row="2" Margin="10,0,0,0"
Command="{Binding AccountInfoStringCommand}"
Content="AccountInfoString" HorizontalAlignment="Left" />
</Grid>
<Grid Margin="10" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Text="{Binding MessageText}" Margin="5"/>
<Button Grid.Column="1" Content="Print" Command="{Binding PrintCommand}" Margin="5"/>
</Grid>
</Grid>
</TabItem>
<TabItem Header="Timeseries and Indicators Access">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Row="0" Text="symbolName"/>
<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}}"
SelectedItem="{Binding TimeSeriesValues.TimeFrame}"/>
<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" Grid.Column="0" Margin="10">
<Button Command="{Binding CopyRatesCommand}" Margin="1"
Content="CopyRates" HorizontalAlignment="Left" />
<Button Command="{Binding CopyTimesCommand}" Margin="1"
Content="CopyTimes" HorizontalAlignment="Left" />
<Button Command="{Binding CopyOpenCommand}" Margin="1"
Content="CopyOpen" HorizontalAlignment="Left" />
<Button Command="{Binding CopyHighCommand}" Margin="1"
Content="CopyHigh" HorizontalAlignment="Left" />
<Button Command="{Binding CopyLowCommand}" Margin="1"
Content="CopyLow" HorizontalAlignment="Left" />
<Button Command="{Binding CopyCloseCommand}" Margin="1"
Content="CopyClose" HorizontalAlignment="Left" />
<Button Command="{Binding CopyTickVolumeCommand}" Margin="1"
Content="CopyTickVolume" HorizontalAlignment="Left" />
<Button Command="{Binding CopyRealVolumeCommand}" Margin="1"
Content="CopyRealVolume" HorizontalAlignment="Left" />
<Button Command="{Binding CopySpreadCommand}" Margin="1"
Content="CopySpread" HorizontalAlignment="Left" />
<Button Command="{Binding CopyTicksCommand}" Margin="1"
Content="CopyTicks" HorizontalAlignment="Left" />
<StackPanel Grid.Row="4" Orientation="Horizontal" Margin="5">
<Button Command="{Binding ChartIdCommand}" Content="ChartId" Margin="2"/>
<TextBlock Text="ChartID" VerticalAlignment="Center" Margin="20,2,2,2"/>
<TextBox Width="150" Text="{Binding ChartFunctionsChartIdValue}" Margin="2"/>
</StackPanel>
<WrapPanel Grid.Row="5" VerticalAlignment="Top" Margin="5">
<Button Command="{Binding ChartRedrawCommand}" Content="ChartRedraw" Margin="2"/>
<Button Command="{Binding ChartWindowFindCommand}" Content="ChartWindowFind" Margin="2"/>
<Button Command="{Binding ChartCloseCommand}" Content="ChartClose" Margin="2"/>
<Button Command="{Binding ChartPeriodCommand}" Content="ChartPeriod" Margin="2"/>
<Button Command="{Binding ChartSetDoubleCommand}" Content="ChartSetDouble" Margin="2"/>
<Button Command="{Binding ChartSetIntegerCommand}" Content="ChartSetInteger" Margin="2"/>
<Button Command="{Binding ChartSetStringCommand}" Content="ChartSetString" Margin="2"/>
<Button Command="{Binding ChartGetDoubleCommand}" Content="ChartGetDouble" Margin="2"/>
<Button Command="{Binding ChartGetIntegerCommand}" Content="ChartGetInteger" Margin="2"/>
<Button Command="{Binding ChartNavigateCommand}" Content="ChartNavigate" Margin="2"/>
<Button Command="{Binding ChartIndicatorAddCommand}" Content="ChartIndicatorAdd" Margin="2"/>
<Button Command="{Binding ChartIndicatorDeleteCommand}" Content="ChartIndicatorDelete" Margin="2"/>
<Button Command="{Binding ChartIndicatorGetCommand}" Content="ChartIndicatorGet" Margin="2"/>
<Button Command="{Binding ChartIndicatorNameCommand}" Content="ChartIndicatorName" Margin="2"/>
<Button Command="{Binding ChartIndicatorsTotalCommand}" Content="ChartIndicatorsTotal" Margin="2"/>
<Button Command="{Binding ChartWindowOnDroppedCommand}" Content="ChartWindowOnDropped" Margin="2"/>
<Button Command="{Binding ChartPriceOnDroppedCommand}" Content="ChartPriceOnDropped" Margin="2"/>
<Button Command="{Binding ChartTimeOnDroppedCommand}" Content="ChartTimeOnDropped" Margin="2"/>
<Button Command="{Binding ChartXOnDroppedCommand}" Content="ChartXOnDropped" Margin="2"/>
<Button Command="{Binding ChartYOnDroppedCommand}" Content="ChartYOnDropped" Margin="2"/>
<Button Command="{Binding ChartSetSymbolPeriodCommand}" Content="ChartSetSymbolPeriod" Margin="2"/>
<Button Command="{Binding ChartScreenShotCommand}" Content="ChartScreenShot" Margin="2"/>
</WrapPanel>
</Grid>
</TabItem>
<TabItem Header="Time and Date">
<WrapPanel VerticalAlignment="Top" Margin="5">
<Button Command="{Binding TimeCurrentCommand}" Content="TimeCurrent" Margin="2"/>
<Button Command="{Binding TimeTradeServerCommand}" Content="TimeTradeServer" Margin="2"/>
<Button Command="{Binding TimeLocalCommand}" Content="TimeLocal" Margin="2"/>
<Button Command="{Binding TimeGMTCommand}" Content="TimeGMT" Margin="2"/>
</WrapPanel>
</TabItem>
<ListBox ItemsSource="{Binding TimeSeriesResults}" />
<TabItem Header="Checkup and Common Functions">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
</Grid>
</TabItem>
<TabItem Header="Market Info">
<WrapPanel VerticalAlignment="Top" Margin="5">
<Button Command="{Binding SymbolsTotalCommand}" Content="SymbolsTotal" Margin="2"/>
<Button Command="{Binding SymbolNameCommand}" Content="SymbolName" Margin="2"/>
<Button Command="{Binding SymbolSelectCommand}" Content="SymbolSelect" Margin="2"/>
<Button Command="{Binding SymbolIsSynchronizedCommand}" Content="SymbolIsSynchronized" Margin="2"/>
<Button Command="{Binding SymbolInfoDoubleCommand}" Content="SymbolInfoDouble" Margin="2"/>
<Button Command="{Binding SymbolInfoIntegerCommand}" Content="SymbolInfoInteger" Margin="2"/>
<Button Command="{Binding SymbolInfoStringCommand}" Content="SymbolInfoString" Margin="2"/>
<Button Command="{Binding SymbolInfoTickCommand}" Content="SymbolInfoTick" Margin="2"/>
<Button Command="{Binding SymbolInfoSessionQuoteCommand}" Content="SymbolInfoSessionQuote" Margin="2"/>
<Button Command="{Binding SymbolInfoSessionTradeCommand}" Content="SymbolInfoSessionTrade" Margin="2"/>
<Button Command="{Binding MarketBookAddCommand}" Content="MarketBookAdd" Margin="2"/>
<Button Command="{Binding MarketBookReleaseCommand}" Content="MarketBookRelease" Margin="2"/>
<Button Command="{Binding MarketBookGetCommand}" Content="MarketBookGet" Margin="2"/>
</WrapPanel>
</TabItem>
<WrapPanel VerticalAlignment="Top" Margin="5">
<Button Command="{Binding GetLastErrorCommand}" Content="GetLastError" Margin="2"/>
<Button Command="{Binding ResetLastErrorCommand}" Content="ResetLastError" Margin="2"/>
</WrapPanel>
<TabItem Header="CTrade">
<WrapPanel VerticalAlignment="Top" Margin="5">
<Button Command="{Binding PositionOpenCommand}" Content="PositionOpen" Margin="2"/>
</WrapPanel>
</TabItem>
</TabControl>
<Grid Margin="10" Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Text="{Binding MessageText}" Margin="2"/>
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Command="{Binding PrintCommand}" Content="Print" Margin="2" />
<Button Command="{Binding AlertCommand}" Content="Alert" Margin="2" />
</StackPanel>
<Expander Grid.Row="2" Header="History" IsExpanded="True">
<ListBox mtApi5TestClient:ListBoxBehavior.ScrollOnNewItem="true" Height="200" ItemsSource="{Binding History}"/>
</Expander>
</Grid>
</Grid>
</TabItem>
</TabControl>
</Grid>
<GridSplitter Grid.Row="1" Height="2" HorizontalAlignment="Stretch" />
<Border Grid.Row="2" BorderThickness="1" BorderBrush="DarkBlue" Margin="2">
<Grid Margin="3">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Content="Output Console" Background="LightYellow" />
<ListBox Grid.Row="1" ItemsSource="{Binding History}"
mtApi5TestClient:ListBoxBehavior.ScrollOnNewItem="true" />
</Grid>
</Border>
<StatusBar Grid.Row="3">
<StatusBarItem>

Some files were not shown because too many files have changed in this diff Show More