mirror of
https://gitee.com/fasiondog/hikyuu.git
synced 2024-12-02 11:58:21 +08:00
Merge branch 'master' of https://github.com/fasiondog/hikyuu into feature/docs
This commit is contained in:
commit
71b8f41f4c
@ -57,6 +57,12 @@ class STOCKTYPE:
|
||||
BOND = 7 # 其他债券
|
||||
GEM = 8 # 创业板
|
||||
START = 9 # 科创板
|
||||
A_BJ = 11 # 北交所A股
|
||||
|
||||
|
||||
def get_a_stktype_list():
|
||||
"""获取A股市场证券类型元组,含B股"""
|
||||
return (STOCKTYPE.A, STOCKTYPE.INDEX, STOCKTYPE.B, STOCKTYPE.GEM, STOCKTYPE.START, STOCKTYPE.A_BJ)
|
||||
|
||||
|
||||
def get_stktype_list(quotations=None):
|
||||
@ -68,13 +74,13 @@ def get_stktype_list(quotations=None):
|
||||
:return: 股票类别元组
|
||||
"""
|
||||
if not quotations:
|
||||
return (1, 2, 3, 4, 5, 6, 7, 8, 9)
|
||||
return (1, 2, 3, 4, 5, 6, 7, 8, 9, 11)
|
||||
|
||||
result = []
|
||||
for quotation in quotations:
|
||||
new_quotation = quotation.lower()
|
||||
if new_quotation == 'stock':
|
||||
result += [STOCKTYPE.A, STOCKTYPE.INDEX, STOCKTYPE.B, STOCKTYPE.GEM, STOCKTYPE.START]
|
||||
result += list(get_a_stktype_list())
|
||||
elif new_quotation == 'fund':
|
||||
result += [STOCKTYPE.FUND, STOCKTYPE.ETF]
|
||||
elif new_quotation == 'bond':
|
||||
|
3
hikyuu/data/mysql_upgrade/0014.sql
Normal file
3
hikyuu/data/mysql_upgrade/0014.sql
Normal file
@ -0,0 +1,3 @@
|
||||
UPDATE `hku_base`.`stock` set `type`=11 where `marketid`=3;
|
||||
UPDATE `hku_base`.`coderuletype` set `type`=11 where `marketid`=3;
|
||||
UPDATE `hku_base`.`version` set `version` = 14;
|
@ -22,7 +22,7 @@
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
from hikyuu.data.common import MARKETID, STOCKTYPE, historyfinancialreader
|
||||
from hikyuu.data.common import MARKETID, STOCKTYPE, historyfinancialreader, get_a_stktype_list
|
||||
from hikyuu.data.common_mysql import get_marketid
|
||||
from hikyuu.util import *
|
||||
|
||||
@ -31,8 +31,8 @@ from hikyuu.util import *
|
||||
def pytdx_import_finance_to_mysql(db_connect, pytdx_connect, market):
|
||||
"""导入公司财务信息"""
|
||||
marketid = get_marketid(db_connect, market)
|
||||
sql = "select `stockid`, `marketid`, `code`, `valid`, `type` from `hku_base`.`stock` where marketid={} and type = {} and valid=1"\
|
||||
.format(marketid, STOCKTYPE.A)
|
||||
sql = "select `stockid`, `marketid`, `code`, `valid`, `type` from `hku_base`.`stock` where marketid={} and type in {} and valid=1"\
|
||||
.format(marketid, get_a_stktype_list())
|
||||
|
||||
cur = db_connect.cursor()
|
||||
a = cur.execute(sql)
|
||||
|
@ -22,15 +22,15 @@
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
from hikyuu.data.common import MARKETID, STOCKTYPE, historyfinancialreader
|
||||
from hikyuu.data.common import MARKETID, STOCKTYPE, historyfinancialreader, get_a_stktype_list
|
||||
from hikyuu.data.common_sqlite3 import get_marketid, create_database
|
||||
|
||||
|
||||
def pytdx_import_finance_to_sqlite(db_connect, pytdx_connect, market):
|
||||
"""导入公司财务信息"""
|
||||
marketid = get_marketid(db_connect, market)
|
||||
sql = "select stockid, marketid, code, valid, type from stock where marketid={} and type = {} and valid=1"\
|
||||
.format(marketid, STOCKTYPE.A)
|
||||
sql = "select stockid, marketid, code, valid, type from stock where marketid={} and type in {} and valid=1"\
|
||||
.format(marketid, get_a_stktype_list())
|
||||
|
||||
cur = db_connect.cursor()
|
||||
all_list = cur.execute(sql).fetchall()
|
||||
|
@ -454,8 +454,9 @@ def import_trans(connect, market, quotations, api, dest_dir, max_days=30, progre
|
||||
stock_list = get_stock_list(connect, market, quotations)
|
||||
|
||||
total = len(stock_list)
|
||||
a_stktype_list = get_a_stktype_list()
|
||||
for i, stock in enumerate(stock_list):
|
||||
if stock[3] == 0 or len(stock[2]) != 6 or stock[4] not in (STOCKTYPE.A, STOCKTYPE.B, STOCKTYPE.GEM):
|
||||
if stock[3] == 0 or len(stock[2]) != 6 or stock[4] not in a_stktype_list:
|
||||
if progress:
|
||||
progress(i, total)
|
||||
continue
|
||||
|
@ -559,8 +559,9 @@ def import_trans(
|
||||
|
||||
stock_list = get_stock_list(connect, market, quotations)
|
||||
total = len(stock_list)
|
||||
a_stktype_list = get_a_stktype_list()
|
||||
for i, stock in enumerate(stock_list):
|
||||
if stock[3] == 0 or len(stock[2]) != 6 or stock[4] not in (STOCKTYPE.A, STOCKTYPE.B, STOCKTYPE.GEM):
|
||||
if stock[3] == 0 or len(stock[2]) != 6 or stock[4] not in a_stktype_list:
|
||||
if progress:
|
||||
progress(i, total)
|
||||
continue
|
||||
|
7
hikyuu/data/sqlite_upgrade/0015.sql
Normal file
7
hikyuu/data/sqlite_upgrade/0015.sql
Normal file
@ -0,0 +1,7 @@
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
UPDATE `Stock` set `type`=11 where `marketid`=3;
|
||||
UPDATE `CodeRuleType` set `type`=11 where `marketid`=3;
|
||||
UPDATE `version` set `version` = 15;
|
||||
|
||||
COMMIT;
|
@ -8,7 +8,7 @@ def deprecated_func(new_func, old_func_name, new_func_name):
|
||||
def wrap_deprecated_func(func):
|
||||
def wrapfunc(*args, **kwarg):
|
||||
print(
|
||||
#'Deprecated warning: "{}" will be deprecated, please use: "{}"'.format(
|
||||
# 'Deprecated warning: "{}" will be deprecated, please use: "{}"'.format(
|
||||
'警告: "{}" 函数即将废弃,请使用 "{}" 代替'.format(old_func_name, new_func_name)
|
||||
)
|
||||
return new_func(*args, **kwarg)
|
||||
@ -25,11 +25,11 @@ def deprecated_attr(name_dict):
|
||||
clzname = self.__class__.__name__
|
||||
if name in name_dict:
|
||||
if name_dict[name] is None:
|
||||
#print('Removed warning: the {}.{} will be removed!'.format(clzname, name))
|
||||
# print('Removed warning: the {}.{} will be removed!'.format(clzname, name))
|
||||
print('警告: "{}.{}" 接口已被删除!'.format(clzname, name))
|
||||
else:
|
||||
print(
|
||||
#'Deprecated warning: the "{}.{}" will be deprecated, please use: "{}.{}"'.
|
||||
# 'Deprecated warning: the "{}.{}" will be deprecated, please use: "{}.{}"'.
|
||||
'警告: "{}.{}" 即将被废弃,请使用 "{}.{}" 代替'.format(clzname, name, clzname, name_dict[name])
|
||||
)
|
||||
return func(self, name_dict[name])
|
||||
@ -42,11 +42,11 @@ def deprecated_attr(name_dict):
|
||||
return wrap_deprecated_attr
|
||||
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# --------------------------------------------------------------------
|
||||
#
|
||||
# 待废弃函数
|
||||
#
|
||||
#--------------------------------------------------------------------
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
|
||||
@deprecated_func(get_version, 'getVersion', 'get_version')
|
||||
@ -104,11 +104,11 @@ def SL_FixedValue(*args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# --------------------------------------------------------------------
|
||||
#
|
||||
# 待废弃属性
|
||||
#
|
||||
#--------------------------------------------------------------------
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
|
||||
@deprecated_attr(
|
||||
@ -486,7 +486,6 @@ SlippageBase.__getattr__ = SlippageBase_getattr
|
||||
'getKRecordList': 'get_krecord_list',
|
||||
'getDatetimeList': 'get_datetime_list',
|
||||
'getFinanceInfo': 'get_finance_info',
|
||||
'getHistoryFinanceInfo': 'get_history_finance_info',
|
||||
'realtimeUpdate': 'realtime_update',
|
||||
'getWeight': 'get_weight',
|
||||
'loadKDataToBuffer': 'load_kdata_to_buffer',
|
||||
|
155
hikyuu/extend.py
155
hikyuu/extend.py
@ -1,9 +1,9 @@
|
||||
#
|
||||
# 对 C++ 引出类和函数进行扩展, pybind11 对小函数到导出效率不如 python 直接执行
|
||||
#
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
from datetime import *
|
||||
from .util.slice import list_getitem
|
||||
from .core import *
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
@ -293,94 +293,87 @@ def new_Query_init(self, start=0, end=None, ktype=Query.DAY, recover_type=Query.
|
||||
|
||||
Query.__init__ = new_Query_init
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 增加转化为 np.array、pandas.DataFrame 的功能
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
try:
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
def KData_to_np(kdata):
|
||||
"""转化为numpy结构数组"""
|
||||
if kdata.get_query().ktype in ('DAY', 'WEEK', 'MONTH', 'QUARTER', 'HALFYEAR', 'YEAR'):
|
||||
k_type = np.dtype(
|
||||
{
|
||||
'names': ['datetime', 'open', 'high', 'low', 'close', 'amount', 'volume'],
|
||||
'formats': ['datetime64[D]', 'd', 'd', 'd', 'd', 'd', 'd']
|
||||
}
|
||||
)
|
||||
else:
|
||||
k_type = np.dtype(
|
||||
{
|
||||
'names': ['datetime', 'open', 'high', 'low', 'close', 'amount', 'volume'],
|
||||
'formats': ['datetime64[ms]', 'd', 'd', 'd', 'd', 'd', 'd']
|
||||
}
|
||||
)
|
||||
return np.array(
|
||||
[(k.datetime.datetime(), k.open, k.high, k.low, k.close, k.amount, k.volume) for k in kdata], dtype=k_type
|
||||
)
|
||||
|
||||
def KData_to_df(kdata):
|
||||
"""转化为pandas的DataFrame"""
|
||||
return pd.DataFrame.from_records(KData_to_np(kdata), index='datetime')
|
||||
|
||||
KData.to_np = KData_to_np
|
||||
KData.to_df = KData_to_df
|
||||
|
||||
def PriceList_to_np(data):
|
||||
"""仅在安装了numpy模块时生效,转换为numpy.array"""
|
||||
return np.array(data, dtype='d')
|
||||
|
||||
def PriceList_to_df(data):
|
||||
"""仅在安装了pandas模块时生效,转换为pandas.DataFrame"""
|
||||
return pd.DataFrame(data.to_np(), columns=('Value', ))
|
||||
|
||||
PriceList.to_np = PriceList_to_np
|
||||
PriceList.to_df = PriceList_to_df
|
||||
|
||||
def DatetimeList_to_np(data):
|
||||
"""仅在安装了numpy模块时生效,转换为numpy.array"""
|
||||
return np.array(data, dtype='datetime64[D]')
|
||||
|
||||
def DatetimeList_to_df(data):
|
||||
"""仅在安装了pandas模块时生效,转换为pandas.DataFrame"""
|
||||
return pd.DataFrame(data.to_np(), columns=('Datetime', ))
|
||||
|
||||
DatetimeList.to_np = DatetimeList_to_np
|
||||
DatetimeList.to_df = DatetimeList_to_df
|
||||
|
||||
def TimeLine_to_np(data):
|
||||
"""转化为numpy结构数组"""
|
||||
t_type = np.dtype({'names': ['datetime', 'price', 'vol'], 'formats': ['datetime64[ms]', 'd', 'd']})
|
||||
return np.array([(t.date.datetime(), t.price, t.vol) for t in data], dtype=t_type)
|
||||
|
||||
def TimeLine_to_df(kdata):
|
||||
"""转化为pandas的DataFrame"""
|
||||
return pd.DataFrame.from_records(TimeLine_to_np(kdata), index='datetime')
|
||||
|
||||
TimeLineList.to_np = TimeLine_to_np
|
||||
TimeLineList.to_df = TimeLine_to_df
|
||||
|
||||
def TransList_to_np(data):
|
||||
"""转化为numpy结构数组"""
|
||||
t_type = np.dtype(
|
||||
def KData_to_np(kdata):
|
||||
"""转化为numpy结构数组"""
|
||||
if kdata.get_query().ktype in ('DAY', 'WEEK', 'MONTH', 'QUARTER', 'HALFYEAR', 'YEAR'):
|
||||
k_type = np.dtype(
|
||||
{
|
||||
'names': ['datetime', 'price', 'vol', 'direct'],
|
||||
'formats': ['datetime64[ms]', 'd', 'd', 'd']
|
||||
'names': ['datetime', 'open', 'high', 'low', 'close', 'amount', 'volume'],
|
||||
'formats': ['datetime64[D]', 'd', 'd', 'd', 'd', 'd', 'd']
|
||||
}
|
||||
)
|
||||
return np.array([(t.date.datetime(), t.price, t.vol, t.direct) for t in data], dtype=t_type)
|
||||
else:
|
||||
k_type = np.dtype(
|
||||
{
|
||||
'names': ['datetime', 'open', 'high', 'low', 'close', 'amount', 'volume'],
|
||||
'formats': ['datetime64[ms]', 'd', 'd', 'd', 'd', 'd', 'd']
|
||||
}
|
||||
)
|
||||
return np.array(
|
||||
[(k.datetime.datetime(), k.open, k.high, k.low, k.close, k.amount, k.volume) for k in kdata], dtype=k_type
|
||||
)
|
||||
|
||||
def TransList_to_df(kdata):
|
||||
"""转化为pandas的DataFrame"""
|
||||
return pd.DataFrame.from_records(TransList_to_np(kdata), index='datetime')
|
||||
|
||||
TransList.to_np = TransList_to_np
|
||||
TransList.to_df = TransList_to_df
|
||||
def KData_to_df(kdata):
|
||||
"""转化为pandas的DataFrame"""
|
||||
return pd.DataFrame.from_records(KData_to_np(kdata), index='datetime')
|
||||
|
||||
except:
|
||||
pass
|
||||
|
||||
KData.to_np = KData_to_np
|
||||
KData.to_df = KData_to_df
|
||||
|
||||
|
||||
def DatetimeList_to_np(data):
|
||||
"""仅在安装了numpy模块时生效,转换为numpy.array"""
|
||||
return np.array(data, dtype='datetime64[D]')
|
||||
|
||||
|
||||
def DatetimeList_to_df(data):
|
||||
"""仅在安装了pandas模块时生效,转换为pandas.DataFrame"""
|
||||
return pd.DataFrame(data.to_np(), columns=('Datetime', ))
|
||||
|
||||
|
||||
DatetimeList.to_np = DatetimeList_to_np
|
||||
DatetimeList.to_df = DatetimeList_to_df
|
||||
|
||||
|
||||
def TimeLine_to_np(data):
|
||||
"""转化为numpy结构数组"""
|
||||
t_type = np.dtype({'names': ['datetime', 'price', 'vol'], 'formats': ['datetime64[ms]', 'd', 'd']})
|
||||
return np.array([(t.date.datetime(), t.price, t.vol) for t in data], dtype=t_type)
|
||||
|
||||
|
||||
def TimeLine_to_df(kdata):
|
||||
"""转化为pandas的DataFrame"""
|
||||
return pd.DataFrame.from_records(TimeLine_to_np(kdata), index='datetime')
|
||||
|
||||
|
||||
TimeLineList.to_np = TimeLine_to_np
|
||||
TimeLineList.to_df = TimeLine_to_df
|
||||
|
||||
|
||||
def TransList_to_np(data):
|
||||
"""转化为numpy结构数组"""
|
||||
t_type = np.dtype(
|
||||
{
|
||||
'names': ['datetime', 'price', 'vol', 'direct'],
|
||||
'formats': ['datetime64[ms]', 'd', 'd', 'd']
|
||||
}
|
||||
)
|
||||
return np.array([(t.date.datetime(), t.price, t.vol, t.direct) for t in data], dtype=t_type)
|
||||
|
||||
|
||||
def TransList_to_df(kdata):
|
||||
"""转化为pandas的DataFrame"""
|
||||
return pd.DataFrame.from_records(TransList_to_np(kdata), index='datetime')
|
||||
|
||||
|
||||
TransList.to_np = TransList_to_np
|
||||
TransList.to_df = TransList_to_df
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 增强 Parameter
|
||||
|
@ -62,30 +62,20 @@ Indicator.__getitem__ = indicator_getitem
|
||||
Indicator.__iter__ = indicator_iter
|
||||
|
||||
|
||||
try:
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
def indicator_to_df(indicator):
|
||||
"""转化为pandas.DataFrame"""
|
||||
if indicator.get_result_num() == 1:
|
||||
return pd.DataFrame(indicator.to_np(), columns=[indicator.name])
|
||||
data = {}
|
||||
name = indicator.name
|
||||
columns = []
|
||||
for i in range(indicator.get_result_num()):
|
||||
data[name + str(i)] = indicator.get_result(i)
|
||||
columns.append(name + str(i + 1))
|
||||
return pd.DataFrame(data, columns=columns)
|
||||
|
||||
def indicator_to_df(indicator):
|
||||
"""转化为pandas.DataFrame"""
|
||||
if indicator.get_result_num() == 1:
|
||||
return pd.DataFrame(indicator.to_np(), columns=[indicator.name])
|
||||
|
||||
data = {}
|
||||
name = indicator.name
|
||||
columns = []
|
||||
for i in range(indicator.get_result_num()):
|
||||
data[name + str(i)] = indicator.get_result(i)
|
||||
columns.append(name + str(i + 1))
|
||||
return pd.DataFrame(data, columns=columns)
|
||||
|
||||
Indicator.to_df = indicator_to_df
|
||||
|
||||
except:
|
||||
print(
|
||||
"warning:can't import numpy or pandas lib, ",
|
||||
"you can't use method Inidicator.to_np() and to_df!"
|
||||
)
|
||||
Indicator.to_df = indicator_to_df
|
||||
|
||||
|
||||
def concat_to_df(dates, ind_list, head_stock_code=True, head_ind_name=False):
|
||||
|
@ -2,10 +2,10 @@
|
||||
# -*- coding: utf8 -*-
|
||||
# gb18030
|
||||
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# 作者:fasiondog
|
||||
# 历史:1)20130316, Added by fasiondog
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
import unittest
|
||||
|
||||
@ -18,7 +18,7 @@ class MoneyManagerPython(MoneyManagerBase):
|
||||
self.set_param("n", 10)
|
||||
self._m_flag = False
|
||||
|
||||
def getBuyNumber(self, datetime, stock, price, risk):
|
||||
def get_buy_num(self, datetime, stock, price, risk):
|
||||
if self._m_flag:
|
||||
return 10
|
||||
else:
|
||||
@ -44,14 +44,14 @@ class MoneyManagerTest(unittest.TestCase):
|
||||
self.assertEqual(p.get_param("n"), 10)
|
||||
p.set_param("n", 20)
|
||||
self.assertEqual(p.get_param("n"), 20)
|
||||
self.assertEqual(p.getBuyNumber(Datetime(200101010000), stock, 10.0, 0.0), 20)
|
||||
self.assertEqual(p.get_buy_num(Datetime(200101010000), stock, 10.0, 0.0), 20)
|
||||
p.reset()
|
||||
self.assertEqual(p.getBuyNumber(Datetime(200101010000), stock, 10.0, 0.0), 10)
|
||||
self.assertEqual(p.get_buy_num(Datetime(200101010000), stock, 10.0, 0.0), 10)
|
||||
|
||||
p_clone = p.clone()
|
||||
self.assertEqual(p_clone.name, "MoneyManagerPython")
|
||||
self.assertEqual(p_clone.get_param("n"), 20)
|
||||
self.assertEqual(p_clone.getBuyNumber(Datetime(200101010000), stock, 10, 0.0), 10)
|
||||
self.assertEqual(p_clone.get_buy_num(Datetime(200101010000), stock, 10, 0.0), 10)
|
||||
|
||||
p.set_param("n", 1)
|
||||
p_clone.set_param("n", 3)
|
||||
@ -63,18 +63,18 @@ def testCrtMM(self):
|
||||
pass
|
||||
|
||||
|
||||
def testgetBuyNumber(self, datetime, stock, price, risk):
|
||||
def testget_buy_num(self, datetime, stock, price, risk, part):
|
||||
return 10.0 if datetime == Datetime(200101010000) else 0.0
|
||||
|
||||
|
||||
class TestCrtMM(unittest.TestCase):
|
||||
def test_crt_mm(self):
|
||||
p = crtMM(testCrtMM, params={'n': 10}, name="TestMM")
|
||||
p.getBuyNumber = testgetBuyNumber
|
||||
p = crtMM(testget_buy_num, testCrtMM, params={'n': 10}, name="TestMM")
|
||||
p.tm = crtTM(Datetime(200101010000))
|
||||
self.assertEqual(p.name, "TestMM")
|
||||
stock = sm['sh000001']
|
||||
self.assertEqual(p.getBuyNumber(p, Datetime(200101010000), stock, 1.0, 1.0), 10.0)
|
||||
self.assertEqual(p.getBuyNumber(p, Datetime(200101020000), stock, 1.0, 1.0), 0.0)
|
||||
self.assertEqual(p.get_buy_num(Datetime(200101010000), stock, 1.0, 1.0, SystemPart.MM), 10.0)
|
||||
self.assertEqual(p.get_buy_num(Datetime(200101020000), stock, 1.0, 1.0, SystemPart.MM), 0.0)
|
||||
|
||||
p_clone = p.clone()
|
||||
self.assertEqual(p_clone.name, "TestMM")
|
||||
@ -85,4 +85,4 @@ def suite():
|
||||
|
||||
|
||||
def suiteTestCrtMM():
|
||||
return unittest.TestLoader().loadTestsFromTestCase(TestCrtMM)
|
||||
return unittest.TestLoader().loadTestsFromTestCase(TestCrtMM)
|
||||
|
@ -2,10 +2,10 @@
|
||||
# -*- coding: utf8 -*-
|
||||
# gb18030
|
||||
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# 作者:fasiondog
|
||||
# 历史:1)20130321, Added by fasiondog
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
import unittest
|
||||
|
||||
@ -17,12 +17,12 @@ class SlippagePython(SlippageBase):
|
||||
super(SlippagePython, self).__init__("SlippagePython")
|
||||
self._x = 0
|
||||
|
||||
def getRealBuyPrice(self, datetime, price):
|
||||
def get_real_buy_price(self, datetime, price):
|
||||
if self._x < 10:
|
||||
return 0.0
|
||||
return 1.0
|
||||
|
||||
def getRealSellPrice(self, datetime, price):
|
||||
def get_real_sell_price(self, datetime, price):
|
||||
if self._x < 10:
|
||||
return 0.0
|
||||
return 1.0
|
||||
@ -43,14 +43,14 @@ class SlippageTest(unittest.TestCase):
|
||||
def test_SlippageBase(self):
|
||||
p = SlippagePython()
|
||||
self.assertEqual(p.name, "SlippagePython")
|
||||
self.assertEqual(p.getRealBuyPrice(Datetime(200101010000), 1.0), 0.0)
|
||||
self.assertEqual(p.getRealSellPrice(Datetime(200101010000), 1.0), 0.0)
|
||||
self.assertEqual(p.get_real_buy_price(Datetime(200101010000), 1.0), 0.0)
|
||||
self.assertEqual(p.get_real_sell_price(Datetime(200101010000), 1.0), 0.0)
|
||||
|
||||
self.assertEqual(p._x, 0)
|
||||
p._x = 10
|
||||
self.assertEqual(p._x, 10)
|
||||
self.assertEqual(p.getRealBuyPrice(Datetime(200101010000), 1.0), 1.0)
|
||||
self.assertEqual(p.getRealSellPrice(Datetime(200101010000), 1.0), 1.0)
|
||||
self.assertEqual(p.get_real_buy_price(Datetime(200101010000), 1.0), 1.0)
|
||||
self.assertEqual(p.get_real_sell_price(Datetime(200101010000), 1.0), 1.0)
|
||||
p.reset()
|
||||
self.assertEqual(p._x, 0)
|
||||
|
||||
@ -66,18 +66,16 @@ def test_crtSL_func(self):
|
||||
pass
|
||||
|
||||
|
||||
def test_getRealBuyPrice_func(self, datetime, price):
|
||||
def test_get_real_buy_price_func(self, datetime, price):
|
||||
return 10.0 if datetime == Datetime(200101010000) else 0.0
|
||||
|
||||
|
||||
class TestCrtSL(unittest.TestCase):
|
||||
def test_crtSL(self):
|
||||
p = crtSL(test_crtSL_func, params={'n': 10}, name="TestSL")
|
||||
p.getRealBuyPrice = test_getRealBuyPrice_func
|
||||
def test_crtSP(self):
|
||||
p = crtSP(test_get_real_buy_price_func, test_crtSL_func, params={'n': 10}, name="TestSL")
|
||||
self.assertEqual(p.name, "TestSL")
|
||||
self.assertEqual(p.getRealBuyPrice(p, Datetime(200101010000), 1.0), 10.0)
|
||||
self.assertEqual(p.getRealBuyPrice(p, Datetime(200101020000), 1.0), 0.0)
|
||||
|
||||
self.assertEqual(p.get_real_buy_price(Datetime(200101010000), 1.0), 10.0)
|
||||
self.assertEqual(p.get_real_buy_price(Datetime(200101020000), 1.0), 0.0)
|
||||
p_clone = p.clone()
|
||||
self.assertEqual(p_clone.name, "TestSL")
|
||||
|
||||
@ -87,4 +85,4 @@ def suite():
|
||||
|
||||
|
||||
def suiteTestCrtSL():
|
||||
return unittest.TestLoader().loadTestsFromTestCase(TestCrtSL)
|
||||
return unittest.TestLoader().loadTestsFromTestCase(TestCrtSL)
|
||||
|
@ -2,10 +2,10 @@
|
||||
# -*- coding: utf8 -*-
|
||||
# gb18030
|
||||
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# 作者:fasiondog
|
||||
# 历史:1)20120928, Added by fasiondog
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
import unittest
|
||||
|
||||
@ -59,6 +59,69 @@ class StockTest(unittest.TestCase):
|
||||
self.assertEqual(stock.name, b.name)
|
||||
self.assertEqual(b.market_code, 'SH000001')
|
||||
|
||||
def test_external_stock(self):
|
||||
stk = Stock("xy", "00z", "测试")
|
||||
self.assertEqual(stk.name, "测试")
|
||||
self.assertEqual(stk.market, "XY")
|
||||
self.assertEqual(stk.code, "00z")
|
||||
self.assertEqual(stk.market_code, "XY00z")
|
||||
|
||||
stk.market = "aB"
|
||||
self.assertEqual(stk.market, "AB")
|
||||
self.assertEqual(stk.market_code, "AB00z")
|
||||
|
||||
stk.code = "000001"
|
||||
self.assertEqual(stk.code, "000001")
|
||||
self.assertEqual(stk.market_code, "AB000001")
|
||||
|
||||
stk.name = "test"
|
||||
self.assertEqual(stk.name, "test")
|
||||
|
||||
self.assertEqual(stk.valid, False)
|
||||
stk.valid = True
|
||||
self.assert_(stk.valid)
|
||||
|
||||
self.assertNotEqual(stk.type, constant.STOCKTYPE_A)
|
||||
stk.type = constant.STOCKTYPE_A
|
||||
self.assertEqual(stk.type, constant.STOCKTYPE_A)
|
||||
|
||||
self.assertNotEqual(stk.tick, 1)
|
||||
stk.tick = 1
|
||||
self.assertEqual(stk.tick, 1)
|
||||
|
||||
self.assertNotEqual(stk.tick_value, 2)
|
||||
stk.tick_value = 2
|
||||
self.assertEqual(stk.tick_value, 2)
|
||||
self.assertEqual(stk.unit, 2)
|
||||
|
||||
self.assertNotEqual(stk.atom, 2)
|
||||
stk.atom = 2
|
||||
self.assertEqual(stk.atom, 2)
|
||||
|
||||
self.assertNotEqual(stk.min_trade_number, 1)
|
||||
stk.min_trade_number = 1
|
||||
self.assertEqual(stk.min_trade_number, 1)
|
||||
|
||||
self.assertNotEqual(stk.max_trade_number, 10000)
|
||||
stk.max_trade_number = 10000
|
||||
self.assertEqual(stk.max_trade_number, 10000)
|
||||
|
||||
ks = [KRecord(Datetime(20010101), 5.0, 9.0, 4.0, 6.5, 1000.0, 100000.0)]
|
||||
stk.set_krecord_list(ks)
|
||||
self.assertEqual(stk.get_count(), 1)
|
||||
k = stk.get_kdata(Query(0))
|
||||
self.assertEqual(len(k), 1)
|
||||
self.assertEqual(k[0], KRecord(Datetime(20010101), 5.0, 9.0, 4.0, 6.5, 1000.0, 100000.0))
|
||||
|
||||
self.assert_(stk not in sm)
|
||||
sm.add_stock(stk)
|
||||
self.assert_(stk in sm)
|
||||
stk2 = sm['ab000001']
|
||||
self.assert_(not stk2.is_null())
|
||||
self.assert_(stk2, stk)
|
||||
sm.remove_stock("ab000001")
|
||||
self.assert_(stk not in sm)
|
||||
|
||||
|
||||
def suite():
|
||||
return unittest.TestLoader().loadTestsFromTestCase(StockTest)
|
||||
|
@ -31,80 +31,81 @@
|
||||
|
||||
from hikyuu.util.slice import list_getitem
|
||||
from hikyuu import *
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
try:
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
def TradeList_to_np(t_list):
|
||||
"""转化为numpy结构数组"""
|
||||
t_type = np.dtype(
|
||||
{
|
||||
'names': [
|
||||
'交易日期', '证券代码', '证券名称', '业务名称', '计划交易价格', '实际成交价格', '目标价格', '成交数量', '佣金', '印花税', '过户费', '其它成本',
|
||||
'交易总成本', '止损价', '现金余额', '信号来源'
|
||||
],
|
||||
'formats':
|
||||
['datetime64[D]', 'U10', 'U20', 'U10', 'd', 'd', 'd', 'i', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'U5']
|
||||
}
|
||||
)
|
||||
return np.array(
|
||||
[
|
||||
(
|
||||
t.datetime, t.stock.market_code, t.stock.name, get_business_name(t.business), t.plan_price,
|
||||
t.real_price, t.goal_price, t.number, t.cost.commission, t.cost.stamptax, t.cost.transferfee,
|
||||
t.cost.others, t.cost.total, t.stoploss, t.cash, get_system_part_name(t.part)
|
||||
) for t in t_list
|
||||
def TradeList_to_np(t_list):
|
||||
"""转化为numpy结构数组"""
|
||||
t_type = np.dtype(
|
||||
{
|
||||
'names': [
|
||||
'交易日期', '证券代码', '证券名称', '业务名称', '计划交易价格', '实际成交价格', '目标价格', '成交数量', '佣金', '印花税', '过户费', '其它成本',
|
||||
'交易总成本', '止损价', '现金余额', '信号来源'
|
||||
],
|
||||
dtype=t_type
|
||||
)
|
||||
'formats':
|
||||
['datetime64[D]', 'U10', 'U20', 'U10', 'd', 'd', 'd', 'i', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'U5']
|
||||
}
|
||||
)
|
||||
return np.array(
|
||||
[
|
||||
(
|
||||
t.datetime, t.stock.market_code, t.stock.name, get_business_name(t.business), t.plan_price,
|
||||
t.real_price, t.goal_price, t.number, t.cost.commission, t.cost.stamptax, t.cost.transferfee,
|
||||
t.cost.others, t.cost.total, t.stoploss, t.cash, get_system_part_name(t.part)
|
||||
) for t in t_list
|
||||
],
|
||||
dtype=t_type
|
||||
)
|
||||
|
||||
def TradeList_to_df(t):
|
||||
"""转化为pandas的DataFrame"""
|
||||
return pd.DataFrame.from_records(TradeList_to_np(t), index='交易日期')
|
||||
|
||||
TradeRecordList.to_np = TradeList_to_np
|
||||
TradeRecordList.to_df = TradeList_to_df
|
||||
def TradeList_to_df(t):
|
||||
"""转化为pandas的DataFrame"""
|
||||
return pd.DataFrame.from_records(TradeList_to_np(t), index='交易日期')
|
||||
|
||||
def PositionList_to_np(pos_list):
|
||||
"""转化为numpy结构数组"""
|
||||
t_type = np.dtype(
|
||||
{
|
||||
'names': ['证券代码', '证券名称', '买入日期', '已持仓天数', '持仓数量', '投入金额', '当前市值', '盈亏金额', '盈亏比例'],
|
||||
'formats': ['U10', 'U20', 'datetime64[D]', 'i', 'i', 'd', 'd', 'd', 'd']
|
||||
}
|
||||
)
|
||||
|
||||
sm = StockManager.instance()
|
||||
query = Query(-1)
|
||||
data = []
|
||||
for pos in pos_list:
|
||||
invest = pos.buy_money - pos.sell_money + pos.total_cost
|
||||
k = pos.stock.get_kdata(query)
|
||||
cur_val = k[0].close * pos.number
|
||||
bonus = cur_val - invest
|
||||
date_list = sm.get_trading_calendar(Query(Datetime(pos.take_datetime.date())))
|
||||
data.append(
|
||||
(
|
||||
pos.stock.market_code, pos.stock.name, pos.take_datetime, len(date_list), pos.number, invest,
|
||||
cur_val, bonus, 100 * bonus / invest
|
||||
)
|
||||
TradeRecordList.to_np = TradeList_to_np
|
||||
TradeRecordList.to_df = TradeList_to_df
|
||||
|
||||
|
||||
def PositionList_to_np(pos_list):
|
||||
"""转化为numpy结构数组"""
|
||||
t_type = np.dtype(
|
||||
{
|
||||
'names': ['证券代码', '证券名称', '买入日期', '已持仓天数', '持仓数量', '投入金额', '当前市值', '盈亏金额', '盈亏比例'],
|
||||
'formats': ['U10', 'U20', 'datetime64[D]', 'i', 'i', 'd', 'd', 'd', 'd']
|
||||
}
|
||||
)
|
||||
sm = StockManager.instance()
|
||||
query = Query(-1)
|
||||
data = []
|
||||
for pos in pos_list:
|
||||
invest = pos.buy_money - pos.sell_money + pos.total_cost
|
||||
k = pos.stock.get_kdata(query)
|
||||
cur_val = k[0].close * pos.number
|
||||
bonus = cur_val - invest
|
||||
date_list = sm.get_trading_calendar(Query(Datetime(pos.take_datetime.date())))
|
||||
data.append(
|
||||
(
|
||||
pos.stock.market_code, pos.stock.name, pos.take_datetime, len(date_list), pos.number, invest,
|
||||
cur_val, bonus, 100 * bonus / invest
|
||||
)
|
||||
)
|
||||
return np.array(data, dtype=t_type)
|
||||
|
||||
return np.array(data, dtype=t_type)
|
||||
|
||||
def PositionList_to_df(pos_list):
|
||||
"""转化为pandas的DataFrame"""
|
||||
return pd.DataFrame.from_records(PositionList_to_np(pos_list), index='证券代码')
|
||||
def PositionList_to_df(pos_list):
|
||||
"""转化为pandas的DataFrame"""
|
||||
return pd.DataFrame.from_records(PositionList_to_np(pos_list), index='证券代码')
|
||||
|
||||
PositionRecordList.to_np = PositionList_to_np
|
||||
PositionRecordList.to_df = PositionList_to_df
|
||||
|
||||
def Performance_to_df(per):
|
||||
"""将 Performance 统计结果转换为 DataFrame 格式"""
|
||||
return pd.DataFrame(dict(name=per.names(), value=per.values()))
|
||||
PositionRecordList.to_np = PositionList_to_np
|
||||
PositionRecordList.to_df = PositionList_to_df
|
||||
|
||||
Performance.to_df = Performance_to_df
|
||||
|
||||
except:
|
||||
pass
|
||||
def Performance_to_df(per):
|
||||
"""将 Performance 统计结果转换为 DataFrame 格式"""
|
||||
return pd.DataFrame(dict(name=per.names(), value=per.values()))
|
||||
|
||||
|
||||
Performance.to_df = Performance_to_df
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include "GlobalInitializer.h"
|
||||
#include "StockManager.h"
|
||||
#include "data_driver/KDataDriver.h"
|
||||
#include "data_driver/HistoryFinanceReader.h"
|
||||
#include "KData.h"
|
||||
|
||||
namespace hku {
|
||||
@ -145,17 +144,16 @@ Stock& Stock::operator=(Stock&& x) {
|
||||
}
|
||||
|
||||
Stock::Stock(const string& market, const string& code, const string& name) {
|
||||
m_data =
|
||||
shared_ptr<Data>(new Data(market, code, name, default_type, default_valid, default_startDate,
|
||||
default_lastDate, default_tick, default_tickValue,
|
||||
default_precision, default_minTradeNumber, default_maxTradeNumber));
|
||||
m_data = make_shared<Data>(market, code, name, default_type, default_valid, default_startDate,
|
||||
default_lastDate, default_tick, default_tickValue, default_precision,
|
||||
default_minTradeNumber, default_maxTradeNumber);
|
||||
}
|
||||
|
||||
Stock::Stock(const string& market, const string& code, const string& name, uint32_t type,
|
||||
bool valid, const Datetime& startDate, const Datetime& lastDate) {
|
||||
m_data = shared_ptr<Data>(new Data(market, code, name, type, valid, startDate, lastDate,
|
||||
default_tick, default_tickValue, default_precision,
|
||||
default_minTradeNumber, default_maxTradeNumber));
|
||||
m_data = make_shared<Data>(market, code, name, type, valid, startDate, lastDate, default_tick,
|
||||
default_tickValue, default_precision, default_minTradeNumber,
|
||||
default_maxTradeNumber);
|
||||
}
|
||||
|
||||
Stock::Stock(const string& market, const string& code, const string& name, uint32_t type,
|
||||
@ -194,11 +192,11 @@ bool Stock::valid() const {
|
||||
return m_data ? m_data->m_valid : default_valid;
|
||||
}
|
||||
|
||||
Datetime Stock::startDatetime() const {
|
||||
const Datetime& Stock::startDatetime() const {
|
||||
return m_data ? m_data->m_startDate : default_startDate;
|
||||
}
|
||||
|
||||
Datetime Stock::lastDatetime() const {
|
||||
const Datetime& Stock::lastDatetime() const {
|
||||
return m_data ? m_data->m_lastDate : default_lastDate;
|
||||
}
|
||||
|
||||
@ -230,6 +228,152 @@ double Stock::maxTradeNumber() const {
|
||||
return m_data ? m_data->m_maxTradeNumber : default_maxTradeNumber;
|
||||
}
|
||||
|
||||
void Stock::market(const string& market_) {
|
||||
string n_market(market_);
|
||||
to_upper(n_market);
|
||||
if (!m_data) {
|
||||
m_data =
|
||||
make_shared<Data>(n_market, default_code, default_name, default_type, default_valid,
|
||||
default_startDate, default_lastDate, default_tick, default_tickValue,
|
||||
default_precision, default_minTradeNumber, default_maxTradeNumber);
|
||||
} else {
|
||||
m_data->m_market = n_market;
|
||||
m_data->m_market_code = m_data->marketCode();
|
||||
}
|
||||
}
|
||||
|
||||
void Stock::code(const string& code_) {
|
||||
if (!m_data) {
|
||||
m_data =
|
||||
make_shared<Data>(default_market, code_, default_name, default_type, default_valid,
|
||||
default_startDate, default_lastDate, default_tick, default_tickValue,
|
||||
default_precision, default_minTradeNumber, default_maxTradeNumber);
|
||||
} else {
|
||||
m_data->m_code = code_;
|
||||
m_data->m_market_code = m_data->marketCode();
|
||||
}
|
||||
}
|
||||
|
||||
void Stock::name(const string& name_) {
|
||||
if (!m_data) {
|
||||
m_data =
|
||||
make_shared<Data>(default_market, default_code, name_, default_type, default_valid,
|
||||
default_startDate, default_lastDate, default_tick, default_tickValue,
|
||||
default_precision, default_minTradeNumber, default_maxTradeNumber);
|
||||
} else {
|
||||
m_data->m_name = name_;
|
||||
}
|
||||
}
|
||||
|
||||
void Stock::type(uint32_t type_) {
|
||||
if (!m_data) {
|
||||
m_data =
|
||||
make_shared<Data>(default_market, default_code, default_name, type_, default_valid,
|
||||
default_startDate, default_lastDate, default_tick, default_tickValue,
|
||||
default_precision, default_minTradeNumber, default_maxTradeNumber);
|
||||
} else {
|
||||
m_data->m_type = type_;
|
||||
}
|
||||
}
|
||||
|
||||
void Stock::valid(bool valid_) {
|
||||
if (!m_data) {
|
||||
m_data =
|
||||
make_shared<Data>(default_market, default_code, default_name, default_type, valid_,
|
||||
default_startDate, default_lastDate, default_tick, default_tickValue,
|
||||
default_precision, default_minTradeNumber, default_maxTradeNumber);
|
||||
} else {
|
||||
m_data->m_valid = valid_;
|
||||
}
|
||||
}
|
||||
|
||||
void Stock::precision(int precision_) {
|
||||
if (!m_data) {
|
||||
m_data =
|
||||
make_shared<Data>(default_market, default_code, default_name, default_type, default_valid,
|
||||
default_startDate, default_lastDate, default_tick, default_tickValue,
|
||||
precision_, default_minTradeNumber, default_maxTradeNumber);
|
||||
} else {
|
||||
m_data->m_precision = precision_;
|
||||
}
|
||||
}
|
||||
|
||||
void Stock::startDatetime(const Datetime& date) {
|
||||
if (!m_data) {
|
||||
m_data =
|
||||
make_shared<Data>(default_market, default_code, default_name, default_type, default_valid,
|
||||
date, default_lastDate, default_tick, default_tickValue,
|
||||
default_precision, default_minTradeNumber, default_maxTradeNumber);
|
||||
} else {
|
||||
m_data->m_startDate = date;
|
||||
}
|
||||
}
|
||||
|
||||
void Stock::lastDatetime(const Datetime& date) {
|
||||
if (!m_data) {
|
||||
m_data =
|
||||
make_shared<Data>(default_market, default_code, default_name, default_type, default_valid,
|
||||
default_startDate, date, default_tick, default_tickValue,
|
||||
default_precision, default_minTradeNumber, default_maxTradeNumber);
|
||||
} else {
|
||||
m_data->m_lastDate = date;
|
||||
}
|
||||
}
|
||||
|
||||
void Stock::tick(price_t tick_) {
|
||||
if (!m_data) {
|
||||
m_data =
|
||||
make_shared<Data>(default_market, default_code, default_name, default_type, default_valid,
|
||||
default_startDate, default_lastDate, default_tick, default_tickValue,
|
||||
default_precision, default_minTradeNumber, default_maxTradeNumber);
|
||||
}
|
||||
m_data->m_tick = tick_;
|
||||
if (0.0 == m_data->m_tick) {
|
||||
HKU_WARN("tick should not be zero! now use as 1.0");
|
||||
m_data->m_unit = 1.0;
|
||||
} else {
|
||||
m_data->m_unit = m_data->m_tickValue / m_data->m_tick;
|
||||
}
|
||||
}
|
||||
|
||||
void Stock::tickValue(price_t val) {
|
||||
if (!m_data) {
|
||||
m_data =
|
||||
make_shared<Data>(default_market, default_code, default_name, default_type, default_valid,
|
||||
default_startDate, default_lastDate, default_tick, default_tickValue,
|
||||
default_precision, default_minTradeNumber, default_maxTradeNumber);
|
||||
}
|
||||
m_data->m_tickValue = val;
|
||||
if (0.0 == m_data->m_tick) {
|
||||
HKU_WARN("tick should not be zero! now use as 1.0");
|
||||
m_data->m_unit = 1.0;
|
||||
} else {
|
||||
m_data->m_unit = m_data->m_tickValue / m_data->m_tick;
|
||||
}
|
||||
}
|
||||
|
||||
void Stock::minTradeNumber(double num) {
|
||||
if (!m_data) {
|
||||
m_data =
|
||||
make_shared<Data>(default_market, default_code, default_name, default_type, default_valid,
|
||||
default_startDate, default_lastDate, default_tick, default_tickValue,
|
||||
default_precision, num, default_maxTradeNumber);
|
||||
} else {
|
||||
m_data->m_minTradeNumber = num;
|
||||
}
|
||||
}
|
||||
|
||||
void Stock::maxTradeNumber(double num) {
|
||||
if (!m_data) {
|
||||
m_data =
|
||||
make_shared<Data>(default_market, default_code, default_name, default_type, default_valid,
|
||||
default_startDate, default_lastDate, default_tick, default_tickValue,
|
||||
default_precision, default_minTradeNumber, num);
|
||||
} else {
|
||||
m_data->m_maxTradeNumber = num;
|
||||
}
|
||||
}
|
||||
|
||||
void Stock::setKDataDriver(const KDataDriverConnectPoolPtr& kdataDriver) {
|
||||
HKU_CHECK(kdataDriver, "kdataDriver is nullptr!");
|
||||
m_kdataDriver = kdataDriver;
|
||||
@ -687,17 +831,6 @@ Parameter Stock::getFinanceInfo() const {
|
||||
return result;
|
||||
}
|
||||
|
||||
PriceList Stock::getHistoryFinanceInfo(const Datetime& date) const {
|
||||
PriceList result;
|
||||
HKU_IF_RETURN(type() != STOCKTYPE_A && type() != STOCKTYPE_GEM && type() != STOCKTYPE_START &&
|
||||
type() != STOCKTYPE_A_BJ,
|
||||
result);
|
||||
const StockManager& sm = StockManager::instance();
|
||||
HistoryFinanceReader rd(sm.datadir() + "/downloads/finance");
|
||||
result = rd.getHistoryFinanceInfo(date, market(), code());
|
||||
return result;
|
||||
}
|
||||
|
||||
// 判断是否在交易时间段内(不判断日期)
|
||||
bool Stock::isTransactionTime(Datetime time) {
|
||||
MarketInfo market_info = StockManager::instance().getMarketInfo(market());
|
||||
@ -771,7 +904,7 @@ void Stock::setKRecordList(const KRecordList& ks, const KQuery::KType& ktype) {
|
||||
(*(m_data->pKData[nktype])) = ks;
|
||||
|
||||
Parameter param;
|
||||
param.set<string>("type", "DoNothin");
|
||||
param.set<string>("type", "DoNothing");
|
||||
m_kdataDriver = DataDriverFactory::getKDataDriverPool(param);
|
||||
|
||||
m_data->m_valid = true;
|
||||
@ -795,7 +928,7 @@ void Stock::setKRecordList(KRecordList&& ks, const KQuery::KType& ktype) {
|
||||
(*m_data->pKData[nktype]) = std::move(ks);
|
||||
|
||||
Parameter param;
|
||||
param.set<string>("type", "DoNothin");
|
||||
param.set<string>("type", "DoNothing");
|
||||
m_kdataDriver = DataDriverFactory::getKDataDriverPool(param);
|
||||
|
||||
m_data->m_valid = true;
|
||||
|
@ -95,10 +95,10 @@ public:
|
||||
bool valid() const;
|
||||
|
||||
/** 获取证券起始日期 */
|
||||
Datetime startDatetime() const;
|
||||
const Datetime& startDatetime() const;
|
||||
|
||||
/** 获取证券最后日期 */
|
||||
Datetime lastDatetime() const;
|
||||
const Datetime& lastDatetime() const;
|
||||
|
||||
/** 获取最小跳动量 */
|
||||
price_t tick() const;
|
||||
@ -121,6 +121,22 @@ public:
|
||||
/** 获取最大交易量 */
|
||||
double maxTradeNumber() const;
|
||||
|
||||
void market(const string& market_);
|
||||
void code(const string& code_);
|
||||
void name(const string& name_);
|
||||
void type(uint32_t type_);
|
||||
void valid(bool valid_);
|
||||
void precision(int precision_);
|
||||
void startDatetime(const Datetime&);
|
||||
void lastDatetime(const Datetime&);
|
||||
void tick(price_t tick_);
|
||||
void tickValue(price_t val);
|
||||
void minTradeNumber(double num);
|
||||
void maxTradeNumber(double num);
|
||||
void atom(double num) {
|
||||
return minTradeNumber(num);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定时间段[start,end)内的权息信息
|
||||
* @param start 起始日期
|
||||
@ -177,10 +193,7 @@ public:
|
||||
|
||||
/**
|
||||
* 获取历史财务信息
|
||||
* @param date 指定日期必须是0331、0630、0930、1231,如 Datetime(201109300000)
|
||||
*/
|
||||
PriceList getHistoryFinanceInfo(const Datetime& date) const;
|
||||
|
||||
const vector<HistoryFinanceInfo>& getHistoryFinance() const;
|
||||
|
||||
/** 设置权息信息, 仅供初始化时调用 */
|
||||
|
@ -403,7 +403,8 @@ vector<HistoryFinanceInfo> MySQLBaseInfoDriver::getHistoryFinance(const string &
|
||||
to_upper(market_code);
|
||||
vector<HistoryFinanceTable> finances;
|
||||
con->batchLoad(finances, ((Field("market_code") == market_code) &
|
||||
(Field("report_date") >= new_start.ymd())) +
|
||||
(Field("report_date") >= new_start.ymd()) &
|
||||
(Field("report_date") < new_end.ymd())) +
|
||||
ASC("report_date"));
|
||||
size_t total = finances.size();
|
||||
result.resize(total);
|
||||
|
@ -393,7 +393,8 @@ vector<HistoryFinanceInfo> SQLiteBaseInfoDriver::getHistoryFinance(const string&
|
||||
to_upper(market_code);
|
||||
vector<HistoryFinanceTable> finances;
|
||||
con->batchLoad(finances, ((Field("market_code") == market_code) &
|
||||
(Field("report_date") >= start.ymd())) +
|
||||
(Field("report_date") >= new_start.ymd()) &
|
||||
(Field("report_date") < new_end.ymd())) +
|
||||
ASC("report_date"));
|
||||
size_t total = finances.size();
|
||||
result.resize(total);
|
||||
|
@ -21,10 +21,6 @@ public:
|
||||
return std::make_shared<DoNothingKDataDriver>();
|
||||
}
|
||||
|
||||
virtual bool _init() override {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool isIndexFirst() override {
|
||||
return true;
|
||||
}
|
||||
|
@ -1842,7 +1842,7 @@ TEST_CASE("test_Stock_getKRecord_By_Date") {
|
||||
Stock stock = sm.getStock("sh000001");
|
||||
KRecord record;
|
||||
|
||||
///测试日线
|
||||
/// 测试日线
|
||||
///===================================
|
||||
|
||||
/** @arg 日期小于第一条记录 */
|
||||
@ -1873,7 +1873,7 @@ TEST_CASE("test_Stock_getKRecord_By_Date") {
|
||||
CHECK_EQ(record, Null<KRecord>());
|
||||
|
||||
///===================================
|
||||
///测试周线
|
||||
/// 测试周线
|
||||
///===================================
|
||||
|
||||
/** @arg 日期小于第一条记录 */
|
||||
@ -1904,7 +1904,7 @@ TEST_CASE("test_Stock_getKRecord_By_Date") {
|
||||
CHECK_EQ(record, Null<KRecord>());
|
||||
|
||||
///===================================
|
||||
///测试月线
|
||||
/// 测试月线
|
||||
///===================================
|
||||
|
||||
/** @arg 日期小于第一条记录 */
|
||||
@ -1935,7 +1935,7 @@ TEST_CASE("test_Stock_getKRecord_By_Date") {
|
||||
CHECK_EQ(record, Null<KRecord>());
|
||||
|
||||
///===================================
|
||||
///测试15分钟线
|
||||
/// 测试15分钟线
|
||||
///===================================
|
||||
|
||||
/** @arg 日期小于第一条记录 */
|
||||
@ -2051,27 +2051,6 @@ TEST_CASE("test_Stock_id_map") {
|
||||
MEMORY_CHECK;
|
||||
}
|
||||
|
||||
/** @par 检测点 */
|
||||
TEST_CASE("test_Stock_getHistoryFinanceInfo") {
|
||||
StockManager& sm = StockManager::instance();
|
||||
Stock stk = getStock("sh600000");
|
||||
PriceList result = stk.getHistoryFinanceInfo(Datetime(201109300000));
|
||||
CHECK_EQ(result.size(), 286);
|
||||
CHECK_EQ(result[0], doctest::Approx(1.067).epsilon(0.00001));
|
||||
CHECK_EQ(result[1], doctest::Approx(1.061).epsilon(0.00001));
|
||||
CHECK_EQ(result[2], doctest::Approx(1.360).epsilon(0.00001));
|
||||
CHECK_EQ(result[3], doctest::Approx(7.482).epsilon(0.00001));
|
||||
CHECK_EQ(result[9], doctest::Approx(0.0).epsilon(0.00001));
|
||||
CHECK_EQ(result[14], doctest::Approx(7.87818e+09).epsilon(0.00001));
|
||||
CHECK_EQ(result[282], doctest::Approx(6.327156e+06).epsilon(0.00001));
|
||||
CHECK_EQ(result[285], doctest::Approx(0.0).epsilon(0.00001));
|
||||
// for (int i = 0; i < 286; i++) {
|
||||
// std::cout << result[i] << std::endl;
|
||||
//}
|
||||
|
||||
MEMORY_CHECK;
|
||||
}
|
||||
|
||||
/** @par 检测点 */
|
||||
TEST_CASE("test_Stock_getFinanceInfo") {
|
||||
StockManager& sm = StockManager::instance();
|
||||
|
@ -21,11 +21,14 @@ void export_MarketInfo(py::module& m) {
|
||||
.def("__repr__", &MarketInfo::toString)
|
||||
|
||||
.def_property_readonly("market", py::overload_cast<>(&MarketInfo::market, py::const_),
|
||||
"市场标识(如:沪市“SH”, 深市“SZ”)")
|
||||
.def_property_readonly("name", py::overload_cast<>(&MarketInfo::name, py::const_), "市场全称")
|
||||
py::return_value_policy::copy, "市场标识(如:沪市“SH”, 深市“SZ”)")
|
||||
.def_property_readonly("name", py::overload_cast<>(&MarketInfo::name, py::const_),
|
||||
py::return_value_policy::copy, "市场全称")
|
||||
.def_property_readonly("description",
|
||||
py::overload_cast<>(&MarketInfo::description, py::const_), "描述说明")
|
||||
py::overload_cast<>(&MarketInfo::description, py::const_),
|
||||
py::return_value_policy::copy, "描述说明")
|
||||
.def_property_readonly("code", py::overload_cast<>(&MarketInfo::code, py::const_),
|
||||
py::return_value_policy::copy,
|
||||
"该市场对应的主要指数代码,用于获取交易日历")
|
||||
|
||||
.def_property_readonly("last_datetime", &MarketInfo::lastDate, "该市场K线数据最后交易日期")
|
||||
|
@ -29,23 +29,40 @@ void export_Stock(py::module& m) {
|
||||
.def("__repr__", &Stock::toString)
|
||||
|
||||
.def_property_readonly("id", &Stock::id, "内部id")
|
||||
.def_property_readonly("market", py::overload_cast<>(&Stock::market, py::const_),
|
||||
"所属市场简称,市场简称是市场的唯一标识")
|
||||
.def_property_readonly("code", py::overload_cast<>(&Stock::code, py::const_), "证券代码")
|
||||
.def_property("market", py::overload_cast<>(&Stock::market, py::const_),
|
||||
py::overload_cast<const string&>(&Stock::market), py::return_value_policy::copy,
|
||||
"所属市场简称,市场简称是市场的唯一标识")
|
||||
.def_property("code", py::overload_cast<>(&Stock::code, py::const_),
|
||||
py::overload_cast<const string&>(&Stock::code), py::return_value_policy::copy,
|
||||
"证券代码")
|
||||
.def_property_readonly("market_code", py::overload_cast<>(&Stock::market_code, py::const_),
|
||||
"市场简称+证券代码,如: sh000001")
|
||||
.def_property_readonly("name", py::overload_cast<>(&Stock::name, py::const_), "证券名称")
|
||||
.def_property_readonly("type", &Stock::type, "证券类型,参见:constant")
|
||||
.def_property_readonly("valid", &Stock::valid, "该证券当前是否有效")
|
||||
.def_property_readonly("start_datetime", &Stock::startDatetime, "证券起始日期")
|
||||
.def_property_readonly("last_datetime", &Stock::lastDatetime, "证券最后日期")
|
||||
.def_property_readonly("tick", &Stock::tick, "最小跳动量")
|
||||
.def_property_readonly("tick_value", &Stock::tickValue, "最小跳动量价值")
|
||||
.def_property("name", py::overload_cast<>(&Stock::name, py::const_),
|
||||
py::overload_cast<const string&>(&Stock::name), py::return_value_policy::copy,
|
||||
"证券名称")
|
||||
.def_property("type", py::overload_cast<>(&Stock::type, py::const_),
|
||||
py::overload_cast<uint32_t>(&Stock::type), "证券类型,参见:constant")
|
||||
.def_property("valid", py::overload_cast<>(&Stock::valid, py::const_),
|
||||
py::overload_cast<bool>(&Stock::valid), "该证券当前是否有效")
|
||||
.def_property("start_datetime", py::overload_cast<>(&Stock::startDatetime, py::const_),
|
||||
py::overload_cast<const Datetime&>(&Stock::startDatetime),
|
||||
py::return_value_policy::copy, "证券起始日期")
|
||||
.def_property("last_datetime", py::overload_cast<>(&Stock::lastDatetime, py::const_),
|
||||
py::overload_cast<const Datetime&>(&Stock::lastDatetime),
|
||||
py::return_value_policy::copy, "证券最后日期")
|
||||
.def_property("tick", py::overload_cast<>(&Stock::tick, py::const_),
|
||||
py::overload_cast<price_t>(&Stock::tick), "最小跳动量")
|
||||
.def_property("tick_value", py::overload_cast<>(&Stock::tickValue, py::const_),
|
||||
py::overload_cast<price_t>(&Stock::tickValue), "最小跳动量价值")
|
||||
.def_property_readonly("unit", &Stock::unit, "每单位价值 = tickValue / tick")
|
||||
.def_property_readonly("precision", &Stock::precision, "价格精度")
|
||||
.def_property_readonly("atom", &Stock::atom, "最小交易数量,同min_tradeNumber")
|
||||
.def_property_readonly("min_trade_number", &Stock::minTradeNumber, "最小交易数量")
|
||||
.def_property_readonly("max_trade_number", &Stock::maxTradeNumber, "最大交易数量")
|
||||
.def_property("precision", py::overload_cast<>(&Stock::precision, py::const_),
|
||||
py::overload_cast<int>(&Stock::precision), "价格精度")
|
||||
.def_property("atom", py::overload_cast<>(&Stock::atom, py::const_),
|
||||
py::overload_cast<double>(&Stock::atom), "最小交易数量,同min_tradeNumber")
|
||||
.def_property("min_trade_number", py::overload_cast<>(&Stock::minTradeNumber, py::const_),
|
||||
py::overload_cast<double>(&Stock::minTradeNumber), "最小交易数量")
|
||||
.def_property("max_trade_number", py::overload_cast<>(&Stock::maxTradeNumber, py::const_),
|
||||
py::overload_cast<double>(&Stock::maxTradeNumber), "最大交易数量")
|
||||
|
||||
.def("is_null", &Stock::isNull, R"(is_null(self)
|
||||
|
||||
@ -139,14 +156,6 @@ void export_Stock(py::module& m) {
|
||||
|
||||
:rtype: Parameter)")
|
||||
|
||||
.def("get_history_finance_info", &Stock::getHistoryFinanceInfo,
|
||||
R"(get_history_finance_info(self, date)
|
||||
|
||||
获取历史财务信息, 字段含义参见:https://hikyuu.org/finance_fields.html
|
||||
|
||||
:param Datetime date: 指定日期必须是0331、0630、0930、1231,如 Datetime(201109300000)
|
||||
:rtype: list)")
|
||||
|
||||
.def("realtime_update", &Stock::realtimeUpdate, py::arg("krecord"),
|
||||
py::arg("ktype") = KQuery::DAY,
|
||||
R"(realtime_update(self, krecord)
|
||||
|
@ -184,15 +184,18 @@ void export_StockManager(py::module& m) {
|
||||
|
||||
根据字段名称,获取历史财务信息相应字段索引)")
|
||||
|
||||
.def("get_history_finance_all_fields",
|
||||
[](const StockManager& sm) {
|
||||
auto fields = sm.getHistoryFinanceAllFields();
|
||||
py::list ret;
|
||||
for (const auto& f : fields) {
|
||||
ret.append(py::make_tuple(f.first, f.second));
|
||||
}
|
||||
return ret;
|
||||
})
|
||||
.def(
|
||||
"get_history_finance_all_fields",
|
||||
[](const StockManager& sm) {
|
||||
auto fields = sm.getHistoryFinanceAllFields();
|
||||
py::list ret;
|
||||
for (const auto& f : fields) {
|
||||
ret.append(py::make_tuple(f.first, f.second));
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
R"(get_history_finance_all_fields(self)
|
||||
获取所有历史财务信息字段及其索引)")
|
||||
|
||||
.def("add_stock", &StockManager::addStock, R"(add_stock(self, stock)
|
||||
|
||||
|
@ -1825,8 +1825,19 @@ void export_Indicator_build_in(py::module& m) {
|
||||
:param Indicator data: 指定的指标
|
||||
:param int result_ix: 指定的结果集)");
|
||||
|
||||
m.def("FINANCE", py::overload_cast<int>(FINANCE));
|
||||
m.def("FINANCE", py::overload_cast<const string&>(FINANCE));
|
||||
m.def("FINANCE", py::overload_cast<const KData&, int>(FINANCE));
|
||||
m.def("FINANCE", py::overload_cast<const KData&, const string&>(FINANCE));
|
||||
m.def("FINANCE", py::overload_cast<int>(FINANCE), py::arg("ix"));
|
||||
m.def("FINANCE", py::overload_cast<const string&>(FINANCE), py::arg("name"));
|
||||
m.def("FINANCE", py::overload_cast<const KData&, int>(FINANCE), py::arg("kdata"),
|
||||
py::arg("ix"));
|
||||
m.def("FINANCE", py::overload_cast<const KData&, const string&>(FINANCE), py::arg("kdata"),
|
||||
py::arg("name"),
|
||||
R"(FINANCE([kdata, ix, name])
|
||||
|
||||
获取历史财务信息。(可通过 StockManager.get_history_finance_all_fields 查询相应的历史财务字段信息)
|
||||
|
||||
ix, name 使用时,为二选一。即要不使用 ix,要不就使用 name 进行获取。
|
||||
|
||||
:param KData kdata: K线数据
|
||||
:param int ix: 历史财务信息字段索引
|
||||
:param int name: 历史财务信息字段名称)");
|
||||
}
|
||||
|
@ -22,5 +22,16 @@ void export_SystemPart(py::module& m) {
|
||||
.value("PROFITGOAL", PART_PROFITGOAL, "盈利目标策略")
|
||||
.value("SLIPPAGE", PART_SLIPPAGE, "移滑价差算法")
|
||||
.value("ALLOCATEFUNDS", PART_ALLOCATEFUNDS, "资产分配算法")
|
||||
.value("INVALID", PART_INVALID, "无效系统部件");
|
||||
.value("INVALID", PART_INVALID, "无效系统部件")
|
||||
|
||||
// 支持简写
|
||||
.value("EV", PART_ENVIRONMENT, "外部环境")
|
||||
.value("CN", PART_CONDITION, "系统前提条件")
|
||||
.value("SG", PART_SIGNAL, "信号产生器")
|
||||
.value("ST", PART_STOPLOSS, "止损策略")
|
||||
.value("TP", PART_TAKEPROFIT, "止赢策略")
|
||||
.value("MM", PART_MONEYMANAGER, "资金管理策略")
|
||||
.value("PG", PART_PROFITGOAL, "盈利目标策略")
|
||||
.value("SP", PART_SLIPPAGE, "移滑价差算法")
|
||||
.value("AF", PART_ALLOCATEFUNDS, "资产分配算法");
|
||||
}
|
Loading…
Reference in New Issue
Block a user