cfquant 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- LTtx/__init__.py +2 -0
- LTtx/tx/Config.txt +8 -0
- LTtx/tx/LTtx_server.py +1177 -0
- LTtx/tx/__init__.py +5 -0
- LTtx/tx/tx.py +1935 -0
- cfquant/__init__.py +26 -0
- cfquant/account_routing.py +119 -0
- cfquant/channels.py +76 -0
- cfquant/cli.py +266 -0
- cfquant/client.py +365 -0
- cfquant/config.py +86 -0
- cfquant/hub.py +304 -0
- cfquant/logging_i18n.py +348 -0
- cfquant/normal_bridge.py +676 -0
- cfquant/pipe_bridge.py +249 -0
- cfquant/pipe_client.py +223 -0
- cfquant/pipe_hub.py +602 -0
- cfquant/pipe_transport.py +493 -0
- cfquant/protocol.py +238 -0
- cfquant/qmt_bridge.py +1081 -0
- cfquant/runtime_report.py +334 -0
- cfquant/tx.py +1898 -0
- cfquant/tx_trade_bridge.py +1905 -0
- cfquant/version.py +5 -0
- cfquant/xtconstant.py +262 -0
- cfquant/xtdata.py +462 -0
- cfquant/xttrader.py +955 -0
- cfquant/xttype.py +586 -0
- cfquant-0.2.0.dist-info/LICENSE +21 -0
- cfquant-0.2.0.dist-info/METADATA +144 -0
- cfquant-0.2.0.dist-info/RECORD +90 -0
- cfquant-0.2.0.dist-info/WHEEL +5 -0
- cfquant-0.2.0.dist-info/entry_points.txt +4 -0
- cfquant-0.2.0.dist-info/top_level.txt +6 -0
- cfquant_pipe_hub.py +45 -0
- cfquant_web_server.py +12137 -0
- qmt_scripts/CFQUANT.py +507 -0
- qmt_scripts/CFQUANT_CTYPE_ALL_LOWLAT.py +830 -0
- qmt_scripts/CFQUANT_LITE.py +4928 -0
- qmt_scripts/CFQUANT_TRADE_LOWLAT.py +382 -0
- qmt_scripts/__init__.py +1 -0
- qmt_scripts//321/205/320/240/320/234/321/210/342/224/244/320/266/321/205/320/237/342/225/226/321/207/320/233/320/274/321/207/320/273/320/233/321/205/342/225/225/320/222/321/205/320/254/342/225/221/CFQUANT_CTYPE_ALL_LOWLAT_SH.py +866 -0
- qmt_scripts//321/205/320/240/320/234/321/210/342/224/244/320/266/321/205/320/237/342/225/226/321/207/320/233/320/274/321/207/320/273/320/233/321/205/342/225/225/320/222/321/205/320/254/342/225/221/CFQUANT_CTYPE_ALL_LOWLAT_SZ.py +866 -0
- qmt_scripts//321/205/320/240/320/234/321/210/342/224/244/320/266/321/205/320/237/342/225/226/321/207/320/233/320/274/321/207/320/273/320/233/321/205/342/225/225/320/222/321/205/320/254/342/225/221/CFQUANT_LITE_SH.py +5020 -0
- qmt_scripts//321/205/320/240/320/234/321/210/342/224/244/320/266/321/205/320/237/342/225/226/321/207/320/233/320/274/321/207/320/273/320/233/321/205/342/225/225/320/222/321/205/320/254/342/225/221/CFQUANT_LITE_SZ.py +5020 -0
- qmt_scripts//321/205/320/240/320/234/321/210/342/224/244/320/266/321/205/320/237/342/225/226/321/207/320/233/320/274/321/207/320/273/320/233/321/205/342/225/225/320/222/321/205/320/254/342/225/221/CFQUANT_TRADE_LOWLAT_SH.py +436 -0
- qmt_scripts//321/205/320/240/320/234/321/210/342/224/244/320/266/321/205/320/237/342/225/226/321/207/320/233/320/274/321/207/320/273/320/233/321/205/342/225/225/320/222/321/205/320/254/342/225/221/CFQUANT_TRADE_LOWLAT_SZ.py +436 -0
- qmt_scripts//321/205/320/240/320/234/321/210/342/224/244/320/266/321/205/320/237/342/225/226/321/207/320/233/320/274/321/207/320/273/320/233/321/205/342/225/225/320/222/321/205/320/254/342/225/221/readme.md +95 -0
- web_dashboard/__init__.py +1 -0
- web_dashboard/app.js +9847 -0
- web_dashboard/avatars/amber-pulse.svg +15 -0
- web_dashboard/avatars/copper-grid.svg +15 -0
- web_dashboard/avatars/market-blue.svg +15 -0
- web_dashboard/avatars/rose-circuit.svg +15 -0
- web_dashboard/avatars/signal-green.svg +15 -0
- web_dashboard/avatars/slate-wave.svg +15 -0
- web_dashboard/avatars/teal-orbit.svg +16 -0
- web_dashboard/avatars/violet-node.svg +15 -0
- web_dashboard/favicon.svg +5 -0
- web_dashboard/image/qmt_deploy/image-10.png +0 -0
- web_dashboard/image/qmt_deploy/image-11.png +0 -0
- web_dashboard/image/qmt_deploy/image-12.png +0 -0
- web_dashboard/image/qmt_deploy/image-13.png +0 -0
- web_dashboard/image/qmt_deploy/image-14.png +0 -0
- web_dashboard/image/qmt_deploy/image-15.png +0 -0
- web_dashboard/image/qmt_deploy/image-16.png +0 -0
- web_dashboard/image/qmt_deploy/image-17.png +0 -0
- web_dashboard/image/qmt_deploy/image-18.png +0 -0
- web_dashboard/image/qmt_deploy/image-19.png +0 -0
- web_dashboard/image/qmt_deploy/image-20.png +0 -0
- web_dashboard/image/qmt_deploy/image-21.png +0 -0
- web_dashboard/image/qmt_deploy/image-4.png +0 -0
- web_dashboard/image/qmt_deploy/image-5.png +0 -0
- web_dashboard/image/qmt_deploy/image-6.png +0 -0
- web_dashboard/image/qmt_deploy/image-7.png +0 -0
- web_dashboard/image/qmt_deploy/image-8.png +0 -0
- web_dashboard/image/qmt_deploy/image-9.png +0 -0
- web_dashboard/image//321/211/320/220/320/252/321/207/320/244/320/270/321/206/320/270/320/261/321/205/342/225/235/320/237/321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/image-1.png +0 -0
- web_dashboard/image//321/211/320/220/320/252/321/207/320/244/320/270/321/206/320/270/320/261/321/205/342/225/235/320/237/321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/image-2.png +0 -0
- web_dashboard/image//321/211/320/220/320/252/321/207/320/244/320/270/321/206/320/270/320/261/321/205/342/225/235/320/237/321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/image-3.png +0 -0
- web_dashboard/image//321/211/320/220/320/252/321/207/320/244/320/270/321/206/320/270/320/261/321/205/342/225/235/320/237/321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/image.png +0 -0
- web_dashboard/image//321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/1783479325179.png +0 -0
- web_dashboard/image//321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/1783479745262.png +0 -0
- web_dashboard/image//321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/1783480178700.png +0 -0
- web_dashboard/image//321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/1783480428759.png +0 -0
- web_dashboard/image//321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/1783489807217.png +0 -0
- web_dashboard/image//321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/1783490503491.png +0 -0
- web_dashboard/index.html +2317 -0
- web_dashboard/styles.css +7817 -0
- web_dashboard/vendor/mermaid.min.js +2029 -0
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
#coding:gbk
|
|
2
|
+
#! /usr/bin/python
|
|
3
|
+
|
|
4
|
+
import os
|
|
5
|
+
import sys
|
|
6
|
+
import importlib
|
|
7
|
+
import io
|
|
8
|
+
import json
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
_trade_bridge = None
|
|
12
|
+
DEFAULT_ACCOUNT_ID = ""
|
|
13
|
+
USER_BRIDGE_ID = "default"
|
|
14
|
+
BRIDGE_ID = os.environ.get("CFQUANT_BRIDGE_ID", USER_BRIDGE_ID)
|
|
15
|
+
RUNTIME_CONFIG = {}
|
|
16
|
+
RUNTIME_CHANNELS = {}
|
|
17
|
+
QMT_MARKET = os.environ.get("CFQUANT_MARKET", "").strip().upper()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _entry_file_path():
|
|
21
|
+
path = globals().get("__file__") or ""
|
|
22
|
+
path = str(path or "").strip()
|
|
23
|
+
if path and not path.startswith("<"):
|
|
24
|
+
try:
|
|
25
|
+
return os.path.abspath(path)
|
|
26
|
+
except Exception:
|
|
27
|
+
return path
|
|
28
|
+
return ""
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _entry_base_dir():
|
|
32
|
+
entry_file = _entry_file_path()
|
|
33
|
+
if entry_file:
|
|
34
|
+
return os.path.dirname(entry_file)
|
|
35
|
+
for name in ("CFQUANT_QMT_SCRIPT_DIR", "CFQUANT_SCRIPT_DIR", "CFQUANT_ENTRY_DIR"):
|
|
36
|
+
path = str(os.environ.get(name) or "").strip()
|
|
37
|
+
if path and os.path.isdir(path):
|
|
38
|
+
return os.path.abspath(path)
|
|
39
|
+
try:
|
|
40
|
+
cwd = os.path.abspath(os.getcwd())
|
|
41
|
+
if (
|
|
42
|
+
os.path.isfile(os.path.join(cwd, "CFQUANT_TRADE_LOWLAT.py"))
|
|
43
|
+
or os.path.isfile(os.path.join(cwd, "cfquant_bridge_config.json"))
|
|
44
|
+
or os.path.isdir(os.path.join(cwd, "cfquant"))
|
|
45
|
+
):
|
|
46
|
+
return cwd
|
|
47
|
+
except Exception:
|
|
48
|
+
pass
|
|
49
|
+
for path in sys.path:
|
|
50
|
+
path = str(path or "").strip()
|
|
51
|
+
if path and os.path.isdir(path):
|
|
52
|
+
base = os.path.abspath(path)
|
|
53
|
+
if (
|
|
54
|
+
os.path.isfile(os.path.join(base, "CFQUANT_TRADE_LOWLAT.py"))
|
|
55
|
+
or os.path.isfile(os.path.join(base, "cfquant_bridge_config.json"))
|
|
56
|
+
or os.path.isdir(os.path.join(base, "cfquant"))
|
|
57
|
+
):
|
|
58
|
+
return base
|
|
59
|
+
try:
|
|
60
|
+
return os.path.abspath(os.getcwd())
|
|
61
|
+
except Exception:
|
|
62
|
+
return ""
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _runtime_config_paths():
|
|
66
|
+
try:
|
|
67
|
+
base_dir = _entry_base_dir()
|
|
68
|
+
parent_dir = os.path.dirname(base_dir)
|
|
69
|
+
candidates = []
|
|
70
|
+
env_path = os.environ.get("CFQUANT_BRIDGE_CONFIG_FILE")
|
|
71
|
+
if env_path:
|
|
72
|
+
candidates.append(env_path)
|
|
73
|
+
market = str(os.environ.get("CFQUANT_MARKET") or QMT_MARKET or "").strip().upper()
|
|
74
|
+
market_filenames = []
|
|
75
|
+
if market in ("SH", "SZ"):
|
|
76
|
+
market_filenames.append("cfquant_bridge_config_%s.json" % market)
|
|
77
|
+
if os.path.basename(base_dir).lower() == "python":
|
|
78
|
+
for filename in market_filenames:
|
|
79
|
+
candidates.append(os.path.join(parent_dir, "bin.x64", filename))
|
|
80
|
+
candidates.append(os.path.join(base_dir, filename))
|
|
81
|
+
candidates.append(os.path.join(parent_dir, "bin.x64", "cfquant_bridge_config.json"))
|
|
82
|
+
candidates.append(os.path.join(base_dir, "cfquant_bridge_config.json"))
|
|
83
|
+
else:
|
|
84
|
+
for filename in market_filenames:
|
|
85
|
+
candidates.append(os.path.join(base_dir, filename))
|
|
86
|
+
candidates.append(os.path.join(base_dir, "bin.x64", filename))
|
|
87
|
+
candidates.append(os.path.join(base_dir, "cfquant_bridge_config.json"))
|
|
88
|
+
candidates.append(os.path.join(base_dir, "bin.x64", "cfquant_bridge_config.json"))
|
|
89
|
+
for filename in market_filenames:
|
|
90
|
+
candidates.append(os.path.join(parent_dir, filename))
|
|
91
|
+
candidates.append(os.path.join(parent_dir, "cfquant_bridge_config.json"))
|
|
92
|
+
result = []
|
|
93
|
+
seen = set()
|
|
94
|
+
for path in candidates:
|
|
95
|
+
if not path:
|
|
96
|
+
continue
|
|
97
|
+
path = os.path.abspath(os.path.expandvars(os.path.expanduser(path)))
|
|
98
|
+
key = os.path.normcase(path)
|
|
99
|
+
if key in seen:
|
|
100
|
+
continue
|
|
101
|
+
seen.add(key)
|
|
102
|
+
result.append(path)
|
|
103
|
+
return result
|
|
104
|
+
except Exception:
|
|
105
|
+
return []
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def _load_runtime_config():
|
|
109
|
+
for path in _runtime_config_paths():
|
|
110
|
+
if not os.path.isfile(path):
|
|
111
|
+
continue
|
|
112
|
+
for opener in (
|
|
113
|
+
lambda: io.open(path, "r", encoding="utf-8"),
|
|
114
|
+
lambda: open(path, "r"),
|
|
115
|
+
):
|
|
116
|
+
try:
|
|
117
|
+
with opener() as f:
|
|
118
|
+
data = json.loads(f.read())
|
|
119
|
+
if isinstance(data, dict):
|
|
120
|
+
return data
|
|
121
|
+
except Exception:
|
|
122
|
+
pass
|
|
123
|
+
return {}
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def _config_bool(value, default=True):
|
|
127
|
+
if isinstance(value, bool):
|
|
128
|
+
return value
|
|
129
|
+
if value is None:
|
|
130
|
+
return default
|
|
131
|
+
text = str(value).strip().lower()
|
|
132
|
+
if text in ("0", "false", "no", "off", "disable", "disabled", "closed", "close"):
|
|
133
|
+
return False
|
|
134
|
+
if text in ("1", "true", "yes", "on", "enable", "enabled", "open"):
|
|
135
|
+
return True
|
|
136
|
+
return default
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def _env_allows_runtime_override(name, default_value=""):
|
|
140
|
+
value = str(os.environ.get(name) or "").strip()
|
|
141
|
+
if not value:
|
|
142
|
+
return True
|
|
143
|
+
if str(os.environ.get("%s_SOURCE" % name) or "").strip() == "cfquant_entry":
|
|
144
|
+
return True
|
|
145
|
+
return bool(default_value and value == default_value)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def _apply_runtime_config():
|
|
149
|
+
global BRIDGE_ID, RUNTIME_CONFIG, RUNTIME_CHANNELS, QMT_MARKET
|
|
150
|
+
|
|
151
|
+
data = _load_runtime_config()
|
|
152
|
+
RUNTIME_CONFIG = data
|
|
153
|
+
if not data:
|
|
154
|
+
return
|
|
155
|
+
if data.get("bridge_id") and _env_allows_runtime_override("CFQUANT_BRIDGE_ID", USER_BRIDGE_ID):
|
|
156
|
+
BRIDGE_ID = data.get("bridge_id")
|
|
157
|
+
if data.get("market"):
|
|
158
|
+
market = str(data.get("market") or "").strip().upper()
|
|
159
|
+
if market in ("SH", "SZ"):
|
|
160
|
+
QMT_MARKET = market
|
|
161
|
+
if not os.environ.get("CFQUANT_MARKET"):
|
|
162
|
+
os.environ["CFQUANT_MARKET"] = market
|
|
163
|
+
os.environ["CFQUANT_MARKET_SOURCE"] = "cfquant_entry"
|
|
164
|
+
channels = data.get("channels") or {}
|
|
165
|
+
if isinstance(channels, dict):
|
|
166
|
+
RUNTIME_CHANNELS = channels
|
|
167
|
+
if not os.environ.get("CFQUANT_QMT_LOG_LANGUAGE") and data.get("qmt_log_language"):
|
|
168
|
+
os.environ["CFQUANT_QMT_LOG_LANGUAGE"] = str(data.get("qmt_log_language") or "zh")
|
|
169
|
+
if not os.environ.get("CFQUANT_QMT_LOG_ENABLED") and "qmt_log_enabled" in data:
|
|
170
|
+
os.environ["CFQUANT_QMT_LOG_ENABLED"] = "1" if _config_bool(data.get("qmt_log_enabled"), True) else "0"
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def _ensure_path():
|
|
174
|
+
try:
|
|
175
|
+
base_dir = _entry_base_dir()
|
|
176
|
+
parent_dir = os.path.dirname(base_dir)
|
|
177
|
+
env_paths = [p for p in os.environ.get("CFQUANT_PYTHONPATH", "").split(os.pathsep) if p]
|
|
178
|
+
if os.path.basename(base_dir).lower() == "python":
|
|
179
|
+
candidates = env_paths + [os.path.join(parent_dir, "bin.x64"), base_dir, parent_dir]
|
|
180
|
+
else:
|
|
181
|
+
candidates = env_paths + [
|
|
182
|
+
base_dir,
|
|
183
|
+
os.path.join(base_dir, "bin.x64"),
|
|
184
|
+
parent_dir,
|
|
185
|
+
os.path.join(parent_dir, "bin.x64"),
|
|
186
|
+
os.path.join(parent_dir, "python"),
|
|
187
|
+
]
|
|
188
|
+
ordered = []
|
|
189
|
+
seen = set()
|
|
190
|
+
for path in candidates:
|
|
191
|
+
if not path or not os.path.isdir(path):
|
|
192
|
+
continue
|
|
193
|
+
path = os.path.abspath(path)
|
|
194
|
+
key = os.path.normcase(path)
|
|
195
|
+
if key in seen:
|
|
196
|
+
continue
|
|
197
|
+
seen.add(key)
|
|
198
|
+
ordered.append(path)
|
|
199
|
+
if ordered:
|
|
200
|
+
sys.path[:] = ordered + [
|
|
201
|
+
path for path in sys.path
|
|
202
|
+
if os.path.normcase(os.path.abspath(path or os.curdir)) not in seen
|
|
203
|
+
]
|
|
204
|
+
except Exception:
|
|
205
|
+
pass
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def _install_logging_compat():
|
|
209
|
+
"""Keep this entry compatible with older cfquant packages in QMT."""
|
|
210
|
+
logging_module = importlib.import_module("cfquant.logging_i18n")
|
|
211
|
+
|
|
212
|
+
if not hasattr(logging_module, "normalize_log_language"):
|
|
213
|
+
def _normalize_log_language(value=None):
|
|
214
|
+
value = str(value or "").strip().lower()
|
|
215
|
+
return "en" if value in ("en", "english") else "zh"
|
|
216
|
+
|
|
217
|
+
logging_module.normalize_log_language = _normalize_log_language
|
|
218
|
+
|
|
219
|
+
if not hasattr(logging_module, "normalize_log_enabled"):
|
|
220
|
+
def _normalize_log_enabled(value=None):
|
|
221
|
+
if isinstance(value, bool):
|
|
222
|
+
return value
|
|
223
|
+
if value is None:
|
|
224
|
+
return True
|
|
225
|
+
text = str(value).strip().lower()
|
|
226
|
+
return text not in ("0", "false", "no", "off", "disable", "disabled", "closed", "close")
|
|
227
|
+
|
|
228
|
+
logging_module.normalize_log_enabled = _normalize_log_enabled
|
|
229
|
+
|
|
230
|
+
if not hasattr(logging_module, "_CFQUANT_COMPAT_LOG_LANGUAGE"):
|
|
231
|
+
logging_module._CFQUANT_COMPAT_LOG_LANGUAGE = ""
|
|
232
|
+
if not hasattr(logging_module, "_CFQUANT_COMPAT_LOG_ENABLED"):
|
|
233
|
+
logging_module._CFQUANT_COMPAT_LOG_ENABLED = None
|
|
234
|
+
|
|
235
|
+
if not hasattr(logging_module, "get_log_language"):
|
|
236
|
+
def _get_log_language():
|
|
237
|
+
if logging_module._CFQUANT_COMPAT_LOG_LANGUAGE:
|
|
238
|
+
return logging_module._CFQUANT_COMPAT_LOG_LANGUAGE
|
|
239
|
+
return logging_module.normalize_log_language(
|
|
240
|
+
os.environ.get("CFQUANT_QMT_LOG_LANGUAGE")
|
|
241
|
+
or os.environ.get("CFQUANT_LOG_LANGUAGE")
|
|
242
|
+
or "zh"
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
logging_module.get_log_language = _get_log_language
|
|
246
|
+
|
|
247
|
+
if not hasattr(logging_module, "set_log_language"):
|
|
248
|
+
def _set_log_language(value):
|
|
249
|
+
language = logging_module.normalize_log_language(value)
|
|
250
|
+
logging_module._CFQUANT_COMPAT_LOG_LANGUAGE = language
|
|
251
|
+
return language
|
|
252
|
+
|
|
253
|
+
logging_module.set_log_language = _set_log_language
|
|
254
|
+
|
|
255
|
+
if not hasattr(logging_module, "get_log_enabled"):
|
|
256
|
+
def _get_log_enabled():
|
|
257
|
+
if logging_module._CFQUANT_COMPAT_LOG_ENABLED is not None:
|
|
258
|
+
return bool(logging_module._CFQUANT_COMPAT_LOG_ENABLED)
|
|
259
|
+
return logging_module.normalize_log_enabled(
|
|
260
|
+
os.environ.get("CFQUANT_QMT_LOG_ENABLED")
|
|
261
|
+
or os.environ.get("CFQUANT_LOG_ENABLED")
|
|
262
|
+
or "1"
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
logging_module.get_log_enabled = _get_log_enabled
|
|
266
|
+
|
|
267
|
+
if not hasattr(logging_module, "set_log_enabled"):
|
|
268
|
+
def _set_log_enabled(value):
|
|
269
|
+
enabled = logging_module.normalize_log_enabled(value)
|
|
270
|
+
logging_module._CFQUANT_COMPAT_LOG_ENABLED = enabled
|
|
271
|
+
return enabled
|
|
272
|
+
|
|
273
|
+
logging_module.set_log_enabled = _set_log_enabled
|
|
274
|
+
|
|
275
|
+
if not hasattr(logging_module, "translate_log"):
|
|
276
|
+
def _translate_log(message, language=None):
|
|
277
|
+
return str(message)
|
|
278
|
+
|
|
279
|
+
logging_module.translate_log = _translate_log
|
|
280
|
+
|
|
281
|
+
return logging_module
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
_ensure_path()
|
|
285
|
+
_apply_runtime_config()
|
|
286
|
+
|
|
287
|
+
_logging_i18n = _install_logging_compat()
|
|
288
|
+
get_log_enabled = _logging_i18n.get_log_enabled
|
|
289
|
+
translate_log = _logging_i18n.translate_log
|
|
290
|
+
|
|
291
|
+
from cfquant import __version__ as _ENTRY_VERSION
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
def _print_log(message):
|
|
295
|
+
if get_log_enabled():
|
|
296
|
+
print(translate_log(message))
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
def _load_bridge_starter():
|
|
300
|
+
import cfquant.tx_trade_bridge as tx_trade_bridge
|
|
301
|
+
|
|
302
|
+
try:
|
|
303
|
+
tx_trade_bridge = importlib.reload(tx_trade_bridge)
|
|
304
|
+
except Exception as e:
|
|
305
|
+
_print_log("tx trade bridge reload failed:%s" % e)
|
|
306
|
+
return tx_trade_bridge.start_tx_trade_bridge
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
start_tx_trade_bridge = _load_bridge_starter()
|
|
310
|
+
|
|
311
|
+
from cfquant.channels import channels_for_bridge, normalize_bridge_id
|
|
312
|
+
|
|
313
|
+
BRIDGE_ID = normalize_bridge_id(BRIDGE_ID)
|
|
314
|
+
QMT_MARKET = str(QMT_MARKET or os.environ.get("CFQUANT_MARKET") or RUNTIME_CONFIG.get("market") or "").strip().upper()
|
|
315
|
+
if QMT_MARKET not in ("SH", "SZ"):
|
|
316
|
+
QMT_MARKET = ""
|
|
317
|
+
if not os.environ.get("CFQUANT_BRIDGE_ID"):
|
|
318
|
+
os.environ["CFQUANT_BRIDGE_ID"] = BRIDGE_ID
|
|
319
|
+
os.environ["CFQUANT_BRIDGE_ID_SOURCE"] = "cfquant_entry"
|
|
320
|
+
if QMT_MARKET and not os.environ.get("CFQUANT_MARKET"):
|
|
321
|
+
os.environ["CFQUANT_MARKET"] = QMT_MARKET
|
|
322
|
+
os.environ["CFQUANT_MARKET_SOURCE"] = "cfquant_entry"
|
|
323
|
+
BRIDGE_CHANNELS = channels_for_bridge(BRIDGE_ID)
|
|
324
|
+
_trade_channel_value = RUNTIME_CHANNELS.get("trade") or RUNTIME_CONFIG.get("trade_channel")
|
|
325
|
+
if _trade_channel_value:
|
|
326
|
+
BRIDGE_CHANNELS["trade"] = str(_trade_channel_value).strip()
|
|
327
|
+
|
|
328
|
+
_trade_bridge = start_tx_trade_bridge(
|
|
329
|
+
None,
|
|
330
|
+
ip="127.0.0.1",
|
|
331
|
+
port=2049,
|
|
332
|
+
token="LTtx",
|
|
333
|
+
request_channel=BRIDGE_CHANNELS["trade"],
|
|
334
|
+
bridge_id=BRIDGE_ID,
|
|
335
|
+
account_id=DEFAULT_ACCOUNT_ID,
|
|
336
|
+
show=True,
|
|
337
|
+
)
|
|
338
|
+
_print_log("cfquant lowlat trade bridge module loaded")
|
|
339
|
+
_print_log("cfquant lowlat entry version:%s" % _ENTRY_VERSION)
|
|
340
|
+
_print_log("cfquant bridge id:%s trade_channel:%s" % (BRIDGE_ID, BRIDGE_CHANNELS["trade"]))
|
|
341
|
+
if QMT_MARKET:
|
|
342
|
+
_print_log("cfquant lowlat market route market:%s bridge_id:%s" % (QMT_MARKET, BRIDGE_ID))
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
def _attach_trade_status_extra():
|
|
346
|
+
if not _trade_bridge:
|
|
347
|
+
return
|
|
348
|
+
original_status_extra = _trade_bridge._status_extra
|
|
349
|
+
|
|
350
|
+
def status_extra_with_market():
|
|
351
|
+
data = original_status_extra()
|
|
352
|
+
data.update({
|
|
353
|
+
"qmt_runtime_market": QMT_MARKET,
|
|
354
|
+
"qmt_runtime_market_role": RUNTIME_CONFIG.get("market_role") or ("trade" if QMT_MARKET else ""),
|
|
355
|
+
"qmt_runtime_market_parent_bridge_id": RUNTIME_CONFIG.get("market_route_parent_bridge_id") or "",
|
|
356
|
+
})
|
|
357
|
+
return data
|
|
358
|
+
|
|
359
|
+
_trade_bridge._status_extra = status_extra_with_market
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
_attach_trade_status_extra()
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
def init(ContextInfo):
|
|
366
|
+
if _trade_bridge:
|
|
367
|
+
_trade_bridge.set_context(ContextInfo)
|
|
368
|
+
_print_log("cfquant lowlat trade context ready version:%s" % _ENTRY_VERSION)
|
|
369
|
+
_trade_bridge.run_forever(sleep_seconds=0.001)
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
def handlebar(ContextInfo):
|
|
373
|
+
pass
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
def stop(ContextInfo):
|
|
377
|
+
global _trade_bridge
|
|
378
|
+
|
|
379
|
+
if _trade_bridge:
|
|
380
|
+
_trade_bridge.close()
|
|
381
|
+
_trade_bridge = None
|
|
382
|
+
_print_log("cfquant lowlat trade bridge stopped")
|
qmt_scripts/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""QMT-side entry scripts distributed with cfquant."""
|