Merge branch 'master' of https://github.com/fasiondog/hikyuu into feature/docs

This commit is contained in:
fasiondog 2024-04-18 22:12:20 +08:00
commit 71b8f41f4c
25 changed files with 534 additions and 312 deletions

View File

@ -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':

View 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;

View File

@ -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)

View File

@ -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()

View File

@ -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

View File

@ -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

View 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;

View File

@ -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',

View File

@ -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

View File

@ -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):

View File

@ -2,10 +2,10 @@
# -*- coding: utf8 -*-
# gb18030
#===============================================================================
# ===============================================================================
# 作者fasiondog
# 历史120130316, 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)

View File

@ -2,10 +2,10 @@
# -*- coding: utf8 -*-
# gb18030
#===============================================================================
# ===============================================================================
# 作者fasiondog
# 历史120130321, 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)

View File

@ -2,10 +2,10 @@
# -*- coding: utf8 -*-
# gb18030
#===============================================================================
# ===============================================================================
# 作者fasiondog
# 历史120120928, 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)

View File

@ -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

View File

@ -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;

View File

@ -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 0331063009301231 Datetime(201109300000)
*/
PriceList getHistoryFinanceInfo(const Datetime& date) const;
const vector<HistoryFinanceInfo>& getHistoryFinance() const;
/** 设置权息信息, 仅供初始化时调用 */

View File

@ -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);

View File

@ -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);

View File

@ -21,10 +21,6 @@ public:
return std::make_shared<DoNothingKDataDriver>();
}
virtual bool _init() override {
return true;
}
virtual bool isIndexFirst() override {
return true;
}

View File

@ -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();

View File

@ -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线数据最后交易日期")

View File

@ -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: 0331063009301231 Datetime(201109300000)
:rtype: list)")
.def("realtime_update", &Stock::realtimeUpdate, py::arg("krecord"),
py::arg("ktype") = KQuery::DAY,
R"(realtime_update(self, krecord)

View File

@ -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)

View File

@ -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: )");
}

View File

@ -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, "资产分配算法");
}