├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── pull_request_template.md ├── .gitignore ├── CHANGES.txt ├── LICENSE.txt ├── README.md ├── __init__.py ├── con2mtapi.py ├── docs ├── ea_settings.png ├── image1.png └── image2.png ├── libs ├── MtApi.dll ├── Newtonsoft.Json.dll └── README.txt ├── liveTicks.py ├── setup.cfg └── setup.py /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | tidelift: #"pypi/mt4pycon" 4 | github: eabase 5 | patreon: # Replace with a single Patreon username 6 | open_collective: #mt4pycon 7 | ko_fi: # Replace with a single Ko-fi username 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | custom: # https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=xxxxxxxxx 10 | 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: Create a bug report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Your OS Environment** 11 | 12 | ```bash 13 | # Please paste the output of the following commands: 14 | python -V && pip -V 15 | python -c "import platform as p; print(p.platform())" 16 | 17 | # HERE 18 | ``` 19 | 20 | 21 | 22 | **Problem Description** 23 | 24 | 25 | 26 | **How to Reproduce** 27 | 28 | 29 | 30 | 1. Get package from '...' 31 | 2. Then run '...' 32 | 3. An error occurs 33 | 34 | 35 | **Expected Behavior** 36 | 37 | 38 | 39 | **Actual Behavior** 40 | 41 | 42 | 43 | ``` 44 | Paste the output of the steps above, including the commands themselves. 45 | HERE 46 | ``` 47 | 48 | **Screenshots** 49 | 50 | 51 | 52 | 53 | (A picture is worth...) 54 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature Request 3 | about: Suggest an enhancement or new idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | 22 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | #### Description 4 | 5 | 6 | #### Related Issue 7 | 8 | 9 | 10 | 11 | 12 | #### Motivation and Context 13 | 14 | 15 | #### Requires Documentation Change 16 | 17 | 18 | #### How Has This Been Tested? 19 | 20 | 21 | 22 | 23 | #### Types of changes 24 | 25 | - [ ] Bug fix (non-breaking change which fixes an issue) 26 | - [ ] Refactor (non-breaking change which improves implementation) 27 | - [ ] Performance (non-breaking change which improves performance. Please add associated performance test and results) 28 | - [ ] New feature (non-breaking change which adds functionality) 29 | - [ ] Breaking change (fix or feature that would cause existing functionality to change) 30 | - [ ] Non-functional change (xml comments/documentation/etc) 31 | 32 | #### Checklist: 33 | 34 | 35 | - [ ] My code follows the code style of this project. 36 | - [ ] I have read the **CONTRIBUTING** [document](https://github.com/eabase/mt4pycon/blob/master/CONTRIBUTING.md). 37 | 38 | 39 | 40 | - [ ] My branch follows the naming convention `bug--` or `feature--` 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled python modules 2 | *.pyc 3 | 4 | # Setuptools distribution folders 5 | /dist/ 6 | /build/ 7 | 8 | # Python egg metadata, regenerated from source files by setuptools. 9 | /*.egg-info 10 | /*.egg 11 | 12 | # git 13 | /.git/ 14 | 15 | # various dev junk 16 | /junk/ 17 | 18 | # MtAtpi DLL's 19 | #*.dll 20 | #/**/*.dll 21 | 22 | -------------------------------------------------------------------------------- /CHANGES.txt: -------------------------------------------------------------------------------- 1 | 2 | v1.0.2, 2020-11-09 -- Initial release 3 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 EABASE 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### mt4pycon - The MT4 Python Connector 2 | 3 | [![pypi supported versions][1]][2] 4 | [![PyPI version][3]][4] 5 | [![Last Update][5]][6] 6 | 7 | [1]: https://img.shields.io/pypi/pyversions/mt4pycon.svg 8 | [2]: https://pypi.python.org/pypi/mt4pycon "Supported Python versions" 9 | [3]: https://badge.fury.io/py/mt4pycon.svg 10 | [4]: https://badge.fury.io/py/mt4pycon "PIP Package Version" 11 | [5]: https://img.shields.io/badge/Release_Date-2020--11--11-green.svg 12 | [6]: https://GitHub.com/eabase/mt4pycon/graphs/commit-activity "Last Release Date" 13 | 14 | 15 | The **`mt4pycon`** repo is a collection of Python3 code used to interface with MT4 and MT5 16 | terminals via 3rd party API's. As of today there is only 2 scripts available, but will 17 | soon contain several other examples for simple indicators, data scrapers/analyzers to 18 | AI/ML automated trading bots. 19 | 20 | 21 | --- 22 | 23 | **`con2mtapi.py`** 24 | 25 | This is a simple *Python3* CLI client that is using the MT4 bridge API 26 | ([mtapi](https://github.com/vdemydiuk/mtapi/)) to connect to a MT4 Terminal which 27 | is running the `MtApi.ex4` *Expert Advisor (EA)*. It communicates with the EA using either 28 | a TCP/IP `host:port` pair or a *pipe* port, to get some historical OHLCV formatted candle data 29 | for a specified symbol and timeframe. This particular script is using the MQL built-in 30 | `CopyRates` and `iBars()` functions for receiving the candle data. 31 | 32 | 33 | **`liveTicks.py`** 34 | 35 | A very rudimentary data feed that is continusly *polling* the MQL `SymbolInfoTick(sym)` 36 | funtion, to display *Time, Bid, Ask* and *Spread* (in points), for a given symbol. 37 | This should probably be rewritten using a threaded listener... 38 | 39 | Example Output: 40 | 41 | Using symbolic TF and normal tabulated output. 42 | ![Full](./docs/image1.png) 43 | 44 | Using numerical TF and CSV output. 45 | ![Full](./docs/image2.png) 46 | 47 | Live Tick stream with Spread... 48 | ![Full](./docs/image3.png) 49 | 50 | --- 51 | 52 | **Q:** *What is **`mtapi`** and what does it do?* 53 | 54 | The *MetaTrader API* is a Windows library bridging your MT4/5 *Terminal* and .NET. 55 | It consists of a number of DLL files created in .NET that need to be installed separately, 56 | which in turn depends on wheater you are using MT4 or MT5 as your terminal server. 57 | (Installation instructions and links to the Windows installers can be found below.) 58 | 59 | 60 | **Q:** *What does **`con2mtapi.py`** do?* 61 | 62 | The primary use is for demonstrating how to use Python3 to connect to an MT4 or MT5 Terminal 63 | instance using the *mtapi* library. It will retrienve and display historical OHLCV formatted 64 | candle data, given a specific *symbol, timeframe* and the number of requsted candles. 65 | 66 | Furthermore, you can easily expand the example to get and make use all of the native MQL4 67 | commands. In which case you can do anything already available in the MQL4 and much more, 68 | since you are no longer limited by MT4's lack of API support. Although the perfomance 69 | offered is far from excellent, it's more than good enough to excute and monitor scalping 70 | trades on low timeframes. 71 | 72 | 73 | **Q:** *What does it **not** do?* 74 | 75 | - Does not send your python code and algorithms to *MetaQuotes* servers. 76 | - Does not allow for *HFT* trading, althogh 1M and 5M scalping is possible. 77 | - Does not provide any reliability for trading safely. 78 | - Does not (yet) have a listener for live feeds. 79 | 80 | 81 | **Q:** *What other limitations does it have?* 82 | 83 | :red_circle: The number of candles available for download, is completely determined by the 84 | settings of your terminal (*`MaxBars`*) **and** how much symbol history is avalable 85 | from your broker. If you can only see a few months (or <4000 `M5` candles) of data, 86 | you should consider changing your broker. 87 | 88 | 89 | 90 | **Q:** *Why is this needed?* 91 | 92 | It probably isn't if you are already happy to use MT5, **BUT** most brokers still get 93 | talked into using the high-maintenace MT4 terminal *client, manager* and *server* 94 | infrastructure. Afterall, it works and is well proven although outdated by decades. 95 | 96 | Another very good reason is that the MT5 Python API provided by *MetaQutes* (MQ) is 97 | closed-source and are also sending your Python code to their own MQ servers, thus 98 | rendering all your intellectual property wide open and available for unknown 3rd 99 | parties. Obviously not a good idea in world where algorithms are money. 100 | 101 | 102 | **Q:** *Will I continue to support this tool?* 103 | 104 | Maybe, if it is broken, but I will not spend much more time for new features. 105 | There are plenty of alternative and far better platforms (such as 106 | *[xStation](https://xstation5.xtb.com/)* and *[cTrader](https://ctrader.com/)*) 107 | that are doing quite a bit of open-source development and trading integration in a far 108 | more modern context. However, if you would like me to add something, just send me a PR, 109 | or at the very least a detailed enhancement issue of what you would like to implement. 110 | As always, any small crypto donation is an inspitring incentive to make things happen faster. 111 | 112 | --- 113 | 114 | ### Dependencies 115 | 116 | Python packages: 117 | 118 | * [pythonnet](https://github.com/pythonnet/pythonnet) - `Python.NET` for the .NET *Common Language Runtime* (CLR) 119 | * [pyreadline](https://github.com/pyreadline/pyreadline) - [Not Required] *"You don't wanna develop without it!"* 120 | 121 | and what you already have: 122 | * [MT4](https://github.com/rosasurfer/mt4-mql) - Latest (unbranded) MT4 and MetaEditor4 downloads 123 | * [MtApi](https://github.com/vdemydiuk/mtapi/) - The MT4/5 Terminal to .NET bridge library 124 | 125 | 126 | ### Installation 127 | 128 | Using the scripts in this repo code, require 3 things: 129 | 1. Installing the MtApi DLL Libraries 130 | 2. Copying some DLL's to the script directory 131 | 3. Installing the MtApi Expert Advisor 132 | 4. Installing `con2mtapi.py` 133 | 134 | #### 1. Installing the MtApi DLL Libraries 135 | 136 | The *MtApi* DLL's are installed with a normal (WIX-based) Windows installer. 137 | Make sure to use the correct installer for your OS, and for the MT4/5 Terminal 138 | you want to connect with. Always, check the 139 | [releases](https://github.com/vdemydiuk/mtapi/releases) in the original MtApi 140 | repo for the latest versions. Pay attention to the MT4 vs MT5 versions, as 141 | the installers are different. 142 | 143 | * For `MT4 (32-bit x86)` use: [`MtApi_Setup.exe`](https://github.com/vdemydiuk/mtapi/releases/download/MT4-v1.0.42/MtApi_Setup.exe) [1.0.42] 144 | * For `MT5 (32-bit x86)` use: [`MtApi5_Setup_x86.exe`](https://github.com/vdemydiuk/mtapi/releases/download/MT5-v1.0.24/MtApi5_Setup_x86.exe) [1.0.24] 145 | * For `MT5 (64-bit x64)` use: [`MtApi5_Setup_x64.exe`](https://github.com/vdemydiuk/mtapi/releases/download/MT5-v1.0.24/MtApi5_Setup_x64.exe) [1.0.24] 146 | 147 | 148 | The installation locations for the installed DLL files are: 149 | ```powershell 150 | MtApi.dll # MQL API # C:\Program Files (x86)\MtApi\MtApi.dll 151 | Newtonsoft.Json.dll # JSON handler # C:\Program Files (x86)\MtApi\Newtonsoft.Json.dll 152 | MTConnector.dll # MT4 specific connector # C:\windows\SysWOW64\MTConnector.dll 153 | MT5Connector.dll # MT5-x86 specific connector # C:\windows\SysWOW64\MT5Connector.dll 154 | MT5Connector.dll # MT5-x64 specific connector # C:\windows\System32\MT5Connector.dll 155 | MTApiService.dll # API bridge # C:\windows\Microsoft.NET\assembly\GAC_MSIL\MTApiService\...\MTApiService.dll 156 | ``` 157 | 158 | *For example:* 159 | 160 | For an MT4 installation the following default locations are used: 161 | 162 | ```bash 163 | # tree 'C:\Program Files (x86)\MtApi\' 164 | C:\Program Files (x86)\MtApi\ 165 | ├── Experts 166 | │   └── MtApi.ex4 167 | ├── MtApi.dll 168 | └── Newtonsoft.Json.dll 169 | 170 | # tree 'C:\windows\Microsoft.NET\assembly\GAC_MSIL\MTApiService' 171 | C:\windows\Microsoft.NET\assembly\GAC_MSIL\MTApiService 172 | └── v4.0_1.0.33.0__fe39c8c11cabcd1e 173 | └── MTApiService.dll 174 | 175 | # find /cygdrive/c/Windows/{System32,SysWOW64}/ -iname "MT*Connector.dll" 176 | C:\windows\SysWOW64\MTConnector.dll 177 | ``` 178 | 179 | #### 2. Copying some DLL's to the script directory 180 | 181 | Unless the DLL locations (above) have also been added to your Windows 182 | System PATH variable, your scripts will not know where to find them. 183 | So you need to copy the following DLL's to the same location as your script. 184 | 185 | ``` 186 | MtApi.dll 187 | Newtonsoft.Json.dll 188 | ``` 189 | 190 | #### 3. Installing the MtApi Expert Advisor 191 | 192 | 1. Open your MT4/5 Terminal 193 | 2. Find the correct *Data Directory* of your MT4/5 Terminal 194 | [`File >> Open Data Folder`] 195 | 3. Locate the *path* to the `../MQL4/Experts/` folder in (2). 196 | 4. Copy the `MtApi.ex4` file from the installation directory, to the folder above (3). 197 | 5. Open the MT (file) *Navigator* window with `CTRL-N`. 198 | 6. Drag the EA in (4) to any chart in your MT4/5 Terminal 199 | 7. Make sure your EA Settings are as follows: 200 | 201 |
202 | Click Here! 203 | 204 | ![Full](./docs/ea_settings.png) 205 | 206 |
207 | 208 | 209 | #### 4. Installing *con2mtapi* 210 | 211 | * For pip installation: 212 | 213 | ```bash 214 | pip install mt4pycon 215 | ``` 216 | 217 |
218 | Click Here for other options 219 | 220 | 221 | * For single file installation: 222 | 223 | ```bash 224 | cd /usr/bin/ 225 | wget -Lk https://github.com/eabase/mt4pycon/raw/master/con2mtapi.py 226 | chmod 755 con2mtapi.py 227 | ``` 228 | 229 | * For developer installation: 230 | 231 | ```bash 232 | # git clone --single-branch --depth=1 https://github.com/eabase/mt4pycon.git 233 | git clone https://github.com/eabase/mt4pycon.git 234 | cd mt4pycon 235 | pip install mt4pycon --user 236 | ``` 237 | 238 |
239 | 240 | 241 | 242 | :sparkles: **Done!** 243 | 244 | --- 245 | 246 | ### Modifying the EA and Compilation 247 | 248 | If you want to compile your own MtApi libraries, please check the original 249 | *mtapi* github repo for detailed compilation instructions. 250 | 251 | In summary, for modifying the EA, you would need to: 252 | **(a)** Copy the `MtApi.mq4` file into the `../MQL4/Experts/` folder. 253 | **(b)** Copy the following MQL Library files into the `../MQL4/Include/` folder: 254 | 255 | ```bash 256 | hash.mqh 257 | json.mqh 258 | mql4-auth.mqh 259 | ``` 260 | 261 | **(c)** Recompile `MtApi.mq4` in *MetaEditor4*. 262 | 263 | 264 | --- 265 | 266 | ### How to Run 267 | 268 | 1. Make sure you have installed the correct DLL's (as described above) 269 | 2. Make sure you have copied the 2 DLL's to your script location (or that they are in the Windows System PATH.) 270 | 3. Make sure you are allowing these (default) connections through you Windows Firewall: 271 | * For MT4: use port **`8222`** 272 | * For MT5: use port **`8228`** 273 | 274 |
275 | Click For Details 276 | 277 | In Windows powershell, you can check these FW ports with: 278 | ```powershell 279 | # Check on what interfaces the FW is enabled 280 | Get-NetFirewallProfile -Profile Domain, Public, Private | Select-Object Name, Enabled 281 | 282 | # Check for specific port rules 283 | Get-NetFirewallPortFilter | ?{$_.LocalPort -eq 8222} | Get-NetFirewallRule 284 | 285 | # Set FW rule for MT4API (for localhost?) 286 | $desc = "This port is used by the MtApi .NET MT4 API connector." 287 | New-NetFirewallRule -Name mtapi -DisplayName 'MT4API' -Description $desc -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 8222 288 | ``` 289 | 290 |
291 | 292 | 293 | 4. Copy the EA into the `../MQL4/Experts/` data folder of your MT4 Terminal, normally located at: 294 | 295 | ```xml 296 | C:\Users\\AppData\Roaming\MetaQuotes\Terminal\\MQL4\Experts\ 297 | ``` 298 | 299 | 5. Check the available `con2mtapi` command line options with: 300 | 301 | 349 |
Click To See 302 | 303 | ```bash 304 | # python.exe .\con2mtapi.py -h 305 | ``` 306 | 307 | 308 | ```bash 309 | 310 | Usage: ./con2mtapi.py 311 | 312 | This connects to an MT4 EA via a TCP port (or pipe) to receive OHLCV data. 313 | 314 | -------------------------------------------------------------------------------- 315 | Command Line Options: 316 | -d : Enable extra debug info 317 | -n : Show number of candles back 318 | -p : Use a "Named Pipe" connection (instead of a TCP IP host:port) 319 | -l : Show candle data as a list (one line per OHLC item) 320 | -s : Set symbol name to ["EURUSD"] 321 | -t : Set timeframe to [M1,M5,M15*,M30,H1,H4,D1,W1,MN1]** 322 | -h, --help : Show THIS help list 323 | -v, --version : Show THIS program version 324 | -------------------------------------------------------------------------------- 325 | * = a default setting 326 | ** = The standard MT4 TF's are: 327 | [M1,M5,M15,M30,H1,H4,D1,W1,MN1] 328 | [1,5,15,30,60,240,1440,10080,43200] 329 | 330 | The non-standard TF's are: (not yet available) 331 | [M2,M3,M4,M6,M10,M12,M20,H2,H3,H6,H8,H12] 332 | [2,3,4,6,10,12,20,120,180,360,480,720] 333 | -------------------------------------------------------------------------------- 334 | 335 | Example for Windows: 336 | python.exe .\con2mtapi.py -n4 -s "CADCHF.x" -t H4 -p -d 337 | 338 | Please file any bug reports at: 339 | https://github.com/eabase/mt4pycon/ 340 | 341 | For support of the MT4/5 API, see: 342 | https://github.com/vdemydiuk/mtapi/ 343 | 344 | Version: 1.0.2 345 | License: MIT (2020) 346 | 347 | ``` 348 |
350 | 351 | 352 | --- 353 | 354 | #### References: 355 | 356 | 357 | 358 | * [mtapi](https://github.com/vdemydiuk/mtapi/) 359 | 360 | 361 | 362 | #### Recommeded Similar Tools: 363 | 364 | * [dwx-zeromq-connector](https://github.com/darwinex/dwx-zeromq-connector) (*ZeroMQ-enabled MetaTrader Bridge EA*) 365 | * [mql4-lib](https://github.com/dingmaotu/mql4-lib) (*MQL4/5 Foundation Library*) 366 | * [mql-zmq](https://github.com/dingmaotu/mql-zmq) (*ZMQ binding for the MQL*) 367 | 368 | 369 | #### Known Bugs and Warnings 370 | 371 | :negative_squared_cross_mark: When running the script for the *first* time on a certain symbol and timeframe, the 372 | candle data will not be available in the MT4 terminal buffer, so the script will fail. 373 | Just run it again and MT4 will most likely have already downloaded the new data. A bug report 374 | has been filed in this [issue](#4). 375 | 376 | 377 | #### ToDo / Help Needed 378 | 379 | See issues marked [ToDo](https://github.com/eabase/mt4pycon/issues?q=is%3Aopen+is%3Aissue+label%3AToDo). 380 | 381 | #### Contribution 382 | 383 | Feel free to post issues and PR's related to this tool. 384 | Feel free to fork, break, fix and contribute. Enjoy! 385 | 386 | 387 | #### Donations 388 | 389 | Almost everything I do is Free and Open Source Software (FOSS). 390 | This means that I do not receive any income on any of my projects. 391 | So if you find any of my projects or code, cool & useful, please 392 | consider making a small donation to any of my crypto accounts. 393 | 394 | See my [profile](https://github.com/eabase) page for Crypto Adresses. 395 | 396 | 397 | #### Additional Badges 398 | 399 | 402 | 403 | 404 | #### License 405 | 406 | [![GitHub license][21]][22] 407 | A license to :sparkling_heart:! 408 | 409 | I use an `MIT` license because I support [mtapi](https://github.com/vdemydiuk/mtapi/). 410 | 411 | [11]: https://ci.appveyor.com/api/projects/status/github/mt4pycon/mt4pycon?branch=master&svg=true 412 | [12]: https://ci.appveyor.com/project/mt4pycon/mt4pycon 413 | [13]: https://api.codacy.com/project/badge/Grade/176ceaabe43d4113b535f2fbd0487a9e 414 | [14]: https://www.codacy.com/app/eabase/mt4pycon?utm_source=github.com&utm_medium=referral&utm_content=eabase/mt4pycon&utm_campaign=Badge_Grade 415 | [15]: https://codecov.io/gh/mt4pycon/mt4pycon/branch/master/graph/badge.svg 416 | [16]: https://codecov.io/gh/mt4pycon/mt4pycon 417 | 418 | [21]: https://img.shields.io/github/license/eabase/mt4pycon.svg 419 | [22]: https://github.com/eabase/mt4pycon/blob/master/LICENSE.txt 420 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- 1 | # Q: Why do we need this file? 2 | # A1: We don't 3 | # A2: To make functions accessible for inidividual import 4 | # https://stackoverflow.com/a/29509611/ 5 | name = "mt4pycon" 6 | __version__ = "1.0.2" 7 | -------------------------------------------------------------------------------- /con2mtapi.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # con2mtapi.py - An example for connecting to the mtapi EA on MT4 and get some data 3 | # -*- coding: utf-8 -*- 4 | # --------------------------------------------------------------------- 5 | # Author: EAML 6 | # Date: 2020-11-10 7 | # Version: 1.0.2 8 | # License: MIT 9 | # URL: https://github.com/eabase/mt4pycon/ 10 | # --------------------------------------------------------------------- 11 | # 12 | # Description: 13 | # 14 | # This is an example client using the MT4 API (mtapi) to connect 15 | # to the MT4 EA, using either an TCP/IP or a pipe port, to get some 16 | # historical candle OHLCV data for a specified symbol and timeframe. 17 | # 18 | # ToDo: 19 | # 20 | # [ ] Make a native pip installer package (PyPi) 21 | # [ ] Automatic detection of MT5 22 | # [ ] Fix bug when requested chart does not (yet) have any candle data... double run! 23 | # [x] Allow TF specification as MT4/5 text ('4H') and not in minutes ('240') 24 | # [ ] Add CLI options: 25 | # ---------------------------------------------------------- 26 | # - [ ] '-5' : Use script for MT5 installs (this will use MT5 DLL's) 27 | # - [ ] '-c' : Enable ANSI color markup of output 28 | # - [x] '-d' : Enable extra debug info 29 | # - [ ] '-e' : Show candle data as minimal CSV list (ignores -l) ??? 30 | # - [x] '-h' : Show THIS help list 31 | # - [x] '-n ' : Show number of candles back ['0' is last complete candle] 32 | # - [x] '-p' : Use a named pipe connection (instead of a TCP/IP host:port) 33 | # - [x] '-l' : Show candle data as a list (one line per OHLC item) 34 | # - [x] '-s ' : Set symbol name to ['EURUSD'] 35 | # - [x] '-t ' : Set timeframe to 36 | # - [x] '-v' : Show THIS program version 37 | # ---------------------------------------------------------- 38 | # 39 | # Installation: 40 | # 41 | # 42 | # 43 | # Usage: 44 | # 45 | # 46 | # 47 | # Requirements: 48 | # 49 | # pip install pythonnet 50 | # pip install 51 | # 52 | # NOTES 53 | # 54 | # 1. Spread for candles are meaningless, unless we talk about an "average", 55 | # which is not available without also getting all the ticks inside. 56 | # 57 | # 2. Some Default Settings: 58 | # For MT5: 59 | # MTPATH = C:\Program Files\MtApi5 # Default Path to installed MtApi library files 60 | # MTSERV = 127.0.0.1 # Default IP address of your localhost where MtApi terminal is running 61 | # MTPORT = 8228 # Default Port setting of your MtApi EA 62 | # 63 | # 3. Using TCP vs. a "Named Pipe" connection: 64 | # TCP: client.BeginConnect(ip, port) 65 | # Pipe: client.BeginConnect(port) 66 | # (Note that a Windows "named pipe" is using the "localhost" interface.) 67 | # 68 | # 4. What is the deal with: 0.0.0.0 & 127.0.0.1 ? 69 | # See [4] 70 | # 71 | # 5. To measure performance, use: 72 | # (Measure-Command { python.exe .\con2mtapi.py -n10000 -s "CADCHF" -t 15 -p }).TotalSeconds 73 | # 74 | # 6. How to get Tick data streamed? 75 | # 76 | # struct MqlTick { 77 | # datetime time; // Time of the last prices update 78 | # double bid; // Current Bid price 79 | # double ask; // Current Ask price 80 | # double last; // Price of the last deal (Last) 81 | # ulong volume; // Volume for the current Last price 82 | # 83 | # REFERENCES 84 | # 85 | # [1] https://www.mql5.com/en/docs/constants/structures/mqlrates 86 | # [2] https://docs.mql4.com/constants/structures/mqltick 87 | # [3] https://stackoverflow.com/questions/48542644/python-and-windows-named-pipes 88 | # [4] https://www.howtogeek.com/225487/what-is-the-difference-between-127.0.0.1-and-0.0.0.0/ 89 | # [5] https://docs.mql4.com/constants/chartconstants/enum_timeframes 90 | # 91 | # --------------------------------------------------------------------- 92 | import os, sys 93 | import clr 94 | import time 95 | import getopt 96 | 97 | #-------------------------------------- 98 | # For MT5 installs 99 | #-------------------------------------- 100 | # C:\Program Files\MtApi5 101 | #sys.path.append(r"C:\Program Files\MtApi5") 102 | #asm = clr.AddReference("MtApi5") 103 | #import MtApi5 as mt 104 | 105 | #-------------------------------------- 106 | # For MT4 installs 107 | #-------------------------------------- 108 | # C:\Program Files (x86)\MtApi 109 | #sys.path.append(r"C:\Program Files\MtApi") 110 | #sys.path.append(r"C:\Program Files (x86)\MtApi") 111 | sys.path.append(r".\libs") 112 | asm = clr.AddReference('MtApi') 113 | import MtApi as mt 114 | 115 | #-------------------------------------- 116 | # Import/Use colorama 117 | #-------------------------------------- 118 | ##from colorama import Fore, Style 119 | #from colorama import init, AnsiToWin32 120 | #init(wrap=False) 121 | #stream = AnsiToWin32(sys.stderr).stream 122 | #-------------------------------------- 123 | 124 | #---------------------------------------------------------- 125 | # Global Variables 126 | #---------------------------------------------------------- 127 | __author__ = 'EAML (EABASE)' 128 | __copyright__ = 'MIT (2020)' 129 | __version__ = '1.0.2' 130 | 131 | debug = 0 # Enable debug printing 132 | 133 | #---------------------------------------------------------- 134 | # Default Program Constants 135 | #---------------------------------------------------------- 136 | #MTSERV = '192.168.1.101' # IP address of "your local machine" where MtApi terminal is running 137 | MTSERV = '127.0.0.1' # IP address of "your localhost" where MtApi terminal is running 138 | #MTSERV = '0.0.0.0' # IP address of "ALL on local net" where MtApi terminal is running 139 | MTPORT = 8222 # Port setting of your MT4 EA [Default:8222] 140 | #MTPORT = 8228 # Port setting of your MT5 EA [Default:8228] 141 | MTSYMB = 'EURUSD.e' # 143 | 144 | #------------------------------------------------ 145 | # mt.ENUM_TIMEFRAMES.PERIOD_M15 146 | #------------------------------------------------ 147 | t1 = '[M1,M5,M15,M30,H1,H4,D1,W1,MN1]' # Standard Periods 148 | t2 = '[M2,M3,M4,M6,M10,M12,M20,H2,H3,H6,H8,H12]' # Extended Periods (MQL/API only) 149 | p1 = [1,5,15,30,60,240,1440,10080,43200] # [min] 150 | p2 = [2,3,4,6,10,12,20,120,180,360,480,720] # [min] 151 | 152 | z1 = t1.translate(str.maketrans('','','[]')).split(',') # Remove "[" and "]" 153 | z2 = t2.translate(str.maketrans('','','[]')).split(',') # 154 | d1 = dict(zip(z1,p1)) # convert to dict 155 | d2 = dict(zip(z2,p2)) # convert to dict 156 | d3 = {**d1,**d2} # Add the 2 dicts (in Py3.9+ use: d3=d1|d2) 157 | 158 | d4 = {k: v for k, v in sorted(d3.items(), key=lambda item: item[1])} # sort dict 159 | 160 | # "reverse" the dict key:value pairs, so we can use 161 | # get('value') to obtain the key of the original 162 | #d4r = dict(zip(d4.values(),d4.keys())) 163 | 164 | #TF = d4.get('M15') 165 | # Get the key, given a value 166 | #TFk = [k for k in d4 if (d4[k] == TF)][0] 167 | #TFk = next((k for k in d4 if d4[k] == TF), None) 168 | 169 | #------------------------------------------------ 170 | # Text Coloring 171 | #------------------------------------------------ 172 | # Usage: print(yellow("This is yellow")) 173 | def color(text, color_code): 174 | #if self.nposix: 175 | #if not is_posix(): 176 | # return text 177 | # for brighter colors, use "1;" in front of "color_code" 178 | bright = '' # '1;' 179 | return '\x1b[%s%sm%s\x1b[0m' % (bright, color_code, text) 180 | 181 | def red(text): return color(text, 31) # # noqa 182 | def green(text): return color(text, 32) # '1;49;32' # noqa 183 | def bgreen(text): return color(text, '1;49;32') # bright green # noqa 184 | def orange(text): return color(text, '0;49;91') # 31 - looks bad! # noqa 185 | def yellow(text): return color(text, 33) # # noqa 186 | def blue(text): return color(text, '1;49;34') # bright blue # noqa 187 | def purple(text): return color(text, 35) # aka. magenta # noqa 188 | def cyan(text): return color(text, '0;49;96') # 36 # noqa 189 | def white(text): return color(text, '0;49;97') # bright white # noqa 190 | 191 | #------------------------------------------------ 192 | # Print Usage 193 | #------------------------------------------------ 194 | def usage(): 195 | myName = os.path.basename(__file__) 196 | print('\n Usage: ./{}\n'.format(myName)) 197 | print(' This connects to an MT4 EA via a TCP port (or pipe) to receive OHLCV data.\n') 198 | # [:cdhprvn:s:t:] 199 | print(' ','-'*80) 200 | print(' Command Line Options:') 201 | # print(' -5 : Use script for MT5 installs (this will use MT5 DLL\'s)') 202 | # print(' -c : Enable ANSI color markup of output') 203 | print(' -d : Enable extra debug info') 204 | #print(' -e : Show candle data as minimal CSV list (ignores -l)') # ??? 205 | print(' -n : Show number of candles back') 206 | print(' -p : Use a "Named Pipe" connection (instead of a TCP IP host:port) ') 207 | print(' -l : Show candle data as a list (one line per OHLC item)') 208 | print(' -s : Set symbol name to ["EURUSD"]') 209 | print(' -t : Set timeframe to [M1,M5,M15*,M30,H1,H4,D1,W1,MN1]**') 210 | print(' -h, --help : Show THIS help list') 211 | print(' -v, --version : Show THIS program version') 212 | print(' ','-'*80) 213 | print(' * = a default setting') 214 | print(' ** = The standard MT4 TF\'s are:') 215 | print(' [M1,M5,M15,M30,H1,H4,D1,W1,MN1]') 216 | print(' [1,5,15,30,60,240,1440,10080,43200]\n') 217 | print(' The non-standard TF\'s are: (not yet available)') 218 | print(' [M2,M3,M4,M6,M10,M12,M20,H2,H3,H6,H8,H12]') 219 | print(' [2,3,4,6,10,12,20,120,180,360,480,720] ') 220 | print(' ','-'*80) 221 | print('\n Example for Windows:') 222 | #print(' python.exe .\\{} -n4 -s "CADCHF.x" -t 240 -p -d\n'.format(myName)) 223 | print(' python.exe .\\{} -n4 -s "CADCHF.x" -t H4 -p -d\n'.format(myName)) 224 | print(' Please file any bug reports at:') 225 | print(' https://github.com/eabase/mt4pycon/\n') 226 | print(' For support of the MT4/5 API, see:') 227 | print(' https://github.com/vdemydiuk/mtapi/\n') 228 | print(' Version: {}'.format(__version__)) 229 | print(' License: {}\n'.format(__copyright__)) 230 | sys.exit(2) 231 | 232 | #---------------------------------------------------------- 233 | # Helper Functions 234 | #---------------------------------------------------------- 235 | # Test if a given TF argument is a integer 236 | def isArgInt(a) : 237 | try: 238 | int(a) 239 | return True 240 | except ValueError: 241 | return False 242 | 243 | def printTFerr(a,b) : 244 | print(" ERROR: Bad TF argument: {} reverting to default: {} min.".format(a,b)) 245 | 246 | #---------------------------------------------------------- 247 | # Description: 248 | # Get history data of MqlRates structure of a specified symbol-period 249 | # in specified quantity into the ratesArray array. The elements ordering 250 | # of the copied data is from present to the past, i.e., starting 251 | # position of 0 means the current bar. 252 | # 253 | # NOTE: 254 | # 255 | # The CopyRates() implementations are different between MT4 and MT5. 256 | # 257 | # [1] https://docs.mql4.com/series/copyrates 258 | # [2] https://www.mql5.com/en/docs/series/copyrates 259 | # 260 | # MT5: int CopyRates(string symbolName, ENUM_TIMEFRAMES timeframe, int startPos, int count, out MqlRates[] ratesArray) 261 | # MT4: List CopyRates(string symbolName, ENUM_TIMEFRAMES timeframe, int startPos, int count) 262 | #---------------------------------------------------------- 263 | def getCopyRates(count,SYM,TF,useList,useCSV): 264 | 265 | startPos = 1 # Starting position of candle (backward counting up!) 266 | #count = 3 # Number of candles requested (to be received into Rate Array) 267 | rA = [] # The "Rate Array" for Receiving results 268 | ccnt = 0 # Number of candles actually recived (into array) 269 | errn = 0 # The GetLastError "code" (supposedly?) 270 | 271 | try: 272 | # Check how many candles are available to download: 273 | #cc = c.iBars(SYM,TF) 274 | # if cc < count : print(' INFO: CopyRates: Not all candles are available!'); 275 | 276 | #ccnt = client.CopyRates(SYM, TF, startPos, count, rA) # MT5: int 277 | rA = client.CopyRates(SYM, TF, startPos, count) # MT4: List 278 | ccnt = len(rA) # Rate Array length 279 | 280 | except Exception as e: 281 | print('\n ERROR: in CopyRates(): \n {}\n'.format(e)) 282 | if debug : 283 | print(' DBG: CopyRates:ccnt = ', ccnt) 284 | errn = client.GetLastError() 285 | errd = client.ErrorDescription(errn) if errn else ''; 286 | print(' DBG: CopyRates: ErrorCode : {:d}'.format(errn)) 287 | print(' DBG: CopyRates: ErrorDescription :\n {}'.format(errd)) 288 | exit() 289 | 290 | errn = client.GetLastError(); 291 | #TFk = next((k for k in d4 if d4[k] == TF), None) 292 | TFk = [k for k in d1 if (d1[k] == TF)][0] 293 | 294 | #if debug : 295 | print() 296 | print(' ','-'*60) 297 | print(' INFO: CopyRates: Symbol : {}'.format(SYM)) 298 | print(' INFO: CopyRates: TimeFrame : {}'.format(TFk)) 299 | print(' INFO: CopyRates: Requested : {:d} candles'.format(count)) 300 | print(' INFO: CopyRates: Received : {:d} candles'.format(ccnt)) 301 | print(' INFO: CopyRates: ErrorCode : {:d}'.format(errn)) # rA[0].ErrorCode)) 302 | print(' ','-'*60) 303 | print(' INFO: CopyRates: Rate Array (rA):\n') 304 | 305 | #-------------------------------------------- 306 | # Response = {"ErrorCode" : 0, "Rates" : 307 | # [{ "Close" : 1.17094, 308 | # "Open" : 1.17206, 309 | # "MtTime" : 1604432700, 310 | # "Low" : 1.17079, 311 | # "High" : 1.17207, 312 | # "TickVolume" : 1251, 313 | # "RealVolume" : 0, 314 | # "Spread" : 0}, ... 315 | #-------------------------------------------- 316 | # We skip: rA[i].Spread (see notes) 317 | #-------------------------------------------- 318 | 319 | if useCSV : 320 | csv_th = 'Time,Open,High,Low,Close,Volume' 321 | csv_tf = '{},{:.5f},{:.5f},{:.5f},{:.5f},{:d}' 322 | print(csv_th) 323 | for i in range(ccnt): 324 | print(csv_tf.format(rA[i].Time, rA[i].Open, rA[i].High, rA[i].Low, rA[i].Close, rA[i].TickVolume)) 325 | sys.exit(2) 326 | 327 | if useList : 328 | myLformat = '[{}]: {}\nO: {}\nH: {}\nL: {}\nC: {}\nV: {:d}\n' # S: {:.2f} 329 | for i in range(ccnt): 330 | print(myLformat.format(i, rA[i].Time, rA[i].Open, rA[i].High, rA[i].Low, rA[i].Close, rA[i].TickVolume)) 331 | else : 332 | tableHeader = ' {:<4} {:<19} {:<7} {:<7} {:<7} {:<7} {:<6}' 333 | header_str = tableHeader.format('#','Time','Open', 'High', 'Low', 'Close', 'Volume') 334 | # 0: 2020-11-04 01:45:00 1.17531 1.17616 1.17500 1.17613 590 335 | hlen = len(header_str) 336 | print(header_str) 337 | print(' ','-'*hlen) 338 | 339 | myRformat = ' {:<3}: {} {:.5f} {:.5f} {:.5f} {:.5f} {:d}' 340 | for i in range(ccnt): 341 | print(myRformat.format(i, rA[i].Time, rA[i].Open, rA[i].High, rA[i].Low, rA[i].Close, rA[i].TickVolume)) 342 | 343 | #---------------------------------------------------------- 344 | # ToDo 345 | #---------------------------------------------------------- 346 | #def getLiveTicks(): 347 | # Here be dragons 348 | # SymbolInfoTick 349 | # MqlTick tick; 350 | # if (!SymbolInfoTick(symbol, tick)) { 351 | # response = CreateErrorResponse(GetLastError(), "SymbolInfoDouble failed"); 352 | # return; 353 | # } 354 | #SymbolInfoTick 355 | 356 | #---------------------------------------------------------- 357 | # MAIN 358 | #---------------------------------------------------------- 359 | if __name__ == '__main__': 360 | #def main(self): 361 | 362 | #---------------------------------------------------------- 363 | # CLI arguments 364 | #---------------------------------------------------------- 365 | dTF = d1.get('M15') 366 | nmax = 3 # Default number of candles 367 | mtVer = 4 # Default to MT4 API version [4,5] 368 | aSym = str(MTSYMB) # Default Symbol() 369 | aTF = dTF # Default TimeFrame [Default: M15] 370 | apipe = 0 # Use a Named Pipe port for connection (instead of TCP host:port) 371 | alist = 0 # 372 | useCSV = 0 # ... CSV 373 | 374 | narg = len(sys.argv) - 1 375 | try: 376 | opts, args = getopt.getopt(sys.argv[1:], ":cdehpvln:s:t:", ["help", "version"]) 377 | except getopt.GetoptError : 378 | usage(); sys.exit(); 379 | 380 | if not opts : 381 | if not args : 382 | usage(); sys.exit(); 383 | else : 384 | for opt, arg in opts: 385 | if (debug) : 386 | print ("opt: ", opt) 387 | print ("arg: ", arg) 388 | 389 | if opt in ("-h", "--help"): usage(); sys.exit(); 390 | elif opt in ("-v", "--version"): print ("Version: ", __version__); sys.exit(); 391 | #elif opt == "-c": useColors=1; # Use colored markup on: (Time, Volume, OHCL) 392 | elif opt == "-d": debug = 1; # 393 | elif opt == "-e": useCSV = 1; # print OHLCV data as CSV 394 | elif opt == "-l": alist = 1; # print each OHLCV on new line 395 | elif opt == "-p": apipe = 1; # use named pipe connection 396 | elif opt == "-n": nmax = int(arg); # Number of received candles 397 | elif opt == "-s": aSym = str(arg); # Instrument Symbol 398 | elif opt == "-t": # 399 | if (isArgInt(arg)) : # 400 | if int(arg) in d1.values() : # check if '30' in d1 401 | aTF = int(arg) # convert '30' to 30 402 | else : 403 | printTFerr(arg,dTF) 404 | continue 405 | else: 406 | if arg in d1.keys() : # check if 'M30' in d1 407 | aTF = d1.get(arg) # get 30 from 'M30' 408 | else : 409 | printTFerr(arg,dTF) 410 | continue 411 | #---------------------------------------------------------- 412 | 413 | #client = mt.MtApi5Client() 414 | client = mt.MtApiClient() 415 | 416 | ip = str(MTSERV) # Host IP 417 | port = MTPORT # EA port 418 | sleeps = 10 # Sleep this many times 419 | cnt = 1 # 420 | 421 | print('\n INFO: Attmpting to Connect to: {}:{}'.format(ip,port)) 422 | if (debug): print(' DBG : using {}'.format('a name pipe' if apipe else 'TCP IP')) 423 | 424 | try: 425 | while sleeps > 0: 426 | 427 | print(' [{}] Connecting '.format(cnt), end='') 428 | if (apipe == 0) : 429 | client.BeginConnect(ip, port) 430 | else : 431 | client.BeginConnect(port) 432 | 433 | time.sleep(1) 434 | sleeps = sleeps - 1 435 | cnt += 1 436 | 437 | #------------------------------------ 438 | # Check Connection state: 439 | #------------------------------------ 440 | # 0 = Disconnected 441 | # 1 = Connecting 442 | # 2 = Connected 443 | # 3 = Failed 444 | #------------------------------------ 445 | if client.ConnectionState == 0: print('Disconnected'); continue; 446 | if client.ConnectionState == 1: print('.', end=''); continue; 447 | if client.ConnectionState == 2: print('OK'); getCopyRates(nmax,aSym,aTF,alist,useCSV); break 448 | if client.ConnectionState == 3: print('FAILED'); break 449 | 450 | if (debug): print(' DBG: Unknown ConnectionState: ', client.ConnectionState) 451 | 452 | except Exception as e: 453 | print(e) 454 | 455 | client.BeginDisconnect() 456 | 457 | if (debug): print('\n DBG: Disconnected!') 458 | print('\n Done.') 459 | 460 | #---------------------------------------------------------- 461 | # END 462 | #---------------------------------------------------------- 463 | #if __name__ == "__main__": 464 | # main() 465 | # sys.exit(0) 466 | -------------------------------------------------------------------------------- /docs/ea_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eabase/mt4pycon/585fd96361d35683487c4a1a4e93f05e39ef4c08/docs/ea_settings.png -------------------------------------------------------------------------------- /docs/image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eabase/mt4pycon/585fd96361d35683487c4a1a4e93f05e39ef4c08/docs/image1.png -------------------------------------------------------------------------------- /docs/image2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eabase/mt4pycon/585fd96361d35683487c4a1a4e93f05e39ef4c08/docs/image2.png -------------------------------------------------------------------------------- /libs/MtApi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eabase/mt4pycon/585fd96361d35683487c4a1a4e93f05e39ef4c08/libs/MtApi.dll -------------------------------------------------------------------------------- /libs/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eabase/mt4pycon/585fd96361d35683487c4a1a4e93f05e39ef4c08/libs/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /libs/README.txt: -------------------------------------------------------------------------------- 1 | This folder contain the latest built DLL's from the mtapi releases. 2 | For usage, please consult that repo. 3 | 4 | -------------------------------------------------------------------------------- /liveTicks.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # liveTicks.py - An mtapi PoC to provide a live tick feed for a given symbol and timeframe 3 | # -*- coding: utf-8 -*- 4 | # --------------------------------------------------------------------- 5 | # Author: EAML 6 | # Date: 2020-11-11 7 | # Version: 1.0.2 8 | # License: MIT 9 | # URL: https://github.com/eabase/mt4pycon/ 10 | # --------------------------------------------------------------------- 11 | print('\nLet Here Be Dragons!') 12 | print('This is an inspiring for:') 13 | print('A script using mtapi to provide a live tick feed for a given symbol and timeframe') 14 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | description-file = README.md 3 | license_file = LICENSE.txt 4 | 5 | [bdist_wheel] 6 | # 1 : Generate wheels that support both Python 2 and Python3 7 | # 0 : Generate separate wheels for each Python version 8 | universal=0 9 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | from os import path 3 | 4 | #------------------------------------------------------------------------------ 5 | # The current standard for setup info. 6 | # For details, see: 7 | # https://packaging.python.org/guides/distributing-packages-using-setuptools/ 8 | # https://github.com/pypa/sampleproject/blob/master/setup.py 9 | # https://pypi.org/classifiers/ 10 | # https://choosealicense.com/ 11 | #------------------------------------------------------------------------------ 12 | 13 | def readme(): 14 | # Get the long description from the README file 15 | here = path.abspath(path.dirname(__file__)) 16 | with open(path.join(here, 'README.md'), encoding='utf-8') as f: 17 | return f.read() 18 | 19 | setup( 20 | name = 'mt4pycon', 21 | # For test uploads, use: X.YaN, X.Y.devN, or X.Y.postN 22 | version = '1.0.2', 23 | author = 'eabase', 24 | # author_email can be ignored for provacy 25 | #author_email = 'eabase@users.noreply.github.com', 26 | description = 'A python script using the mtapi EA on MT4 to get candle data', 27 | long_description = 'This is an example client using the MT4 API (mtapi) to connect to the MT4 EA, using either an TCP/IP or a pipe port.', 28 | long_description_content_type='text/plain', 29 | #long_description = readme(), 30 | #long_description_content_type = 'text/markdown', 31 | license='LICENSE.txt', 32 | url = 'https://github.com/eabase/mt4pycon/', 33 | packages = find_packages(), 34 | scripts=['con2mtapi.py', 'liveTicks.py'], 35 | keywords = 'mt4 mt5 mql metaquotes metatrader api mtapi port pipe pip package', 36 | install_requires=[ 37 | 'pythonnet', 38 | ], 39 | python_requires = '>=3', 40 | classifiers=[ 41 | # https://pypi.org/classifiers/ 42 | #'Private :: Do Not Upload', 43 | 'Development Status :: 5 - Production/Stable', 44 | 'Environment :: Console', 45 | 'Intended Audience :: Financial and Insurance Industry', 46 | 'License :: OSI Approved :: MIT License', 47 | #'License :: OSI Approved :: GNU General Public License v3 (GPLv3)', 48 | 'Operating System :: OS Independent', 49 | 'Programming Language :: Python :: 3', 50 | 'Programming Language :: Python :: 3.7', 51 | 'Programming Language :: Python :: 3.8', 52 | 'Programming Language :: Python :: 3.9', 53 | 'Topic :: Office/Business :: Financial', 54 | 'Topic :: Software Development :: Libraries', 55 | #'Topic :: Software Development :: Version Control', 56 | 'Topic :: System :: Software Distribution', 57 | 'Topic :: System :: Installation/Setup', 58 | 'Topic :: Utilities', 59 | ], 60 | project_urls={ 61 | 'Bug Reports' : 'https://github.com/eabase/mt4pycon/issues', 62 | 'MT API Repo' : 'https://github.com/vdemydiuk/mtapi', 63 | #'Funding' : 'https://donate.pypi.org', 64 | #'Credits' : 'http://saythanks.io/to/example', 65 | #'Source' : 'https://github.com/pypa/sampleproject/', 66 | }, 67 | #zip_safe = False, 68 | ) 69 | --------------------------------------------------------------------------------