Compare commits

..
169 Commits
Author SHA1 Message Date
vdemydiuk f01ec01a5f Disable debug loging in MtApi.ex5 2018-06-06 15:11:56 +03:00
vdemydiuk 0c38d37559 Issue #107: Added function PositionCloseAll 2018-06-06 14:24:39 +03:00
vdemydiuk 897892dc89 Issue #122: Added event OnLockTicksEvent (MT5) 2018-06-06 12:46:24 +03:00
vdemydiuk 1a5882b75a Issue #122: Implemented UnlockTicks function in MtApi (MT5) 2018-06-05 19:19:35 +03:00
vdemydiuk 0f717f1cb7 Issue #119: Added out parameter MqlTradeResult to function PositionClose 2018-06-04 17:48:14 +03:00
vdemydiuk 5d78ad5067 Issue #120: set field 'Symbol' as optional in MqlTradeRequest (MT5) 2018-06-04 15:36:35 +03:00
vdemydiuk 6c45f28a05 Issue #121: Added original MtTime field to MqlRates (MT5) 2018-06-04 15:04:12 +03:00
vdemydiuk ca3c0e735f Issue #110: Implemented function for working with global variables (MT5) 2018-06-04 13:53:55 +03:00
vdemydiuk f71151104b Issue #111: Added enum value SYMBOL_VISIBLE 2018-05-08 19:07:52 +03:00
vdemydiuk 28816a75ac Issue #113: Changed extension of logging files to *.log 2018-05-08 16:44:57 +03:00
vdemydiuk 6023bffed6 Issue #106: Extended structure Mt5Quote with fields from MqlTick (volume, last, time) 2018-05-08 14:53:31 +03:00
vdemydiuk fd34f009cd Started version 1.0.19 (MT5) 2018-05-08 14:50:25 +03:00
Vyacheslav DemidyukandGitHub 1bb2b65cdf Merge pull request #115 from CVasquezG/master
Updated README
2018-04-02 16:27:58 +03:00
CVasquezGandGitHub 37e8275465 Updated README
Changes made to the README file to be more formal.
I am doing this as a university assignment where I am required to improve documentation in the open source community.  I hope changes suggested in this commit are useful for your project.
2018-03-31 14:08:20 -07:00
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 DemidyukandGitHub 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 DemidyukandGitHub 9ea58354be Merge pull request #103 from Janderson/master
Missing function to mql5
2018-03-12 16:49:21 +02:00
Janderson FFerreiraandGitHub 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 DemidyukandGitHub 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
Tr4DrandGitHub 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 DemidyukandGitHub 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 DemidyukandGitHub 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
Tr4DrandGitHub 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 DemidyukandGitHub 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 d63a53b8a9 MtApi (MT4) version 1.0.32.1 (HotFix) 2016-11-25 16:06:11 +02:00
DW 7e821fcade Issue #38: Removed MemoryAppender in LogConfigurator (MtApiService) 2016-11-25 15:50:56 +02:00
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
128 changed files with 16291 additions and 4294 deletions
-2
View File
@@ -36,5 +36,3 @@ using namespace System::Security::Permissions;
[assembly:ComVisible(false)]; [assembly:ComVisible(false)];
[assembly:CLSCompliantAttribute(true)]; [assembly:CLSCompliantAttribute(true)];
[assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)];
+156 -343
View File
@@ -6,14 +6,15 @@
#include "MT5Handler.h" #include "MT5Handler.h"
#include "Windows.h" #include "Windows.h"
#include < vcclr.h > #include <vcclr.h>
#include <functional>
using namespace System; using namespace System;
using namespace MTApiService; using namespace MTApiService;
using namespace System::Runtime::InteropServices; using namespace System::Runtime::InteropServices;
using namespace System::Reflection; using namespace System::Reflection;
using namespace System::Text; using namespace System::Text;
using namespace System::Collections::Generic; using namespace System::Collections::Generic;
using namespace System::Diagnostics; using namespace System::Diagnostics;
using namespace System::Security::Cryptography; using namespace System::Security::Cryptography;
using namespace System::Security; using namespace System::Security;
@@ -50,277 +51,162 @@ public struct CMqlBookInfo
void convertSystemString(wchar_t* dest, String^ src) void convertSystemString(wchar_t* dest, String^ src)
{ {
pin_ptr<const wchar_t> wch = PtrToStringChars(src); if (src != nullptr) {
memcpy(dest, wch, wcslen(wch) * sizeof(wchar_t)); pin_ptr<const wchar_t> wch = PtrToStringChars(src);
dest[wcslen(wch)] = '\0'; 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) #define _DLLAPI extern "C" __declspec(dllexport)
{
bool verifyResult = false;
template <typename T> T Execute(std::function<T()> func, wchar_t* err, T default_value)
{
T result = default_value;
try try
{ {
DSACryptoServiceProvider^ dsa = gcnew DSACryptoServiceProvider(); result = func();
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);
} }
catch (Exception^ e) catch (Exception^ e)
{ {
convertSystemString(err, e->Message); 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 return Execute<int>([&expertHandle, &port, symbol, &bid, &ask, &isTestMode]() {
{ bool isTesting = (isTestMode != 0) ? true : false;
MtServerInstance::GetInstance()->DeinitExpert(expertHandle); auto expert = gcnew Mt5Expert(expertHandle, gcnew String(symbol), bid, ask, gcnew MT5Handler(), isTesting);
} MtAdapter::GetInstance()->AddExpert(port, expert);
catch (Exception^ e) return 1;
{ }, err, 0);
convertSystemString(err, e->Message);
Debug::WriteLine("[ERROR] MT5Connector:deinitExpert(): " + e->Message);
return 0;
}
return 1;
} }
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 return Execute<int>([&expertHandle]() {
{ MtAdapter::GetInstance()->RemoveExpert(expertHandle);
MtServerInstance::GetInstance()->SendQuote(expertHandle, gcnew String(symbol), bid, ask); return 1;
} }, err, 0);
catch (Exception^ e)
{
convertSystemString(err, e->Message);
Debug::WriteLine("[ERROR] MT5Connector:updateQuote(): " + e->Message);
return 0;
}
return 1;
} }
int _stdcall sendIntResponse(int expertHandle, int response) _DLLAPI int _stdcall updateQuote(int expertHandle, wchar_t* symbol, double bid, double ask, wchar_t* err)
{ {
try return Execute<int>([&expertHandle, symbol, &bid, &ask]() {
{ MtAdapter::GetInstance()->SendQuote(expertHandle, gcnew String(symbol), bid, ask);
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseInt(response)); return 1;
} }, err, 0);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:sendIntResponse(): " + e->Message);
return 0;
}
return 1;
} }
int _stdcall sendLongResponse(int expertHandle, __int64 response) _DLLAPI bool _stdcall sendEvent(int expertHandle, int eventType, wchar_t* payload, wchar_t* err)
{ {
try return Execute<bool>([&expertHandle, &eventType, payload]() {
{ MtAdapter::GetInstance()->SendEvent(expertHandle, eventType, gcnew String(payload));
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLong(response)); return true;
} }, err, false);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:sendLongResponse(): " + e->Message);
return 0;
}
return 1;
} }
int _stdcall sendULongResponse(int expertHandle, unsigned __int64 response) _DLLAPI int _stdcall sendIntResponse(int expertHandle, int response, wchar_t* err)
{ {
try return Execute<int>([&expertHandle, &response]() {
{ MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseInt(response));
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseULong(response)); return 1;
} }, err, 0);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:sendLongResponse(): " + e->Message);
return 0;
}
return 1;
} }
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; bool value = (response != 0) ? true : false;
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseBool(value));
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseBool(value)); return 1;
} }, err, 0);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:sendBooleanResponse(): " + e->Message);
return 0;
}
return 1;
} }
int _stdcall sendDoubleResponse(int expertHandle, double response) _DLLAPI int _stdcall sendDoubleResponse(int expertHandle, double response, wchar_t* err)
{ {
try return Execute<int>([&expertHandle, &response]() {
{ MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDouble(response));
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDouble(response)); return 1;
} }, err, 0);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:sendDoubleResponse(): " + e->Message);
return 0;
}
return 1;
} }
int _stdcall sendStringResponse(int expertHandle, wchar_t* response) _DLLAPI int _stdcall sendStringResponse(int expertHandle, wchar_t* response, wchar_t* err)
{ {
try return Execute<int>([&expertHandle, response]() {
{ MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseString(gcnew String(response)));
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseString(gcnew String(response))); return 1;
} }, err, 0);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:sendStringResponse(): " + e->Message);
return 0;
}
return 1;
} }
int _stdcall sendVoidResponse(int expertHandle) _DLLAPI int _stdcall sendVoidResponse(int expertHandle, wchar_t* err)
{ {
try return Execute<int>([&expertHandle]() {
{ MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseObject(nullptr));
MtServerInstance::GetInstance()->SendResponse(expertHandle, nullptr); return 1;
} }, err, 0);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:sendVoidResponse(): " + e->Message);
return 0;
}
return 1;
} }
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); array<double>^ list = gcnew array<double>(size);
for (int i = 0; i < size; i++)
for(int i = 0; i < size; i++)
{
list[i] = values[i]; list[i] = values[i];
} MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDoubleArray(list));
return 1;
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDoubleArray(list)); }, err, 0);
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:sendDoubleArrayResponse(): " + e->Message);
return 0;
}
return 1;
} }
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); array<int>^ list = gcnew array<int>(size);
for (int i = 0; i < size; i++)
for(int i = 0; i < size; i++)
{
list[i] = values[i]; list[i] = values[i];
} MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseIntArray(list));
return 1;
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseIntArray(list)); }, err, 0);
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:sendIntArrayResponse(): " + e->Message);
return 0;
}
return 1;
} }
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); array<System::Int64>^ list = gcnew array<System::Int64>(size);
for (int i = 0; i < size; i++)
for(int i = 0; i < size; i++)
{
list[i] = values[i]; list[i] = values[i];
} MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLongArray(list));
return 1;
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLongArray(list)); }, err, 0);
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:sendLongArrayResponse(): " + e->Message);
return 0;
}
return 1;
} }
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); array<MtMqlRates^>^ list = gcnew array<MtMqlRates^>(size);
for (int i = 0; i < size; i++)
for(int i = 0; i < size; i++)
{ {
MtMqlRates^ rates = gcnew MtMqlRates(); MtMqlRates^ rates = gcnew MtMqlRates();
rates->time = values[i].time; rates->time = values[i].time;
@@ -331,180 +217,107 @@ int _stdcall sendMqlRatesArrayResponse(int expertHandle, CMqlRates values[], int
rates->tick_volume = values[i].tick_volume; rates->tick_volume = values[i].tick_volume;
rates->spread = values[i].spread; rates->spread = values[i].spread;
rates->real_volume = values[i].real_volume; rates->real_volume = values[i].real_volume;
list[i] = rates; list[i] = rates;
} }
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlRatesArray(list));
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlRatesArray(list)); return 1;
} }, err, 0);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:sendMqlRatesArrayResponse(): " + e->Message);
return 0;
}
return 1;
} }
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(); MtMqlTick^ mtResponse = gcnew MtMqlTick();
mtResponse->time = response->time; mtResponse->time = response->time;
mtResponse->bid = response->bid; mtResponse->bid = response->bid;
mtResponse->ask = response->ask; mtResponse->ask = response->ask;
mtResponse->last = response->last; mtResponse->last = response->last;
mtResponse->volume = response->volume; mtResponse->volume = response->volume;
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlTick(mtResponse));
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlTick(mtResponse)); return 1;
} }, err, 0);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:sendMqlTickResponse(): " + e->Message);
return 0;
}
return 1;
} }
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); array<MtMqlBookInfo^>^ list = gcnew array<MtMqlBookInfo^>(size);
for (int i = 0; i < size; i++)
for(int i = 0; i < size; i++)
{ {
MtMqlBookInfo^ info = gcnew MtMqlBookInfo(); MtMqlBookInfo^ info = gcnew MtMqlBookInfo();
info->type = values[i].type; info->type = values[i].type;
info->price = values[i].price; info->price = values[i].price;
info->volume = values[i].volume; info->volume = values[i].volume;
list[i] = info; list[i] = info;
} }
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlBookInfoArray(list));
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseMqlBookInfoArray(list)); return 1;
} }, err, 0);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:sendMqlRatesArrayResponse(): " + e->Message);
return 0;
}
return 1;
} }
//----------- get values ------------------------------- //----------- get values -------------------------------
int _stdcall getCommandType(int expertHandle, int* res) _DLLAPI int _stdcall getCommandType(int expertHandle, int* res, wchar_t* err)
{ {
try return Execute<int>([&expertHandle, res]() {
{ *res = MtAdapter::GetInstance()->GetCommandType(expertHandle);
*res = MtServerInstance::GetInstance()->GetCommandType(expertHandle); return 1;
} }, err, 0);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:getCommandType(): " + e->Message);
return 0;
}
return 1;
} }
int _stdcall getIntValue(int expertHandle, int paramIndex, int* res) _DLLAPI int _stdcall getIntValue(int expertHandle, int paramIndex, int* res, wchar_t* err)
{ {
try return Execute<int>([&expertHandle, &paramIndex, res]() {
{ *res = (int)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
*res = (int)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex); return 1;
} }, err, 0);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:getIntValue(): " + e->Message);
return 0;
}
return 1;
} }
int _stdcall getDoubleValue(int expertHandle, int paramIndex, double* res) _DLLAPI int _stdcall getDoubleValue(int expertHandle, int paramIndex, double* res, wchar_t* err)
{ {
try return Execute<int>([&expertHandle, &paramIndex, res]() {
{ *res = (double)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
*res = (double)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex); return 1;
} }, err, 0);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:getDoubleValue(): " + e->Message);
return 0;
}
return 1;
} }
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 return Execute<int>([&expertHandle, &paramIndex, res]() {
{ convertSystemString(res, (String^)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex));
convertSystemString(res, (String^)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex)); return 1;
} }, err, 0);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:getStringValue(): " + e->Message);
return 0;
}
return 1;
} }
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 return Execute<int>([&expertHandle, &paramIndex, res]() {
{ *res = (unsigned __int64)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
*res = (unsigned long)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex); return 1;
} }, err, 0);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:getULongValue(): " + e->Message);
return 0;
}
return 1;
} }
int _stdcall getLongValue(int expertHandle, int paramIndex, __int64* res) _DLLAPI int _stdcall getLongValue(int expertHandle, int paramIndex, __int64* res, wchar_t* err)
{ {
try return Execute<int>([&expertHandle, &paramIndex, res]() {
{ *res = (__int64)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
*res = (long)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex); return 1;
} }, err, 0);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:getLongValue(): " + e->Message);
return 0;
}
return 1;
} }
int _stdcall getBooleanValue(int expertHandle, int paramIndex, int* res) _DLLAPI int _stdcall getBooleanValue(int expertHandle, int paramIndex, int* res, wchar_t* err)
{ {
try return Execute<int>([&expertHandle, &paramIndex, res]() {
{ bool val = (bool)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
bool val = (bool)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
*res = val == true ? 1 : 0; *res = val == true ? 1 : 0;
} return 1;
catch (Exception^ e) }, err, 0);
{
Debug::WriteLine("[ERROR] MT5Connector:getBooleanValue(): " + e->Message);
return 0;
}
return 1;
} }
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 return Execute<int>([&expertHandle, &paramIndex, res]() {
{ *res = (unsigned int)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
*res = (unsigned int)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex); return 1;
} }, err, 0);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MT5Connector:getUIntValue(): " + e->Message);
return 0;
}
return 1;
} }
-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> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>user32.lib</AdditionalDependencies> <AdditionalDependencies>user32.lib</AdditionalDependencies>
<ModuleDefinitionFile>.\MT5Connector.def</ModuleDefinitionFile>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -108,7 +107,6 @@
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>.\MT5Connector.def</ModuleDefinitionFile>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -120,7 +118,6 @@
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>.\MT5Connector.def</ModuleDefinitionFile>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -132,7 +129,6 @@
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>.\MT5Connector.def</ModuleDefinitionFile>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
@@ -157,7 +153,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="app.ico" /> <None Include="app.ico" />
<None Include="MT5Connector.def" />
<None Include="ReadMe.txt" /> <None Include="ReadMe.txt" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@@ -44,9 +44,6 @@
<None Include="app.ico"> <None Include="app.ico">
<Filter>Resource Files</Filter> <Filter>Resource Files</Filter>
</None> </None>
<None Include="MT5Connector.def">
<Filter>Source Files</Filter>
</None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="app.rc"> <ResourceCompile Include="app.rc">
+2 -3
View File
@@ -1,8 +1,7 @@
namespace MTApiService namespace MTApiService
{ {
public interface ICommandManager internal interface ICommandManager
{ {
void EnqueueCommandTask(MtCommandTask task); MtCommandTask SendCommand(MtCommand task);
MtCommandTask DequeueCommandTask();
} }
} }
+1 -6
View File
@@ -1,9 +1,4 @@
using System; namespace MTApiService
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MTApiService
{ {
public interface IMetaTraderHandler public interface IMetaTraderHandler
{ {
+9
View File
@@ -0,0 +1,9 @@
namespace MTApiService
{
internal interface ITaskExecutor
{
void Execute(MtCommandTask task);
int Handle { get; }
}
}
+54 -6
View File
@@ -8,9 +8,53 @@ using log4net.Repository.Hierarchy;
namespace MTApiService 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 public class LogConfigurator
{ {
private const string LogFileNameExtension = "txt"; private const string LogFileNameExtension = "log";
public static void Setup(string profileName) public static void Setup(string profileName)
{ {
@@ -29,7 +73,7 @@ namespace MTApiService
var roller = new RollingFileAppender var roller = new RollingFileAppender
{ {
AppendToFile = false, AppendToFile = true,
File = $@"{System.IO.Path.GetTempPath()}{profileName}\Logs\{filename}", File = $@"{System.IO.Path.GetTempPath()}{profileName}\Logs\{filename}",
Layout = patternLayout, Layout = patternLayout,
PreserveLogFileNameExtension = true, PreserveLogFileNameExtension = true,
@@ -41,10 +85,6 @@ namespace MTApiService
roller.ActivateOptions(); roller.ActivateOptions();
hierarchy.Root.AddAppender(roller); hierarchy.Root.AddAppender(roller);
var memory = new MemoryAppender();
memory.ActivateOptions();
hierarchy.Root.AddAppender(memory);
#if (DEBUG) #if (DEBUG)
hierarchy.Root.Level = Level.Debug; hierarchy.Root.Level = Level.Debug;
#else #else
@@ -52,5 +92,13 @@ namespace MTApiService
#endif #endif
hierarchy.Configured = true; 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> <ItemGroup>
<Compile Include="ICommandManager.cs" /> <Compile Include="ICommandManager.cs" />
<Compile Include="IMetaTraderHandler.cs" /> <Compile Include="IMetaTraderHandler.cs" />
<Compile Include="ITaskExecutor.cs" />
<Compile Include="LogConfigurator.cs" /> <Compile Include="LogConfigurator.cs" />
<Compile Include="Mt5Expert.cs" />
<Compile Include="MtCommandEventArgs.cs" /> <Compile Include="MtCommandEventArgs.cs" />
<Compile Include="IDisposableChannel.cs" /> <Compile Include="IDisposableChannel.cs" />
<Compile Include="IMtApiServer.cs" /> <Compile Include="IMtApiServer.cs" />
@@ -78,11 +80,11 @@
<Compile Include="MtConnectionProfile.cs" /> <Compile Include="MtConnectionProfile.cs" />
<Compile Include="MtExecutorManager.cs" /> <Compile Include="MtExecutorManager.cs" />
<Compile Include="MtExpert.cs" /> <Compile Include="MtExpert.cs" />
<Compile Include="MtInstrument.cs" /> <Compile Include="MtQuote.cs" />
<Compile Include="MtResponse.cs" /> <Compile Include="MtResponse.cs" />
<Compile Include="MtServer.cs" /> <Compile Include="MtServer.cs" />
<Compile Include="MtCommand.cs" /> <Compile Include="MtCommand.cs" />
<Compile Include="MtServerInstance.cs" /> <Compile Include="MtAdapter.cs" />
<Compile Include="MtService.cs" /> <Compile Include="MtService.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
+77
View File
@@ -0,0 +1,77 @@
using log4net;
namespace MTApiService
{
public class Mt5Expert : MtExpert
{
private static readonly ILog Log = LogManager.GetLogger(typeof(Mt5Expert));
private const int StopExpertInterval = 2000; // 2 sec for testing mode
private System.Timers.Timer _stopTimer;
public Mt5Expert(int handle, string symbol, double bid, double ask, IMetaTraderHandler mtHandler, bool isTestMode) :
base(handle, symbol, bid, ask, mtHandler)
{
IsTestMode = isTestMode;
}
public bool IsTestMode { get; }
public override int GetCommandType()
{
Log.Debug("GetCommandType: called.");
if (IsTestMode)
{
ResetTestModeTimer();
}
return base.GetCommandType();
}
public override void SendEvent(MtEvent mtEvent)
{
Log.DebugFormat("SendEvent: begin. event = {0}", mtEvent);
if (IsTestMode)
{
if (_stopTimer == null)
{
_stopTimer = new System.Timers.Timer
{
Interval = StopExpertInterval,
AutoReset = false
};
_stopTimer.Elapsed += _stopTimer_Elapsed;
}
}
base.SendEvent(mtEvent);
Log.Debug("SendEvent: 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();
_stopTimer.Elapsed -= _stopTimer_Elapsed;
_stopTimer = null;
Log.Debug("_stopTimer_Elapsed: end.");
}
private void ResetTestModeTimer()
{
if (_stopTimer == null)
return;
//reset timer
_stopTimer.Stop();
_stopTimer.Start();
}
}
}
+90 -23
View File
@@ -4,13 +4,13 @@ using log4net;
namespace MTApiService namespace MTApiService
{ {
public class MtServerInstance public class MtAdapter
{ {
#region Fields #region Fields
private const string LogProfileName = "MtApiService"; private const string LogProfileName = "MtApiService";
private static readonly ILog Log = LogManager.GetLogger(typeof(MtServerInstance)); private static readonly ILog Log = LogManager.GetLogger(typeof(MtAdapter));
private static readonly MtServerInstance Instance = new MtServerInstance(); private static readonly MtAdapter Instance = new MtAdapter();
private readonly Dictionary<int, MtServer> _servers = new Dictionary<int, MtServer>(); private readonly Dictionary<int, MtServer> _servers = new Dictionary<int, MtServer>();
private readonly Dictionary<int, MtExpert> _experts = new Dictionary<int, MtExpert>(); private readonly Dictionary<int, MtExpert> _experts = new Dictionary<int, MtExpert>();
@@ -18,16 +18,16 @@ namespace MTApiService
#region Init Instance #region Init Instance
private MtServerInstance() private MtAdapter()
{ {
LogConfigurator.Setup(LogProfileName); LogConfigurator.Setup(LogProfileName);
} }
static MtServerInstance() static MtAdapter()
{ {
} }
public static MtServerInstance GetInstance() public static MtAdapter GetInstance()
{ {
return Instance; return Instance;
} }
@@ -36,12 +36,12 @@ namespace MTApiService
#region Public Methods #region Public Methods
public void InitExpert(int expertHandle, int port, string symbol, double bid, double ask, IMetaTraderHandler mtHandler) public void AddExpert(int port, MtExpert expert)
{ {
if (mtHandler == null) if (expert == null)
throw new ArgumentNullException(nameof(mtHandler)); 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; MtServer server;
lock (_servers) lock (_servers)
@@ -60,21 +60,20 @@ namespace MTApiService
} }
} }
var expert = new MtExpert(expertHandle, new MtQuote(symbol, bid, ask), mtHandler);
lock (_experts) lock (_experts)
{ {
_experts[expert.Handle] = expert; _experts[expert.Handle] = expert;
} }
server.AddExpert(expert); server.AddExpert(expert);
expert.Deinited += ExpertOnDeinited;
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; MtExpert expert = null;
@@ -83,7 +82,6 @@ namespace MTApiService
if (_experts.ContainsKey(expertHandle)) if (_experts.ContainsKey(expertHandle))
{ {
expert = _experts[expertHandle]; expert = _experts[expertHandle];
_experts.Remove(expertHandle);
} }
} }
@@ -93,15 +91,15 @@ namespace MTApiService
} }
else 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) 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; MtExpert expert;
lock (_experts) lock (_experts)
@@ -111,14 +109,14 @@ namespace MTApiService
if (expert != null) if (expert != null)
{ {
expert.Quote = new MtQuote(symbol, bid, ask); expert.UpdateQuote(new MtQuote { Instrument = symbol, Bid = bid, Ask = ask, ExpertHandle = expertHandle });
} }
else 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) public void SendEvent(int expertHandle, int eventType, string payload)
@@ -133,7 +131,7 @@ namespace MTApiService
if (expert != null) if (expert != null)
{ {
expert.SendEvent(new MtEvent(eventType, payload)); expert.SendEvent(new MtEvent { EventType = eventType, Payload = payload, ExpertHandle = expertHandle });
} }
else else
{ {
@@ -208,6 +206,50 @@ namespace MTApiService
return retval; return retval;
} }
public object GetNamedParameter(int expertHandle, string name)
{
Log.DebugFormat("GetNamedParameter: begin. expertHandle = {0}, name = {1}", expertHandle, name);
MtExpert expert;
lock (_experts)
{
expert = _experts[expertHandle];
}
if (expert == null)
{
Log.WarnFormat("GetNamedParameter: expert with id {0} has not been found.", expertHandle);
}
var retval = expert?.GetNamedParameter(name);
Log.DebugFormat("GetNamedParameter: end. retval = {0}", retval);
return retval;
}
public bool ContainsNamedParameter(int expertHandle, string name)
{
Log.DebugFormat("ContainsNamedParameter: begin. expertHandle = {0}, name = {1}", expertHandle, name);
MtExpert expert;
lock (_experts)
{
expert = _experts[expertHandle];
}
if (expert == null)
{
Log.WarnFormat("ContainsNamedParameter: expert with id {0} has not been found.", expertHandle);
}
bool retval = expert != null ? expert.ContainsNamedParameter(name) : false;
Log.DebugFormat("ContainsNamedParameter: end. retval = {0}", retval);
return retval;
}
#endregion #endregion
#region Private Methods #region Private Methods
@@ -228,6 +270,31 @@ namespace MTApiService
} }
} }
} }
private void ExpertOnDeinited(object sender, EventArgs eventArgs)
{
Log.Debug("ExpertOnDeinited: begin.");
var expert = sender as MtExpert;
if (expert == null)
{
Log.Warn("expert_Deinited: end. Expert is not defined.");
return;
}
lock (_experts)
{
if (_experts.ContainsKey(expert.Handle))
{
_experts.Remove(expert.Handle);
}
}
Log.DebugFormat("ExpertOnDeinited: removed expert {0}", expert.Handle);
Log.Debug("ExpertOnDeinited: end.");
}
#endregion #endregion
} }
} }
+1 -1
View File
@@ -11,13 +11,13 @@ namespace MTApiService
: base(callbackContext, binding, remoteAddress) : base(callbackContext, binding, remoteAddress)
{ {
InnerDuplexChannel.Faulted += InnerDuplexChannel_Faulted; InnerDuplexChannel.Faulted += InnerDuplexChannel_Faulted;
InnerDuplexChannel.Open();
} }
#region IMtApi Members #region IMtApi Members
public bool Connect() public bool Connect()
{ {
InnerDuplexChannel.Open();
return Channel.Connect(); return Channel.Connect();
} }
+42 -90
View File
@@ -6,38 +6,33 @@ using log4net;
namespace MTApiService namespace MTApiService
{ {
[CallbackBehavior(UseSynchronizationContext = false)] [CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)]
public class MtClient: IMtApiCallback, IDisposable public class MtClient : IMtApiCallback, IDisposable
{ {
private const string ServiceName = "MtApiService"; private const string ServiceName = "MtApiService";
public delegate void MtQuoteHandler(MtQuote quote); public delegate void MtQuoteHandler(MtQuote quote);
public delegate void MtEventHandler(MtEvent e);
#region Fields #region Fields
private static readonly ILog Log = LogManager.GetLogger(typeof(MtClient)); private static readonly ILog Log = LogManager.GetLogger(typeof(MtClient));
private MtApiProxy _proxy; private readonly MtApiProxy _proxy;
private bool _isConnected;
#endregion #endregion
#region Public Methods #region ctor
public void Open(string host, int port) public MtClient(string host, int port)
{ {
Log.DebugFormat("Open: begin. host = {0}, port = {1}", host, port);
if (string.IsNullOrEmpty(host)) if (string.IsNullOrEmpty(host))
throw new ArgumentNullException(nameof(host), "host is null or empty"); throw new ArgumentNullException(nameof(host), "host is null or empty");
if (port < 0 || port > 65536) if (port < 0 || port > 65536)
throw new ArgumentOutOfRangeException(nameof(port), "port value is invalid"); throw new ArgumentOutOfRangeException(nameof(port), "port value is invalid");
var urlService = $"net.tcp://{host}:{port}/{ServiceName}"; Host = host;
Port = port;
if (_proxy != null) var urlService = $"net.tcp://{host}:{port}/{ServiceName}";
{
Log.Warn("Open: end. _proxy is not null.");
return;
}
var bind = new NetTcpBinding(SecurityMode.None) var bind = new NetTcpBinding(SecurityMode.None)
{ {
@@ -55,28 +50,19 @@ namespace MTApiService
MaxNameTableCharCount = 2147483647 MaxNameTableCharCount = 2147483647
} }
}; };
// Commented next statement since it is not required
_proxy = new MtApiProxy(new InstanceContext(this), bind, new EndpointAddress(urlService)); _proxy = new MtApiProxy(new InstanceContext(this), bind, new EndpointAddress(urlService));
_proxy.Faulted += ProxyFaulted; _proxy.Faulted += ProxyFaulted;
Log.Debug("Open: end.");
} }
public void Open(int port) public MtClient(int port)
{ {
Log.DebugFormat("Open: begin. port = {0}", port);
if (port < 0 || port > 65536) if (port < 0 || port > 65536)
throw new ArgumentOutOfRangeException(nameof(port), "port value is invalid"); throw new ArgumentOutOfRangeException(nameof(port), "port value is invalid");
var urlService = $"net.pipe://localhost/{ServiceName}_{port}"; Port = port;
if (_proxy != null) var urlService = $"net.pipe://localhost/{ServiceName}_{port}";
{
Log.Warn("Open: end. _proxy is not null.");
return;
}
var bind = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None) var bind = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
{ {
@@ -94,61 +80,40 @@ namespace MTApiService
MaxNameTableCharCount = 2147483647 MaxNameTableCharCount = 2147483647
} }
}; };
// Commented next statement since it is not required
_proxy = new MtApiProxy(new InstanceContext(this), bind, new EndpointAddress(urlService)); _proxy = new MtApiProxy(new InstanceContext(this), bind, new EndpointAddress(urlService));
_proxy.Faulted += ProxyFaulted; _proxy.Faulted += ProxyFaulted;
Log.Debug("Open: end.");
} }
public void Close()
{
Log.Debug("Close: begin.");
if (_proxy != null) #endregion
{
_proxy.Faulted -= ProxyFaulted;
_proxy.Dispose();
_proxy = null;
}
_isConnected = false;
Log.Debug("Close: end.");
}
#region Public Methods
/// <exception cref="CommunicationException">Thrown when connection failed</exception> /// <exception cref="CommunicationException">Thrown when connection failed</exception>
public void Connect() public void Connect()
{ {
Log.Debug("Connect: begin."); Log.Debug("Connect: begin.");
if (_proxy == null) if (_proxy.State != CommunicationState.Created)
{ {
Log.Error("Connect: _proxy is not defined."); Log.ErrorFormat("Connected: end. Client has invalid state {0}", _proxy.State);
throw new CommunicationException("Connection failed to service. Proxy is not defined (needs to call Open)");
}
if (_isConnected)
{
Log.Warn("Connected: end. Client is already connected.");
return; return;
} }
bool coonected;
try try
{ {
_isConnected = _proxy.Connect(); coonected = _proxy.Connect();
} }
catch (Exception ex) catch (Exception ex)
{ {
Log.ErrorFormat("Connect: Exception - {0}", ex.Message); Log.ErrorFormat("Connect: Exception - {0}", ex.Message);
Close();
throw new CommunicationException($"Connection failed to service. {ex.Message}"); throw new CommunicationException($"Connection failed to service. {ex.Message}");
} }
if (_isConnected == false) if (coonected == false)
{ {
Log.Error("Connect: end. Connection failed."); Log.Error("Connect: end. Connection failed.");
throw new CommunicationException("Connection failed"); throw new CommunicationException("Connection failed");
@@ -163,72 +128,60 @@ namespace MTApiService
try try
{ {
_isConnected = false; _proxy.Disconnect();
_proxy?.Disconnect();
} }
catch (Exception ex) catch (Exception ex)
{ {
Log.ErrorFormat("Disconnect: Exception - {0}", ex.Message); Log.ErrorFormat("Disconnect: Exception - {0}", ex.Message);
Close();
} }
Log.Debug("Disconnect: end."); Log.Debug("Disconnect: end.");
} }
/// <exception cref="CommunicationException">Thrown when connection failed</exception> /// <exception cref="CommunicationException">Thrown when connection failed</exception>
public MtResponse SendCommand(int commandType, ArrayList parameters) public MtResponse SendCommand(int commandType, ArrayList parameters, Dictionary<string, object> namedParams, int expertHandle)
{ {
Log.DebugFormat("SendCommand: begin. commandType = {0}, parameters count = {1}", commandType, parameters?.Count); Log.DebugFormat("SendCommand: begin. commandType = {0}, parameters count = {1}", commandType, parameters?.Count);
MtResponse result; if (IsConnected == false)
if (_isConnected == false)
{ {
Log.Error("SendCommand: Client is not connected."); Log.Error("SendCommand: Client is not connected.");
throw new CommunicationException("Client is not connected."); throw new CommunicationException("Client is not connected.");
} }
if (_proxy == null) MtResponse result;
{
Log.Error("SendCommand: Proxy is not defined.");
throw new CommunicationException("Proxy is not defined.");
}
try try
{ {
result = _proxy.SendCommand(new MtCommand(commandType, parameters)); result = _proxy.SendCommand(new MtCommand {
CommandType = commandType,
Parameters = parameters,
NamedParams = namedParams,
ExpertHandle = expertHandle});
} }
catch (Exception ex) catch (Exception ex)
{ {
Log.ErrorFormat("SendCommand: Exception - {0}", ex.Message); Log.ErrorFormat("SendCommand: Exception - {0}", ex.Message);
Close();
throw new CommunicationException("Service connection failed! " + ex.Message); throw new CommunicationException("Service connection failed! " + ex.Message);
} }
Log.DebugFormat("SendCommand: end. result = {0}", result);
return result; return result;
} }
/// <exception cref="CommunicationException">Thrown when connection failed</exception> /// <exception cref="CommunicationException">Thrown when connection failed</exception>
public IEnumerable<MtQuote> GetQuotes() public List<MtQuote> GetQuotes()
{ {
Log.Debug("GetQuotes: begin."); Log.Debug("GetQuotes: begin.");
if (_isConnected == false) if (IsConnected == false)
{ {
Log.Warn("GetQuotes: end. Client is not connected."); Log.Warn("GetQuotes: end. Client is not connected.");
return null; return null;
} }
if (_proxy == null)
{
Log.Warn("GetQuotes: end. _proxy is not defined.");
return null;
}
List<MtQuote> result; List<MtQuote> result;
try try
@@ -239,8 +192,6 @@ namespace MTApiService
{ {
Log.ErrorFormat("GetQuotes: Exception - {0}", ex.Message); Log.ErrorFormat("GetQuotes: Exception - {0}", ex.Message);
Close();
throw new CommunicationException($"Service connection failed! {ex.Message}"); throw new CommunicationException($"Service connection failed! {ex.Message}");
} }
@@ -286,18 +237,17 @@ namespace MTApiService
{ {
Log.Debug("OnServerStopped: begin."); Log.Debug("OnServerStopped: begin.");
Close();
ServerDisconnected?.Invoke(this, EventArgs.Empty); ServerDisconnected?.Invoke(this, EventArgs.Empty);
Log.Debug("OnServerStopped: end."); Log.Debug("OnServerStopped: end.");
} }
public void OnMtEvent(MtEvent mtEvent) public void OnMtEvent(MtEvent e)
{ {
Log.DebugFormat("OnMtEvent: begin. event = {0}", mtEvent); Log.DebugFormat("OnMtEvent: begin. event = {0}", e);
MtEventReceived?.Invoke(this, new MtEventArgs(mtEvent)); MtEventReceived?.Invoke(e);
Log.Debug("OnMtEvent: end."); Log.Debug("OnMtEvent: end.");
} }
@@ -305,7 +255,10 @@ namespace MTApiService
#endregion #endregion
#region Properties #region Properties
public bool IsConnected => _proxy.State == CommunicationState.Opened && _isConnected; public string Host { get; private set; }
public int Port { get; private set; }
private bool IsConnected => _proxy.State == CommunicationState.Opened;
#endregion #endregion
@@ -315,7 +268,6 @@ namespace MTApiService
{ {
Log.Debug("ProxyFaulted: begin."); Log.Debug("ProxyFaulted: begin.");
Close();
ServerFailed?.Invoke(this, EventArgs.Empty); ServerFailed?.Invoke(this, EventArgs.Empty);
Log.Debug("ProxyFaulted: end."); Log.Debug("ProxyFaulted: end.");
@@ -329,7 +281,7 @@ namespace MTApiService
{ {
Log.Debug("Dispose: begin."); Log.Debug("Dispose: begin.");
Close(); _proxy.Dispose();
Log.Debug("Dispose: end."); Log.Debug("Dispose: end.");
} }
@@ -342,7 +294,7 @@ namespace MTApiService
public event MtQuoteHandler QuoteUpdated; public event MtQuoteHandler QuoteUpdated;
public event EventHandler ServerDisconnected; public event EventHandler ServerDisconnected;
public event EventHandler ServerFailed; public event EventHandler ServerFailed;
public event EventHandler<MtEventArgs> MtEventReceived; public event MtEventHandler MtEventReceived;
#endregion #endregion
} }
} }
+9 -8
View File
@@ -1,26 +1,27 @@
using System.Runtime.Serialization; using System.Runtime.Serialization;
using System.Collections; using System.Collections;
using System.Collections.Generic;
namespace MTApiService namespace MTApiService
{ {
[DataContract] [DataContract]
public class MtCommand public class MtCommand
{ {
public MtCommand(int commandType, ArrayList parameters) [DataMember]
{ public int CommandType { get; set; }
CommandType = commandType;
Parameters = parameters;
}
[DataMember] [DataMember]
public int CommandType { get; private set; } public ArrayList Parameters { get; set; }
[DataMember] [DataMember]
public ArrayList Parameters { get; private set; } public Dictionary<string, object> NamedParams { get; set; }
[DataMember]
public int ExpertHandle { get; set; }
public override string ToString() public override string ToString()
{ {
return $"CommandType = {CommandType}"; return $"CommandType = {CommandType}; ExpertHandle = {ExpertHandle}";
} }
} }
} }
+1 -1
View File
@@ -17,7 +17,7 @@ namespace MTApiService
Command = command; Command = command;
} }
public MtCommand Command { get; private set; } public MtCommand Command { get; }
public MtResponse WaitResult(int time) public MtResponse WaitResult(int time)
{ {
+5 -18
View File
@@ -7,30 +7,17 @@ namespace MTApiService
public class MtEvent public class MtEvent
{ {
[DataMember] [DataMember]
public int EventType { get; private set; } public int EventType { get; internal set; }
[DataMember] [DataMember]
public string Payload { get; private set; } public string Payload { get; internal set; }
public MtEvent(int eventType, string payload) [DataMember]
{ public int ExpertHandle { get; internal set; }
EventType = eventType;
Payload = payload;
}
public override string ToString() public override string ToString()
{ {
return "MtEvent = " + EventType + ", Payload = " + Payload; return $"EventType = {EventType}; Payload = {Payload}; ExpertHandle = {ExpertHandle}";
} }
} }
public class MtEventArgs: EventArgs
{
public MtEventArgs(MtEvent e)
{
Event = e;
}
public MtEvent Event { get; private set; }
}
} }
+55 -111
View File
@@ -4,14 +4,13 @@ using log4net;
namespace MTApiService namespace MTApiService
{ {
internal class MtCommandExecutorManager : ICommandManager internal class MtExecutorManager : ICommandManager
{ {
#region Private Fields #region Private Fields
private static readonly ILog Log = LogManager.GetLogger(typeof(MtCommandExecutorManager)); private static readonly ILog Log = LogManager.GetLogger(typeof(MtExecutorManager));
private readonly List<MtExpert> _commandExecutors = new List<MtExpert>();
private readonly Queue<MtCommandTask> _commandTasks = new Queue<MtCommandTask>();
private readonly List<ITaskExecutor> _executorList = new List<ITaskExecutor>();
private readonly Dictionary<int, ITaskExecutor> _executorMap = new Dictionary<int, ITaskExecutor>();
private readonly object _locker = new object(); private readonly object _locker = new object();
#endregion #endregion
@@ -23,149 +22,94 @@ namespace MTApiService
lock (_locker) lock (_locker)
{ {
_commandExecutors.Clear(); _executorList.Clear();
_commandTasks.Clear(); _executorMap.Clear();
} }
Log.Debug("Stop: end."); Log.Debug("Stop: end.");
} }
public void AddCommandExecutor(MtExpert commandExecutor) public void AddExecutor(ITaskExecutor executor)
{ {
if (commandExecutor == null) if (executor == null)
throw new ArgumentNullException(nameof(commandExecutor)); throw new ArgumentNullException(nameof(executor));
Log.DebugFormat("AddCommandExecutor: begin. commandExecutor = {0}", commandExecutor); Log.DebugFormat("AddExecutor: begin. executor = {0}", executor);
var notify = false;
lock (_locker) lock (_locker)
{ {
if (_commandExecutors.Contains(commandExecutor)) if (_executorList.Contains(executor))
{ {
Log.Warn("AddCommandExecutor: end. Command executor already exist."); Log.Warn("AddExecutor: end. Executor already exist.");
return; return;
} }
_commandExecutors.Add(commandExecutor); _executorList.Add(executor);
if (_commandTasks.Count > 0) _executorMap[executor.Handle] = executor;
{
notify = true;
}
}
commandExecutor.CommandExecuted += CommandExecutor_CommandExecuted;
commandExecutor.CommandManager = this;
if (notify)
{
NotifyCommandReady();
} }
Log.Debug("AddCommandExecutor: end."); Log.Debug("AddCommandExecutor: end.");
} }
public void RemoveCommandExecutor(MtExpert commandExecutor) public void RemoveExecutor(ITaskExecutor executor)
{ {
if (commandExecutor == null) if (executor == null)
throw new ArgumentNullException(nameof(commandExecutor)); throw new ArgumentNullException(nameof(executor));
Log.DebugFormat("RemoveCommandExecutor: begin. commandExecutor = {0}", commandExecutor); Log.DebugFormat("RemoveExecutor: begin. executor = {0}", executor);
var notify = false;
lock (_locker) lock (_locker)
{ {
if (_commandExecutors.Contains(commandExecutor) == false) if (_executorList.Contains(executor) == false)
{ {
Log.Warn("RemoveCommandExecutor: end. Command executor is not exist in collection."); Log.Warn("RemoveExecutor: end. Executor is not exist in collection.");
return; return;
} }
_commandExecutors.Remove(commandExecutor); _executorList.Remove(executor);
if (_commandTasks.Count > 0) _executorMap.Remove(executor.Handle);
}
Log.Debug("RemoveExecutor: end.");
}
public MtCommandTask SendCommand(MtCommand command)
{
if (command == null)
throw new ArgumentNullException(nameof(command));
var task = new MtCommandTask(command);
Log.DebugFormat("SendTask: begin. command = {0}", command);
ITaskExecutor executor;
lock (_locker)
{
if (_executorMap.ContainsKey(command.ExpertHandle))
{ {
notify = true; executor = _executorMap[command.ExpertHandle];
}
else
{
executor = _executorList.Count > 0 ? _executorList[0] : null;
} }
} }
commandExecutor.CommandExecuted -= CommandExecutor_CommandExecuted; if (executor == null)
commandExecutor.CommandManager = null;
if (notify)
{ {
NotifyCommandReady(); Log.Error("SendTask: Executor is null!");
}
else
{
executor.Execute(task);
} }
Log.Debug("RemoveCommandExecutor: end."); Log.Debug("SendTask: end.");
return task;
} }
public void EnqueueCommandTask(MtCommandTask task)
{
if (task == null)
throw new ArgumentNullException(nameof(task));
Log.DebugFormat("EnqueueCommandTask: begin. task = {0}", task);
lock (_locker)
{
_commandTasks.Enqueue(task);
}
NotifyCommandReady();
Log.Debug("EnqueueCommandTask: end.");
}
public MtCommandTask DequeueCommandTask()
{
Log.Debug("DequeueCommandTask: called.");
lock (_locker)
{
return _commandTasks.Count > 0 ? _commandTasks.Dequeue() : null;
}
}
#endregion
#region Private Methods
private void NotifyCommandReady()
{
Log.Debug("NotifyCommandReady: begin.");
var commandExecutors = new List<MtExpert>();
lock (_locker)
{
commandExecutors.AddRange(_commandExecutors);
}
foreach (var executor in commandExecutors)
{
executor.NotifyCommandReady();
}
Log.DebugFormat("NotifyCommandReady: end. Notified executor count = {0}", commandExecutors.Count);
}
private void CommandExecutor_CommandExecuted(object sender, EventArgs e)
{
Log.Debug("CommandExecutor_CommandExecuted: begin.");
var notify = false;
lock (_locker)
{
if (_commandTasks.Count > 0)
{
notify = true;
}
}
if (notify)
{
NotifyCommandReady();
}
Log.Debug("CommandExecutor_CommandExecuted: end.");
}
#endregion #endregion
} }
} }
+107 -80
View File
@@ -1,37 +1,38 @@
using System; using System;
using log4net; using log4net;
using System.Collections.Generic;
namespace MTApiService namespace MTApiService
{ {
public class MtExpert public class MtExpert: ITaskExecutor
{ {
public delegate void MtQuoteHandler(MtExpert expert, MtQuote quote); public delegate void MtQuoteHandler(MtExpert expert, MtQuote quote);
public delegate void MtEventHandler(MtExpert expert, MtEvent e);
#region Private Fields #region Private Fields
private static readonly ILog Log = LogManager.GetLogger(typeof(MtExpert)); private static readonly ILog Log = LogManager.GetLogger(typeof(MtExpert));
private readonly IMetaTraderHandler _mtHadler; private readonly IMetaTraderHandler _mtHadler;
private MtCommandTask _commandTask; private MtCommandTask _currentTask;
private ICommandManager _commandManager; private readonly Queue<MtCommandTask> _taskQueue = new Queue<MtCommandTask>();
private readonly object _locker = new object(); private readonly object _locker = new object();
#endregion #endregion
#region Public Methods #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) if (mtHandler == null)
throw new ArgumentNullException(nameof(mtHandler)); throw new ArgumentNullException(nameof(mtHandler));
Quote = quote; _quote = new MtQuote { ExpertHandle = handle, Instrument = symbol, Bid = bid, Ask = ask};
Handle = handle; Handle = handle;
_mtHadler = mtHandler; _mtHadler = mtHandler;
} }
public void Deinit() public virtual void Deinit()
{ {
Log.Debug("Deinit: begin."); Log.Debug("Deinit: begin.");
IsEnable = false;
FireOnDeinited(); FireOnDeinited();
Log.Debug("Deinit: end."); Log.Debug("Deinit: end.");
@@ -41,31 +42,26 @@ namespace MTApiService
{ {
Log.DebugFormat("SendResponse: begin. response = {0}", response); Log.DebugFormat("SendResponse: begin. response = {0}", response);
_commandTask.SetResult(response); _currentTask.SetResult(response);
_commandTask = null; _currentTask = null;
FireOnCommandExecuted();
Log.Debug("SendResponse: end."); Log.Debug("SendResponse: end.");
} }
public int GetCommandType() public virtual int GetCommandType()
{ {
Log.Debug("GetCommandType: called."); Log.Debug("GetCommandType: called.");
var commandManager = CommandManager; _currentTask = DequeueTask();
if (commandManager != null)
{
_commandTask = commandManager.DequeueCommandTask();
}
return _commandTask?.Command?.CommandType ?? 0; return _currentTask?.Command?.CommandType ?? 0;
} }
public object GetCommandParameter(int index) public object GetCommandParameter(int index)
{ {
Log.DebugFormat("GetCommandType: called. index = {0}", index); Log.DebugFormat("GetCommandParameter: called. index = {0}", index);
var command = _commandTask?.Command; var command = _currentTask?.Command;
if (command?.Parameters != null && index >= 0 && index < command.Parameters.Count) if (command?.Parameters != null && index >= 0 && index < command.Parameters.Count)
{ {
return command.Parameters[index]; return command.Parameters[index];
@@ -74,7 +70,47 @@ namespace MTApiService
return null; return null;
} }
public void SendEvent(MtEvent mtEvent) 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 virtual void SendEvent(MtEvent mtEvent)
{ {
Log.DebugFormat("SendEvent: begin. event = {0}", mtEvent); Log.DebugFormat("SendEvent: begin. event = {0}", mtEvent);
@@ -83,14 +119,38 @@ namespace MTApiService
Log.Debug("SendEvent: end."); Log.Debug("SendEvent: end.");
} }
public void UpdateQuote(MtQuote quote)
{
Log.DebugFormat("UpdateQuote: begin. quote = {0}", quote);
Quote = quote;
Log.Debug("UpdateQuote: end.");
}
public override string ToString() 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 #endregion
#region Properties #region Properties
private MtQuote _quote; private MtQuote _quote;
public MtQuote Quote public MtQuote Quote
{ {
@@ -101,7 +161,7 @@ namespace MTApiService
return _quote; return _quote;
} }
} }
set private set
{ {
lock (_locker) lock (_locker)
{ {
@@ -113,61 +173,34 @@ namespace MTApiService
} }
public int Handle { get; } 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 #endregion
#region Private Methods #region Private Methods
private void SendTickToMetaTrader() private MtCommandTask DequeueTask()
{ {
Log.Debug("DequeueTask: called.");
MtCommandTask task;
int count;
lock (_locker)
{
count = _taskQueue.Count;
task = _taskQueue.Count > 0 ? _taskQueue.Dequeue() : null;
}
Log.DebugFormat("DequeueTask: end. left task count = {0}.", count);
return task;
}
private void NotifyCommandReady()
{
Log.Debug("NotifyCommandReady: begin.");
_mtHadler.SendTickToMetaTrader(Handle); _mtHadler.SendTickToMetaTrader(Handle);
Log.Debug("NotifyCommandReady: end.");
} }
private void FireOnQuoteChanged(MtQuote quote) private void FireOnQuoteChanged(MtQuote quote)
@@ -180,22 +213,16 @@ namespace MTApiService
Deinited?.Invoke(this, EventArgs.Empty); Deinited?.Invoke(this, EventArgs.Empty);
} }
private void FireOnCommandExecuted()
{
CommandExecuted?.Invoke(this, EventArgs.Empty);
}
private void FireOnMtEvent(MtEvent mtEvent) private void FireOnMtEvent(MtEvent mtEvent)
{ {
OnMtEvent?.Invoke(this, new MtEventArgs(mtEvent)); OnMtEvent?.Invoke(this, mtEvent);
} }
#endregion #endregion
#region Events #region Events
public event EventHandler Deinited; public event EventHandler Deinited;
public event MtQuoteHandler QuoteChanged; public event MtQuoteHandler QuoteChanged;
public event EventHandler CommandExecuted; public event MtEventHandler OnMtEvent;
public event EventHandler<MtEventArgs> OnMtEvent;
#endregion #endregion
} }
} }
-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] [DataMember]
public int Action { get; set; } public int Action { get; set; }
[DataMember] [DataMember]
public uint Magic { get; set; } public ulong Magic { get; set; }
[DataMember] [DataMember]
public uint Order { get; set; } public ulong Order { get; set; }
[DataMember] [DataMember]
public string Symbol { get; set; } public string Symbol { get; set; }
[DataMember] [DataMember]
@@ -25,7 +25,7 @@ namespace MTApiService
[DataMember] [DataMember]
public double Tp { get; set; } public double Tp { get; set; }
[DataMember] [DataMember]
public uint Deviation { get; set; } public ulong Deviation { get; set; }
[DataMember] [DataMember]
public int Type { get; set; } public int Type { get; set; }
[DataMember] [DataMember]
@@ -36,5 +36,9 @@ namespace MTApiService
public DateTime Expiration { get; set; } public DateTime Expiration { get; set; }
[DataMember] [DataMember]
public string Comment { get; set; } 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() static IEnumerable<Type> GetKnownTypes()
{ {
return new Type[] { typeof(MtResponseInt), typeof(MtResponseDouble), return new Type[] { typeof(MtResponseObject),
typeof(MtResponseInt), typeof(MtResponseDouble),
typeof(MtResponseString), typeof(MtResponseBool), typeof(MtResponseString), typeof(MtResponseBool),
typeof(MtResponseLong), typeof(MtResponseULong), typeof(MtResponseLong), typeof(MtResponseULong),
typeof(MtResponseDoubleArray), typeof(MtResponseIntArray), typeof(MtResponseDoubleArray), typeof(MtResponseIntArray),
@@ -22,6 +23,28 @@ namespace MTApiService
} }
public abstract object GetValue(); public abstract object GetValue();
[DataMember]
public int ErrorCode { get; set; }
}
[DataContract]
public class MtResponseObject : MtResponse
{
public MtResponseObject(object value)
{
Value = value;
}
[DataMember]
public object Value { get; private set; }
public override object GetValue() { return Value; }
public override string ToString()
{
return Value?.ToString() ?? string.Empty;
}
} }
[DataContract] [DataContract]
+28 -16
View File
@@ -21,7 +21,7 @@ namespace MTApiService
private readonly MtService _service; private readonly MtService _service;
private readonly List<ServiceHost> _hosts = new List<ServiceHost>(); private readonly List<ServiceHost> _hosts = new List<ServiceHost>();
private readonly MtCommandExecutorManager _executorManager = new MtCommandExecutorManager(); private readonly MtExecutorManager _executorManager = new MtExecutorManager();
private readonly List<MtExpert> _experts = new List<MtExpert>(); private readonly List<MtExpert> _experts = new List<MtExpert>();
#endregion #endregion
@@ -62,8 +62,16 @@ namespace MTApiService
} }
//init local pipe host //init local pipe host
var localUrl = CreateConnectionAddress(null, port, true); var localPipeUrl = CreateConnectionAddress(null, port, true);
var localServiceHost = CreateServiceHost(localUrl, true); var localPipeServiceHost = CreateServiceHost(localPipeUrl, true);
if (localPipeServiceHost != null)
{
_hosts.Add(localPipeServiceHost);
}
//init localhost
var localUrl = CreateConnectionAddress("localhost", port, false);
var localServiceHost = CreateServiceHost(localUrl, false);
if (localServiceHost != null) if (localServiceHost != null)
{ {
_hosts.Add(localServiceHost); _hosts.Add(localServiceHost);
@@ -72,11 +80,6 @@ namespace MTApiService
//init network hosts //init network hosts
var dnsHostName = Dns.GetHostName(); var dnsHostName = Dns.GetHostName();
var ips = Dns.GetHostEntry(dnsHostName); 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) foreach (var ipAddress in ips.AddressList)
{ {
@@ -149,7 +152,7 @@ namespace MTApiService
_experts.Add(expert); _experts.Add(expert);
} }
_executorManager.AddCommandExecutor(expert); _executorManager.AddExecutor(expert);
_service.OnQuoteAdded(expert.Quote); _service.OnQuoteAdded(expert.Quote);
@@ -170,11 +173,20 @@ namespace MTApiService
return null; return null;
} }
var task = new MtCommandTask(command); var task = _executorManager.SendCommand(command);
_executorManager.EnqueueCommandTask(task);
//wait for execute command in MetaTrader //wait for execute command in MetaTrader
var response = task.WaitResult(WaitResponseTime); MtResponse response = null;
try
{
response = task.WaitResult(WaitResponseTime);
}
catch (Exception ex)
{
Log.WarnFormat("SendCommand: Exception - {0}", ex.Message);
}
Log.DebugFormat("SendCommand: end. response = {0}", response);
return response; return response;
} }
@@ -371,7 +383,7 @@ namespace MTApiService
expertsCount = _experts.Count; expertsCount = _experts.Count;
} }
_executorManager.RemoveCommandExecutor(expert); _executorManager.RemoveExecutor(expert);
expert.Deinited -= expert_Deinited; expert.Deinited -= expert_Deinited;
expert.QuoteChanged -= expert_QuoteChanged; expert.QuoteChanged -= expert_QuoteChanged;
@@ -398,11 +410,11 @@ namespace MTApiService
Log.Debug("expert_QuoteChanged: end."); Log.Debug("expert_QuoteChanged: end.");
} }
private void Expert_OnMtEvent(object sender, MtEventArgs e) private void Expert_OnMtEvent(MtExpert expert, MtEvent e)
{ {
Log.DebugFormat("Expert_OnMtEvent: begin. event = {0}", e.Event); Log.DebugFormat("Expert_OnMtEvent: begin. expert = {0}, event = {1}", expert, e);
_service.OnMtEvent(e.Event); _service.OnMtEvent(e);
Log.Debug("Expert_OnMtEvent: end."); Log.Debug("Expert_OnMtEvent: end.");
} }
+7 -7
View File
@@ -66,7 +66,7 @@ namespace MTApiService
if (callback == null) if (callback == null)
{ {
Log.Warn("Connect: end. Callback is not definded."); Log.Warn("Connect: end. Callback is not defined.");
return false; return false;
} }
@@ -158,7 +158,7 @@ namespace MTApiService
public void QuoteUpdate(MtQuote quote) public void QuoteUpdate(MtQuote quote)
{ {
Log.Debug("QuoteUpdate: begin."); Log.DebugFormat("QuoteUpdate: begin. quote = {0}", quote);
ExecuteCallbackAction(a => a.OnQuoteUpdate(quote)); ExecuteCallbackAction(a => a.OnQuoteUpdate(quote));
@@ -167,7 +167,7 @@ namespace MTApiService
public void OnQuoteAdded(MtQuote quote) public void OnQuoteAdded(MtQuote quote)
{ {
Log.Debug("OnQuoteAdded: begin."); Log.DebugFormat("OnQuoteAdded: begin. quote = {0}", quote);
ExecuteCallbackAction(a => a.OnQuoteAdded(quote)); ExecuteCallbackAction(a => a.OnQuoteAdded(quote));
@@ -176,18 +176,18 @@ namespace MTApiService
public void OnQuoteRemoved(MtQuote quote) public void OnQuoteRemoved(MtQuote quote)
{ {
Log.Debug("OnQuoteRemoved: begin."); Log.DebugFormat("OnQuoteRemoved: begin. quote = {0}", quote);
ExecuteCallbackAction(a => a.OnQuoteRemoved(quote)); ExecuteCallbackAction(a => a.OnQuoteRemoved(quote));
Log.Debug("OnQuoteRemoved: end."); Log.Debug("OnQuoteRemoved: end.");
} }
public void OnMtEvent(MtEvent mtEvent) public void OnMtEvent(MtEvent e)
{ {
Log.Debug("OnMtEvent: begin."); Log.DebugFormat("OnMtEvent: begin.quote = {0}", e);
ExecuteCallbackAction(a => a.OnMtEvent(mtEvent)); ExecuteCallbackAction(a => a.OnMtEvent(e));
Log.Debug("OnMtEvent: end."); Log.Debug("OnMtEvent: end.");
} }
+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 // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.23.0")] [assembly: AssemblyVersion("1.0.30.0")]
[assembly: AssemblyFileVersion("1.0.23.0")] [assembly: AssemblyFileVersion("1.0.30.0")]
+175 -196
View File
@@ -4,7 +4,8 @@
#include "MT4Handler.h" #include "MT4Handler.h"
#include "Windows.h" #include "Windows.h"
#include < vcclr.h > #include <vcclr.h>
#include <functional>
using namespace System; using namespace System;
using namespace MTApiService; using namespace MTApiService;
@@ -17,6 +18,8 @@ using namespace System::IO;
using namespace System::Collections::Generic; using namespace System::Collections::Generic;
using namespace System::Diagnostics; using namespace System::Diagnostics;
#define _DLLAPI extern "C" __declspec(dllexport)
void convertSystemString(wchar_t* dest, String^ src) void convertSystemString(wchar_t* dest, String^ src)
{ {
pin_ptr<const wchar_t> wch = PtrToStringChars(src); pin_ptr<const wchar_t> wch = PtrToStringChars(src);
@@ -24,264 +27,240 @@ void convertSystemString(wchar_t* dest, String^ src)
dest[wcslen(wch)] = '\0'; dest[wcslen(wch)] = '\0';
} }
int _stdcall initExpert(int expertHandle, int port, wchar_t* symbol, double bid, double ask, wchar_t* err) template <typename T> T Execute(std::function<T()> func, wchar_t* err, T default_value)
{ {
T result = default_value;
try try
{ {
MT4Handler^ mtHandler = gcnew MT4Handler(); result = func();
MtServerInstance::GetInstance()->InitExpert(expertHandle, port, gcnew String(symbol), bid, ask, mtHandler);
} }
catch (Exception^ e) catch (Exception^ e)
{ {
convertSystemString(err, e->Message); convertSystemString(err, e->Message);
Debug::WriteLine("[ERROR] MTConnector:initExpert(): " + e->Message);
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 return Execute<bool>([&expertHandle, &port, symbol, &bid, &ask]() {
{ auto expert = gcnew MtExpert(expertHandle, gcnew String(symbol), bid, ask, gcnew MT4Handler());
MtServerInstance::GetInstance()->DeinitExpert(expertHandle); MtAdapter::GetInstance()->AddExpert(port, expert);
} return true;
catch (Exception^ e) }, err, false);
{
convertSystemString(err, e->Message);
Debug::WriteLine("[ERROR] MTConnector:deinitExpert(): " + e->Message);
return 0;
}
return 1;
} }
int _stdcall updateQuote(int expertHandle, wchar_t* symbol, double bid, double ask, wchar_t* err) _DLLAPI bool _stdcall deinitExpert(int expertHandle, wchar_t* err)
{ {
try return Execute<bool>([&expertHandle]() {
{ MtAdapter::GetInstance()->RemoveExpert(expertHandle);
MtServerInstance::GetInstance()->SendQuote(expertHandle, gcnew String(symbol), bid, ask); return true;
} }, err, false);
catch (Exception^ e) }
{
convertSystemString(err, e->Message); _DLLAPI bool _stdcall updateQuote(int expertHandle, wchar_t* symbol, double bid, double ask, wchar_t* err)
Debug::WriteLine("[ERROR] MTConnector:updateQuote(): " + e->Message); {
return 0; return Execute<bool>([&expertHandle, symbol, &bid, &ask]() {
} MtAdapter::GetInstance()->SendQuote(expertHandle, gcnew String(symbol), bid, ask);
return 1; 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 return Execute<bool>([&expertHandle, &eventType, payload]() {
{ MtAdapter::GetInstance()->SendEvent(expertHandle, eventType, gcnew String(payload));
MtServerInstance::GetInstance()->SendEvent(expertHandle, eventType, gcnew String(payload)); return true;
} }, err, false);
catch (Exception^ e)
{
convertSystemString(err, e->Message);
Debug::WriteLine("[ERROR] MTConnector:updateTimeBar(): " + e->Message);
return 0;
}
return 1;
} }
int _stdcall sendIntResponse(int expertHandle, int response) _DLLAPI bool _stdcall sendIntResponse(int expertHandle, int response, wchar_t* err)
{ {
try return Execute<bool>([&expertHandle, &response]() {
{ MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseInt(response));
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseInt(response)); return true;
} }, err, false);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendIntResponse(): " + e->Message);
return 0;
}
return 1;
} }
int _stdcall sendBooleanResponse(int expertHandle, int response) _DLLAPI bool _stdcall sendBooleanResponse(int expertHandle, bool response, wchar_t* err)
{ {
try return Execute<bool>([&expertHandle, &response]() {
{ MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseBool(response));
bool value = (response != 0) ? true : false; return true;
}, err, false);
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseBool(value));
}
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendBooleanResponse(): " + e->Message);
return 0;
}
return 1;
} }
int _stdcall sendDoubleResponse(int expertHandle, double response) _DLLAPI bool _stdcall sendDoubleResponse(int expertHandle, double response, wchar_t* err)
{ {
try return Execute<bool>([&expertHandle, &response]() {
{ MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDouble(response));
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDouble(response)); return true;
} }, err, false);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendDoubleResponse(): " + e->Message);
return 0;
}
return 1;
} }
int _stdcall sendStringResponse(int expertHandle, wchar_t* response) _DLLAPI bool _stdcall sendStringResponse(int expertHandle, wchar_t* response, wchar_t* err)
{ {
try return Execute<bool>([&expertHandle, response]() {
{ MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseString(gcnew String(response)));
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseString(gcnew String(response))); return true;
} }, err, false);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendStringResponse(): " + e->Message);
return 0;
}
return 1;
} }
int _stdcall sendVoidResponse(int expertHandle) _DLLAPI bool _stdcall sendErrorResponse(int expertHandle, int code, wchar_t* message, wchar_t* err)
{ {
try return Execute<bool>([&expertHandle, &code, message]() {
{ MtResponseString^ res = gcnew MtResponseString(gcnew String(message));
MtServerInstance::GetInstance()->SendResponse(expertHandle, nullptr); res->ErrorCode = code;
} MtAdapter::GetInstance()->SendResponse(expertHandle, res);
catch (Exception^ e) return true;
{ }, err, false);
Debug::WriteLine("[ERROR] MTConnector:sendVoidResponse(): " + e->Message);
return 0;
}
return 1;
} }
int _stdcall sendDoubleArrayResponse(int expertHandle, double* values, int size) _DLLAPI bool _stdcall sendVoidResponse(int expertHandle, wchar_t* err)
{ {
try return Execute<bool>([&expertHandle]() {
{ MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseObject(nullptr));
return true;
}, err, false);
}
_DLLAPI bool _stdcall sendDoubleArrayResponse(int expertHandle, double* values, int size, wchar_t* err)
{
return Execute<bool>([&expertHandle, values, &size]() {
array<double>^ list = gcnew array<double>(size); array<double>^ list = gcnew array<double>(size);
for (int i = 0; i < size; i++)
for(int i = 0; i < size; i++)
{ {
list[i] = values[i]; list[i] = values[i];
} }
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDoubleArray(list));
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseDoubleArray(list)); return true;
} }, err, false);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendDoubleArrayResponse(): " + e->Message);
return 0;
}
return 1;
} }
int _stdcall sendIntArrayResponse(int expertHandle, int* values, int size) _DLLAPI bool _stdcall sendIntArrayResponse(int expertHandle, int* values, int size, wchar_t* err)
{ {
try return Execute<bool>([&expertHandle, values, &size]() {
{
array<int>^ list = gcnew array<int>(size); array<int>^ list = gcnew array<int>(size);
for (int i = 0; i < size; i++)
for(int i = 0; i < size; i++)
{ {
list[i] = values[i]; list[i] = values[i];
} }
MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseIntArray(list));
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseIntArray(list)); return true;
} }, err, false);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendIntArrayResponse(): " + e->Message);
return 0;
}
return 1;
} }
int _stdcall sendLongResponse(int expertHandle, __int64 response) _DLLAPI bool _stdcall sendLongResponse(int expertHandle, __int64 response, wchar_t* err)
{ {
try return Execute<bool>([&expertHandle, &response]() {
{ MtAdapter::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLong(response));
MtServerInstance::GetInstance()->SendResponse(expertHandle, gcnew MtResponseLong(response)); return true;
} }, err, false);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:sendLongResponse(): " + e->Message);
return 0;
}
return 1;
} }
int _stdcall getCommandType(int expertHandle, int* res) _DLLAPI bool _stdcall getCommandType(int expertHandle, int* res, wchar_t* err)
{ {
try return Execute<bool>([&expertHandle, res]() {
{ *res = MtAdapter::GetInstance()->GetCommandType(expertHandle);
*res = MtServerInstance::GetInstance()->GetCommandType(expertHandle); return true;
} }, err, false);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:getCommandType(): " + e->Message);
return 0;
}
return 1;
} }
int _stdcall getIntValue(int expertHandle, int paramIndex, int* res) _DLLAPI bool _stdcall getIntValue(int expertHandle, int paramIndex, int* res, wchar_t* err)
{ {
try return Execute<bool>([&expertHandle, &paramIndex, res]() {
{ *res = (int)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
*res = (int)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex); return true;
} }, err, false);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:getIntValue(): " + e->Message);
return 0;
}
return 1;
} }
int _stdcall getDoubleValue(int expertHandle, int paramIndex, double* res) // --- index parameters
_DLLAPI bool _stdcall getDoubleValue(int expertHandle, int paramIndex, double* res, wchar_t* err)
{ {
try return Execute<bool>([&expertHandle, &paramIndex, res]() {
{ *res = (double)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
*res = (double)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex); return true;
} }, err, false);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:getDoubleValue(): " + e->Message);
return 0;
}
return 1;
} }
int _stdcall getStringValue(int expertHandle, int paramIndex, wchar_t* res) _DLLAPI bool _stdcall getStringValue(int expertHandle, int paramIndex, wchar_t* res, wchar_t* err)
{ {
try return Execute<bool>([&expertHandle, &paramIndex, res]() {
{ convertSystemString(res, (String^)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex));
convertSystemString(res, (String^)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex)); return true;
} }, err, false);
catch (Exception^ e)
{
Debug::WriteLine("[ERROR] MTConnector:getStringValue(): " + e->Message);
return 0;
}
return 1;
} }
int _stdcall getBooleanValue(int expertHandle, int paramIndex, int* res) _DLLAPI bool _stdcall getBooleanValue(int expertHandle, int paramIndex, int* res, wchar_t* err)
{ {
try return Execute<bool>([&expertHandle, &paramIndex, res]() {
{ *res = (bool)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
bool val = (bool)MtServerInstance::GetInstance()->GetCommandParameter(expertHandle, paramIndex); return true;
*res = val == true ? 1 : 0; }, err, false);
} }
catch (Exception^ e)
{ _DLLAPI bool _stdcall getLongValue(int expertHandle, int paramIndex, __int64* res, wchar_t* err)
Debug::WriteLine("[ERROR] MT5Connector:getBooleanValue(): " + e->Message); {
return 0; return Execute<bool>([&expertHandle, &paramIndex, res]() {
} *res = (__int64)MtAdapter::GetInstance()->GetCommandParameter(expertHandle, paramIndex);
return 1; return true;
}, err, false);
}
// --- named parameters
_DLLAPI bool _stdcall containsNamedValue(int expertHandle, wchar_t* paramName)
{
wchar_t err[1000];
return Execute<bool>([&expertHandle, paramName]() {
return MtAdapter::GetInstance()->ContainsNamedParameter(expertHandle, gcnew String(paramName));
}, err, false);
}
_DLLAPI bool _stdcall getNamedIntValue(int expertHandle, wchar_t* paramName, int* res, wchar_t* err)
{
return Execute<bool>([&expertHandle, paramName, res]() {
System::Object^ obj = MtAdapter::GetInstance()->GetNamedParameter(expertHandle, gcnew String(paramName));
*res = (int)obj;
return true;
}, err, false);
}
_DLLAPI bool _stdcall getNamedDoubleValue(int expertHandle, wchar_t* paramName, double* res, wchar_t* err)
{
return Execute<bool>([&expertHandle, paramName, res]() {
System::Object^ obj = MtAdapter::GetInstance()->GetNamedParameter(expertHandle, gcnew String(paramName));
*res = (double)obj;
return true;
}, err, false);
}
_DLLAPI bool _stdcall getNamedStringValue(int expertHandle, wchar_t* paramName, wchar_t* res, wchar_t* err)
{
return Execute<bool>([&expertHandle, paramName, res]() {
System::Object^ obj = MtAdapter::GetInstance()->GetNamedParameter(expertHandle, gcnew String(paramName));
convertSystemString(res, (String^)obj);
return true;
}, err, false);
}
_DLLAPI bool _stdcall getNamedBooleanValue(int expertHandle, wchar_t* paramName, int* res, wchar_t* err)
{
return Execute<bool>([&expertHandle, paramName, res]() {
System::Object^ obj = MtAdapter::GetInstance()->GetNamedParameter(expertHandle, gcnew String(paramName));
*res = (bool)obj;
return true;
}, err, false);
}
_DLLAPI bool _stdcall getNamedLongValue(int expertHandle, wchar_t* paramName, __int64* res, wchar_t* err)
{
return Execute<bool>([&expertHandle, paramName, res]() {
System::Object^ obj = MtAdapter::GetInstance()->GetNamedParameter(expertHandle, gcnew String(paramName));
if (obj != nullptr)
*res = (__int64)obj;
return true;
}, err, false);
} }
-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> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>.\MTConnector.def</ModuleDefinitionFile>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -109,7 +108,6 @@
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>.\MTConnector.def</ModuleDefinitionFile>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -121,7 +119,6 @@
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>.\MTConnector.def</ModuleDefinitionFile>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -133,7 +130,6 @@
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>.\MTConnector.def</ModuleDefinitionFile>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
@@ -154,7 +150,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="app.ico" /> <None Include="app.ico" />
<None Include="MTConnector.def" />
<None Include="ReadMe.txt" /> <None Include="ReadMe.txt" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
-3
View File
@@ -44,9 +44,6 @@
<None Include="app.ico"> <None Include="app.ico">
<Filter>Resource Files</Filter> <Filter>Resource Files</Filter>
</None> </None>
<None Include="MTConnector.def">
<Filter>Source Files</Filter>
</None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="app.rc"> <ResourceCompile Include="app.rc">
+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" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="ChartEventArgs.cs" />
<Compile Include="ChartPeriod.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="EnumSeriesInfoInteger.cs" />
<Compile Include="EnumSymbolInfoDouble.cs" /> <Compile Include="EnumSymbolInfoDouble.cs" />
<Compile Include="EnumSymbolInfoInteger.cs" /> <Compile Include="EnumSymbolInfoInteger.cs" />
<Compile Include="EnumTerminalInfoDouble.cs" /> <Compile Include="EnumTerminalInfoDouble.cs" />
<Compile Include="EnumTerminalInfoInteger.cs" /> <Compile Include="EnumTerminalInfoInteger.cs" />
<Compile Include="ExtensionMethods.cs" /> <Compile Include="FlagFontStyle.cs" />
<Compile Include="Monitors\AvailabilityOrdersEventArgs.cs" /> <Compile Include="Monitors\AvailabilityOrdersEventArgs.cs" />
<Compile Include="MqlRates.cs" /> <Compile Include="MqlRates.cs" />
<Compile Include="MqlTick.cs" /> <Compile Include="MqlTick.cs" />
<Compile Include="MtChartEvent.cs" />
<Compile Include="MtConnectionEventArgs.cs" /> <Compile Include="MtConnectionEventArgs.cs" />
<Compile Include="MtConnectionException.cs" /> <Compile Include="MtConnectionException.cs" />
<Compile Include="MtConnectionState.cs" /> <Compile Include="MtConnectionState.cs" />
+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)); 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)); return new DateTime(tmpTime.Ticks + (time * 0x989680L));
} }
public static int ConvertToMtTime(DateTime time) public static int ConvertToMtTime(DateTime? time)
{ {
int result = 0; int result = 0;
if (time != DateTime.MinValue) if (time != null && time != DateTime.MinValue)
{ {
DateTime tmpTime = new DateTime(1970, 1, 1); DateTime tmpTime = new DateTime(1970, 1, 1);
result = (int)((time.Ticks - tmpTime.Ticks) / 0x989680L); result = (int)((time.Value.Ticks - tmpTime.Ticks) / 0x989680L);
} }
return result; return result;
} }
+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; namespace MtApi
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MtApi
{ {
enum MtCommandType enum MtCommandType
{ {
@@ -116,6 +111,7 @@ namespace MtApi
TimeSeconds = 86, TimeSeconds = 86,
TimeYear = 87, TimeYear = 87,
Year = 88, Year = 88,
TimeGMT = 281,
//Global Variables //Global Variables
GlobalVariableCheck = 89, GlobalVariableCheck = 89,
@@ -140,8 +136,8 @@ namespace MtApi
iBullsPower = 106, iBullsPower = 106,
iCCI = 107, iCCI = 107,
iCCIOnArray = 108, iCCIOnArray = 108,
iCustom = 109, //iCustom = 109,
iCustom_d = 10109, //iCustom_d = 10109,
iDeMarker = 110, iDeMarker = 110,
iEnvelopes = 111, iEnvelopes = 111,
iEnvelopesOnArray = 112, iEnvelopesOnArray = 112,
@@ -201,6 +197,87 @@ namespace MtApi
SymbolsTotal = 200, SymbolsTotal = 200,
SymbolName = 201, SymbolName = 201,
SymbolSelect = 202, 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;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MtApi namespace MtApi
{ {
public class MtConnectionEventArgs: EventArgs public class MtConnectionEventArgs: EventArgs
{ {
public MtConnectionState Status { get; private set; } public MtConnectionState Status { get; private set; }
public String ConnectionMessage { get; private set; } public string ConnectionMessage { get; private set; }
public MtConnectionEventArgs(MtConnectionState status, string message) public MtConnectionEventArgs(MtConnectionState status, string message)
{ {
+2 -1
View File
@@ -2,6 +2,7 @@
{ {
public enum MtEventTypes public enum MtEventTypes
{ {
LastTimeBar = 1 LastTimeBar = 1,
ChartEvent = 2
} }
} }
+9
View File
@@ -5,6 +5,7 @@
public string Instrument { get; private set; } public string Instrument { get; private set; }
public double Bid { get; private set; } public double Bid { get; private set; }
public double Ask { get; private set; } public double Ask { get; private set; }
public int ExpertHandle { get; private set; }
public MtQuote(string instrument, double bid, double ask) public MtQuote(string instrument, double bid, double ask)
{ {
@@ -12,5 +13,13 @@
Bid = bid; Bid = bid;
Ask = ask; Ask = ask;
} }
internal MtQuote(MTApiService.MtQuote quote)
{
Instrument = quote.Instrument;
Bid = quote.Bid;
Ask = quote.Ask;
ExpertHandle = quote.ExpertHandle;
}
} }
} }
-3
View File
@@ -1,7 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MtApi namespace MtApi
{ {
+2 -11
View File
@@ -11,16 +11,7 @@ namespace MtApi
public double Close { get; set; } public double Close { get; set; }
public double High { get; set; } public double High { get; set; }
public double Low { get; set; } public double Low { get; set; }
public DateTime OpenTime => MtApiTimeConverter.ConvertFromMtTime(MtOpenTime);
public DateTime OpenTime public DateTime CloseTime => MtApiTimeConverter.ConvertFromMtTime(MtCloseTime);
{
get { return MtApiTimeConverter.ConvertFromMtTime(MtOpenTime); }
}
public DateTime CloseTime
{
get { return MtApiTimeConverter.ConvertFromMtTime(MtCloseTime); }
}
} }
} }
+3 -1
View File
@@ -1,4 +1,6 @@
namespace MtApi // ReSharper disable InconsistentNaming
namespace MtApi
{ {
public enum ENUM_TERMINAL_INFO_STRING 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 // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.32.0")] [assembly: AssemblyVersion("1.0.40.0")]
[assembly: AssemblyFileVersion("1.0.32.0")] [assembly: AssemblyFileVersion("1.0.40.0")]
+8 -5
View File
@@ -1,18 +1,21 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MtApi namespace MtApi
{ {
public class TimeBarArgs: EventArgs public class TimeBarArgs: EventArgs
{ {
internal TimeBarArgs(int expertHandle, MtTimeBar timeBar)
: this(timeBar)
{
ExpertHandle = expertHandle;
}
public TimeBarArgs(MtTimeBar timeBar) public TimeBarArgs(MtTimeBar timeBar)
{ {
TimeBar = timeBar; TimeBar = timeBar;
} }
public MtTimeBar TimeBar { get; private set; } public int ExpertHandle { get; }
public MtTimeBar TimeBar { get; }
} }
} }
+11
View File
@@ -0,0 +1,11 @@
namespace MtApi5.Events
{
internal enum Mt5EventTypes
{
OnTradeTransaction = 1,
OnBookEvent = 2,
OnTick = 3,
OnLastTimeBar = 4,
OnLockTicks = 5
}
}
+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
{
public class OnLastTimeBarEvent
{
public MqlRates Rates { get; set; }
public string Instrument { get; set; }
public int ExpertHandle { get; set; }
}
}
+7
View File
@@ -0,0 +1,7 @@
namespace MtApi5.Events
{
internal class OnLockTicksEvent
{
public string Instrument { get; set; }
}
}
+9
View File
@@ -0,0 +1,9 @@
namespace MtApi5.Events
{
internal class OnTickEvent
{
public MqlTick Tick { get; set; }
public string Instrument { get; set; }
public int ExpertHandle { 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; // ReSharper disable InconsistentNaming
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MtApi5 namespace MtApi5
{ {
public class MqlBookInfo public class MqlBookInfo
@@ -14,8 +10,16 @@ namespace MtApi5
this.volume = volume; this.volume = volume;
} }
public ENUM_BOOK_TYPE type { get; private set; } // Order type from ENUM_BOOK_TYPE enumeration public MqlBookInfo()
public double price { get; private set; } // Price { }
public long volume { get; private set; } // Volume
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; }
}
}
+17 -3
View File
@@ -1,4 +1,5 @@
using System; // ReSharper disable InconsistentNaming
using System;
namespace MtApi5 namespace MtApi5
{ {
@@ -6,7 +7,19 @@ namespace MtApi5
{ {
public MqlRates(DateTime time, double open, double high, double low, double close, long tick_volume, int spread, long real_volume) public MqlRates(DateTime time, double open, double high, double low, double close, long tick_volume, int spread, long real_volume)
{ {
this.time = time; mt_time = Mt5TimeConverter.ConvertToMtTime(time);
this.open = open;
this.high = high;
this.low = low;
this.close = close;
this.tick_volume = tick_volume;
this.spread = spread;
this.real_volume = real_volume;
}
internal MqlRates(long time, double open, double high, double low, double close, long tick_volume, int spread, long real_volume)
{
mt_time = time;
this.open = open; this.open = open;
this.high = high; this.high = high;
this.low = low; this.low = low;
@@ -20,7 +33,8 @@ namespace MtApi5
{ {
} }
public DateTime time { get; set; } // Period start time public DateTime time => Mt5TimeConverter.ConvertFromMtTime(mt_time); // Period start time
public long mt_time { get; set; } // Period start time (original MT time)
public double open { get; set; } // Open price public double open { get; set; } // Open price
public double high { get; set; } // The highest price of the period public double high { get; set; } // The highest price of the period
public double low { get; set; } // The lowest price of the period public double low { get; set; } // The lowest price of the period
+2 -1
View File
@@ -1,4 +1,5 @@
using System; // ReSharper disable InconsistentNaming
using System;
namespace MtApi5 namespace MtApi5
{ {
+17 -12
View File
@@ -1,20 +1,17 @@
using System; // ReSharper disable InconsistentNaming
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MtApi5 namespace MtApi5
{ {
public class MqlTradeCheckResult public class MqlTradeCheckResult
{ {
public uint Retcode { get; private set; } // Reply code public uint Retcode { get; set; } // Reply code
public double Balance { get; private set; } // Balance after the execution of the deal public double Balance { get; set; } // Balance after the execution of the deal
public double Equity { get; private set; } // Equity after the execution of the deal public double Equity { get; set; } // Equity after the execution of the deal
public double Profit { get; private set; } // Floating profit public double Profit { get; set; } // Floating profit
public double Margin { get; private set; } // Margin requirements public double Margin { get; set; } // Margin requirements
public double Margin_free { get; private set; } // Free margin public double Margin_free { get; set; } // Free margin
public double Margin_level { get; private set; } // Margin level public double Margin_level { get; set; } // Margin level
public string Comment { get; private set; } // Comment to the reply code (description of the error) public string Comment { get; set; } // Comment to the reply code (description of the error)
public MqlTradeCheckResult(uint retcode public MqlTradeCheckResult(uint retcode
, double balance , double balance
@@ -34,5 +31,13 @@ namespace MtApi5
Margin_level = margin_level; Margin_level = margin_level;
Comment = comment; 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 namespace MtApi5
{ {
public class MqlTradeRequest public class MqlTradeRequest
{ {
public ENUM_TRADE_REQUEST_ACTIONS Action { get; set; } // Trade operation type public ENUM_TRADE_REQUEST_ACTIONS Action { get; set; } // Trade operation type
public uint Magic { get; set; } // Expert Advisor ID (magic number) public ulong Magic { get; set; } // Expert Advisor ID (magic number)
public ulong Order { get; set; } // Order ticket public ulong Order { get; set; } // Order ticket
public string Symbol { get; set; } // Trade symbol public string Symbol { get; set; } // Trade symbol
public double Volume { get; set; } // Requested volume for a deal in lots public double Volume { get; set; } // Requested volume for a deal in lots
@@ -13,11 +15,27 @@ namespace MtApi5
public double Stoplimit { get; set; } // StopLimit level of the order public double Stoplimit { get; set; } // StopLimit level of the order
public double Sl { get; set; } // Stop Loss 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 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 Type { get; set; } // Order type
public ENUM_ORDER_TYPE_FILLING Type_filling { get; set; } // Order execution 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 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 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; // ReSharper disable InconsistentNaming
using System.Linq;
using System.Text;
namespace MtApi5 namespace MtApi5
{ {
@@ -19,14 +17,32 @@ namespace MtApi5
Request_id = request_id; Request_id = request_id;
} }
public uint Retcode { get; private set; } // Operation return code internal MqlTradeResult(MqlTradeResult o)
public ulong Deal { get; private set; } // Deal ticket, if it is performed {
public ulong Order { get; private set; } // Order ticket, if it is placed Retcode = o.Retcode;
public double Volume { get; private set; } // Deal volume, confirmed by broker Deal = o.Deal;
public double Price { get; private set; } // Deal price, confirmed by broker Order = o.Order;
public double Bid { get; private set; } // Current Bid price Volume = o.Volume;
public double Ask { get; private set; } // Current Ask price Price = o.Price;
public string Comment { get; private set; } // Broker comment to operation (by default it is filled by the operation description) Bid = o.Bid;
public uint Request_id { get; private set; } // Request ID set by the terminal during the dispatch 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.
}
}
+148 -10
View File
@@ -1,8 +1,4 @@
using System; // ReSharper disable InconsistentNaming
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MtApi5 namespace MtApi5
{ {
internal enum Mt5CommandType internal enum Mt5CommandType
@@ -10,10 +6,9 @@ namespace MtApi5
//NoCommand = 0 //NoCommand = 0
//trade operations //trade operations
OrderSend = 1, //OrderSend = 1,
OrderCalcMargin = 2, OrderCalcMargin = 2,
OrderCalcProfit = 3, OrderCalcProfit = 3,
OrderCheck = 4,
//OrderSendAsync = 5, //OrderSendAsync = 5,
PositionsTotal = 6, PositionsTotal = 6,
PositionGetSymbol = 7, PositionGetSymbol = 7,
@@ -21,6 +16,7 @@ namespace MtApi5
PositionGetDouble = 9, PositionGetDouble = 9,
PositionGetInteger = 10, PositionGetInteger = 10,
PositionGetString = 11, PositionGetString = 11,
PositionGetTicket = 4,
OrdersTotal = 12, OrdersTotal = 12,
OrderGetTicket = 13, OrderGetTicket = 13,
OrderSelect = 14, OrderSelect = 14,
@@ -99,20 +95,162 @@ namespace MtApi5
SymbolInfoSessionTrade = 59, SymbolInfoSessionTrade = 59,
MarketBookAdd = 60, MarketBookAdd = 60,
MarketBookRelease = 61, MarketBookRelease = 61,
MarketBookGet = 62, //MarketBookGet = 62,
OrderCloseAll = 63, OrderCloseAll = 63,
//CTrade //CTrade
PositionClose = 64, PositionClose = 64,
PositionOpen = 65, PositionOpen = 65,
//PositionOpenWithResult = 1065,
//Backtesting //Backtesting
BacktestingReady = 66, BacktestingReady = 66,
IsTesting = 67, IsTesting = 67,
Print = 68,
//Requests //Requests
MtRequest = 155, 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
//Global Variables
GlobalVariableCheck = 146,
GlobalVariableTime = 147,
GlobalVariableDel = 148,
GlobalVariableGet = 149,
GlobalVariableName = 150,
GlobalVariableSet = 151,
GlobalVariablesFlush = 152,
GlobalVariableTemp = 154,
GlobalVariableSetOnCondition = 156,
GlobalVariablesDeleteAll = 157,
GlobalVariablesTotal = 158,
UnlockTicks = 159,
PositionCloseAll = 160
} }
} }
+2 -5
View File
@@ -1,14 +1,11 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MtApi5 namespace MtApi5
{ {
public class Mt5ConnectionEventArgs: EventArgs public class Mt5ConnectionEventArgs: EventArgs
{ {
public Mt5ConnectionState Status { get; private set; } public Mt5ConnectionState Status { get; }
public String ConnectionMessage { get; private set; } public string ConnectionMessage { get; }
public Mt5ConnectionEventArgs(Mt5ConnectionState status, string message) public Mt5ConnectionEventArgs(Mt5ConnectionState status, string message)
{ {
+818 -211
View File
File diff suppressed because it is too large Load Diff
+14
View File
@@ -0,0 +1,14 @@
using System;
namespace MtApi5
{
public class Mt5LockTicksEventArgs : EventArgs
{
internal Mt5LockTicksEventArgs(string symbol)
{
Symbol = symbol;
}
public string Symbol { get; }
}
}
+17 -7
View File
@@ -1,21 +1,31 @@
using System; using System;
using System.Collections.Generic; using MTApiService;
using System.Linq;
using System.Text;
namespace MtApi5 namespace MtApi5
{ {
public class Mt5Quote public class Mt5Quote
{ {
public string Instrument { get; private set; } public string Instrument { get; }
public double Bid { get; private set; } public double Bid { get; }
public double Ask { get; private set; } public double Ask { get; }
public int ExpertHandle { get; set; }
public DateTime Time { get; set; }
public double Last { get; set; }
public ulong Volume { get; set; }
// public long TimeMsc { get; set; }
// public uint Flags { get; set; }
public Mt5Quote(string instrument, double bid, double ask) internal Mt5Quote(string instrument, double bid, double ask)
{ {
Instrument = instrument; Instrument = instrument;
Bid = bid; Bid = bid;
Ask = ask; 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;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MtApi5 namespace MtApi5
{ {
public class Mt5QuoteEventArgs: EventArgs public class Mt5QuoteEventArgs: EventArgs
{ {
public Mt5Quote Quote { get; private set; } public Mt5Quote Quote { get; }
public Mt5QuoteEventArgs(Mt5Quote quote) public Mt5QuoteEventArgs(Mt5Quote quote)
{ {
+18
View File
@@ -0,0 +1,18 @@
using System;
namespace MtApi5
{
public class Mt5TimeBarArgs: EventArgs
{
internal Mt5TimeBarArgs(int expertHandle, string symbol, MqlRates rates)
{
ExpertHandle = expertHandle;
Rates = rates;
Symbol = symbol;
}
public int ExpertHandle { get; }
public string Symbol { get; }
public MqlRates Rates { get; }
}
}
+9 -13
View File
@@ -1,32 +1,28 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MtApi5 namespace MtApi5
{ {
class Mt5TimeConverter internal class Mt5TimeConverter
{ {
public static DateTime ConvertFromMtTime(int time) 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)); return new DateTime(tmpTime.Ticks + (time * 0x989680L));
} }
public static DateTime ConvertFromMtTime(long time) 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)); return new DateTime(tmpTime.Ticks + (time * 0x989680L));
} }
public static int ConvertToMtTime(DateTime time) public static int ConvertToMtTime(DateTime? time)
{ {
int result = 0; var result = 0;
if (time != DateTime.MinValue) if (time == null || time == DateTime.MinValue)
{ return result;
DateTime tmpTime = new DateTime(1970, 1, 1); var tmpTime = new DateTime(1970, 1, 1);
result = (int)((time.Ticks - tmpTime.Ticks) / 0x989680L); result = (int)((time.Value.Ticks - tmpTime.Ticks) / 0x989680L);
}
return result; return result;
} }
} }
+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
}
}
+30 -3
View File
@@ -48,30 +48,56 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="CopyTicksFlag.cs" /> <Compile Include="CopyTicksFlag.cs" />
<Compile Include="Events\OnBookEvent.cs" />
<Compile Include="Events\OnLastTimeBarEvent.cs" />
<Compile Include="Events\OnLockTicksEvent.cs" />
<Compile Include="Events\OnTickEvent.cs" />
<Compile Include="Events\OnTradeTransactionEvent.cs" />
<Compile Include="Mt5LockTicksEventArgs.cs" />
<Compile Include="Mt5TimeBarArgs.cs" />
<Compile Include="MqlBookInfo.cs" /> <Compile Include="MqlBookInfo.cs" />
<Compile Include="MqlParam.cs" />
<Compile Include="MqlRates.cs" /> <Compile Include="MqlRates.cs" />
<Compile Include="MqlTick.cs" /> <Compile Include="MqlTick.cs" />
<Compile Include="MqlTradeCheckResult.cs" /> <Compile Include="MqlTradeCheckResult.cs" />
<Compile Include="MqlTradeTransaction.cs" />
<Compile Include="Mt5BookEventArgs.cs" />
<Compile Include="Mt5TimeConverter.cs" /> <Compile Include="Mt5TimeConverter.cs" />
<Compile Include="Mt5Enums.cs" /> <Compile Include="Mt5Enums.cs" />
<Compile Include="Mt5ConnectionEventArgs.cs" /> <Compile Include="Mt5ConnectionEventArgs.cs" />
<Compile Include="Mt5ConnectionState.cs" /> <Compile Include="Mt5ConnectionState.cs" />
<Compile Include="ExtensionMethods.cs" />
<Compile Include="MqlTradeRequest.cs" /> <Compile Include="MqlTradeRequest.cs" />
<Compile Include="MqlTradeResult.cs" /> <Compile Include="MqlTradeResult.cs" />
<Compile Include="Mt5QuoteEventArgs.cs" /> <Compile Include="Mt5QuoteEventArgs.cs" />
<Compile Include="Mt5TradeTransactionEventArgs.cs" />
<Compile Include="MtApi5Client.cs" /> <Compile Include="MtApi5Client.cs" />
<Compile Include="Mt5CommandType.cs" /> <Compile Include="Mt5CommandType.cs" />
<Compile Include="MtConverters.cs" /> <Compile Include="MtConverters.cs" />
<Compile Include="ErrorCode.cs" /> <Compile Include="ErrorCode.cs" />
<Compile Include="ExecutionException.cs" /> <Compile Include="ExecutionException.cs" />
<Compile Include="Events\Mt5EventTypes.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Mt5Quote.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\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\PositionCloseRequest.cs" />
<Compile Include="Requests\PositionCloseResult.cs" />
<Compile Include="Requests\PositionOpenRequest.cs" />
<Compile Include="Requests\RequestBase.cs" /> <Compile Include="Requests\RequestBase.cs" />
<Compile Include="Requests\RequestType.cs" /> <Compile Include="Requests\RequestType.cs" />
<Compile Include="Responses\CopyTicksResponse.cs" /> <Compile Include="Requests\OrderSendResult.cs" />
<Compile Include="Responses\ResponseBase.cs" /> <Compile Include="Requests\Response.cs" />
<Compile Include="Requests\SymbolInfoStringRequest.cs" />
<Compile Include="Requests\SymbolInfoStringResult.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\MTApiService\MTApiService.csproj"> <ProjectReference Include="..\MTApiService\MTApiService.csproj">
@@ -82,6 +108,7 @@
<ItemGroup> <ItemGroup>
<None Include="packages.config" /> <None Include="packages.config" />
</ItemGroup> </ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.
+1955 -165
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 internal static class MtConverters
{ {
private static readonly MtLog Log = LogConfigurator.GetLogger(typeof(MtConverters));
#region Values Converters #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) public static bool ParseResult(this string inputString, char separator, out double result)
{ {
Log.Debug($"ParseResult: inputString = {inputString}, separator = {separator}");
var retVal = false; var retVal = false;
result = 0; result = 0;
@@ -98,18 +28,25 @@ namespace MtApi5
result = double.Parse(values[1]); result = double.Parse(values[1]);
} }
catch (Exception) catch (Exception ex)
{ {
retVal = false; retVal = false;
Log.Error($"ParseResult: {ex.Message}");
} }
} }
} }
else
{
Log.Warn("ParseResult: input srting is null or empty!");
}
return retVal; return retVal;
} }
public static bool ParseResult(this string inputString, char separator, out DateTime from, out DateTime to) public static bool ParseResult(this string inputString, char separator, out DateTime from, out DateTime to)
{ {
Log.Debug($"ParseResult: inputString = {inputString}, separator = {separator}");
var retVal = false; var retVal = false;
from = new DateTime(); from = new DateTime();
@@ -130,12 +67,17 @@ namespace MtApi5
var iTo= int.Parse(values[2]); var iTo= int.Parse(values[2]);
to = Mt5TimeConverter.ConvertFromMtTime(iTo); to = Mt5TimeConverter.ConvertFromMtTime(iTo);
} }
catch (Exception) catch (Exception ex)
{ {
retVal = false; retVal = false;
Log.Error($"ParseResult: {ex.Message}");
} }
} }
} }
else
{
Log.Warn("ParseResult: input srting is null or empty!");
}
return retVal; return retVal;
} }
@@ -149,7 +91,7 @@ namespace MtApi5
return new ArrayList { (int)request.Action, request.Magic, request.Order, request.Symbol, request.Volume return new ArrayList { (int)request.Action, request.Magic, request.Order, request.Symbol, request.Volume
, request.Price, request.Stoplimit, request.Sl, request.Tp, request.Deviation, (int)request.Type , request.Price, request.Stoplimit, request.Sl, request.Tp, request.Deviation, (int)request.Type
, (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 #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 // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.11.0")] [assembly: AssemblyVersion("1.0.19")]
[assembly: AssemblyFileVersion("1.0.11.0")] [assembly: AssemblyFileVersion("1.0.19")]
@@ -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; }
}
}
+10
View File
@@ -0,0 +1,10 @@
namespace MtApi5.Requests
{
internal class PositionCloseRequest : RequestBase
{
public override RequestType RequestType => RequestType.PositionClose;
public ulong Ticket { get; set; }
public ulong Deviation { get; set; }
}
}
+8
View File
@@ -0,0 +1,8 @@
namespace MtApi5.Requests
{
internal class PositionCloseResult
{
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; }
}
}

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