jgtfx2console 0.4.27__tar.gz → 0.5.15__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- jgtfx2console-0.5.15/MANIFEST.in +32 -0
- {jgtfx2console-0.4.27 → jgtfx2console-0.5.15}/PKG-INFO +8 -11
- {jgtfx2console-0.4.27 → jgtfx2console-0.5.15}/jgtfx2console/LiveChartDataExport.py +2 -2
- {jgtfx2console-0.4.27 → jgtfx2console-0.5.15}/jgtfx2console/__init__.py +1 -1
- jgtfx2console-0.5.15/jgtfx2console/common_samples/BatchOrderMonitor.py +84 -0
- jgtfx2console-0.5.15/jgtfx2console/common_samples/OrderMonitor.py +171 -0
- jgtfx2console-0.5.15/jgtfx2console/common_samples/OrderMonitorNetting.py +195 -0
- jgtfx2console-0.5.15/jgtfx2console/common_samples/TableListenerContainer.py +197 -0
- jgtfx2console-0.5.15/jgtfx2console/common_samples/__init__.py +23 -0
- jgtfx2console-0.5.15/jgtfx2console/common_samples/common.py +219 -0
- {jgtfx2console-0.4.27 → jgtfx2console-0.5.15}/jgtfx2console/config_generator.py +12 -5
- {jgtfx2console-0.4.27 → jgtfx2console-0.5.15}/jgtfx2console/forexconnect/ForexConnect.py +7 -2
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/_fix_import.sh +3 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/linux/__init__.py +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/linux/fxcorepy.so +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/linux/libForexConnect.so +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/linux/libboost_python3.so.1.64.0 +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/linux/libboost_system.so.1.64.0 +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/linux/libfxmsg.so +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/linux/libfxtp.so +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/linux/libgsexpat.so +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/linux/libgstool3.so +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/linux/libhttplib.so +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/linux/liblog4cplus.so +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/linux/liblogger.so +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/linux/libpdas.so +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/linux/libpricehistorymgr.so.2.8.0 +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/linux/libpython3.7m.so +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/linux/libquotesmgr2.so.2.8 +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/linux/libsqlite3.8.so +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/linux/requirements.txt +5 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/ForexConnect.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/__init__.py +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/_depend_on.txt +11 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-core-console-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-core-datetime-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-core-debug-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-core-errorhandling-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-core-file-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-core-file-l1-2-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-core-file-l2-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-core-handle-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-core-heap-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-core-interlocked-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-core-libraryloader-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-core-localization-l1-2-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-core-memory-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-core-namedpipe-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-core-processenvironment-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-core-processthreads-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-core-processthreads-l1-1-1.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-core-profile-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-core-rtlsupport-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-core-string-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-core-synch-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-core-synch-l1-2-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-core-sysinfo-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-core-timezone-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-core-util-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-crt-conio-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-crt-convert-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-crt-environment-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-crt-filesystem-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-crt-heap-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-crt-locale-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-crt-math-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-crt-multibyte-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-crt-private-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-crt-process-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-crt-runtime-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-crt-stdio-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-crt-string-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-crt-time-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/api-ms-win-crt-utility-l1-1-0.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/cacert.pem +3314 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/concrt140.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/fxcorepy.pyd +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/fxmsg.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/fxtp.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/gscurl.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/gsexpat.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/gslibeay32.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/gsssleay32.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/gstool3.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/gszlib.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/httplib.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/log4cplus.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/msvcp140.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/pdas.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/pricehistorymgr.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/python3.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/quotesmgr2.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/requirements.txt +5 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/sqlite3.8.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/ucrtbase.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/vccorlib140.dll +0 -0
- jgtfx2console-0.5.15/jgtfx2console/forexconnect/lib/windows/vcruntime140.dll +0 -0
- {jgtfx2console-0.4.27 → jgtfx2console-0.5.15}/jgtfx2console/fxcli2console.py +12 -7
- {jgtfx2console-0.4.27 → jgtfx2console-0.5.15}/jgtfx2console.egg-info/PKG-INFO +8 -11
- jgtfx2console-0.5.15/jgtfx2console.egg-info/SOURCES.txt +119 -0
- jgtfx2console-0.5.15/jgtfx2console.egg-info/entry_points.txt +2 -0
- {jgtfx2console-0.4.27 → jgtfx2console-0.5.15}/jgtfx2console.egg-info/requires.txt +3 -10
- {jgtfx2console-0.4.27 → jgtfx2console-0.5.15}/pyproject.toml +21 -4
- jgtfx2console-0.5.15/setup.py +40 -0
- jgtfx2console-0.4.27/jgtfx2console.egg-info/SOURCES.txt +0 -27
- jgtfx2console-0.4.27/jgtfx2console.egg-info/entry_points.txt +0 -4
- jgtfx2console-0.4.27/setup.py +0 -67
- {jgtfx2console-0.4.27 → jgtfx2console-0.5.15}/LICENSE +0 -0
- {jgtfx2console-0.4.27 → jgtfx2console-0.5.15}/README.md +0 -0
- {jgtfx2console-0.4.27 → jgtfx2console-0.5.15}/README.rst +0 -0
- {jgtfx2console-0.4.27 → jgtfx2console-0.5.15}/jgtfx2console/forexconnect/EachRowListener.py +0 -0
- {jgtfx2console-0.4.27 → jgtfx2console-0.5.15}/jgtfx2console/forexconnect/LiveHistory.py +0 -0
- {jgtfx2console-0.4.27 → jgtfx2console-0.5.15}/jgtfx2console/forexconnect/ResponseListener.py +0 -0
- {jgtfx2console-0.4.27 → jgtfx2console-0.5.15}/jgtfx2console/forexconnect/SessionStatusListener.py +0 -0
- {jgtfx2console-0.4.27 → jgtfx2console-0.5.15}/jgtfx2console/forexconnect/TableListener.py +0 -0
- {jgtfx2console-0.4.27 → jgtfx2console-0.5.15}/jgtfx2console/forexconnect/TableManagerListener.py +0 -0
- {jgtfx2console-0.4.27 → jgtfx2console-0.5.15}/jgtfx2console/forexconnect/__init__.py +0 -0
- {jgtfx2console-0.4.27 → jgtfx2console-0.5.15}/jgtfx2console/forexconnect/common.py +0 -0
- {jgtfx2console-0.4.27 → jgtfx2console-0.5.15}/jgtfx2console/forexconnect/errors.py +0 -0
- {jgtfx2console-0.4.27 → jgtfx2console-0.5.15}/jgtfx2console/forexconnect/x-pyd.py +0 -0
- {jgtfx2console-0.4.27 → jgtfx2console-0.5.15}/jgtfx2console.egg-info/dependency_links.txt +0 -0
- {jgtfx2console-0.4.27 → jgtfx2console-0.5.15}/jgtfx2console.egg-info/top_level.txt +0 -0
- {jgtfx2console-0.4.27 → jgtfx2console-0.5.15}/setup.cfg +0 -0
@@ -0,0 +1,32 @@
|
|
1
|
+
include jgtfx2console/forexconnect/TableManagerListener.py
|
2
|
+
include jgtfx2console/forexconnect/__init__.py
|
3
|
+
include jgtfx2console/forexconnect/lib/linux/libhttplib.so
|
4
|
+
include jgtfx2console/forexconnect/lib/linux/__init__.py
|
5
|
+
include jgtfx2console/forexconnect/lib/linux/libForexConnect.so
|
6
|
+
include jgtfx2console/forexconnect/lib/linux/libpricehistorymgr.so.2.8.0
|
7
|
+
include jgtfx2console/forexconnect/lib/linux/libgstool3.so
|
8
|
+
include jgtfx2console/forexconnect/lib/linux/libpdas.so
|
9
|
+
include jgtfx2console/forexconnect/lib/linux/libfxmsg.so
|
10
|
+
include jgtfx2console/forexconnect/lib/linux/fxcorepy.so
|
11
|
+
include jgtfx2console/forexconnect/lib/linux/libsqlite3.8.so
|
12
|
+
include jgtfx2console/forexconnect/lib/linux/libpython3.7m.so
|
13
|
+
include jgtfx2console/forexconnect/lib/linux/libquotesmgr2.so.2.8
|
14
|
+
include jgtfx2console/forexconnect/lib/linux/libfxtp.so
|
15
|
+
include jgtfx2console/forexconnect/lib/linux/liblogger.so
|
16
|
+
include jgtfx2console/forexconnect/lib/linux/libgsexpat.so
|
17
|
+
include jgtfx2console/forexconnect/lib/linux/libboost_system.so.1.64.0
|
18
|
+
include jgtfx2console/forexconnect/lib/linux/requirements.txt
|
19
|
+
include jgtfx2console/forexconnect/lib/linux/libboost_python3.so.1.64.0
|
20
|
+
include jgtfx2console/forexconnect/lib/linux/liblog4cplus.so
|
21
|
+
recursive-include jgtfx2console/forexconnect/lib/linux/__pycache__ *
|
22
|
+
recursive-include jgtfx2console/forexconnect/lib *
|
23
|
+
include jgtfx2console/forexconnect/ForexConnect.py
|
24
|
+
include jgtfx2console/forexconnect/errors.py
|
25
|
+
include jgtfx2console/forexconnect/common.py
|
26
|
+
include jgtfx2console/forexconnect/LiveHistory.py
|
27
|
+
include jgtfx2console/forexconnect/SessionStatusListener.py
|
28
|
+
include jgtfx2console/forexconnect/x-pyd.py
|
29
|
+
include jgtfx2console/forexconnect/TableListener.py
|
30
|
+
include jgtfx2console/forexconnect/ResponseListener.py
|
31
|
+
include jgtfx2console/forexconnect/EachRowListener.py
|
32
|
+
recursive-include jgtfx2console/forexconnect *
|
@@ -1,12 +1,13 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.2
|
2
2
|
Name: jgtfx2console
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.5.15
|
4
4
|
Summary: PDS Services
|
5
5
|
Home-page: https://github.com/jgwill/jgtfx2console
|
6
6
|
Author: GUillaume Isabelle
|
7
7
|
Author-email: Guillaume Isabelle <jgi@jgwill.com>
|
8
8
|
Project-URL: Homepage, https://github.com/jgwill/jgtfx2console
|
9
9
|
Project-URL: Bug Tracker, https://github.com/jgwill/jgtfx2console/issues
|
10
|
+
Keywords: data
|
10
11
|
Classifier: Programming Language :: Python :: 3
|
11
12
|
Classifier: License :: OSI Approved :: MIT License
|
12
13
|
Classifier: Operating System :: OS Independent
|
@@ -15,16 +16,8 @@ Description-Content-Type: text/markdown
|
|
15
16
|
License-File: LICENSE
|
16
17
|
Requires-Dist: pandas>=0.25.1
|
17
18
|
Requires-Dist: python-dotenv>=0.19.2
|
18
|
-
Requires-Dist: jgtutils>=0.
|
19
|
+
Requires-Dist: jgtutils>=0.2.218
|
19
20
|
Requires-Dist: tlid
|
20
|
-
Provides-Extra: dev
|
21
|
-
Requires-Dist: flake8<3.7.0,>=3.6.0; extra == "dev"
|
22
|
-
Requires-Dist: isort<4.4.0,>=4.3.4; extra == "dev"
|
23
|
-
Requires-Dist: coverage; extra == "dev"
|
24
|
-
Requires-Dist: pytest>=3.10; extra == "dev"
|
25
|
-
Requires-Dist: readme_renderer; extra == "dev"
|
26
|
-
Requires-Dist: sphinx; extra == "dev"
|
27
|
-
Requires-Dist: sphinx_rtd_theme>=0.4.0; extra == "dev"
|
28
21
|
Provides-Extra: dev-lint
|
29
22
|
Requires-Dist: flake8<3.7.0,>=3.6.0; extra == "dev-lint"
|
30
23
|
Requires-Dist: isort<4.4.0,>=4.3.4; extra == "dev-lint"
|
@@ -35,6 +28,10 @@ Provides-Extra: dev-docs
|
|
35
28
|
Requires-Dist: readme_renderer; extra == "dev-docs"
|
36
29
|
Requires-Dist: sphinx; extra == "dev-docs"
|
37
30
|
Requires-Dist: sphinx_rtd_theme>=0.4.0; extra == "dev-docs"
|
31
|
+
Requires-Dist: html2text>=2020.1.16; extra == "dev-docs"
|
32
|
+
Requires-Dist: html2markdown>=0.1.7; extra == "dev-docs"
|
33
|
+
Dynamic: author
|
34
|
+
Dynamic: home-page
|
38
35
|
|
39
36
|
|
40
37
|
|
@@ -47,7 +47,7 @@ def parse_args():
|
|
47
47
|
metavar="PASSWORD",
|
48
48
|
required=False,
|
49
49
|
help='Your password.')
|
50
|
-
arg_parser.add_argument('-config', metavar="CONFIG_FILE", default='
|
50
|
+
arg_parser.add_argument('-config', metavar="CONFIG_FILE", default='fxliveconfig.xml',
|
51
51
|
help='Config file')
|
52
52
|
|
53
53
|
args = arg_parser.parse_args()
|
@@ -233,7 +233,7 @@ def parse_xml(config_file):
|
|
233
233
|
output_dir = os.getenv('JGTPY_DATA') or jgtconf.get('JGTPY_DATA')
|
234
234
|
dt_separator = find_in_tree(settings, "DateTimeSeparator").text
|
235
235
|
|
236
|
-
if dt_separator == '' or dt_separator is None:
|
236
|
+
if dt_separator == '' or dt_separator is None or dt_separator=='0' or dt_separator=='space' or dt_separator=='\n' :
|
237
237
|
dt_separator = ' '
|
238
238
|
fdp = find_in_tree(settings, "FormatDecimalPlaces").text
|
239
239
|
tzone = find_in_tree(settings, "Timezone").text
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# Copyright 2019 Gehtsoft USA LLC
|
2
|
+
|
3
|
+
# Licensed under the license derived from the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
|
8
|
+
# http://fxcodebase.com/licenses/open-source/license.html
|
9
|
+
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
from typing import List
|
17
|
+
|
18
|
+
from forexconnect import fxcorepy
|
19
|
+
|
20
|
+
from common_samples.OrderMonitor import OrderMonitor
|
21
|
+
|
22
|
+
|
23
|
+
class BatchOrderMonitor:
|
24
|
+
__request_ids = None
|
25
|
+
__monitors = []
|
26
|
+
|
27
|
+
def __init__(self) -> None:
|
28
|
+
pass
|
29
|
+
|
30
|
+
@property
|
31
|
+
def monitors(self) -> List[OrderMonitor]:
|
32
|
+
return self.__monitors
|
33
|
+
|
34
|
+
@property
|
35
|
+
def is_batch_executed(self) -> bool:
|
36
|
+
all_completed = True
|
37
|
+
for monitor in self.__monitors:
|
38
|
+
if monitor.is_order_completed:
|
39
|
+
self.remove_request_id(monitor.order.request_id)
|
40
|
+
else:
|
41
|
+
all_completed = False
|
42
|
+
return len(self.__request_ids) == 0 and all_completed
|
43
|
+
|
44
|
+
def set_request_ids(self, request_ids: List[str]) -> None:
|
45
|
+
self.__request_ids = request_ids
|
46
|
+
|
47
|
+
def on_request_completed(self, request_id: str, response: fxcorepy.O2GResponse) -> None:
|
48
|
+
pass
|
49
|
+
|
50
|
+
def remove_request_id(self, request_id: str) -> None:
|
51
|
+
if self.is_own_request(request_id):
|
52
|
+
self.__request_ids.remove(request_id)
|
53
|
+
|
54
|
+
def on_request_failed(self, request_id: str) -> None:
|
55
|
+
self.remove_request_id(request_id)
|
56
|
+
|
57
|
+
def on_trade_added(self, trade_row: fxcorepy.O2GTradeRow) -> None:
|
58
|
+
for monitor in self.__monitors:
|
59
|
+
monitor.on_trade_added(trade_row)
|
60
|
+
|
61
|
+
def on_order_added(self, order: fxcorepy.O2GOrderRow) -> None:
|
62
|
+
request_id = order.request_id
|
63
|
+
print("Order Added " + order.order_id)
|
64
|
+
if self.is_own_request(request_id):
|
65
|
+
if OrderMonitor.is_closing_order(order) or OrderMonitor.is_opening_order(order):
|
66
|
+
self._add_to_monitoring(order)
|
67
|
+
|
68
|
+
def on_order_deleted(self, order: fxcorepy.O2GOrderRow) -> None:
|
69
|
+
for monitor in self.__monitors:
|
70
|
+
monitor.on_order_deleted(order)
|
71
|
+
|
72
|
+
def on_message_added(self, message: fxcorepy.O2GMessageRow) -> None:
|
73
|
+
for monitor in self.__monitors:
|
74
|
+
monitor.on_message_added(message)
|
75
|
+
|
76
|
+
def on_closed_trade_added(self, close_trade_row: fxcorepy.O2GClosedTradeRow) -> None:
|
77
|
+
for monitor in self.__monitors:
|
78
|
+
monitor.on_closed_trade_added(close_trade_row)
|
79
|
+
|
80
|
+
def is_own_request(self, request_id: str) -> bool:
|
81
|
+
return request_id in self.__request_ids
|
82
|
+
|
83
|
+
def _add_to_monitoring(self, order: fxcorepy.O2GOrderRow) -> None:
|
84
|
+
self.__monitors.append(OrderMonitor(order))
|
@@ -0,0 +1,171 @@
|
|
1
|
+
# Copyright 2019 Gehtsoft USA LLC
|
2
|
+
|
3
|
+
# Licensed under the license derived from the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
|
8
|
+
# http://fxcodebase.com/licenses/open-source/license.html
|
9
|
+
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
from typing import List
|
17
|
+
from enum import Enum
|
18
|
+
|
19
|
+
from forexconnect import fxcorepy
|
20
|
+
|
21
|
+
|
22
|
+
class OrderMonitor:
|
23
|
+
class ExecutionResult(Enum):
|
24
|
+
EXECUTING = 1
|
25
|
+
EXECUTED = 2
|
26
|
+
PARTIAL_REJECTED = 3
|
27
|
+
FULLY_REJECTED = 4
|
28
|
+
CANCELED = 5
|
29
|
+
|
30
|
+
class OrderState(Enum):
|
31
|
+
ORDER_EXECUTING = 1
|
32
|
+
ORDER_EXECUTED = 2
|
33
|
+
ORDER_CANCELED = 3
|
34
|
+
ORDER_REJECTED = 4
|
35
|
+
|
36
|
+
__market_condition = "5"
|
37
|
+
|
38
|
+
def __init__(self, order: fxcorepy.O2GOrderRow) -> None:
|
39
|
+
self.__order = order
|
40
|
+
self.__trades = []
|
41
|
+
self.__closed_trades = []
|
42
|
+
self.__state = OrderMonitor.OrderState.ORDER_EXECUTING
|
43
|
+
self.__result = OrderMonitor.ExecutionResult.EXECUTING
|
44
|
+
self.__total_amount = 0
|
45
|
+
self.__reject_amount = 0
|
46
|
+
self.__reject_message = ""
|
47
|
+
|
48
|
+
@staticmethod
|
49
|
+
def is_opening_order(order: fxcorepy.O2GOrderRow) -> bool:
|
50
|
+
return order.type.startswith("O")
|
51
|
+
|
52
|
+
@staticmethod
|
53
|
+
def is_closing_order(order: fxcorepy.O2GOrderRow) -> bool:
|
54
|
+
return order.type.startswith("C")
|
55
|
+
|
56
|
+
@property
|
57
|
+
def order_row(self) -> fxcorepy.O2GOrderRow:
|
58
|
+
return self.__order
|
59
|
+
|
60
|
+
@property
|
61
|
+
def trade_rows(self) -> List[fxcorepy.O2GTradeRow]:
|
62
|
+
return self.__trades
|
63
|
+
|
64
|
+
@property
|
65
|
+
def closed_trade_rows(self) -> List[fxcorepy.O2GClosedTradeRow]:
|
66
|
+
return self.__closed_trades
|
67
|
+
|
68
|
+
@property
|
69
|
+
def reject_amount(self) -> int:
|
70
|
+
return self.__reject_amount
|
71
|
+
|
72
|
+
@property
|
73
|
+
def reject_message(self) -> str:
|
74
|
+
return self.__reject_message
|
75
|
+
|
76
|
+
@property
|
77
|
+
def result(self) -> ExecutionResult:
|
78
|
+
return self.__result
|
79
|
+
|
80
|
+
@property
|
81
|
+
def is_order_completed(self) -> bool:
|
82
|
+
print(self.__result)
|
83
|
+
return self.__result != OrderMonitor.ExecutionResult.EXECUTING
|
84
|
+
|
85
|
+
@property
|
86
|
+
def is_all_trades_received(self) -> bool:
|
87
|
+
if self.__state == OrderMonitor.OrderState.ORDER_EXECUTING:
|
88
|
+
return False
|
89
|
+
i_current_total_amount = 0
|
90
|
+
for trade in self.__trades:
|
91
|
+
i_current_total_amount += trade.amount
|
92
|
+
|
93
|
+
for trade in self.__closed_trades:
|
94
|
+
i_current_total_amount += trade.amount
|
95
|
+
|
96
|
+
return i_current_total_amount == self.__total_amount
|
97
|
+
|
98
|
+
def on_trade_added(self, trade: fxcorepy.O2GTradeRow) -> None:
|
99
|
+
trade_order_id = trade.open_order_id
|
100
|
+
order_id = self.__order.order_id
|
101
|
+
if trade_order_id == order_id:
|
102
|
+
self.__trades.append(trade)
|
103
|
+
if self.__state == OrderMonitor.OrderState.ORDER_EXECUTED or \
|
104
|
+
self.__state == OrderMonitor.OrderState.ORDER_REJECTED or \
|
105
|
+
self.__state == OrderMonitor.OrderState.ORDER_CANCELED:
|
106
|
+
if self.is_all_trades_received:
|
107
|
+
self.set_result(True)
|
108
|
+
|
109
|
+
def on_closed_trade_added(self, closed_trade: fxcorepy.O2GClosedTradeRow) -> None:
|
110
|
+
order_id = self.__order.order_id
|
111
|
+
closed_trade_order_id = closed_trade.close_order_id
|
112
|
+
print(closed_trade_order_id, order_id)
|
113
|
+
if order_id == closed_trade_order_id:
|
114
|
+
self.__closed_trades.append(closed_trade)
|
115
|
+
if self.__state == OrderMonitor.OrderState.ORDER_EXECUTED or \
|
116
|
+
self.__state == OrderMonitor.OrderState.ORDER_REJECTED or \
|
117
|
+
self.__state == OrderMonitor.OrderState.ORDER_CANCELED:
|
118
|
+
if self.is_all_trades_received:
|
119
|
+
self.set_result(True)
|
120
|
+
|
121
|
+
def on_order_deleted(self, order: fxcorepy.O2GOrderRow) -> None:
|
122
|
+
deleted_order_id = order.order_id
|
123
|
+
order_id = self.__order.order_id
|
124
|
+
if deleted_order_id == order_id:
|
125
|
+
# Store Reject amount
|
126
|
+
if order.status.startswith("R"):
|
127
|
+
self.__state = OrderMonitor.OrderState.ORDER_REJECTED
|
128
|
+
self.__reject_amount = order.amount
|
129
|
+
self.__total_amount = order.origin_amount - self.__reject_amount
|
130
|
+
if self.__reject_message != "" and self.is_all_trades_received:
|
131
|
+
self.set_result(True)
|
132
|
+
elif order.status.startswith("C"):
|
133
|
+
self.__state = OrderMonitor.OrderState.ORDER_CANCELED
|
134
|
+
self.__reject_amount = order.amount
|
135
|
+
self.__total_amount = order.origin_amount - self.__reject_amount
|
136
|
+
if self.is_all_trades_received:
|
137
|
+
self.set_result(False)
|
138
|
+
else:
|
139
|
+
self.__reject_amount = 0
|
140
|
+
self.__total_amount = order.origin_amount
|
141
|
+
self.__state = OrderMonitor.OrderState.ORDER_EXECUTED
|
142
|
+
if self.is_all_trades_received:
|
143
|
+
self.set_result(True)
|
144
|
+
|
145
|
+
def on_message_added(self, message: fxcorepy.O2GMessageRow) -> None:
|
146
|
+
if self.__state == OrderMonitor.OrderState.ORDER_REJECTED or \
|
147
|
+
self.__state == OrderMonitor.OrderState.ORDER_EXECUTING:
|
148
|
+
is_reject_message = self.check_and_store_message(message)
|
149
|
+
if self.__state == OrderMonitor.OrderState.ORDER_REJECTED and is_reject_message:
|
150
|
+
self.set_result(True)
|
151
|
+
|
152
|
+
def set_result(self, success: bool) -> None:
|
153
|
+
if success:
|
154
|
+
if self.__reject_amount == 0:
|
155
|
+
self.__result = OrderMonitor.ExecutionResult.EXECUTED
|
156
|
+
else:
|
157
|
+
self.__result = OrderMonitor.ExecutionResult.FULLY_REJECTED \
|
158
|
+
if (len(self.__trades) == 0 and len(self.__closed_trades) == 0) \
|
159
|
+
else OrderMonitor.ExecutionResult.PARTIAL_REJECTED
|
160
|
+
|
161
|
+
else:
|
162
|
+
self.__result = OrderMonitor.ExecutionResult.CANCELED
|
163
|
+
|
164
|
+
def check_and_store_message(self, message: fxcorepy.O2GMessageRow) -> bool:
|
165
|
+
feature = message.feature
|
166
|
+
if feature == self.__market_condition:
|
167
|
+
text = message.text
|
168
|
+
if self.__order.order_id in text:
|
169
|
+
self.__reject_message = message.text
|
170
|
+
return True
|
171
|
+
return False
|
@@ -0,0 +1,195 @@
|
|
1
|
+
# Copyright 2019 Gehtsoft USA LLC
|
2
|
+
|
3
|
+
# Licensed under the license derived from the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
|
8
|
+
# http://fxcodebase.com/licenses/open-source/license.html
|
9
|
+
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
from typing import List
|
17
|
+
from enum import Enum
|
18
|
+
|
19
|
+
from forexconnect import fxcorepy
|
20
|
+
|
21
|
+
|
22
|
+
class OrderMonitorNetting:
|
23
|
+
|
24
|
+
class ExecutionResult(Enum):
|
25
|
+
EXECUTING = 1
|
26
|
+
EXECUTED = 2
|
27
|
+
PARTIAL_REJECTED = 3
|
28
|
+
FULLY_REJECTED = 4
|
29
|
+
CANCELED = 5
|
30
|
+
|
31
|
+
class OrderState(Enum):
|
32
|
+
ORDER_EXECUTING = 1
|
33
|
+
ORDER_EXECUTED = 2
|
34
|
+
ORDER_CANCELED = 3
|
35
|
+
ORDER_REJECTED = 4
|
36
|
+
|
37
|
+
__market_condition = "5"
|
38
|
+
|
39
|
+
def __init__(self, order: fxcorepy.O2GOrderRow, i_net_position_amount: int = 0) -> None:
|
40
|
+
self.__order = order
|
41
|
+
self.__trades = []
|
42
|
+
self.__updated_trades = []
|
43
|
+
self.__closed_trades = []
|
44
|
+
self.__state = OrderMonitorNetting.OrderState.ORDER_EXECUTING
|
45
|
+
self.__result = OrderMonitorNetting.ExecutionResult.EXECUTING
|
46
|
+
self.__total_amount = 0
|
47
|
+
self.__reject_amount = 0
|
48
|
+
self.__reject_message = ""
|
49
|
+
self.__initial_amount = i_net_position_amount
|
50
|
+
|
51
|
+
@staticmethod
|
52
|
+
def is_opening_order(order: fxcorepy.O2GOrderRow) -> bool:
|
53
|
+
return order.type.startswith("O")
|
54
|
+
|
55
|
+
@staticmethod
|
56
|
+
def is_closing_order(order: fxcorepy.O2GOrderRow) -> bool:
|
57
|
+
return order.type.startswith("C")
|
58
|
+
|
59
|
+
# Process trade adding during order execution
|
60
|
+
def on_trade_added(self, trade: fxcorepy.O2GTradeRow) -> None:
|
61
|
+
trade_order_id = trade.open_order_id
|
62
|
+
order_id = self.__order.order_id
|
63
|
+
if trade_order_id == order_id:
|
64
|
+
self.__trades.append(trade)
|
65
|
+
if self.__state == OrderMonitorNetting.OrderState.ORDER_EXECUTED or \
|
66
|
+
self.__state == OrderMonitorNetting.OrderState.ORDER_REJECTED or \
|
67
|
+
self.__state == OrderMonitorNetting.OrderState.ORDER_CANCELED:
|
68
|
+
if self.is_all_trades_received:
|
69
|
+
self.set_result(True)
|
70
|
+
|
71
|
+
# Process trade updating during order execution
|
72
|
+
def on_trade_updated(self, trade_row: fxcorepy.O2GTradeRow) -> None:
|
73
|
+
s_trade_order_id = trade_row.open_order_id
|
74
|
+
s_order_id = self.__order.order_id
|
75
|
+
if s_trade_order_id == s_order_id:
|
76
|
+
self.__updated_trades.append(trade_row)
|
77
|
+
if self.__state == OrderMonitorNetting.OrderState.ORDER_EXECUTED or \
|
78
|
+
self.__state == OrderMonitorNetting.OrderState.ORDER_REJECTED or \
|
79
|
+
self.__state == OrderMonitorNetting.OrderState.ORDER_CANCELED:
|
80
|
+
if self.is_all_trades_received:
|
81
|
+
self.set_result(True)
|
82
|
+
|
83
|
+
# Process trade closing during order execution
|
84
|
+
def on_closed_trade_added(self, closed_trade: fxcorepy.O2GClosedTradeRow) -> None:
|
85
|
+
order_id = self.__order.order_id
|
86
|
+
closed_trade_order_id = closed_trade.close_order_id
|
87
|
+
if order_id == closed_trade_order_id:
|
88
|
+
self.__closed_trades.append(closed_trade)
|
89
|
+
if self.__state == OrderMonitorNetting.OrderState.ORDER_EXECUTED or \
|
90
|
+
self.__state == OrderMonitorNetting.OrderState.ORDER_REJECTED or \
|
91
|
+
self.__state == OrderMonitorNetting.OrderState.ORDER_CANCELED:
|
92
|
+
if self.is_all_trades_received:
|
93
|
+
self.set_result(True)
|
94
|
+
|
95
|
+
# Process order deletion as result of execution
|
96
|
+
def on_order_deleted(self, order: fxcorepy.O2GOrderRow) -> None:
|
97
|
+
deleted_order_id = order.order_id
|
98
|
+
order_id = self.__order.order_id
|
99
|
+
if deleted_order_id == order_id:
|
100
|
+
# Store Reject amount
|
101
|
+
if order.Status.startswith("R"):
|
102
|
+
self.__state = OrderMonitorNetting.OrderState.ORDER_REJECTED
|
103
|
+
self.__reject_amount = order.amount
|
104
|
+
self.__total_amount = order.origin_amount - self.__reject_amount
|
105
|
+
if self.__reject_message != "" and self.is_all_trades_received:
|
106
|
+
self.set_result(True)
|
107
|
+
else:
|
108
|
+
if order.Status.startswith("C"):
|
109
|
+
self.__state = OrderMonitorNetting.OrderState.ORDER_CANCELED
|
110
|
+
self.__reject_amount = order.amount
|
111
|
+
self.__total_amount = order.origin_amount - self.__reject_amount
|
112
|
+
if self.is_all_trades_received:
|
113
|
+
self.set_result(False)
|
114
|
+
else:
|
115
|
+
self.__reject_amount = 0
|
116
|
+
self.__total_amount = order.OriginAmount
|
117
|
+
self.__state = OrderMonitorNetting.OrderState.ORDER_EXECUTED
|
118
|
+
if self.is_all_trades_received:
|
119
|
+
self.set_result(True)
|
120
|
+
|
121
|
+
def on_message_added(self, message: fxcorepy.O2GMessageRow) -> None:
|
122
|
+
if self.__state == OrderMonitorNetting.OrderState.ORDER_REJECTED or \
|
123
|
+
self.__state == OrderMonitorNetting.OrderState.ORDER_EXECUTING:
|
124
|
+
is_reject_message = self.check_and_store_message(message)
|
125
|
+
if self.__state == OrderMonitorNetting.OrderState.ORDER_REJECTED and is_reject_message:
|
126
|
+
self.set_result(True)
|
127
|
+
|
128
|
+
@property
|
129
|
+
def order_row(self) -> fxcorepy.O2GOrderRow:
|
130
|
+
return self.__order
|
131
|
+
|
132
|
+
@property
|
133
|
+
def trade_rows(self) -> List[fxcorepy.O2GTradeRow]:
|
134
|
+
return self.__trades
|
135
|
+
|
136
|
+
@property
|
137
|
+
def updated_trade_rows(self) -> List[fxcorepy.O2GTradeRow]:
|
138
|
+
return self.__updated_trades
|
139
|
+
|
140
|
+
@property
|
141
|
+
def closed_trade_rows(self) -> List[fxcorepy.O2GClosedTradeRow]:
|
142
|
+
return self.__closed_trades
|
143
|
+
|
144
|
+
@property
|
145
|
+
def reject_amount(self) -> int:
|
146
|
+
return self.__reject_amount
|
147
|
+
|
148
|
+
@property
|
149
|
+
def reject_message(self) -> str:
|
150
|
+
return self.__reject_message
|
151
|
+
|
152
|
+
@property
|
153
|
+
def result(self) -> ExecutionResult:
|
154
|
+
return self.__result
|
155
|
+
|
156
|
+
@property
|
157
|
+
def is_order_completed(self) -> bool:
|
158
|
+
return self.__result != OrderMonitorNetting.ExecutionResult.EXECUTING
|
159
|
+
|
160
|
+
def check_and_store_message(self, message: fxcorepy.O2GMessageRow) -> bool:
|
161
|
+
feature = message.feature
|
162
|
+
if feature == self.__market_condition:
|
163
|
+
text = message.text
|
164
|
+
if self.__order.order_id in text:
|
165
|
+
self.__reject_message = message.text
|
166
|
+
return True
|
167
|
+
return False
|
168
|
+
|
169
|
+
@property
|
170
|
+
def is_all_trades_received(self) -> bool:
|
171
|
+
if self.__state == OrderMonitorNetting.OrderState.ORDER_EXECUTING:
|
172
|
+
return False
|
173
|
+
i_current_total_amount = 0
|
174
|
+
for trade in self.__trades:
|
175
|
+
i_current_total_amount += trade.amount
|
176
|
+
|
177
|
+
for trade in self.__updated_trades:
|
178
|
+
i_current_total_amount += trade.amount
|
179
|
+
|
180
|
+
for trade in self.__closed_trades:
|
181
|
+
i_current_total_amount += trade.amount
|
182
|
+
|
183
|
+
return abs(i_current_total_amount - self.__initial_amount) == self.__total_amount
|
184
|
+
|
185
|
+
def set_result(self, success: bool) -> None:
|
186
|
+
if success:
|
187
|
+
if self.__reject_amount == 0:
|
188
|
+
self.__result = OrderMonitorNetting.ExecutionResult.EXECUTED
|
189
|
+
else:
|
190
|
+
self.__result = OrderMonitorNetting.ExecutionResult.FULLY_REJECTED \
|
191
|
+
if (len(self.__trades) == 0 and len(self.__closed_trades) == 0) \
|
192
|
+
else OrderMonitorNetting.ExecutionResult.PARTIAL_REJECTED
|
193
|
+
|
194
|
+
else:
|
195
|
+
self.__result = OrderMonitorNetting.ExecutionResult.CANCELED
|