cnhkmcp 1.1.5__tar.gz → 1.1.7__tar.gz
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.
- {cnhkmcp-1.1.5/cnhkmcp.egg-info → cnhkmcp-1.1.7}/PKG-INFO +1 -1
- {cnhkmcp-1.1.5 → cnhkmcp-1.1.7}/cnhkmcp/__init__.py +124 -124
- {cnhkmcp-1.1.5 → cnhkmcp-1.1.7}/cnhkmcp/untracked/platform_functions.py +147 -16
- {cnhkmcp-1.1.5 → cnhkmcp-1.1.7/cnhkmcp.egg-info}/PKG-INFO +1 -1
- {cnhkmcp-1.1.5 → cnhkmcp-1.1.7}/setup.py +63 -63
- {cnhkmcp-1.1.5 → cnhkmcp-1.1.7}/LICENSE +0 -0
- {cnhkmcp-1.1.5 → cnhkmcp-1.1.7}/MANIFEST.in +0 -0
- {cnhkmcp-1.1.5 → cnhkmcp-1.1.7}/README.md +0 -0
- {cnhkmcp-1.1.5 → cnhkmcp-1.1.7}/cnhkmcp/untracked/forum_functions.py +0 -0
- {cnhkmcp-1.1.5 → cnhkmcp-1.1.7}/cnhkmcp/untracked/user_config.json +0 -0
- {cnhkmcp-1.1.5 → cnhkmcp-1.1.7}/cnhkmcp.egg-info/SOURCES.txt +0 -0
- {cnhkmcp-1.1.5 → cnhkmcp-1.1.7}/cnhkmcp.egg-info/dependency_links.txt +0 -0
- {cnhkmcp-1.1.5 → cnhkmcp-1.1.7}/cnhkmcp.egg-info/entry_points.txt +0 -0
- {cnhkmcp-1.1.5 → cnhkmcp-1.1.7}/cnhkmcp.egg-info/not-zip-safe +0 -0
- {cnhkmcp-1.1.5 → cnhkmcp-1.1.7}/cnhkmcp.egg-info/requires.txt +0 -0
- {cnhkmcp-1.1.5 → cnhkmcp-1.1.7}/cnhkmcp.egg-info/top_level.txt +0 -0
- {cnhkmcp-1.1.5 → cnhkmcp-1.1.7}/requirements.txt +0 -0
- {cnhkmcp-1.1.5 → cnhkmcp-1.1.7}/setup.cfg +0 -0
|
@@ -1,125 +1,125 @@
|
|
|
1
|
-
"""
|
|
2
|
-
CNHK MCP Server - A comprehensive Model Context Protocol server for quantitative trading platform integration.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from .untracked.platform_functions import (
|
|
6
|
-
BrainApiClient,
|
|
7
|
-
authenticate,
|
|
8
|
-
create_simulation,
|
|
9
|
-
get_simulation_status,
|
|
10
|
-
wait_for_simulation,
|
|
11
|
-
get_alpha_details,
|
|
12
|
-
get_datasets,
|
|
13
|
-
get_datafields,
|
|
14
|
-
get_alpha_pnl,
|
|
15
|
-
get_user_alphas,
|
|
16
|
-
submit_alpha,
|
|
17
|
-
get_events,
|
|
18
|
-
get_leaderboard,
|
|
19
|
-
batch_process_alphas,
|
|
20
|
-
analyze_alpha_performance,
|
|
21
|
-
get_operators,
|
|
22
|
-
run_selection,
|
|
23
|
-
get_user_profile,
|
|
24
|
-
get_tutorials,
|
|
25
|
-
get_messages_summary,
|
|
26
|
-
get_messages,
|
|
27
|
-
get_alpha_record_sets,
|
|
28
|
-
check_production_correlation,
|
|
29
|
-
check_self_correlation,
|
|
30
|
-
get_submission_check,
|
|
31
|
-
set_alpha_properties,
|
|
32
|
-
get_user_activities,
|
|
33
|
-
get_pyramid_multipliers,
|
|
34
|
-
get_pyramid_alphas,
|
|
35
|
-
get_user_competitions,
|
|
36
|
-
get_competition_details,
|
|
37
|
-
get_competition_agreement,
|
|
38
|
-
get_instrument_options,
|
|
39
|
-
performance_comparison,
|
|
40
|
-
combine_test_results,
|
|
41
|
-
generate_alpha_links,
|
|
42
|
-
get_tutorial_page,
|
|
43
|
-
get_tutorial_badge_status
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
from .untracked.forum_functions import (
|
|
47
|
-
ForumClient,
|
|
48
|
-
get_glossary_terms,
|
|
49
|
-
search_forum_posts,
|
|
50
|
-
read_full_forum_post
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
__version__ = "1.1.
|
|
54
|
-
__author__ = "CNHK"
|
|
55
|
-
__email__ = "cnhk@example.com"
|
|
56
|
-
|
|
57
|
-
__all__ = [
|
|
58
|
-
# Main API client
|
|
59
|
-
"BrainApiClient",
|
|
60
|
-
|
|
61
|
-
# Authentication
|
|
62
|
-
"authenticate",
|
|
63
|
-
|
|
64
|
-
# Simulation management
|
|
65
|
-
"create_simulation",
|
|
66
|
-
"get_simulation_status",
|
|
67
|
-
"wait_for_simulation",
|
|
68
|
-
|
|
69
|
-
# Alpha management
|
|
70
|
-
"get_alpha_details",
|
|
71
|
-
"submit_alpha",
|
|
72
|
-
"get_user_alphas",
|
|
73
|
-
"get_alpha_pnl",
|
|
74
|
-
"get_alpha_record_sets",
|
|
75
|
-
"set_alpha_properties",
|
|
76
|
-
"check_production_correlation",
|
|
77
|
-
"check_self_correlation",
|
|
78
|
-
"get_submission_check",
|
|
79
|
-
|
|
80
|
-
# Data access
|
|
81
|
-
"get_datasets",
|
|
82
|
-
"get_datafields",
|
|
83
|
-
"get_operators",
|
|
84
|
-
"run_selection",
|
|
85
|
-
"get_instrument_options",
|
|
86
|
-
|
|
87
|
-
# Performance analysis
|
|
88
|
-
"analyze_alpha_performance",
|
|
89
|
-
"performance_comparison",
|
|
90
|
-
"combine_test_results",
|
|
91
|
-
|
|
92
|
-
# User management
|
|
93
|
-
"get_user_profile",
|
|
94
|
-
"get_user_activities",
|
|
95
|
-
"get_user_competitions",
|
|
96
|
-
|
|
97
|
-
# Competition and events
|
|
98
|
-
"get_events",
|
|
99
|
-
"get_leaderboard",
|
|
100
|
-
"get_competition_details",
|
|
101
|
-
"get_competition_agreement",
|
|
102
|
-
|
|
103
|
-
# Pyramid system
|
|
104
|
-
"get_pyramid_multipliers",
|
|
105
|
-
"get_pyramid_alphas",
|
|
106
|
-
|
|
107
|
-
# Tutorials and documentation
|
|
108
|
-
"get_tutorials",
|
|
109
|
-
"get_tutorial_page",
|
|
110
|
-
"get_tutorial_badge_status",
|
|
111
|
-
|
|
112
|
-
# Messages
|
|
113
|
-
"get_messages_summary",
|
|
114
|
-
"get_messages",
|
|
115
|
-
|
|
116
|
-
# Utilities
|
|
117
|
-
"batch_process_alphas",
|
|
118
|
-
"generate_alpha_links",
|
|
119
|
-
|
|
120
|
-
# Forum functionality
|
|
121
|
-
"ForumClient",
|
|
122
|
-
"get_glossary_terms",
|
|
123
|
-
"search_forum_posts",
|
|
124
|
-
"read_full_forum_post"
|
|
1
|
+
"""
|
|
2
|
+
CNHK MCP Server - A comprehensive Model Context Protocol server for quantitative trading platform integration.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from .untracked.platform_functions import (
|
|
6
|
+
BrainApiClient,
|
|
7
|
+
authenticate,
|
|
8
|
+
create_simulation,
|
|
9
|
+
get_simulation_status,
|
|
10
|
+
wait_for_simulation,
|
|
11
|
+
get_alpha_details,
|
|
12
|
+
get_datasets,
|
|
13
|
+
get_datafields,
|
|
14
|
+
get_alpha_pnl,
|
|
15
|
+
get_user_alphas,
|
|
16
|
+
submit_alpha,
|
|
17
|
+
get_events,
|
|
18
|
+
get_leaderboard,
|
|
19
|
+
batch_process_alphas,
|
|
20
|
+
analyze_alpha_performance,
|
|
21
|
+
get_operators,
|
|
22
|
+
run_selection,
|
|
23
|
+
get_user_profile,
|
|
24
|
+
get_tutorials,
|
|
25
|
+
get_messages_summary,
|
|
26
|
+
get_messages,
|
|
27
|
+
get_alpha_record_sets,
|
|
28
|
+
check_production_correlation,
|
|
29
|
+
check_self_correlation,
|
|
30
|
+
get_submission_check,
|
|
31
|
+
set_alpha_properties,
|
|
32
|
+
get_user_activities,
|
|
33
|
+
get_pyramid_multipliers,
|
|
34
|
+
get_pyramid_alphas,
|
|
35
|
+
get_user_competitions,
|
|
36
|
+
get_competition_details,
|
|
37
|
+
get_competition_agreement,
|
|
38
|
+
get_instrument_options,
|
|
39
|
+
performance_comparison,
|
|
40
|
+
combine_test_results,
|
|
41
|
+
generate_alpha_links,
|
|
42
|
+
get_tutorial_page,
|
|
43
|
+
get_tutorial_badge_status
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
from .untracked.forum_functions import (
|
|
47
|
+
ForumClient,
|
|
48
|
+
get_glossary_terms,
|
|
49
|
+
search_forum_posts,
|
|
50
|
+
read_full_forum_post
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
__version__ = "1.1.7"
|
|
54
|
+
__author__ = "CNHK"
|
|
55
|
+
__email__ = "cnhk@example.com"
|
|
56
|
+
|
|
57
|
+
__all__ = [
|
|
58
|
+
# Main API client
|
|
59
|
+
"BrainApiClient",
|
|
60
|
+
|
|
61
|
+
# Authentication
|
|
62
|
+
"authenticate",
|
|
63
|
+
|
|
64
|
+
# Simulation management
|
|
65
|
+
"create_simulation",
|
|
66
|
+
"get_simulation_status",
|
|
67
|
+
"wait_for_simulation",
|
|
68
|
+
|
|
69
|
+
# Alpha management
|
|
70
|
+
"get_alpha_details",
|
|
71
|
+
"submit_alpha",
|
|
72
|
+
"get_user_alphas",
|
|
73
|
+
"get_alpha_pnl",
|
|
74
|
+
"get_alpha_record_sets",
|
|
75
|
+
"set_alpha_properties",
|
|
76
|
+
"check_production_correlation",
|
|
77
|
+
"check_self_correlation",
|
|
78
|
+
"get_submission_check",
|
|
79
|
+
|
|
80
|
+
# Data access
|
|
81
|
+
"get_datasets",
|
|
82
|
+
"get_datafields",
|
|
83
|
+
"get_operators",
|
|
84
|
+
"run_selection",
|
|
85
|
+
"get_instrument_options",
|
|
86
|
+
|
|
87
|
+
# Performance analysis
|
|
88
|
+
"analyze_alpha_performance",
|
|
89
|
+
"performance_comparison",
|
|
90
|
+
"combine_test_results",
|
|
91
|
+
|
|
92
|
+
# User management
|
|
93
|
+
"get_user_profile",
|
|
94
|
+
"get_user_activities",
|
|
95
|
+
"get_user_competitions",
|
|
96
|
+
|
|
97
|
+
# Competition and events
|
|
98
|
+
"get_events",
|
|
99
|
+
"get_leaderboard",
|
|
100
|
+
"get_competition_details",
|
|
101
|
+
"get_competition_agreement",
|
|
102
|
+
|
|
103
|
+
# Pyramid system
|
|
104
|
+
"get_pyramid_multipliers",
|
|
105
|
+
"get_pyramid_alphas",
|
|
106
|
+
|
|
107
|
+
# Tutorials and documentation
|
|
108
|
+
"get_tutorials",
|
|
109
|
+
"get_tutorial_page",
|
|
110
|
+
"get_tutorial_badge_status",
|
|
111
|
+
|
|
112
|
+
# Messages
|
|
113
|
+
"get_messages_summary",
|
|
114
|
+
"get_messages",
|
|
115
|
+
|
|
116
|
+
# Utilities
|
|
117
|
+
"batch_process_alphas",
|
|
118
|
+
"generate_alpha_links",
|
|
119
|
+
|
|
120
|
+
# Forum functionality
|
|
121
|
+
"ForumClient",
|
|
122
|
+
"get_glossary_terms",
|
|
123
|
+
"search_forum_posts",
|
|
124
|
+
"read_full_forum_post"
|
|
125
125
|
]
|
|
@@ -81,8 +81,8 @@ class BrainApiClient:
|
|
|
81
81
|
print(f"[{level}] {message}", file=sys.stderr)
|
|
82
82
|
|
|
83
83
|
async def authenticate(self, email: str, password: str) -> Dict[str, Any]:
|
|
84
|
-
"""Authenticate with WorldQuant BRAIN platform
|
|
85
|
-
self.log("🔐 Starting
|
|
84
|
+
"""Authenticate with WorldQuant BRAIN platform with biometric support."""
|
|
85
|
+
self.log("🔐 Starting Authentication process...", "INFO")
|
|
86
86
|
|
|
87
87
|
try:
|
|
88
88
|
# Store credentials for potential re-authentication
|
|
@@ -106,7 +106,7 @@ class BrainApiClient:
|
|
|
106
106
|
|
|
107
107
|
# Check for successful authentication (status code 201)
|
|
108
108
|
if response.status_code == 201:
|
|
109
|
-
self.log("✅
|
|
109
|
+
self.log("✅ Authentication successful", "SUCCESS")
|
|
110
110
|
|
|
111
111
|
# Check if JWT token was automatically stored by session
|
|
112
112
|
jwt_token = self.session.cookies.get('t')
|
|
@@ -120,10 +120,26 @@ class BrainApiClient:
|
|
|
120
120
|
'user': {'email': email},
|
|
121
121
|
'status': 'authenticated',
|
|
122
122
|
'permissions': ['read', 'write'],
|
|
123
|
-
'message': '
|
|
123
|
+
'message': 'Authentication successful',
|
|
124
124
|
'status_code': response.status_code,
|
|
125
125
|
'has_jwt': jwt_token is not None
|
|
126
126
|
}
|
|
127
|
+
|
|
128
|
+
# Check if biometric authentication is required (401 with persona)
|
|
129
|
+
elif response.status_code == 401:
|
|
130
|
+
www_auth = response.headers.get("WWW-Authenticate")
|
|
131
|
+
location = response.headers.get("Location")
|
|
132
|
+
|
|
133
|
+
if www_auth == "persona" and location:
|
|
134
|
+
self.log("🔴 Biometric authentication required", "INFO")
|
|
135
|
+
|
|
136
|
+
# Handle biometric authentication
|
|
137
|
+
from urllib.parse import urljoin
|
|
138
|
+
biometric_url = urljoin(response.url, location)
|
|
139
|
+
|
|
140
|
+
return await self._handle_biometric_auth(biometric_url, email)
|
|
141
|
+
else:
|
|
142
|
+
raise Exception("Incorrect email or password")
|
|
127
143
|
else:
|
|
128
144
|
raise Exception(f"Authentication failed with status code: {response.status_code}")
|
|
129
145
|
|
|
@@ -134,6 +150,97 @@ class BrainApiClient:
|
|
|
134
150
|
self.log(f"❌ Authentication failed: {str(e)}", "ERROR")
|
|
135
151
|
raise
|
|
136
152
|
|
|
153
|
+
async def _handle_biometric_auth(self, biometric_url: str, email: str) -> Dict[str, Any]:
|
|
154
|
+
"""Handle biometric authentication using browser automation."""
|
|
155
|
+
self.log("🌐 Starting biometric authentication...", "INFO")
|
|
156
|
+
|
|
157
|
+
try:
|
|
158
|
+
# Import selenium for browser automation
|
|
159
|
+
from selenium import webdriver
|
|
160
|
+
from selenium.webdriver.chrome.options import Options
|
|
161
|
+
import time
|
|
162
|
+
|
|
163
|
+
# Setup Chrome options
|
|
164
|
+
options = Options()
|
|
165
|
+
options.add_argument('--no-sandbox')
|
|
166
|
+
options.add_argument('--disable-dev-shm-usage')
|
|
167
|
+
|
|
168
|
+
driver = None
|
|
169
|
+
try:
|
|
170
|
+
# Open browser with timeout
|
|
171
|
+
driver = webdriver.Chrome(options=options)
|
|
172
|
+
# Set a short timeout so it doesn't wait forever
|
|
173
|
+
driver.set_page_load_timeout(80) # Only wait 5 seconds
|
|
174
|
+
|
|
175
|
+
self.log("🌐 Opening browser for biometric authentication...", "INFO")
|
|
176
|
+
|
|
177
|
+
# Try to open the URL but handle timeout
|
|
178
|
+
try:
|
|
179
|
+
driver.get(biometric_url)
|
|
180
|
+
self.log("✅ Browser page loaded successfully", "SUCCESS")
|
|
181
|
+
except Exception as timeout_error:
|
|
182
|
+
self.log(f"⚠️ Page load timeout (expected): {str(timeout_error)[:50]}...", "WARNING")
|
|
183
|
+
self.log("✅ Browser window is open for biometric authentication", "INFO")
|
|
184
|
+
|
|
185
|
+
# Print instructions
|
|
186
|
+
print("\n" + "="*60, file=sys.stderr)
|
|
187
|
+
print("🔒 BIOMETRIC AUTHENTICATION REQUIRED", file=sys.stderr)
|
|
188
|
+
print("="*60, file=sys.stderr)
|
|
189
|
+
print("🌐 Browser window is open with biometric authentication page", file=sys.stderr)
|
|
190
|
+
print("🔧 Complete the biometric authentication in the browser", file=sys.stderr)
|
|
191
|
+
print("⏳ The system will automatically check when you're done...", file=sys.stderr)
|
|
192
|
+
print("="*60, file=sys.stderr)
|
|
193
|
+
|
|
194
|
+
# Keep checking until authentication is complete
|
|
195
|
+
max_attempts = 60 # 5 minutes maximum (60 * 5 seconds)
|
|
196
|
+
attempt = 0
|
|
197
|
+
|
|
198
|
+
while attempt < max_attempts:
|
|
199
|
+
time.sleep(5) # Check every 5 seconds
|
|
200
|
+
attempt += 1
|
|
201
|
+
|
|
202
|
+
# Check if authentication completed
|
|
203
|
+
check_response = self.session.post(biometric_url)
|
|
204
|
+
self.log(f"🔄 Checking authentication status (attempt {attempt}/{max_attempts}): {check_response.status_code}", "INFO")
|
|
205
|
+
|
|
206
|
+
if check_response.status_code == 201:
|
|
207
|
+
self.log("✅ Biometric authentication successful!", "SUCCESS")
|
|
208
|
+
|
|
209
|
+
# Close browser
|
|
210
|
+
driver.quit()
|
|
211
|
+
|
|
212
|
+
# Check JWT token
|
|
213
|
+
jwt_token = self.session.cookies.get('t')
|
|
214
|
+
if jwt_token:
|
|
215
|
+
self.log("✅ JWT token received", "SUCCESS")
|
|
216
|
+
|
|
217
|
+
# Return success response
|
|
218
|
+
return {
|
|
219
|
+
'user': {'email': email},
|
|
220
|
+
'status': 'authenticated',
|
|
221
|
+
'permissions': ['read', 'write'],
|
|
222
|
+
'message': 'Biometric authentication successful',
|
|
223
|
+
'status_code': check_response.status_code,
|
|
224
|
+
'has_jwt': jwt_token is not None
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
# If we get here, authentication timed out
|
|
228
|
+
if driver:
|
|
229
|
+
driver.quit()
|
|
230
|
+
raise Exception("Biometric authentication timed out")
|
|
231
|
+
|
|
232
|
+
except Exception as driver_error:
|
|
233
|
+
if driver:
|
|
234
|
+
try:
|
|
235
|
+
driver.quit()
|
|
236
|
+
except:
|
|
237
|
+
pass
|
|
238
|
+
raise Exception(f"Browser automation error: {driver_error}")
|
|
239
|
+
|
|
240
|
+
except Exception as e:
|
|
241
|
+
self.log(f"❌ Biometric authentication failed: {str(e)}", "ERROR")
|
|
242
|
+
raise
|
|
243
|
+
|
|
137
244
|
async def is_authenticated(self) -> bool:
|
|
138
245
|
"""Check if currently authenticated using JWT token."""
|
|
139
246
|
try:
|
|
@@ -263,7 +370,7 @@ class BrainApiClient:
|
|
|
263
370
|
raise
|
|
264
371
|
|
|
265
372
|
async def get_datasets(self, instrument_type: str = "EQUITY", region: str = "USA",
|
|
266
|
-
delay: int = 1, universe: str = "TOP3000", theme: str = "false") -> Dict[str, Any]:
|
|
373
|
+
delay: int = 1, universe: str = "TOP3000", theme: str = "false", search: Optional[str] = None) -> Dict[str, Any]:
|
|
267
374
|
"""Get available datasets."""
|
|
268
375
|
await self.ensure_authenticated()
|
|
269
376
|
|
|
@@ -276,9 +383,14 @@ class BrainApiClient:
|
|
|
276
383
|
'theme': theme
|
|
277
384
|
}
|
|
278
385
|
|
|
386
|
+
if search:
|
|
387
|
+
params['search'] = search
|
|
388
|
+
|
|
279
389
|
response = self.session.get(f"{self.base_url}/data-sets", params=params)
|
|
280
390
|
response.raise_for_status()
|
|
281
|
-
|
|
391
|
+
response = response.json()
|
|
392
|
+
response['extraNote'] = "if your returned result is 0, you may want to check your parameter by using get_instrument_options tool to got correct parameter"
|
|
393
|
+
return response
|
|
282
394
|
except Exception as e:
|
|
283
395
|
self.log(f"Failed to get datasets: {str(e)}", "ERROR")
|
|
284
396
|
raise
|
|
@@ -310,7 +422,9 @@ class BrainApiClient:
|
|
|
310
422
|
|
|
311
423
|
response = self.session.get(f"{self.base_url}/data-fields", params=params)
|
|
312
424
|
response.raise_for_status()
|
|
313
|
-
|
|
425
|
+
response = response.json()
|
|
426
|
+
response['extraNote'] = "if your returned result is 0, you may want to check your parameter by using get_instrument_options tool to got correct parameter"
|
|
427
|
+
return response
|
|
314
428
|
except Exception as e:
|
|
315
429
|
self.log(f"Failed to get datafields: {str(e)}", "ERROR")
|
|
316
430
|
raise
|
|
@@ -827,26 +941,43 @@ class BrainApiClient:
|
|
|
827
941
|
self.log(f"Failed to get pyramid multipliers: {str(e)}", "ERROR")
|
|
828
942
|
raise
|
|
829
943
|
|
|
830
|
-
async def get_pyramid_alphas(self,
|
|
831
|
-
category: Optional[str] = None, start_date: Optional[str] = None,
|
|
944
|
+
async def get_pyramid_alphas(self, start_date: Optional[str] = None,
|
|
832
945
|
end_date: Optional[str] = None) -> Dict[str, Any]:
|
|
833
946
|
"""Get user's current alpha distribution across pyramid categories."""
|
|
834
947
|
await self.ensure_authenticated()
|
|
835
948
|
|
|
836
949
|
try:
|
|
837
950
|
params = {}
|
|
838
|
-
if region:
|
|
839
|
-
params['region'] = region
|
|
840
|
-
if delay is not None:
|
|
841
|
-
params['delay'] = delay
|
|
842
|
-
if category:
|
|
843
|
-
params['category'] = category
|
|
844
951
|
if start_date:
|
|
845
952
|
params['startDate'] = start_date
|
|
846
953
|
if end_date:
|
|
847
954
|
params['endDate'] = end_date
|
|
848
955
|
|
|
849
|
-
|
|
956
|
+
# Try the user-specific activities endpoint first (like pyramid-multipliers)
|
|
957
|
+
response = self.session.get(f"{self.base_url}/users/self/activities/pyramid-alphas", params=params)
|
|
958
|
+
|
|
959
|
+
# If that fails, try alternative endpoints
|
|
960
|
+
if response.status_code == 404:
|
|
961
|
+
# Try alternative endpoint structure
|
|
962
|
+
response = self.session.get(f"{self.base_url}/users/self/pyramid/alphas", params=params)
|
|
963
|
+
|
|
964
|
+
if response.status_code == 404:
|
|
965
|
+
# Try yet another alternative
|
|
966
|
+
response = self.session.get(f"{self.base_url}/activities/pyramid-alphas", params=params)
|
|
967
|
+
|
|
968
|
+
if response.status_code == 404:
|
|
969
|
+
# Return an informative error with what we tried
|
|
970
|
+
return {
|
|
971
|
+
"error": "Pyramid alphas endpoint not found",
|
|
972
|
+
"tried_endpoints": [
|
|
973
|
+
"/users/self/activities/pyramid-alphas",
|
|
974
|
+
"/users/self/pyramid/alphas",
|
|
975
|
+
"/activities/pyramid-alphas",
|
|
976
|
+
"/pyramid/alphas"
|
|
977
|
+
],
|
|
978
|
+
"suggestion": "This endpoint may not be available in the current API version"
|
|
979
|
+
}
|
|
980
|
+
|
|
850
981
|
response.raise_for_status()
|
|
851
982
|
return response.json()
|
|
852
983
|
except Exception as e:
|
|
@@ -1,64 +1,64 @@
|
|
|
1
|
-
from setuptools import setup, find_packages
|
|
2
|
-
import os
|
|
3
|
-
|
|
4
|
-
# Read the README file
|
|
5
|
-
def read_readme():
|
|
6
|
-
with open("README.md", "r", encoding="utf-8") as fh:
|
|
7
|
-
return fh.read()
|
|
8
|
-
|
|
9
|
-
# Read requirements
|
|
10
|
-
def read_requirements():
|
|
11
|
-
with open("requirements.txt", "r", encoding="utf-8") as fh:
|
|
12
|
-
return [line.strip() for line in fh if line.strip() and not line.startswith("#")]
|
|
13
|
-
|
|
14
|
-
setup(
|
|
15
|
-
name="cnhkmcp",
|
|
16
|
-
version="1.1.
|
|
17
|
-
author="CNHK",
|
|
18
|
-
author_email="cnhk@example.com",
|
|
19
|
-
description="A comprehensive Model Context Protocol (MCP) server for quantitative trading platform integration",
|
|
20
|
-
long_description=read_readme(),
|
|
21
|
-
long_description_content_type="text/markdown",
|
|
22
|
-
url="https://github.com/cnhk/cnhkmcp",
|
|
23
|
-
packages=find_packages(),
|
|
24
|
-
classifiers=[
|
|
25
|
-
"Development Status :: 4 - Beta",
|
|
26
|
-
"Intended Audience :: Developers",
|
|
27
|
-
"Intended Audience :: Financial and Insurance Industry",
|
|
28
|
-
"License :: OSI Approved :: MIT License",
|
|
29
|
-
"Operating System :: OS Independent",
|
|
30
|
-
"Programming Language :: Python :: 3",
|
|
31
|
-
"Programming Language :: Python :: 3.8",
|
|
32
|
-
"Programming Language :: Python :: 3.9",
|
|
33
|
-
"Programming Language :: Python :: 3.10",
|
|
34
|
-
"Programming Language :: Python :: 3.11",
|
|
35
|
-
"Topic :: Office/Business :: Financial",
|
|
36
|
-
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
37
|
-
],
|
|
38
|
-
python_requires=">=3.8",
|
|
39
|
-
install_requires=read_requirements(),
|
|
40
|
-
extras_require={
|
|
41
|
-
"dev": [
|
|
42
|
-
"pytest>=6.0",
|
|
43
|
-
"pytest-asyncio>=0.18.0",
|
|
44
|
-
"black>=21.0",
|
|
45
|
-
"flake8>=3.8",
|
|
46
|
-
],
|
|
47
|
-
},
|
|
48
|
-
entry_points={
|
|
49
|
-
"console_scripts": [
|
|
50
|
-
"cnhkmcp=cnhkmcp.untracked.platform_functions:main",
|
|
51
|
-
],
|
|
52
|
-
},
|
|
53
|
-
include_package_data=True,
|
|
54
|
-
zip_safe=False,
|
|
55
|
-
package_data={
|
|
56
|
-
'cnhkmcp': ['untracked/*.py', 'untracked/*.json'],
|
|
57
|
-
},
|
|
58
|
-
keywords="mcp, quantitative, trading, api, client",
|
|
59
|
-
project_urls={
|
|
60
|
-
"Bug Reports": "https://github.com/cnhk/cnhkmcp/issues",
|
|
61
|
-
"Source": "https://github.com/cnhk/cnhkmcp",
|
|
62
|
-
"Documentation": "https://github.com/cnhk/cnhkmcp#readme",
|
|
63
|
-
},
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
# Read the README file
|
|
5
|
+
def read_readme():
|
|
6
|
+
with open("README.md", "r", encoding="utf-8") as fh:
|
|
7
|
+
return fh.read()
|
|
8
|
+
|
|
9
|
+
# Read requirements
|
|
10
|
+
def read_requirements():
|
|
11
|
+
with open("requirements.txt", "r", encoding="utf-8") as fh:
|
|
12
|
+
return [line.strip() for line in fh if line.strip() and not line.startswith("#")]
|
|
13
|
+
|
|
14
|
+
setup(
|
|
15
|
+
name="cnhkmcp",
|
|
16
|
+
version="1.1.7",
|
|
17
|
+
author="CNHK",
|
|
18
|
+
author_email="cnhk@example.com",
|
|
19
|
+
description="A comprehensive Model Context Protocol (MCP) server for quantitative trading platform integration",
|
|
20
|
+
long_description=read_readme(),
|
|
21
|
+
long_description_content_type="text/markdown",
|
|
22
|
+
url="https://github.com/cnhk/cnhkmcp",
|
|
23
|
+
packages=find_packages(),
|
|
24
|
+
classifiers=[
|
|
25
|
+
"Development Status :: 4 - Beta",
|
|
26
|
+
"Intended Audience :: Developers",
|
|
27
|
+
"Intended Audience :: Financial and Insurance Industry",
|
|
28
|
+
"License :: OSI Approved :: MIT License",
|
|
29
|
+
"Operating System :: OS Independent",
|
|
30
|
+
"Programming Language :: Python :: 3",
|
|
31
|
+
"Programming Language :: Python :: 3.8",
|
|
32
|
+
"Programming Language :: Python :: 3.9",
|
|
33
|
+
"Programming Language :: Python :: 3.10",
|
|
34
|
+
"Programming Language :: Python :: 3.11",
|
|
35
|
+
"Topic :: Office/Business :: Financial",
|
|
36
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
37
|
+
],
|
|
38
|
+
python_requires=">=3.8",
|
|
39
|
+
install_requires=read_requirements(),
|
|
40
|
+
extras_require={
|
|
41
|
+
"dev": [
|
|
42
|
+
"pytest>=6.0",
|
|
43
|
+
"pytest-asyncio>=0.18.0",
|
|
44
|
+
"black>=21.0",
|
|
45
|
+
"flake8>=3.8",
|
|
46
|
+
],
|
|
47
|
+
},
|
|
48
|
+
entry_points={
|
|
49
|
+
"console_scripts": [
|
|
50
|
+
"cnhkmcp=cnhkmcp.untracked.platform_functions:main",
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
include_package_data=True,
|
|
54
|
+
zip_safe=False,
|
|
55
|
+
package_data={
|
|
56
|
+
'cnhkmcp': ['untracked/*.py', 'untracked/*.json'],
|
|
57
|
+
},
|
|
58
|
+
keywords="mcp, quantitative, trading, api, client",
|
|
59
|
+
project_urls={
|
|
60
|
+
"Bug Reports": "https://github.com/cnhk/cnhkmcp/issues",
|
|
61
|
+
"Source": "https://github.com/cnhk/cnhkmcp",
|
|
62
|
+
"Documentation": "https://github.com/cnhk/cnhkmcp#readme",
|
|
63
|
+
},
|
|
64
64
|
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|