forked from jimtin/python_trading_bot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
278 lines (252 loc) · 8.62 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
import json
import os
from metatrader_lib import mt5_interaction
import pandas
import display_lib
from sql_lib import sql_interaction
from strategies import ema_cross
from backtest_lib import backtest, setup_backtest, backtest_analysis
import argparse
from indicator_lib import calc_all_indicators, doji_star, rsi
import datetime
# Variable for the location of settings.json
import_filepath = "settings.json"
# Global settings
global exchange
global explore
# Function to import settings from settings.json
def get_project_settings(import_filepath):
"""
Function to import settings from settings.json
:param import_filepath: string to the location of settings.json
:return: JSON object with project settings
"""
# Test the filepath to sure it exists
if os.path.exists(import_filepath):
# Open the file
f = open(import_filepath, "r")
# Get the information from file
project_settings = json.load(f)
# Close the file
f.close()
# Return project settings to program
return project_settings
else:
return ImportError
def check_exchanges(project_settings):
"""
Function to check if exchanges are working
:param project_settings:
:return: Bool
"""
# Check MT5 Live trading
mt5_live_check = mt5_interaction.start_mt5(
username=project_settings["mt5"]["live"]["username"],
password=project_settings["mt5"]["live"]["password"],
server=project_settings["mt5"]["live"]["server"],
path=project_settings["mt5"]["live"]["mt5Pathway"],
)
if not mt5_live_check:
print("MT5 Live Connection Error")
raise PermissionError
# Check MT5 Paper Trading
mt5_paper_check = mt5_interaction.start_mt5(
username=project_settings["mt5"]["paper"]["username"],
password=project_settings["mt5"]["paper"]["password"],
server=project_settings["mt5"]["paper"]["server"],
path=project_settings["mt5"]["paper"]["mt5Pathway"],
)
if not mt5_paper_check:
print("MT5 Paper Connection Error")
raise PermissionError
# Return True if all steps pass
return True
# Function to add arguments to script
def add_arguments(parser):
"""
Function to add arguments to the parser
:param parser: parser object
:return: updated parser object
"""
# Add Options
# Explore Option
parser.add_argument(
"-e",
"--Explore",
help="Use this to explore the data",
action="store_true"
)
# Display Option
parser.add_argument(
"-d",
"--Display",
help="Use this to display the data",
action="store_true"
)
# All Indicators Option
parser.add_argument(
"-a",
"--all_indicators",
help="Select all indicator_lib",
action="store_true"
)
# Doji Star Option
parser.add_argument(
"--doji_star",
help="Select doji star indicator to be calculated",
action="store_true"
)
# RSI Option
parser.add_argument(
"--rsi",
help="Select RSI indicator to be calculated",
action="store_true"
)
# Add Arguments
parser.add_argument(
"-x",
"--Exchange",
help="Set which exchange you will be using"
)
# Custom Symbol
parser.add_argument(
"--symbol",
help="Use this to use a custom symbol with the Explore option"
)
# Custom Timeframe
parser.add_argument(
"-t",
"--timeframe",
help="Select a timeframe to explore data"
)
return parser
# Function to parse provided options
def parse_arguments(args_parser_variable):
"""
Function to parse provided arguments and improve from there
:param args_parser_variable:
:return: True when completed
"""
# Check if data exploration selected
if args_parser_variable.Explore:
print("Data exploration selected")
# Check for exchange
if args_parser_variable.Exchange:
if args_parser_variable.Exchange == "metatrader":
global exchange
exchange = "mt5"
print(f"Exchange selected: {exchange}")
# Check for Timeframe
if args_parser_variable.timeframe:
print(f"Timeframe selected: {args_parser_variable.timeframe}")
else:
print("No timeframe selected")
raise SystemExit(1)
# Check for Symbol
if args_parser_variable.symbol:
print(f"Symbol selected: {args_parser_variable.symbol}")
else:
print("No symbol selected")
raise SystemExit(1)
return True
else:
print("No exchange selected")
raise SystemExit(1)
return False
# Function to manage data exploration
def manage_exploration(args):
"""
Function to manage data exploration when --Explore option selected
:param args: system arguments
:return: dataframe
"""
if args.Exchange == "metatrader":
# Retreive a large amount of data
data = mt5_interaction.query_historic_data(
symbol=args.symbol,
timeframe=args.timeframe,
number_of_candles=1000
)
# Convert to a dataframe
data = pandas.DataFrame(data)
# Retrieve whatever indicator_lib have been selected
# If all indicators selected, calculate all of them
if args.all_indicators:
print(f"All indicators selected. Calculation may take some time")
indicator_dataframe = calc_all_indicators.all_indicators(
dataframe=data
)
return indicator_dataframe
else:
# If display is true, construct the base figure
if args.Display:
# Add a column 'human_time' to the dataframe which converts the unix time to human readable
data['human_time'] = data['time'].apply(lambda x: datetime.datetime.fromtimestamp(x).strftime('%Y-%m-%d %H:%M:%S'))
fig = display_lib.construct_base_candlestick_graph(
dataframe=data,
candlestick_title=f"{args.symbol} {args.timeframe} Data Explorer"
)
# Check for doji_star
if args.doji_star and args.Display:
print(f"Doji Star selected with display")
indicator_dataframe = doji_star.doji_star(
dataframe=data,
display=True,
fig=fig
)
# Check for RSI
if args.rsi:
print(f"RSI selected")
indicator_dataframe = rsi.rsi(
dataframe=data,
display=True,
fig=fig
)
else:
# Check for doji_star
if args.doji_star:
print(f"Doji Star selected")
indicator_dataframe = doji_star.doji_star(
dataframe=data
)
# Check for RSI
if args.rsi:
print(f"RSI selected")
indicator_dataframe = rsi.rsi(
dataframe=data
)
# If display is true, once all indicators have been calculated, display the figure
if args.Display:
print("Displaying data")
display_lib.display_graph(
plotly_fig=fig,
graph_title=f"{args.symbol} {args.timeframe} Data Explorer",
dash=False
)
# Once all indicators have been calculated, return the dataframe
return indicator_dataframe
else:
print("No exchange selected")
raise SystemExit(1)
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
# Import project settings
project_settings = get_project_settings(import_filepath=import_filepath)
# Check exchanges
check_exchanges(project_settings)
# Show all columns pandas
pandas.set_option('display.max_columns', None)
#pandas.set_option('display.max_rows', None)
# Setup arguments to the script
parser = argparse.ArgumentParser()
# Update with options
parser = add_arguments(parser=parser)
# Get the arguments
args = parser.parse_args()
explore = parse_arguments(args_parser_variable=args)
# Branch based upon options
if explore:
manage_exploration(args=args)
else:
data = manage_exploration(args=args)
print(data)