|
@@ -12,6 +12,7 @@ import pymysql
|
|
import multiprocessing as mp
|
|
import multiprocessing as mp
|
|
import math
|
|
import math
|
|
import psutil
|
|
import psutil
|
|
|
|
+from apscheduler.schedulers.blocking import BlockingScheduler
|
|
|
|
|
|
auth('18616891214', 'Ea?*7f68nD.dafcW34d!')
|
|
auth('18616891214', 'Ea?*7f68nD.dafcW34d!')
|
|
db_pool = pymysql.connect(host='localhost',
|
|
db_pool = pymysql.connect(host='localhost',
|
|
@@ -23,6 +24,21 @@ cursor_pool = db_pool.cursor()
|
|
engine_stock = create_engine('mysql+pymysql://root:r6kEwqWU9!v3@localhost:3307/qmt_stocks_whole?charset=utf8')
|
|
engine_stock = create_engine('mysql+pymysql://root:r6kEwqWU9!v3@localhost:3307/qmt_stocks_whole?charset=utf8')
|
|
|
|
|
|
|
|
|
|
|
|
+def run(seq):
|
|
|
|
+ print(seq)
|
|
|
|
+ '''阻塞线程接收行情回调'''
|
|
|
|
+ import time
|
|
|
|
+ client = xtdata.get_client()
|
|
|
|
+ while True:
|
|
|
|
+ time.sleep(3)
|
|
|
|
+ now_date = dt.now()
|
|
|
|
+ if not client.is_connected() or dt.now() > now_date.replace(hour=15, minute=00, second=0):
|
|
|
|
+ xtdata.unsubscribe_quote(seq)
|
|
|
|
+ raise Exception('行情服务连接断开')
|
|
|
|
+ break
|
|
|
|
+ return
|
|
|
|
+
|
|
|
|
+
|
|
def real_price(datas):
|
|
def real_price(datas):
|
|
# i = '000001.SZ'
|
|
# i = '000001.SZ'
|
|
for i in datas:
|
|
for i in datas:
|
|
@@ -70,21 +86,22 @@ def his_vol(stock, num):
|
|
return df['volume_front'].iloc[num]
|
|
return df['volume_front'].iloc[num]
|
|
|
|
|
|
|
|
|
|
-def ma_judge(data, stock_list, results):
|
|
|
|
- print(f'这个ma_judge的PID为:{os.getpid()},收到的data数据为:{len(data.keys())},stock_pool长度为{len(stock_list)},now is {dt.now()}')
|
|
|
|
|
|
+def ma_judge(data, stock_list, rate, results):
|
|
|
|
+ # print(f',收到的data数据为:{len(data.keys())},stock_pool长度为{len(stock_list)},now is {dt.now()}')
|
|
list_judge = list(set(data.keys()) & set(stock_list))
|
|
list_judge = list(set(data.keys()) & set(stock_list))
|
|
- print(f'本轮计算:{len(list_judge)}个股')
|
|
|
|
|
|
+ print(f'这个ma_judge的PID为:{os.getpid()},本轮计算:{len(list_judge)}个股')
|
|
for stock in list_judge:
|
|
for stock in list_judge:
|
|
i = stock.replace('XSHG', 'SH').replace('XSHE', 'SZ')
|
|
i = stock.replace('XSHG', 'SH').replace('XSHE', 'SZ')
|
|
current_price, open_price = data[i]['lastPrice'], data[i]['open']
|
|
current_price, open_price = data[i]['lastPrice'], data[i]['open']
|
|
- MA5, MA10, MA20 = ma(i, 5, data), ma(i, 10, data), ma(i, 20, data)
|
|
|
|
|
|
+ MA5, MA10, MA20, MA30, MA60, MA120 = ma(i, 5, data), ma(i, 10, data), ma(i, 20, data), ma(i, 30, data),\
|
|
|
|
+ ma(i, 60, data), ma(i, 120, data)
|
|
MA5_1 = ma_1(i, 5)
|
|
MA5_1 = ma_1(i, 5)
|
|
# print(i, current_price, open_price, MA5, MA10, MA20, MA5_1)
|
|
# print(i, current_price, open_price, MA5, MA10, MA20, MA5_1)
|
|
|
|
+ # 入交易池标准:阳线\大于MA5\MA5向上\MA20<MA10\离120线有距离
|
|
if (current_price > open_price) & (current_price > MA5) & (MA5 > MA5_1) & (current_price < MA5 * 1.03) & (
|
|
if (current_price > open_price) & (current_price > MA5) & (MA5 > MA5_1) & (current_price < MA5 * 1.03) & (
|
|
- MA20 < MA10):
|
|
|
|
|
|
+ MA20 < MA10) & (current_price > MA120 or current_price < MA120*rate):
|
|
if his_vol(i, -1) > his_vol(i, -2):
|
|
if his_vol(i, -1) > his_vol(i, -2):
|
|
results.append(i.replace('SH', 'XSHG').replace('SZ', 'XSHE'))
|
|
results.append(i.replace('SH', 'XSHG').replace('SZ', 'XSHE'))
|
|
- print('RRRRRRR,', results)
|
|
|
|
|
|
|
|
|
|
|
|
def sell_trader(data, positions_dict):
|
|
def sell_trader(data, positions_dict):
|
|
@@ -111,6 +128,10 @@ def sell_trader(data, positions_dict):
|
|
print(f'本轮没有持仓股票信息!')
|
|
print(f'本轮没有持仓股票信息!')
|
|
|
|
|
|
|
|
|
|
|
|
+def get_fundamentals(results):
|
|
|
|
+ return results
|
|
|
|
+ pass
|
|
|
|
+
|
|
def buy_trader(data, positions):
|
|
def buy_trader(data, positions):
|
|
print('买入函数:', dt.now(), f'接受到{len(data.keys())}个个股')
|
|
print('买入函数:', dt.now(), f'接受到{len(data.keys())}个个股')
|
|
results = mp.Manager().list()
|
|
results = mp.Manager().list()
|
|
@@ -141,8 +162,9 @@ def buy_trader(data, positions):
|
|
|
|
|
|
step = math.ceil(len(stock_pool) / (mp.cpu_count()/2))
|
|
step = math.ceil(len(stock_pool) / (mp.cpu_count()/2))
|
|
print('step:', step)
|
|
print('step:', step)
|
|
|
|
+ rate = 0.8
|
|
for i in range(0, len(stock_pool), step):
|
|
for i in range(0, len(stock_pool), step):
|
|
- p = mp.Process(target=ma_judge, args=(data, stock_pool[i:i + step], results))
|
|
|
|
|
|
+ p = mp.Process(target=ma_judge, args=(data, stock_pool[i:i + step], rate, results))
|
|
mp_list.append(p)
|
|
mp_list.append(p)
|
|
p.start()
|
|
p.start()
|
|
for j in mp_list:
|
|
for j in mp_list:
|
|
@@ -152,8 +174,9 @@ def buy_trader(data, positions):
|
|
|
|
|
|
# 选择板块
|
|
# 选择板块
|
|
if len(results) != 0:
|
|
if len(results) != 0:
|
|
|
|
+ # 基本面过滤
|
|
|
|
+ results = get_fundamentals(results)
|
|
num_industry = get_industry(results)
|
|
num_industry = get_industry(results)
|
|
- print(num_industry)
|
|
|
|
industry_list = []
|
|
industry_list = []
|
|
for key in num_industry.values():
|
|
for key in num_industry.values():
|
|
for key2 in key.values():
|
|
for key2 in key.values():
|
|
@@ -166,7 +189,6 @@ def buy_trader(data, positions):
|
|
for key2 in value.values():
|
|
for key2 in value.values():
|
|
if key2['industry_name'] in max_industry_list:
|
|
if key2['industry_name'] in max_industry_list:
|
|
results_industry.append(key)
|
|
results_industry.append(key)
|
|
- print('所有:', set(results_industry))
|
|
|
|
results_industry = ','.join(set(results_industry))
|
|
results_industry = ','.join(set(results_industry))
|
|
print('1d', '\n', results_industry)
|
|
print('1d', '\n', results_industry)
|
|
|
|
|
|
@@ -182,20 +204,26 @@ def buy_trader(data, positions):
|
|
|
|
|
|
keep_stocks = results_industry.split(",")
|
|
keep_stocks = results_industry.split(",")
|
|
new_keep_stock = [stock.replace('XSHG', 'SH').replace('XSHE', 'SZ') for stock in keep_stocks]
|
|
new_keep_stock = [stock.replace('XSHG', 'SH').replace('XSHE', 'SZ') for stock in keep_stocks]
|
|
- print(f'new_keep_stock is:{len(new_keep_stock)},{new_keep_stock}')
|
|
|
|
|
|
+ print(f'new_keep_stock is:{len(new_keep_stock)}')
|
|
|
|
+
|
|
|
|
|
|
- max_pos = 15
|
|
|
|
|
|
+ #进入购买程序
|
|
|
|
+ max_pos = 7
|
|
for stock in new_keep_stock:
|
|
for stock in new_keep_stock:
|
|
asset = xt_trader.query_stock_asset(acc)
|
|
asset = xt_trader.query_stock_asset(acc)
|
|
cash = asset.cash
|
|
cash = asset.cash
|
|
- if cash > 2000 and len(positions) < max_pos:
|
|
|
|
- if stock in new_keep_stock:
|
|
|
|
- current_price = data[stock]['lastPrice']
|
|
|
|
- volume = int((cash / 2 / current_price) // 100 * 100)
|
|
|
|
- print('买入信号!!!!!!', stock, volume, current_price)
|
|
|
|
- order_id = xt_trader.order_stock(acc, stock, xtconstant.STOCK_BUY, volume, xtconstant.LATEST_PRICE,
|
|
|
|
- current_price, 'strategy1', 'order_test')
|
|
|
|
- print(order_id)
|
|
|
|
|
|
+ positions_dict = {positions[x].stock_code: positions[x].volume for x in range(0, len(positions)) if
|
|
|
|
+ positions[x].volume > 0}
|
|
|
|
+ print(f'判断{stock}:cash={cash},持仓数量为{len(positions_dict)}')
|
|
|
|
+ current_price = data[stock]['lastPrice']
|
|
|
|
+ current_high = data[stock]['high']
|
|
|
|
+ if cash > 5000 and len(positions_dict) < max_pos and current_price > 9 \
|
|
|
|
+ and current_price > (current_high*0.98):
|
|
|
|
+ volume = int((cash / 3 / current_price) // 100 * 100)
|
|
|
|
+ print('买入信号!!!!!!', stock, volume, current_price)
|
|
|
|
+ order_id = xt_trader.order_stock(acc, stock, xtconstant.STOCK_BUY, volume, xtconstant.LATEST_PRICE,
|
|
|
|
+ current_price, 'strategy1', 'order_test')
|
|
|
|
+ print(order_id)
|
|
else:
|
|
else:
|
|
print(f'Cash只有:{cash} 或者 现有持仓{len(positions)} 超过了{max_pos}')
|
|
print(f'Cash只有:{cash} 或者 现有持仓{len(positions)} 超过了{max_pos}')
|
|
engine_hlfx_pool.dispose()
|
|
engine_hlfx_pool.dispose()
|
|
@@ -216,6 +244,13 @@ def trader(data):
|
|
buy_trader(data, positions)
|
|
buy_trader(data, positions)
|
|
|
|
|
|
|
|
|
|
|
|
+def bridge():
|
|
|
|
+ print("start")
|
|
|
|
+ stocks = xtdata.get_stock_list_in_sector('沪深A股')
|
|
|
|
+ seq = xtdata.subscribe_whole_quote(stocks, callback=trader)
|
|
|
|
+ run(seq)
|
|
|
|
+
|
|
|
|
+
|
|
class MyXtQuantTraderCallback(XtQuantTraderCallback):
|
|
class MyXtQuantTraderCallback(XtQuantTraderCallback):
|
|
def on_disconnected(self):
|
|
def on_disconnected(self):
|
|
"""
|
|
"""
|
|
@@ -289,7 +324,6 @@ if __name__ == '__main__':
|
|
pus = psutil.Process()
|
|
pus = psutil.Process()
|
|
pus.cpu_affinity([4, 5, 6, 7])
|
|
pus.cpu_affinity([4, 5, 6, 7])
|
|
|
|
|
|
- print("start")
|
|
|
|
# 指定客户端所在路径
|
|
# 指定客户端所在路径
|
|
path = r'c:\\qmt\\userdata_mini'
|
|
path = r'c:\\qmt\\userdata_mini'
|
|
# 生成session id 整数类型 同时运行的策略不能重复
|
|
# 生成session id 整数类型 同时运行的策略不能重复
|
|
@@ -309,8 +343,13 @@ if __name__ == '__main__':
|
|
subscribe_result = xt_trader.subscribe(acc)
|
|
subscribe_result = xt_trader.subscribe(acc)
|
|
print('对交易回调进行订阅,订阅后可以收到交易主推,返回0表示订阅成功', subscribe_result)
|
|
print('对交易回调进行订阅,订阅后可以收到交易主推,返回0表示订阅成功', subscribe_result)
|
|
|
|
|
|
|
|
+ scheduler = BlockingScheduler()
|
|
|
|
+ scheduler.add_job(func=bridge, trigger='cron', day_of_week='0-4', hour='9', minute='40',
|
|
|
|
+ timezone="Asia/Shanghai")
|
|
|
|
+ try:
|
|
|
|
+ scheduler.start()
|
|
|
|
+ except (KeyboardInterrupt, SystemExit):
|
|
|
|
+ pass
|
|
|
|
+
|
|
|
|
|
|
- stocks = xtdata.get_stock_list_in_sector('沪深A股')
|
|
|
|
- xtdata.subscribe_whole_quote(stocks, callback=trader)
|
|
|
|
- xtdata.run()
|
|
|
|
# xtdata.subscribe_quote('000001.SZ', '1d', '', '', count=1, callback=MA)
|
|
# xtdata.subscribe_quote('000001.SZ', '1d', '', '', count=1, callback=MA)
|