Skip to content

Commit 1e0033e

Browse files
committed
feat: Add command for autogenerating boilerplate code
1 parent b1f70dd commit 1e0033e

File tree

5 files changed

+123
-21
lines changed

5 files changed

+123
-21
lines changed

README.md

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,20 @@
33
![PyPI - Wheel](https://img.shields.io/pypi/wheel/mqpy)
44
![PyPI - License](https://img.shields.io/pypi/l/mqpy)
55

6-
# Mql5-Python-Integration
6+
# Mql5-Python-Integration (MQPy)
77

88
**Current Version: v0.6.0**
99

1010
Welcome to the Mql5-Python-Integration project! This project facilitates the integration between MetaTrader 5 (Mql5) and Python, allowing for efficient algorithmic trading strategies.
1111

1212
## Table of Contents
1313

14-
- [Mql5-Python-Integration](#mql5-python-integration)
14+
- [Mql5-Python-Integration (MQPy)](#mql5-python-integration-mqpy)
1515
- [Table of Contents](#table-of-contents)
1616
- [Project Update: Changes in Progress](#project-update-changes-in-progress)
1717
- [Installation](#installation)
18+
- [Usage](#usage)
19+
- [Generate the File](#generate-the-file)
1820
- [Missing Features/Good Practice](#missing-featuresgood-practice)
1921
- [Delicate Metatrader5 Environment](#delicate-metatrader5-environment)
2022
- [Alternative Libraries](#alternative-libraries)
@@ -39,6 +41,26 @@ pip install mqpy
3941

4042
Make sure to fulfill the prerequisites mentioned above before attempting to use the Mql5-Python-Integration (MQPy) package.
4143

44+
## Usage
45+
46+
Basic Usage
47+
48+
Once installed, you can use the mqpy command to generate the boilerplate code.
49+
50+
### Generate the File
51+
52+
To create a template file for a trading strategy, use the following command:
53+
54+
```bash
55+
mqpy --symbol <Symbol> --file_name <File Name>
56+
```
57+
58+
Please change `<Symbol>` and `<File Name>` to the desired values. For example:
59+
60+
```bash
61+
mqpy --symbol EURUSD --file_name demo
62+
```
63+
4264
## Missing Features/Good Practice
4365

4466
This library has been in existence for several years and was designed to be simple and straightforward. While there are plans to enhance it with features such as logging and other components to improve its overall quality, there are considerations specific to the nature of the Metatrader5 library.

example.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44

55
# Initialize the trading strategy
66
trade = Trade(
7-
expert_name="Example",
8-
version=0.1,
7+
expert_name="Moving Average Crossover",
8+
version=1.0,
99
symbol="EURUSD",
1010
magic_number=567,
11-
lot=1.0,
11+
lot=0.1,
1212
stop_loss=25,
1313
emergency_stop_loss=300,
1414
take_profit=25,
@@ -20,21 +20,29 @@
2020
)
2121

2222
# Main trading loop
23-
time = 0
23+
prev_tick_time = 0
24+
short_window_size = 5
25+
long_window_size = 20 # Adjust the window size as needed
26+
2427
while True:
2528
# Fetch tick and rates data
26-
tick = Tick(trade.symbol)
27-
rates = Rates(trade.symbol, 1, 0, 1)
29+
current_tick = Tick(trade.symbol)
30+
historical_rates = Rates(trade.symbol, long_window_size, 0, 1)
2831

2932
# Check for new tick
30-
if tick.time_msc != time:
31-
buy_signal = tick.last > rates.open
32-
sell_signal = tick.last < rates.open
33+
if current_tick.time_msc != prev_tick_time:
34+
# Calculate moving averages
35+
short_ma = sum(historical_rates.close[-short_window_size:]) / short_window_size
36+
long_ma = sum(historical_rates.close[-long_window_size:]) / long_window_size
37+
38+
# Generate signals based on moving average crossover
39+
is_cross_above = short_ma > long_ma and current_tick.last > short_ma
40+
is_cross_below = short_ma < long_ma and current_tick.last < short_ma
3341

3442
# Execute trading positions based on signals
35-
trade.open_position(buy_signal, sell_signal, "Example Advisor")
43+
trade.open_position(is_cross_above, is_cross_below, "Moving Average Crossover Strategy")
3644

37-
time = tick.time_msc
45+
prev_tick_time = current_tick.time_msc
3846

3947
# Check if it's the end of the trading day
4048
if trade.days_end():

mqpy/src/template.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import argparse
2+
3+
4+
def get_arguments():
5+
parser = argparse.ArgumentParser()
6+
parser.add_argument("--file_name", type=str, action="store", default="demo")
7+
parser.add_argument("--symbol", type=str, action="store", default="EURUSD")
8+
return vars(parser.parse_args())
9+
10+
11+
def main():
12+
file_name = get_arguments()["file_name"]
13+
14+
with open(f"{file_name}.py", "w") as file:
15+
file.write(
16+
"""from mqpy.src.rates import Rates
17+
from mqpy.src.tick import Tick
18+
from mqpy.src.trade import Trade
19+
20+
# Initialize the trading strategy
21+
trade = Trade(
22+
expert_name="Moving Average Crossover",
23+
version=1.0,
24+
symbol="EURUSD",
25+
magic_number=567,
26+
lot=1.0,
27+
stop_loss=25,
28+
emergency_stop_loss=300,
29+
take_profit=25,
30+
emergency_take_profit=300,
31+
start_time="9:15",
32+
finishing_time="17:30",
33+
ending_time="17:50",
34+
fee=0.5,
35+
)
36+
37+
# Main trading loop
38+
prev_tick_time = 0
39+
short_window_size = 5
40+
long_window_size = 20 # Adjust the window size as needed
41+
42+
while True:
43+
# Fetch tick and rates data
44+
current_tick = Tick(trade.symbol)
45+
historical_rates = Rates(trade.symbol, long_window_size, 0, 1)
46+
47+
# Check for new tick
48+
if current_tick.time_msc != prev_tick_time:
49+
# Calculate moving averages
50+
short_ma = sum(historical_rates.close[-short_window_size:]) / short_window_size
51+
long_ma = sum(historical_rates.close[-long_window_size:]) / long_window_size
52+
53+
# Generate signals based on moving average crossover
54+
is_cross_above = short_ma > long_ma and current_tick.last > short_ma
55+
is_cross_below = short_ma < long_ma and current_tick.last < short_ma
56+
57+
# Execute trading positions based on signals
58+
trade.open_position(is_cross_above, is_cross_below, "Moving Average Crossover Strategy")
59+
60+
prev_tick_time = current_tick.time_msc
61+
62+
# Check if it's the end of the trading day
63+
if trade.days_end():
64+
trade.close_position("End of the trading day reached.")
65+
break
66+
67+
print("Finishing the program.")
68+
print("Program finished.")
69+
"""
70+
)

pyproject.toml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
[tool.poetry]
22
name = "mqpy"
3-
version = "v0.6.0"
4-
description = ""
3+
version = "v0.6.5"
4+
description = "I developed this library to simplify the process of creating an Expert Advisor in MQL5. While developing in MQL5 can be complex, the same task is more streamlined in Python."
55
authors = ["Joao Paulo Euko"]
66
license = "MIT"
77
readme = "README.md"
88

99
[tool.poetry.dependencies]
1010
python = "^3.8"
1111
metatrader5 = "^5.0.45"
12-
loguru = "^0.7.2"
1312

1413
[tool.poetry.group.dev.dependencies]
1514
pre-commit = "^3.5.0"
1615
black = "^23.11.0"
1716
isort = "^5.12.0"
18-
pytest = "^7.4.3"
1917

2018
[build-system]
2119
requires = ["poetry-core"]

setup.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import json
2-
import os
31
import pathlib
42

53
import setuptools
@@ -8,14 +6,20 @@
86

97
setuptools.setup(
108
name="mqpy",
11-
version="v0.6.0",
12-
description="",
9+
version="v0.6.5",
10+
description="I developed this library to simplify the process of creating an Expert Advisor in MQL5. While developing in MQL5 can be complex, the same task is more streamlined in Python.",
1311
author="Joao Paulo Euko",
1412
license="MIT",
1513
keywords=["metatrader5", "algotrading", "stock market"],
1614
long_description_content_type="text/markdown",
1715
packages=setuptools.find_packages(),
1816
install_requires=[
1917
"metatrader5 == 5.0.45",
18+
"setuptools == 69.0.2",
2019
],
20+
entry_points={
21+
"console_scripts": [
22+
"mqpy = mqpy.src.template:main",
23+
],
24+
},
2125
)

0 commit comments

Comments
 (0)