mns-common 1.3.9.9__py3-none-any.whl → 1.6.1.4__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.
Potentially problematic release.
This version of mns-common might be problematic. Click here for more details.
- mns_common/__init__.py +1 -0
- mns_common/api/akshare/__init__.py +0 -1
- mns_common/api/akshare/k_line_api.py +19 -2
- mns_common/api/akshare/stock_bid_ask_api.py +21 -14
- mns_common/api/akshare/stock_zb_pool.py +2 -0
- mns_common/api/akshare/stock_zt_pool_api.py +1 -1
- mns_common/api/em/gd/east_money_stock_gdfx_free_top_10_api.py +62 -7
- mns_common/api/em/real_time/__init__.py +1 -1
- mns_common/api/em/real_time/east_money_debt_api.py +168 -71
- mns_common/api/em/real_time/east_money_etf_api.py +165 -27
- mns_common/api/em/real_time/east_money_stock_a_api.py +37 -38
- mns_common/api/em/real_time/east_money_stock_a_v2_api.py +97 -53
- mns_common/api/em/real_time/east_money_stock_common_api.py +174 -0
- mns_common/api/em/real_time/east_money_stock_hk_api.py +252 -271
- mns_common/api/em/real_time/east_money_stock_hk_gtt_api.py +291 -0
- mns_common/api/em/real_time/east_money_stock_multi_thread_api_v3.py +154 -0
- mns_common/api/em/real_time/east_money_stock_us_api.py +210 -82
- mns_common/api/em/real_time/real_time_quotes_repeat_api.py +195 -0
- mns_common/api/foreign_exchange/foreign_exchange_api.py +38 -0
- mns_common/api/k_line/stock_k_line_data_api.py +11 -1
- mns_common/api/kpl/common/__init__.py +3 -2
- mns_common/api/kpl/common/kpl_common_api.py +35 -0
- mns_common/api/kpl/symbol/symbol_his_quotes_api.py +1 -1
- mns_common/api/kpl/theme/kpl_theme_api.py +69 -0
- mns_common/api/kpl/yidong/__init__.py +7 -0
- mns_common/api/kpl/yidong/stock_bid_yi_dong_api.py +52 -0
- mns_common/api/proxies/liu_guan_proxy_api.py +55 -5
- mns_common/api/ths/company/company_product_area_industry_index_query.py +46 -0
- mns_common/api/ths/company/ths_company_info_api.py +2 -1
- mns_common/api/ths/company/ths_company_info_web.py +159 -0
- mns_common/api/ths/concept/app/ths_concept_index_app.py +3 -1
- mns_common/api/ths/wen_cai/ths_wen_cai_api.py +1 -1
- mns_common/api/ths/zt/ths_stock_zt_pool_api.py +20 -1
- mns_common/api/ths/zt/ths_stock_zt_pool_v2_api.py +105 -29
- mns_common/api/ths/zt/ths_stock_zt_reason_web_api.py +100 -0
- mns_common/api/us/ths_us_company_info_api.py +131 -0
- mns_common/api/xueqiu/xue_qiu_k_line_api.py +16 -5
- mns_common/component/common_service_fun_api.py +28 -8
- mns_common/component/company/company_common_service_new_api.py +2 -0
- mns_common/component/cookie/cookie_enum.py +16 -0
- mns_common/component/cookie/cookie_info_service.py +18 -8
- mns_common/component/data/data_init_api.py +13 -8
- mns_common/component/deal/deal_service_api.py +70 -8
- mns_common/component/deal/deal_service_v2_api.py +167 -0
- mns_common/component/em/em_stock_info_api.py +12 -3
- mns_common/component/main_line/__init__.py +7 -0
- mns_common/component/main_line/main_line_zt_reason_service.py +257 -0
- mns_common/component/proxies/proxy_common_api.py +169 -109
- mns_common/component/tfp/stock_tfp_api.py +82 -12
- mns_common/component/us/__init__.py +7 -0
- mns_common/component/us/us_stock_etf_info_api.py +130 -0
- mns_common/constant/db_name_constant.py +75 -26
- mns_common/constant/extra_income_db_name.py +94 -17
- mns_common/constant/strategy_classify.py +72 -0
- mns_common/db/MongodbUtil.py +3 -0
- mns_common/db/MongodbUtilLocal.py +3 -0
- {mns_common-1.3.9.9.dist-info → mns_common-1.6.1.4.dist-info}/METADATA +1 -1
- {mns_common-1.3.9.9.dist-info → mns_common-1.6.1.4.dist-info}/RECORD +62 -47
- mns_common/api/ths/concept/web/ths_company_info_web.py +0 -163
- mns_common/component/qmt/qmt_buy_service.py +0 -172
- mns_common/component/task/real_time_data_sync_check.py +0 -97
- /mns_common/{component/qmt → api/foreign_exchange}/__init__.py +0 -0
- /mns_common/{component/task → api/kpl/theme}/__init__.py +0 -0
- {mns_common-1.3.9.9.dist-info → mns_common-1.6.1.4.dist-info}/WHEEL +0 -0
- {mns_common-1.3.9.9.dist-info → mns_common-1.6.1.4.dist-info}/top_level.txt +0 -0
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
import os
|
|
3
|
-
|
|
4
|
-
file_path = os.path.abspath(__file__)
|
|
5
|
-
end = file_path.index('mns') + 14
|
|
6
|
-
project_path = file_path[0:end]
|
|
7
|
-
sys.path.append(project_path)
|
|
8
|
-
|
|
9
|
-
from loguru import logger
|
|
10
|
-
import pandas as pd
|
|
11
|
-
import requests
|
|
12
|
-
from bs4 import BeautifulSoup
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
# 获取股票基本信息
|
|
16
|
-
# https://basic.10jqka.com.cn/mobile/301016/companyprofilen.html?showtab=1&broker=anelicaiapp
|
|
17
|
-
def get_company_info(symbol: str = "688272") -> pd.DataFrame:
|
|
18
|
-
try:
|
|
19
|
-
url = f"http://basic.10jqka.com.cn/mobile/{symbol}/companyprofilen.html?broker=pingan"
|
|
20
|
-
headers = {
|
|
21
|
-
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 iOS AYLCAPP/9.1.2.0/h4526a24eb9445522492fd64caae11b1f scheme/anelicaiapp deviceinfo/I|9.1.2.0|NA|h4526a24eb9445522492fd64caae11b1f pastheme/0",
|
|
22
|
-
"Cookie": "ps_login_app_name=AYLCAPP;ps_login_token_id=N_C993F777ACC500B354C762A2627A8862348FC8163799A08EBEB2301C28A2135D220475787D0E81425C1134E15D8CC8761D639FEDBD46C00FE8EA6482C1E42D9801B19918FB3F5C34;ps_login_union_id=edc29089a2b64e3882062297030a0386;PAS.CURRENTUNIONID=edc29089a2b64e3882062297030a0386"
|
|
23
|
-
}
|
|
24
|
-
r = requests.get(url, headers=headers)
|
|
25
|
-
soup = BeautifulSoup(r.content.decode("utf-8"), 'lxml')
|
|
26
|
-
soup.find('table', attrs={'class': 'leveldatail-tab'}).find_all('tr')
|
|
27
|
-
temp_df = pd.read_html(r.content)[0]
|
|
28
|
-
temp_df = temp_df.T
|
|
29
|
-
temp_df = temp_df.iloc[1:2]
|
|
30
|
-
temp_df.rename(columns={
|
|
31
|
-
0: "name",
|
|
32
|
-
1: "former_name",
|
|
33
|
-
2: "registered_address",
|
|
34
|
-
3: "chairman",
|
|
35
|
-
4: "board_secretary",
|
|
36
|
-
5: "main_business",
|
|
37
|
-
6: "company_type",
|
|
38
|
-
7: "controlling_shareholder",
|
|
39
|
-
8: "actual_controller",
|
|
40
|
-
9: "ultimate_controller",
|
|
41
|
-
10: "list_date",
|
|
42
|
-
11: "issue_price",
|
|
43
|
-
12: "number_workers",
|
|
44
|
-
13: "tel",
|
|
45
|
-
14: "url",
|
|
46
|
-
15: "email"
|
|
47
|
-
}, inplace=True)
|
|
48
|
-
|
|
49
|
-
return temp_df
|
|
50
|
-
except BaseException as e:
|
|
51
|
-
logger.error("获取symbol控制人基本信息异常:{},{}", symbol, e)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
# 获取股票详细信息
|
|
55
|
-
# HK市场 https://basic.10jqka.com.cn/mobile/HK1456/profile.html https://basic.10jqka.com.cn/mobile/HK1456/company.html
|
|
56
|
-
# https://basic.10jqka.com.cn/new/HK1456/company.html
|
|
57
|
-
# https://basic.10jqka.com.cn/astockph/briefinfo/index.html?showhead=0&fromshare=1&code=300430&marketid=33&client_userid=ESgcM&back_source=hyperlink&share_hxapp=isc&fontzoom=no#/company/ziliao
|
|
58
|
-
def get_company_info_detail(symbol: str = "688272") -> pd.DataFrame:
|
|
59
|
-
try:
|
|
60
|
-
url = f'https://basic.10jqka.com.cn/basicapi/company_info/merge_info/v1/base_info/?code={symbol}&market=33&type=stock'
|
|
61
|
-
headers = {
|
|
62
|
-
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:105.0) Gecko/20100101 Firefox/105.0',
|
|
63
|
-
'Host': 'basic.10jqka.com.cn',
|
|
64
|
-
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
|
|
65
|
-
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
|
|
66
|
-
'Accept-Encoding': 'gzip, deflate, br',
|
|
67
|
-
'Connection': 'keep-alive',
|
|
68
|
-
'Cookie': 'v=A0CN8EBXN21LtMtpV6ldAxf6Ec8XySSbxq14l7rRDNvuNe77Ytn0Ixa9SDQJ',
|
|
69
|
-
'Upgrade-Insecure-Requests': '1',
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
r = requests.get(url, headers=headers)
|
|
73
|
-
data_json = r.json()
|
|
74
|
-
status_code = data_json['status_code']
|
|
75
|
-
status_msg = data_json['status_msg']
|
|
76
|
-
if status_code != 0 or status_msg != 'success':
|
|
77
|
-
logger.error("获取symbol公司详细信息异常:{}", symbol)
|
|
78
|
-
if len(data_json['data']['industry']) == 0:
|
|
79
|
-
return None
|
|
80
|
-
data_df = pd.DataFrame(data_json['data']['industry'], index=[0])
|
|
81
|
-
data_df = data_df[[
|
|
82
|
-
'hy',
|
|
83
|
-
'hycode',
|
|
84
|
-
'hy2',
|
|
85
|
-
'hy2code',
|
|
86
|
-
'hy3',
|
|
87
|
-
'hy3code',
|
|
88
|
-
]]
|
|
89
|
-
|
|
90
|
-
business_nature = data_json['data']['business_nature']
|
|
91
|
-
name = data_json['data']['code_name']
|
|
92
|
-
intro = data_json['data']['intro']
|
|
93
|
-
base_business = data_json['data']['base_business']
|
|
94
|
-
|
|
95
|
-
address = data_json['data']['address']
|
|
96
|
-
data_df['symbol'] = symbol
|
|
97
|
-
data_df['name'] = name
|
|
98
|
-
|
|
99
|
-
data_df['business_nature'] = business_nature
|
|
100
|
-
|
|
101
|
-
if len(data_json['data']['management']['holder_controller']) > 0:
|
|
102
|
-
holder_controller = pd.DataFrame(data_json['data']['management']['holder_controller'])
|
|
103
|
-
holder_controller_name = str(list(holder_controller['name'])).strip('[').strip(']').replace("'", "")
|
|
104
|
-
holder_controller_rate = holder_controller['rate']
|
|
105
|
-
data_df['holder_controller_name'] = holder_controller_name
|
|
106
|
-
data_df['holder_controller_rate'] = sum(holder_controller_rate)
|
|
107
|
-
else:
|
|
108
|
-
data_df['holder_controller_name'] = '暂无'
|
|
109
|
-
data_df['holder_controller_rate'] = 0
|
|
110
|
-
if len(data_json['data']['management']['final_controller']) > 0:
|
|
111
|
-
final_controller = pd.DataFrame(data_json['data']['management']['final_controller'])
|
|
112
|
-
final_controller_name = str(list(final_controller['name'])).strip('[').strip(']').replace("'", "")
|
|
113
|
-
final_controller_rate = sum(final_controller['rate'])
|
|
114
|
-
data_df['final_controller_name'] = final_controller_name
|
|
115
|
-
data_df['final_controller_rate'] = final_controller_rate
|
|
116
|
-
else:
|
|
117
|
-
data_df['final_controller_name'] = '暂无'
|
|
118
|
-
data_df['final_controller_rate'] = 0
|
|
119
|
-
if len(data_json['data']['management']['actual_controller']) > 0:
|
|
120
|
-
actual_controller = pd.DataFrame(data_json['data']['management']['actual_controller'])
|
|
121
|
-
actual_controller_name = str(list(actual_controller['name'])).strip('[').strip(']').replace("'", "")
|
|
122
|
-
actual_controller_rate = sum(actual_controller['rate'])
|
|
123
|
-
data_df['actual_controller_name'] = actual_controller_name
|
|
124
|
-
data_df['actual_controller_rate'] = actual_controller_rate
|
|
125
|
-
else:
|
|
126
|
-
data_df['actual_controller_name'] = '暂无'
|
|
127
|
-
data_df['actual_controller_rate'] = 0
|
|
128
|
-
|
|
129
|
-
data_df['base_business'] = base_business
|
|
130
|
-
data_df['intro'] = intro
|
|
131
|
-
data_df['address'] = address
|
|
132
|
-
market_id = data_json['data']['market_id']
|
|
133
|
-
data_df['market_id'] = market_id
|
|
134
|
-
# 初始化数据
|
|
135
|
-
data_df['main_business_list'] = [[]]
|
|
136
|
-
data_df['most_profitable_business'] = ''
|
|
137
|
-
data_df['most_profitable_business_rate'] = ''
|
|
138
|
-
data_df['most_profitable_business_profit'] = ''
|
|
139
|
-
|
|
140
|
-
# 业务构成
|
|
141
|
-
main_business_list = data_json['data']['main_business']
|
|
142
|
-
# 最盈利业务
|
|
143
|
-
profitable_business = data_json['data']['profitable_business']
|
|
144
|
-
|
|
145
|
-
data_df['main_business_list'] = [main_business_list]
|
|
146
|
-
|
|
147
|
-
most_profitable_business = profitable_business['name']
|
|
148
|
-
|
|
149
|
-
most_profitable_business_rate = profitable_business['profit_rate']
|
|
150
|
-
|
|
151
|
-
most_profitable_business_profit = profitable_business['profit']
|
|
152
|
-
|
|
153
|
-
data_df['most_profitable_business'] = most_profitable_business
|
|
154
|
-
data_df['most_profitable_business_rate'] = most_profitable_business_rate
|
|
155
|
-
data_df['most_profitable_business_profit'] = most_profitable_business_profit
|
|
156
|
-
return data_df
|
|
157
|
-
except BaseException as e:
|
|
158
|
-
logger.warning("获取symbol公司详细信息异常:{},{}", symbol, e)
|
|
159
|
-
return data_df
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
if __name__ == '__main__':
|
|
163
|
-
get_company_info_detail('603683')
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
import os
|
|
3
|
-
|
|
4
|
-
file_path = os.path.abspath(__file__)
|
|
5
|
-
end = file_path.index('mns') + 16
|
|
6
|
-
project_path = file_path[0:end]
|
|
7
|
-
sys.path.append(project_path)
|
|
8
|
-
import time, datetime, traceback, sys
|
|
9
|
-
from xtquant import xtdata
|
|
10
|
-
from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback
|
|
11
|
-
from xtquant.xttype import StockAccount
|
|
12
|
-
from xtquant import xtconstant
|
|
13
|
-
|
|
14
|
-
# 定义一个类 创建类的实例 作为状态的容器
|
|
15
|
-
class _a():
|
|
16
|
-
pass
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
A = _a()
|
|
20
|
-
A.bought_list = []
|
|
21
|
-
A.hsa = xtdata.get_stock_list_in_sector('沪深A股')
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def interact():
|
|
25
|
-
"""执行后进入repl模式"""
|
|
26
|
-
import code
|
|
27
|
-
code.InteractiveConsole(locals=globals()).interact()
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
xtdata.download_sector_data()
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
class MyXtQuantTraderCallback(XtQuantTraderCallback):
|
|
35
|
-
def on_disconnected(self):
|
|
36
|
-
"""
|
|
37
|
-
连接断开
|
|
38
|
-
:return:
|
|
39
|
-
"""
|
|
40
|
-
print(datetime.datetime.now(), '连接断开回调')
|
|
41
|
-
|
|
42
|
-
def on_stock_order(self, order):
|
|
43
|
-
"""
|
|
44
|
-
委托回报推送
|
|
45
|
-
:param order: XtOrder对象
|
|
46
|
-
:return:
|
|
47
|
-
"""
|
|
48
|
-
print(datetime.datetime.now(), '委托回调 投资备注', order.order_remark)
|
|
49
|
-
|
|
50
|
-
def on_stock_trade(self, trade):
|
|
51
|
-
"""
|
|
52
|
-
成交变动推送
|
|
53
|
-
:param trade: XtTrade对象
|
|
54
|
-
:return:
|
|
55
|
-
"""
|
|
56
|
-
print(datetime.datetime.now(), '成交回调', trade.order_remark, f"委托方向(48买 49卖) {trade.offset_flag} 成交价格 {trade.traded_price} 成交数量 {trade.traded_volume}")
|
|
57
|
-
|
|
58
|
-
def on_order_error(self, order_error):
|
|
59
|
-
"""
|
|
60
|
-
委托失败推送
|
|
61
|
-
:param order_error:XtOrderError 对象
|
|
62
|
-
:return:
|
|
63
|
-
"""
|
|
64
|
-
# print("on order_error callback")
|
|
65
|
-
# print(order_error.order_id, order_error.error_id, order_error.error_msg)
|
|
66
|
-
print(f"委托报错回调 {order_error.order_remark} {order_error.error_msg}")
|
|
67
|
-
|
|
68
|
-
def on_cancel_error(self, cancel_error):
|
|
69
|
-
"""
|
|
70
|
-
撤单失败推送
|
|
71
|
-
:param cancel_error: XtCancelError 对象
|
|
72
|
-
:return:
|
|
73
|
-
"""
|
|
74
|
-
print(datetime.datetime.now(), sys._getframe().f_code.co_name)
|
|
75
|
-
|
|
76
|
-
def on_order_stock_async_response(self, response):
|
|
77
|
-
"""
|
|
78
|
-
异步下单回报推送
|
|
79
|
-
:param response: XtOrderResponse 对象
|
|
80
|
-
:return:
|
|
81
|
-
"""
|
|
82
|
-
print(f"异步委托回调 投资备注: {response.order_remark}")
|
|
83
|
-
|
|
84
|
-
def on_cancel_order_stock_async_response(self, response):
|
|
85
|
-
"""
|
|
86
|
-
:param response: XtCancelOrderResponse 对象
|
|
87
|
-
:return:
|
|
88
|
-
"""
|
|
89
|
-
print(datetime.datetime.now(), sys._getframe().f_code.co_name)
|
|
90
|
-
|
|
91
|
-
def on_account_status(self, status):
|
|
92
|
-
"""
|
|
93
|
-
:param response: XtAccountStatus 对象
|
|
94
|
-
:return:
|
|
95
|
-
"""
|
|
96
|
-
print(datetime.datetime.now(), sys._getframe().f_code.co_name)
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if __name__ == '__main__':
|
|
100
|
-
|
|
101
|
-
print("start")
|
|
102
|
-
# 指定客户端所在路径, 券商端指定到 userdata_mini文件夹
|
|
103
|
-
# 注意:如果是连接投研端进行交易,文件目录需要指定到f"{安装目录}\userdata"
|
|
104
|
-
path = r'D:\Program Files\qmt\国金证券QMT交易端\userdata_mini'
|
|
105
|
-
# 生成session id 整数类型 同时运行的策略不能重复
|
|
106
|
-
session_id = int(time.time())
|
|
107
|
-
xt_trader = XtQuantTrader(path, session_id)
|
|
108
|
-
# 开启主动请求接口的专用线程 开启后在on_stock_xxx回调函数里调用XtQuantTrader.query_xxx函数不会卡住回调线程,但是查询和推送的数据在时序上会变得不确定
|
|
109
|
-
# 详见: http://docs.thinktrader.net/vip/pages/ee0e9b/#开启主动请求接口的专用线程
|
|
110
|
-
# xt_trader.set_relaxed_response_order_enabled(True)
|
|
111
|
-
|
|
112
|
-
# 创建资金账号为 800068 的证券账号对象 股票账号为STOCK 信用CREDIT 期货FUTURE
|
|
113
|
-
acc = StockAccount('8882352999', 'STOCK')
|
|
114
|
-
# 创建交易回调类对象,并声明接收回调
|
|
115
|
-
callback = MyXtQuantTraderCallback()
|
|
116
|
-
xt_trader.register_callback(callback)
|
|
117
|
-
# 启动交易线程
|
|
118
|
-
xt_trader.start()
|
|
119
|
-
# 建立交易连接,返回0表示连接成功
|
|
120
|
-
connect_result = xt_trader.connect()
|
|
121
|
-
print('建立交易连接,返回0表示连接成功', connect_result)
|
|
122
|
-
# 对交易回调进行订阅,订阅后可以收到交易主推,返回0表示订阅成功
|
|
123
|
-
subscribe_result = xt_trader.subscribe(acc)
|
|
124
|
-
print('对交易回调进行订阅,订阅后可以收到交易主推,返回0表示订阅成功', subscribe_result)
|
|
125
|
-
# 取账号信息
|
|
126
|
-
account_info = xt_trader.query_stock_asset(acc)
|
|
127
|
-
# 取可用资金
|
|
128
|
-
available_cash = account_info.m_dCash
|
|
129
|
-
|
|
130
|
-
print(acc.account_id, '可用资金', available_cash)
|
|
131
|
-
# 查账号持仓
|
|
132
|
-
positions = xt_trader.query_stock_positions(acc)
|
|
133
|
-
# 取各品种 总持仓 可用持仓
|
|
134
|
-
position_total_dict = {i.stock_code: i.m_nVolume for i in positions}
|
|
135
|
-
position_available_dict = {i.stock_code: i.m_nCanUseVolume for i in positions}
|
|
136
|
-
print(acc.account_id, '持仓字典', position_total_dict)
|
|
137
|
-
print(acc.account_id, '可用持仓字典', position_available_dict)
|
|
138
|
-
|
|
139
|
-
# 买入 浦发银行 最新价 两万元
|
|
140
|
-
stock = '600000.SH'
|
|
141
|
-
target_amount = 20000
|
|
142
|
-
full_tick = xtdata.get_full_tick([stock])
|
|
143
|
-
print(f"{stock} 全推行情: {full_tick}")
|
|
144
|
-
current_price = full_tick[stock]['lastPrice']
|
|
145
|
-
# 买入金额 取目标金额 与 可用金额中较小的
|
|
146
|
-
buy_amount = min(target_amount, available_cash)
|
|
147
|
-
# 买入数量 取整为100的整数倍
|
|
148
|
-
buy_vol = int(buy_amount / current_price / 100) * 100
|
|
149
|
-
print(f"当前可用资金 {available_cash} 目标买入金额 {target_amount} 买入股数 {buy_vol}股")
|
|
150
|
-
async_seq = xt_trader.order_stock_async(acc, stock, xtconstant.STOCK_BUY, buy_vol, xtconstant.FIX_PRICE,
|
|
151
|
-
current_price,
|
|
152
|
-
'strategy_name', stock)
|
|
153
|
-
|
|
154
|
-
# 卖出 500股
|
|
155
|
-
stock = '513130.SH'
|
|
156
|
-
# 目标数量
|
|
157
|
-
target_vol = 500
|
|
158
|
-
# 可用数量
|
|
159
|
-
available_vol = position_available_dict[stock] if stock in position_available_dict else 0
|
|
160
|
-
# 卖出量取目标量与可用量中较小的
|
|
161
|
-
sell_vol = min(target_vol, available_vol)
|
|
162
|
-
print(f"{stock} 目标卖出量 {target_vol} 可用数量 {available_vol} 卖出 {sell_vol}股")
|
|
163
|
-
if sell_vol > 0:
|
|
164
|
-
async_seq = xt_trader.order_stock_async(acc, stock, xtconstant.STOCK_SELL, sell_vol,
|
|
165
|
-
xtconstant.LATEST_PRICE,
|
|
166
|
-
-1,
|
|
167
|
-
'strategy_name', stock)
|
|
168
|
-
print(f"下单完成 等待回调")
|
|
169
|
-
# 阻塞主线程退出
|
|
170
|
-
# xt_trader.run_forever()
|
|
171
|
-
# 如果使用vscode pycharm等本地编辑器 可以进入交互模式 方便调试 (把上一行的run_forever注释掉 否则不会执行到这里)
|
|
172
|
-
interact()
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
import os
|
|
3
|
-
|
|
4
|
-
file_path = os.path.abspath(__file__)
|
|
5
|
-
end = file_path.index('mns') + 16
|
|
6
|
-
project_path = file_path[0:end]
|
|
7
|
-
sys.path.append(project_path)
|
|
8
|
-
|
|
9
|
-
import datetime
|
|
10
|
-
import mns_common.utils.date_handle_util as date_util
|
|
11
|
-
from mns_common.db.MongodbUtil import MongodbUtil
|
|
12
|
-
import mns_common.constant.db_name_constant as db_name_constant
|
|
13
|
-
import mns_common.utils.cmd_util as cmd_util
|
|
14
|
-
import mns_common.utils.data_frame_util as data_frame_util
|
|
15
|
-
import time
|
|
16
|
-
from loguru import logger
|
|
17
|
-
|
|
18
|
-
mongodb_util = MongodbUtil('27017')
|
|
19
|
-
REAL_TIME_SCHEDULER_NAME = "realtime_quotes_now_sync"
|
|
20
|
-
# 实时同步 bat
|
|
21
|
-
REAL_TIME_TASK_NAME_PATH = 'H:\\real_time_task.bat'
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
# 获取同步任务pid
|
|
25
|
-
def get_real_time_quotes_task(all_cmd_processes):
|
|
26
|
-
return all_cmd_processes[
|
|
27
|
-
(all_cmd_processes['total_info'].str.contains(REAL_TIME_SCHEDULER_NAME, case=False, na=False))
|
|
28
|
-
| (all_cmd_processes['total_info'].str.contains(REAL_TIME_SCHEDULER_NAME, case=False, na=False))]
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
# 关闭实时行情任务
|
|
32
|
-
def real_time_sync_task_close():
|
|
33
|
-
all_cmd_processes = cmd_util.get_all_process()
|
|
34
|
-
if data_frame_util.is_empty(all_cmd_processes):
|
|
35
|
-
return False
|
|
36
|
-
all_cmd_processes_real_time_task = get_real_time_quotes_task(all_cmd_processes)
|
|
37
|
-
if data_frame_util.is_empty(all_cmd_processes_real_time_task):
|
|
38
|
-
return False
|
|
39
|
-
for match_task_one in all_cmd_processes_real_time_task.itertuples():
|
|
40
|
-
try:
|
|
41
|
-
processes_pid = match_task_one.process_pid
|
|
42
|
-
# 关闭当前进程
|
|
43
|
-
cmd_util.kill_process_by_pid(processes_pid)
|
|
44
|
-
except BaseException as e:
|
|
45
|
-
logger.error("关闭实时行情任务异常:{}", e)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
# 重开定时任务同步
|
|
49
|
-
def real_time_sync_task_open():
|
|
50
|
-
all_cmd_processes = cmd_util.get_all_process()
|
|
51
|
-
if data_frame_util.is_empty(all_cmd_processes):
|
|
52
|
-
return False
|
|
53
|
-
all_cmd_processes_real_time_task = get_real_time_quotes_task(all_cmd_processes)
|
|
54
|
-
if data_frame_util.is_empty(all_cmd_processes_real_time_task):
|
|
55
|
-
# 重开定时任务
|
|
56
|
-
cmd_util.open_bat_file(REAL_TIME_TASK_NAME_PATH)
|
|
57
|
-
# 防止太快重开多个
|
|
58
|
-
time.sleep(3)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
def query_data_exist(str_day):
|
|
62
|
-
col_name = db_name_constant.REAL_TIME_QUOTES_NOW + '_' + str_day
|
|
63
|
-
query = {'symbol': '000001'}
|
|
64
|
-
return mongodb_util.exist_data_query(col_name, query)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
def exist_sync_task():
|
|
68
|
-
all_cmd_processes = cmd_util.get_all_process()
|
|
69
|
-
if data_frame_util.is_empty(all_cmd_processes):
|
|
70
|
-
return False
|
|
71
|
-
all_cmd_processes_real_time_task = get_real_time_quotes_task(all_cmd_processes)
|
|
72
|
-
if data_frame_util.is_empty(all_cmd_processes_real_time_task):
|
|
73
|
-
return False
|
|
74
|
-
else:
|
|
75
|
-
return True
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
def check_data_sync_task_status():
|
|
79
|
-
now_date = datetime.datetime.now()
|
|
80
|
-
str_day = now_date.strftime('%Y-%m-%d')
|
|
81
|
-
|
|
82
|
-
if bool(date_util.is_trade_time(now_date)):
|
|
83
|
-
if bool(1 - query_data_exist(str_day)) or bool(1 - exist_sync_task()):
|
|
84
|
-
real_time_sync_task_open()
|
|
85
|
-
time.sleep(2)
|
|
86
|
-
elif bool(date_util.is_no_trade_time(now_date)):
|
|
87
|
-
return
|
|
88
|
-
else:
|
|
89
|
-
time.sleep(5)
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if __name__ == '__main__':
|
|
93
|
-
# check_data_sync_task_status()
|
|
94
|
-
d = query_data_exist('2025-03-27')
|
|
95
|
-
print(d)
|
|
96
|
-
s = exist_sync_task()
|
|
97
|
-
print(s)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|