jgtfx2console 0.4.20__tar.gz → 0.4.22__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. {jgtfx2console-0.4.20/jgtfx2console.egg-info → jgtfx2console-0.4.22}/PKG-INFO +1 -1
  2. {jgtfx2console-0.4.20 → jgtfx2console-0.4.22}/jgtfx2console/__init__.py +1 -1
  3. {jgtfx2console-0.4.20 → jgtfx2console-0.4.22/jgtfx2console.egg-info}/PKG-INFO +1 -1
  4. {jgtfx2console-0.4.20 → jgtfx2console-0.4.22}/jgtfx2console.egg-info/SOURCES.txt +0 -2
  5. jgtfx2console-0.4.22/jgtfx2console.egg-info/entry_points.txt +4 -0
  6. {jgtfx2console-0.4.20 → jgtfx2console-0.4.22}/pyproject.toml +3 -3
  7. jgtfx2console-0.4.20/jgtfx2console/LiveChartDataExport.py +0 -428
  8. jgtfx2console-0.4.20/jgtfx2console/config_generator.py +0 -74
  9. jgtfx2console-0.4.20/jgtfx2console.egg-info/entry_points.txt +0 -4
  10. {jgtfx2console-0.4.20 → jgtfx2console-0.4.22}/LICENSE +0 -0
  11. {jgtfx2console-0.4.20 → jgtfx2console-0.4.22}/README.md +0 -0
  12. {jgtfx2console-0.4.20 → jgtfx2console-0.4.22}/README.rst +0 -0
  13. {jgtfx2console-0.4.20 → jgtfx2console-0.4.22}/jgtfx2console/forexconnect/EachRowListener.py +0 -0
  14. {jgtfx2console-0.4.20 → jgtfx2console-0.4.22}/jgtfx2console/forexconnect/ForexConnect.py +0 -0
  15. {jgtfx2console-0.4.20 → jgtfx2console-0.4.22}/jgtfx2console/forexconnect/LiveHistory.py +0 -0
  16. {jgtfx2console-0.4.20 → jgtfx2console-0.4.22}/jgtfx2console/forexconnect/ResponseListener.py +0 -0
  17. {jgtfx2console-0.4.20 → jgtfx2console-0.4.22}/jgtfx2console/forexconnect/SessionStatusListener.py +0 -0
  18. {jgtfx2console-0.4.20 → jgtfx2console-0.4.22}/jgtfx2console/forexconnect/TableListener.py +0 -0
  19. {jgtfx2console-0.4.20 → jgtfx2console-0.4.22}/jgtfx2console/forexconnect/TableManagerListener.py +0 -0
  20. {jgtfx2console-0.4.20 → jgtfx2console-0.4.22}/jgtfx2console/forexconnect/__init__.py +0 -0
  21. {jgtfx2console-0.4.20 → jgtfx2console-0.4.22}/jgtfx2console/forexconnect/common.py +0 -0
  22. {jgtfx2console-0.4.20 → jgtfx2console-0.4.22}/jgtfx2console/forexconnect/errors.py +0 -0
  23. {jgtfx2console-0.4.20 → jgtfx2console-0.4.22}/jgtfx2console/forexconnect/x-pyd.py +0 -0
  24. {jgtfx2console-0.4.20 → jgtfx2console-0.4.22}/jgtfx2console/fxcli2console.py +0 -0
  25. {jgtfx2console-0.4.20 → jgtfx2console-0.4.22}/jgtfx2console.egg-info/dependency_links.txt +0 -0
  26. {jgtfx2console-0.4.20 → jgtfx2console-0.4.22}/jgtfx2console.egg-info/requires.txt +0 -0
  27. {jgtfx2console-0.4.20 → jgtfx2console-0.4.22}/jgtfx2console.egg-info/top_level.txt +0 -0
  28. {jgtfx2console-0.4.20 → jgtfx2console-0.4.22}/setup.cfg +0 -0
  29. {jgtfx2console-0.4.20 → jgtfx2console-0.4.22}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: jgtfx2console
3
- Version: 0.4.20
3
+ Version: 0.4.22
4
4
  Summary: PDS Services
5
5
  Home-page: https://github.com/jgwill/jgtfx2console
6
6
  Author: GUillaume Isabelle
@@ -42,6 +42,6 @@ with warnings.catch_warnings():
42
42
  # your code here
43
43
 
44
44
 
45
- __version__ = "0.4.20"
45
+ __version__ = "0.4.22"
46
46
 
47
47
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: jgtfx2console
3
- Version: 0.4.20
3
+ Version: 0.4.22
4
4
  Summary: PDS Services
5
5
  Home-page: https://github.com/jgwill/jgtfx2console
6
6
  Author: GUillaume Isabelle
@@ -4,9 +4,7 @@ README.rst
4
4
  pyproject.toml
5
5
  setup.cfg
6
6
  setup.py
7
- jgtfx2console/LiveChartDataExport.py
8
7
  jgtfx2console/__init__.py
9
- jgtfx2console/config_generator.py
10
8
  jgtfx2console/fxcli2console.py
11
9
  jgtfx2console.egg-info/PKG-INFO
12
10
  jgtfx2console.egg-info/SOURCES.txt
@@ -0,0 +1,4 @@
1
+ [console_scripts]
2
+ fxcli2console = jgtfx2console.fxcli2console:main
3
+ fxlive = jgtfx2console.ptoLiveChartDataExport.LiveChartDataExport:main
4
+ fxliveconf = jgtfx2console.ptoLiveChartDataExport.config_generator:main
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "jgtfx2console"
7
- version = "0.4.20"
7
+ version = "0.4.22"
8
8
  authors = [
9
9
  { name="Guillaume Isabelle", email="jgi@jgwill.com" },
10
10
  ]
@@ -33,5 +33,5 @@ classifiers = [
33
33
 
34
34
  [project.scripts]
35
35
  fxcli2console = "jgtfx2console.fxcli2console:main"
36
- fxlive = "jgtfx2console.LiveChartDataExport:main"
37
- fxliveconf = "jgtfx2console.config_generator:main"
36
+ fxlive = "jgtfx2console.ptoLiveChartDataExport.LiveChartDataExport:main"
37
+ fxliveconf = "jgtfx2console.ptoLiveChartDataExport.config_generator:main"
@@ -1,428 +0,0 @@
1
- import numpy as np
2
- import time
3
- import argparse
4
- import os
5
- import sys
6
-
7
- from jgtutils import jgtcommon
8
-
9
-
10
- path_from_where_we_call = os.getcwd()
11
-
12
- sys.path.insert(0, os.path.abspath(os.path.dirname(__file__)))
13
-
14
- c_script_dir_name = os.path.dirname(__file__)
15
- abs_path_of_this_file = os.path.abspath(c_script_dir_name)
16
- print("abs_path_of_this_file: "+abs_path_of_this_file)
17
- print("c_script_dir_name: "+c_script_dir_name)
18
- path1 = os.path.join(c_script_dir_name, '.')
19
- print("path1: "+path1)
20
- abs_path1 = os.path.abspath(path1)
21
- print("abs_path1: "+abs_path1)
22
- sys.path.append(abs_path1)
23
- #cd to : abs_path_of_this_file #@STCIssue Wont go further that CONNECTED if we are not in that directory.
24
- os.chdir(abs_path_of_this_file)
25
-
26
- from forexconnect import fxcorepy, ForexConnect
27
- from forexconnect import Common, LiveHistoryCreator
28
-
29
- from dateutil import parser
30
-
31
- import xml.etree.ElementTree as ET
32
-
33
- import common_samples
34
- import csv
35
- import pytz
36
- from datetime import timedelta, datetime
37
-
38
- delimiter = None
39
- datetime_separator = None
40
- format_decimal_places = None
41
- timezone = None
42
-
43
-
44
- def parse_args():
45
- arg_parser = argparse.ArgumentParser(description='Process command parameters.')
46
- arg_parser.add_argument('-p',
47
- metavar="PASSWORD",
48
- required=False,
49
- help='Your password.')
50
- arg_parser.add_argument('-config', metavar="CONFIG_FILE", default='jgtfxliveconfig.xml',
51
- help='Config file')
52
-
53
- args = arg_parser.parse_args()
54
- return args
55
-
56
-
57
- verbose = 0
58
- order_request_id = ""
59
-
60
-
61
- class SaveNewBar:
62
- def __init__(self, symbol, bars):
63
- self.symbol = symbol
64
- self.bars = bars
65
-
66
- def save_bar(self, instrument, history, filename):
67
- global delimiter
68
- global datetime_separator
69
- global format_decimal_places
70
- global timezone
71
-
72
- if timezone == 'Local':
73
- time_difference = -time.timezone
74
- else:
75
- tz = pytz.timezone(timezone)
76
- time_difference = tz.utcoffset(datetime.now).total_seconds()
77
-
78
- hist = history[:-1].tail(1)
79
- with open(filename, "a", newline="") as file:
80
- writer = csv.writer(file, delimiter=delimiter)
81
- last_complete_data_frame = hist
82
- dtime = str(last_complete_data_frame.index.values[0])
83
-
84
- dtime = dtime.replace('T', ' ')
85
- dt = parser.parse(dtime)
86
- dt = dt+timedelta(0, time_difference)
87
- dt = str(dt)
88
- dtime = dt.replace(' ', datetime_separator)
89
- out = [dtime]
90
- str_prices = dtime + ", "
91
- for price_name in last_complete_data_frame:
92
- price_entry = last_complete_data_frame.get(price_name)
93
- price_value = price_entry.values[0]
94
- str_prices += price_name + "=" + str(price_value) + ", "
95
- price = price_entry.values[0]
96
- if format_decimal_places and price_name != "Volume":
97
- if instrument.find("JPY") >= 0:
98
- out.append("%.3f" % price)
99
- else:
100
- out.append("%.5f" % price)
101
- else:
102
- out.append(price)
103
- writer.writerow(out)
104
- file.close()
105
- print("New bar saved to "+filename+": "+str_prices[0: -2])
106
-
107
- return
108
-
109
-
110
- order_created_count = 0
111
-
112
-
113
- def find_in_tree(tree, node):
114
- found = tree.find(node)
115
- if found is None:
116
- found = []
117
- return found
118
-
119
-
120
- def on_request_completed(request_id, response):
121
- del request_id, response
122
- global order_created_count
123
- order_created_count += 1
124
- return True
125
-
126
-
127
- def on_changed(live_history, instrument):
128
- def _on_changed(table_listener, row_id, row):
129
- del table_listener, row_id
130
- try:
131
- if row.table_type == fxcorepy.O2GTableType.OFFERS and row.instrument == instrument:
132
- live_history.add_or_update(row)
133
- except Exception as e:
134
- common_samples.print_exception(e)
135
- return
136
-
137
- return _on_changed
138
-
139
-
140
- def on_bar_added(instrument, filename):
141
- def _on_bar_added(history):
142
- snb = SaveNewBar(instrument, history[:-1])
143
- snb.save_bar(instrument, history, filename)
144
-
145
- return _on_bar_added
146
-
147
-
148
- def session_status_changed(fx, live_history, instrument, str_user_id, str_password, str_url, str_connection,
149
- reconnect_on_disconnected):
150
- offers_listener = None
151
- first_call = reconnect_on_disconnected
152
- orders_listener = None
153
-
154
- def _session_status_changed(session, status):
155
- nonlocal offers_listener
156
- nonlocal first_call
157
- nonlocal orders_listener
158
- if not first_call:
159
- common_samples.session_status_changed(session.trading_session_descriptors, status)
160
- else:
161
- first_call = False
162
- if status == fxcorepy.AO2GSessionStatus.O2GSessionStatus.CONNECTED:
163
- offers = fx.get_table(ForexConnect.OFFERS)
164
- if live_history is not None:
165
- on_changed_callback = on_changed(live_history, instrument)
166
- offers_listener = Common.subscribe_table_updates(offers, on_change_callback=on_changed_callback)
167
- elif status == fxcorepy.AO2GSessionStatus.O2GSessionStatus.DISCONNECTING or \
168
- status == fxcorepy.AO2GSessionStatus.O2GSessionStatus.RECONNECTING or \
169
- status == fxcorepy.AO2GSessionStatus.O2GSessionStatus.SESSION_LOST:
170
- if orders_listener is not None:
171
- orders_listener.unsubscribe()
172
- orders_listener = None
173
- if offers_listener is not None:
174
- offers_listener.unsubscribe()
175
- offers_listener = None
176
- elif status == fxcorepy.AO2GSessionStatus.O2GSessionStatus.DISCONNECTED and reconnect_on_disconnected:
177
- fx.session.login(str_user_id, str_password, str_url, str_connection)
178
-
179
- return _session_status_changed
180
-
181
-
182
- def check_params(instr, tf, offer):
183
- if not instr:
184
- raise Exception(
185
- "The instrument is empty")
186
-
187
- if not tf:
188
- raise Exception(
189
- "The timeframe is empty")
190
-
191
- if not offer:
192
- raise Exception(
193
- "The instrument '{0}' is not valid".format(instr))
194
-
195
-
196
- def parse_xml(config_file):
197
- try:
198
- jgtconf=jgtcommon.readconfig()
199
- #print(jgtconf)
200
- except:
201
- raise Exception(
202
- "The JGT configuration file '$HOME/config.json' does not exist")
203
- try:
204
- os.stat(config_file)
205
- except OSError:
206
- raise Exception(
207
- "The configuration file '{0}' does not exist".format(config_file))
208
-
209
- xmlfile = open(config_file, "r")
210
- conf = ET.parse(xmlfile)
211
- root = conf.getroot()
212
-
213
- settings = find_in_tree(root, "Settings")
214
-
215
-
216
- str_user_id = find_in_tree(settings, "Login").text
217
- if str_user_id == '0' or str_user_id == '' or str_user_id is None:
218
- str_user_id =jgtconf.get('user_id')
219
-
220
- str_url = find_in_tree(settings, "Url").text
221
- str_connection = find_in_tree(settings, "Connection").text
222
- if str_connection == '' or str_connection is None or str_connection=='0':
223
- str_connection = os.getenv('connection') or jgtconf.get('connection')
224
- str_session_id = find_in_tree(settings, "SessionID").text
225
- str_pin = find_in_tree(settings, "Pin").text
226
- delim = find_in_tree(settings, "Delimiter").text
227
- output_dir = find_in_tree(settings, "OutputDir").text
228
- #test if our path is relative
229
- if output_dir and output_dir[0] != '/':
230
- output_dir = os.path.join(path_from_where_we_call, output_dir)
231
- #print("relative output_dir modified: "+output_dir)
232
- if output_dir == '' or output_dir is None or output_dir=='0':
233
- output_dir = os.getenv('JGTPY_DATA') or jgtconf.get('JGTPY_DATA')
234
- dt_separator = find_in_tree(settings, "DateTimeSeparator").text
235
- fdp = find_in_tree(settings, "FormatDecimalPlaces").text
236
- tzone = find_in_tree(settings, "Timezone").text
237
-
238
- if tzone != 'EST' and tzone != 'UTC' and tzone != 'Local':
239
- print('Timezone is not recognized, using EST')
240
- tzone = 'UTC' #Default timezone
241
-
242
- print("=============================")
243
- print("User ID: " + str_user_id)
244
- print("URL: " + str_url)
245
- print("Connection: " + str_connection)
246
- #print("Session ID: " + str_session_id)
247
- #print("Pin: " + str_pin)
248
- print("Delimiter: " + delim)
249
- print("Output Directory: " + output_dir)
250
- print("DateTime Separator: " + dt_separator)
251
- print("Format Decimal Places: " + fdp)
252
- print("Timezone: " + tzone)
253
-
254
- print("=============================")
255
-
256
- if output_dir:
257
- if not os.path.exists(output_dir):
258
- raise Exception(
259
- "The output directory '{0}' does not exist. (try writting an absolute path in the config or use 0 so it will read the JGTPY_DATA environment variable)".format(output_dir))
260
-
261
- if fdp == "Y" or fdp == "y":
262
- fdp = True
263
- else:
264
- fdp = False
265
-
266
- data = []
267
-
268
- for elem in settings.findall("History"):
269
- data2 = [find_in_tree(elem, "Instrument").text]
270
- data2.append(find_in_tree(elem, "Timeframe").text)
271
- if output_dir:
272
- ifn = find_in_tree(elem, "Filename").text
273
- data2.append(os.path.join(output_dir, ifn))
274
- else:
275
- data2.append(find_in_tree(elem, "Filename").text)
276
- data2.append(find_in_tree(elem, "NumBars").text)
277
- data2.append(find_in_tree(elem, "Headers").text)
278
- data.append(data2)
279
-
280
- if len(data) == 0:
281
- raise Exception(
282
- "No instruments in the config file are present")
283
-
284
- return str_user_id, str_url, str_connection, str_session_id, str_pin, \
285
- delim, output_dir, dt_separator, fdp, tzone, data
286
-
287
-
288
- def set_init_history(fx, lhc, instr, tf, filename, numbars, str_user_id, str_password, str_url, str_connection):
289
- lhc.append(LiveHistoryCreator(tf))
290
- last_index = len(lhc)-1
291
- on_bar_added_callback = on_bar_added(instr, filename)
292
- lhc[last_index].subscribe(on_bar_added_callback)
293
- session_status_changed_callback = session_status_changed(fx, lhc[last_index], instr, str_user_id,
294
- str_password, str_url, str_connection, True)
295
- session_status_changed_callback(fx.session, fx.session.session_status)
296
- fx.set_session_status_listener(session_status_changed_callback)
297
-
298
- nd_array_history = fx.get_history(instr, tf, None, None, int(numbars)+2)
299
-
300
- lhc[last_index].history = nd_array_history
301
-
302
- return lhc, nd_array_history
303
-
304
-
305
- def get_time_difference(tzone):
306
- if tzone == 'Local':
307
- time_difference = -time.timezone
308
- else:
309
- tz = pytz.timezone(tzone)
310
- time_difference = tz.utcoffset(datetime.now).total_seconds()
311
- return time_difference
312
-
313
-
314
- def save_old_history(instr, filename, headers, nd_array_history, time_difference, dt_separator):
315
- header = ['DateTime', 'Bid Open', 'Bid High', 'Bid Low', 'Bid Close', 'Ask Open', 'Ask High',
316
- 'Ask Low', 'Ask Close', 'Volume']
317
- with open(filename, "w", newline="") as file:
318
- writer = csv.writer(file, delimiter=delimiter)
319
- if headers:
320
- head = [headers]
321
- writer.writerow(head)
322
- else:
323
- writer.writerow(header)
324
- for i in range(1, len(nd_array_history)-1):
325
- last_complete_data_frame = nd_array_history[i:i+1]
326
- str2 = str(last_complete_data_frame[0])
327
- str2 = str2.replace('(', '')
328
- str2 = str2.replace(')', '')
329
- str2 = str2.replace("'", '')
330
- str2 = str2.replace(' ', '')
331
- str2 = str2.split(',')
332
- array = np.array(str2)
333
- array[0] = array[0].replace('T', ' ')
334
- dt = parser.parse(array[0])
335
- dt = dt+timedelta(0, time_difference)
336
- dt = str(dt)
337
- array[0] = dt.replace(' ', dt_separator)
338
- out = [array[0]]
339
- for i2 in range(1, len(array)-1):
340
- price = float(array[i2])
341
- if format_decimal_places:
342
- if instr.find("JPY") >= 0:
343
- out.append("%.3f" % price)
344
- else:
345
- out.append("%.5f" % price)
346
- else:
347
- out.append(price)
348
- out.append(array[len(array)-1])
349
- writer.writerow(out)
350
-
351
- def main():
352
- global delimiter
353
- global datetime_separator
354
- global format_decimal_places
355
- global timezone
356
-
357
- args = parse_args()
358
- config_file = args.config
359
- if not os.path.exists(config_file):
360
- config_file=os.path.join(path_from_where_we_call,config_file)
361
-
362
- jgtconf=jgtcommon.readconfig()
363
-
364
- if args.p:
365
- str_password = args.p
366
- else:
367
- str_password = jgtconf.get('password') or os.getenv('password')
368
-
369
- if str_password is None:
370
- raise Exception("Password is required. Use -p option or export password=mypasswd")
371
- sys.exit("Password is required. Use -p option or export password=mypasswd")
372
-
373
- str_user_id, str_url, str_connection, str_session_id, str_pin, delimiter, output_dir, \
374
- datetime_separator, format_decimal_places, timezone, data = parse_xml(config_file)
375
-
376
- # print("cwd: "+os.getcwd())
377
- # os.chdir(abs_path_of_this_file)
378
- # print("cwd: "+os.getcwd())
379
- with ForexConnect() as fx:
380
- try:
381
- print("Connecting to: user id:"+str_user_id+", url:"+str_url+", Connection:"+str_connection)
382
- try:
383
- fx.login(str_user_id, str_password, str_url,
384
- str_connection, str_session_id, str_pin,
385
- common_samples.session_status_changed)
386
- except Exception as e:
387
- print("Exception: " + str(e))
388
- raise Exception(
389
- "Login failed. Invalid parameters")
390
-
391
- lhc = []
392
- for param in data:
393
- offer = Common.get_offer(fx, param[0])
394
-
395
- check_params(param[0], param[1], offer)
396
-
397
- tf = ForexConnect.get_timeframe(fx, param[1])
398
- if not tf:
399
- raise Exception(
400
- "The timeframe '{0}' is not valid".format(param[1]))
401
-
402
- lhc, nd_array_history = set_init_history(fx, lhc, param[0], param[1], param[2], param[3],
403
- str_user_id, str_password, str_url, str_connection)
404
-
405
- time_difference = get_time_difference(timezone)
406
-
407
- save_old_history(param[0], param[2], param[4], nd_array_history, time_difference, datetime_separator)
408
-
409
- print("Old history saved to "+param[2])
410
-
411
- while True:
412
- time.sleep(60)
413
-
414
- except Exception as e:
415
- common_samples.print_exception(e)
416
- try:
417
- fx.set_session_status_listener(session_status_changed(fx, None, None, str_user_id, str_password,
418
- str_url, str_connection, False))
419
- fx.logout()
420
- except Exception as e:
421
- common_samples.print_exception(e)
422
-
423
-
424
- if __name__ == "__main__":
425
- main()
426
- print("")
427
- input("Done! Press enter key to exit\n")
428
-
@@ -1,74 +0,0 @@
1
- import argparse
2
-
3
-
4
- import os
5
- import xml.etree.ElementTree as ET
6
-
7
- def generate_config(instruments, timeframes, nb_bar=500, default_headers="DateTime,Bid Open,Bid Close,Ask High,Ask Low,Volume", data_dir=None):
8
- # Split the CSV strings into lists
9
- instruments = instruments.split(',')
10
- timeframes = timeframes.split(',')
11
-
12
- # Create the root element
13
- config = ET.Element('configuration')
14
-
15
- # Create the Settings element
16
- settings = ET.SubElement(config, 'Settings')
17
-
18
- # Add the Login, OutputDir, and Url elements
19
- ET.SubElement(settings, 'Login').text = '0'#os.getenv('user_id','0')
20
- ET.SubElement(settings, 'OutputDir').text = data_dir or os.getenv('JGTPY_DATA')
21
- ET.SubElement(settings, 'Url').text = os.getenv('url','https://www.fxcorporate.com/Hosts.jsp')
22
-
23
- # Add the other elements
24
- ET.SubElement(settings, 'Connection').text = os.getenv('connection','Real')
25
- ET.SubElement(settings, 'SessionID').text = ''
26
- ET.SubElement(settings, 'Pin').text = ''
27
- ET.SubElement(settings, 'Delimiter').text = ','
28
- ET.SubElement(settings, 'DateTimeSeparator').text = 'T'
29
- ET.SubElement(settings, 'FormatDecimalPlaces').text = 'Y'
30
- ET.SubElement(settings, 'Timezone').text = 'UTC'
31
-
32
- # Add the History elements
33
- for instrument in instruments:
34
- for timeframe in timeframes:
35
- history = ET.SubElement(settings, 'History')
36
- ET.SubElement(history, 'Instrument').text = instrument
37
- ET.SubElement(history, 'Timeframe').text = timeframe
38
- ifn = instrument.replace("/","-")
39
- ET.SubElement(history, 'Filename').text = f'{ifn}_{timeframe}.csv'
40
- ET.SubElement(history, 'NumBars').text = str(nb_bar)
41
- ET.SubElement(history, 'Headers').text = default_headers
42
-
43
- # Return the XML as a string
44
- return ET.tostring(config, encoding='utf8', method='xml').decode()
45
-
46
- def main():
47
- import argparse
48
- parser = argparse.ArgumentParser(description='Generate a configuration file for the ptoLiveChartDataExport')
49
- parser.add_argument('--instruments', help='The list of instruments to export (comma-separated)')
50
- parser.add_argument('--timeframes', help='The list of timeframes to export (comma-separated)')
51
- parser.add_argument('--outxml', type=str,default="jgtfxliveconfig.xml", help='Output XML file')
52
-
53
- #data_dir = os.getenv('JGTPY_DATA') or if --data_dir
54
- parser.add_argument('--data_dir', help='The directory where the data will be saved')
55
-
56
-
57
-
58
- args = parser.parse_args()
59
- instruments = args.instruments
60
- timeframes = args.timeframes
61
- data_dir = args.data_dir or os.getenv('JGTPY_DATA')
62
- outxml = args.outxml
63
-
64
- # Generate the configuration
65
- config = generate_config(instruments, timeframes, data_dir=data_dir)
66
-
67
- # Print the configuration
68
- print(config)
69
- with open(outxml, 'w') as f:
70
- f.write(config)
71
- print("Configuration file written to:", outxml)
72
-
73
- if __name__ == '__main__':
74
- main()
@@ -1,4 +0,0 @@
1
- [console_scripts]
2
- fxcli2console = jgtfx2console.fxcli2console:main
3
- fxlive = jgtfx2console.LiveChartDataExport:main
4
- fxliveconf = jgtfx2console.config_generator:main
File without changes
File without changes
File without changes
File without changes