Merge pull request #238 from fasiondog/feature/block

Block支持对应指数
This commit is contained in:
fasiondog 2024-04-23 18:40:54 +08:00 committed by GitHub
commit 3ec9a92386
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 84 additions and 22 deletions

View File

@ -94,7 +94,7 @@ def get_codepre_list(connect, marketid, quotations):
"""获取前缀代码表"""
stktype_list = get_stktype_list(quotations)
sql = "select codepre, type from `hku_base`.`coderuletype` " \
"where marketid={marketid} and type in {type_list}"\
"where marketid={marketid} and type in {type_list} ORDER by length(codepre) DESC"\
.format(marketid=marketid, type_list=stktype_list)
cur = connect.cursor()
cur.execute(sql)

View File

@ -62,11 +62,11 @@ def create_database(connect):
cur.executescript(f.read())
db_version = get_db_version(connect)
files = [x for x in Path(sql_dir).iterdir() \
if x.is_file() \
and x.name != 'createdb.sql' \
and x.name != '__init__.py' \
and int(x.stem) > db_version and not x.is_dir()]
files = [x for x in Path(sql_dir).iterdir()
if x.is_file()
and x.name != 'createdb.sql'
and x.name != '__init__.py'
and int(x.stem) > db_version and not x.is_dir()]
files.sort()
for file in files:
cur.executescript(file.read_text(encoding='utf8'))
@ -88,7 +88,7 @@ def get_codepre_list(connect, marketid, quotations):
"""获取前缀代码表"""
stktype_list = get_stktype_list(quotations)
sql = "select codepre, type from coderuletype " \
"where marketid={marketid} and type in {type_list}"\
"where marketid={marketid} and type in {type_list} ORDER by length(codepre) DESC"\
.format(marketid=marketid, type_list=stktype_list)
cur = connect.cursor()
a = cur.execute(sql)
@ -100,7 +100,7 @@ def get_codepre_list(connect, marketid, quotations):
def update_last_date(connect, marketid, lastdate):
cur = connect.cursor()
cur.execute("update Market set lastDate={} where marketid='{}'".format(lastdate, marketid))
#if marketid == MARKETID.SH:
# if marketid == MARKETID.SH:
# cur.execute("update LastDate set date={}".format(lastdate))
connect.commit()
cur.close()

View File

@ -4,8 +4,6 @@
# Create on: 20240102
# Author: fasiondog
import json
import akshare # 这里必须再导入 akshare 下否则get_all_zsbk_info会报错
from hikyuu.data.common import MARKET, get_stk_code_name_list
from hikyuu.util import *
from hikyuu.fetcher.stock.zh_block_em import *

View File

@ -4,8 +4,6 @@
# Create on: 20240102
# Author: fasiondog
import json
import akshare # 这里必须再导入 akshare 下否则get_all_zsbk_info会报错
from hikyuu.data.common import MARKET, get_stk_code_name_list
from hikyuu.util import *
from hikyuu.fetcher.stock.zh_block_em import *

View File

@ -0,0 +1,4 @@
ALTER TABLE `hku_base`.`coderuletype` modify `id` int(11) auto_increment;
INSERT INTO `hku_base`.`coderuletype` (`marketid`,`codepre`,`type`,`description`) VALUES (3,'92',11,'北证A股');
INSERT INTO `hku_base`.`coderuletype` (`marketid`,`codepre`,`type`,`description`) VALUES (1,'880',2,'通达信板块指数');
UPDATE `hku_base`.`version` set `version` = 15;

View File

@ -0,0 +1,4 @@
CREATE TABLE IF NOT EXISTS `hku_base`.`BlockIndex` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `category` VARCHAR(100) NOT NULL, `name` VARCHAR(100) NOT NULL, `market_code` VARCHAR(30) NOT NULL, PRIMARY KEY (`id`), INDEX `ix_block` (`category`, `name`)
) COLLATE = 'utf8mb4_general_ci' ENGINE = InnoDB;
UPDATE `hku_base`.`version` set `version` = 16;

View File

@ -0,0 +1,8 @@
BEGIN TRANSACTION;
INSERT INTO `coderuletype` (marketid,codepre,type,description) VALUES (3,'92',11,'北证A股');
INSERT INTO `coderuletype` (marketid,codepre,type,description) VALUES (1,'880',2,'通达信板块指数');
UPDATE `version` set `version` = 16;
COMMIT;

View File

@ -0,0 +1,16 @@
BEGIN TRANSACTION;
CREATE TABLE
IF NOT EXISTS `BlockIndex` (
"id" INTEGER,
`category` VARCHAR(100) NOT NULL,
`name` VARCHAR(100) NOT NULL,
`market_code` VARCHAR(30) NOT NULL,
PRIMARY KEY("id" AUTOINCREMENT)
);
CREATE INDEX "ix_blockindex_category_name" ON "block" (category, name);
UPDATE `version` set `version` = 17;
COMMIT;

View File

@ -26,13 +26,20 @@ Block::Block(const string& category, const string& name) : m_data(make_shared<Da
m_data->m_name = name;
}
Block::Block(const Block& block) {
Block::Block(const string& category, const string& name, const string& indexCode)
: Block(category, name) {
if (!indexCode.empty()) {
m_data->m_indexStock = StockManager::instance().getStock(indexCode);
}
}
Block::Block(const Block& block) noexcept {
if (m_data == block.m_data)
return;
m_data = block.m_data;
}
Block& Block::operator=(const Block& block) {
Block& Block::operator=(const Block& block) noexcept {
HKU_IF_RETURN(this == &block || m_data == block.m_data, *this);
m_data = block.m_data;
return *this;
@ -114,4 +121,10 @@ bool Block::remove(const Stock& stock) {
return true;
}
void Block::setIndexStock(const Stock& stk) {
if (!m_data)
m_data = shared_ptr<Data>(new Data);
m_data->m_indexStock = stk;
}
} /* namespace hku */

View File

@ -21,8 +21,9 @@ class HKU_API Block {
public:
Block();
Block(const string& category, const string& name);
Block(const Block&);
Block& operator=(const Block&);
Block(const string& category, const string& name, const string& indexCode);
Block(const Block&) noexcept;
Block& operator=(const Block&) noexcept;
virtual ~Block();
typedef StockMapIterator const_iterator;
@ -118,10 +119,19 @@ public:
m_data->m_stockDict.clear();
}
/** 获取对应的指数,可能为空 Stock */
Stock getIndexStock() const {
return m_data ? m_data->m_indexStock : Stock();
}
/** 设置对应的指数 */
void setIndexStock(const Stock& stk);
private:
struct HKU_API Data {
string m_category;
string m_name;
Stock m_indexStock; // 对应指数,可能不存在
StockMapIterator::stock_map_t m_stockDict;
};
shared_ptr<Data> m_data;

View File

@ -12,10 +12,11 @@
namespace hku {
struct MySQLBlockTable {
TABLE_BIND3(MySQLBlockTable, block, category, name, market_code)
TABLE_BIND4(MySQLBlockTable, block, category, name, market_code, index_code)
string category;
string name;
string market_code;
string index_code;
};
MySQLBlockInfoDriver::~MySQLBlockInfoDriver() {}
@ -36,7 +37,11 @@ void MySQLBlockInfoDriver::load() {
MySQLConnect connect(connect_param);
vector<MySQLBlockTable> records;
connect.batchLoad(records);
connect.batchLoadView(
records,
"select a.id, a.category, a.name, a.market_code, b.market_code as "
"index_code from `hku_base`.`block` a left "
"join `hku_base`.`BlockIndex` b on a.category=b.category and a.name = b.name");
for (auto& record : records) {
auto category_iter = m_buffer.find(record.category);
@ -46,7 +51,7 @@ void MySQLBlockInfoDriver::load() {
auto& name_dict = m_buffer[record.category];
auto name_iter = name_dict.find(record.name);
if (name_iter == name_dict.end()) {
name_dict[record.name] = {Block(record.category, record.name)};
name_dict[record.name] = {Block(record.category, record.name, record.index_code)};
}
name_dict[record.name].add(record.market_code);
}

View File

@ -12,10 +12,11 @@
namespace hku {
struct SQLiteBlockTable {
TABLE_BIND3(SQLiteBlockTable, block, category, name, market_code)
TABLE_BIND4(SQLiteBlockTable, block, category, name, market_code, index_code)
string category;
string name;
string market_code;
string index_code;
};
SQLiteBlockInfoDriver::~SQLiteBlockInfoDriver() {}
@ -32,7 +33,10 @@ void SQLiteBlockInfoDriver::load() {
SQLiteConnect connect(m_params);
vector<SQLiteBlockTable> records;
connect.batchLoad(records);
connect.batchLoadView(records,
"select a.id, a.category, a.name, a.market_code, b.market_code as "
"index_code from block a left "
"join BlockIndex b on a.category=b.category and a.name = b.name");
for (auto& record : records) {
auto category_iter = m_buffer.find(record.category);
@ -42,7 +46,7 @@ void SQLiteBlockInfoDriver::load() {
auto& name_dict = m_buffer[record.category];
auto name_iter = name_dict.find(record.name);
if (name_iter == name_dict.end()) {
name_dict[record.name] = {Block(record.category, record.name)};
name_dict[record.name] = {Block(record.category, record.name, record.index_code)};
}
name_dict[record.name].add(record.market_code);
}

View File

@ -36,6 +36,8 @@ void export_Block(py::module& m) {
.def_property("category", setCategory, getCategory, "板块所属分类")
.def_property("name", getName, setName, "板块名称")
.def_property("index_stock", &Block::getIndexStock, &Block::setIndexStock,
py::return_value_policy::copy, "对应指数")
.def("empty", &Block::empty, R"(empty(self)