mirror of
https://gitee.com/fasiondog/hikyuu.git
synced 2024-12-02 20:08:26 +08:00
spearman(continue)
This commit is contained in:
parent
8cbb5ac918
commit
00a2dfb37c
@ -1568,7 +1568,7 @@ static void spearmanLevel(const IndicatorImp::value_t *data, IndicatorImp::value
|
||||
std::sort(
|
||||
data_index.begin(), data_index.end(),
|
||||
std::bind(
|
||||
std::greater<IndicatorImp::value_t>(),
|
||||
std::less<IndicatorImp::value_t>(),
|
||||
std::bind(&std::pair<IndicatorImp::value_t, size_t>::first, std::placeholders::_1),
|
||||
std::bind(&std::pair<IndicatorImp::value_t, size_t>::first, std::placeholders::_2)));
|
||||
|
||||
@ -1620,8 +1620,11 @@ void IndicatorImp::execute_spearman() {
|
||||
return;
|
||||
}
|
||||
|
||||
discard++;
|
||||
setDiscard(discard);
|
||||
|
||||
size_t startPos = discard;
|
||||
size_t first_end = startPos + n >= total ? total : startPos + n;
|
||||
size_t first_end = startPos + n - 1 >= total ? total : startPos + n - 1;
|
||||
|
||||
auto levela = std::make_unique<value_t[]>(n);
|
||||
auto levelb = std::make_unique<value_t[]>(n);
|
||||
@ -1636,8 +1639,8 @@ void IndicatorImp::execute_spearman() {
|
||||
|
||||
size_t n1 = 2;
|
||||
auto const *a = maxdata + startPos + 1 - n1;
|
||||
auto const *b = mindata + startPos + startPos + 2 - diff - n1;
|
||||
for (size_t i = startPos + 1; i < first_end; i++) {
|
||||
auto const *b = mindata + startPos + 1 - diff - n1;
|
||||
for (size_t i = startPos; i < first_end; i++) {
|
||||
spearmanLevel(a, ptra, n1);
|
||||
spearmanLevel(b, ptrb, n1);
|
||||
value_t sum = 0.0;
|
||||
@ -1645,16 +1648,12 @@ void IndicatorImp::execute_spearman() {
|
||||
sum += std::pow(ptra[j] - ptrb[j], 2);
|
||||
}
|
||||
dst[i] = 1 - 6.0 * sum / (std::pow(value_t(n1), 3) - n1);
|
||||
a++;
|
||||
b++;
|
||||
n1++;
|
||||
}
|
||||
|
||||
// auto const *a = maxdata + discard - n;
|
||||
// auto const *b = mindata + discard + discard - diff - n;
|
||||
for (size_t i = discard; i < total; ++i) {
|
||||
// auto *ptra = levela.get();
|
||||
// auto *ptrb = levelb.get();
|
||||
a++;
|
||||
b++;
|
||||
for (size_t i = first_end; i < total; ++i) {
|
||||
spearmanLevel(a, ptra, n);
|
||||
spearmanLevel(b, ptrb, n);
|
||||
value_t sum = 0.0;
|
||||
@ -1666,8 +1665,6 @@ void IndicatorImp::execute_spearman() {
|
||||
b++;
|
||||
}
|
||||
}
|
||||
|
||||
setDiscard(discard + 2);
|
||||
}
|
||||
|
||||
void IndicatorImp::_dyn_calculate(const Indicator &ind) {
|
||||
|
194
hikyuu_cpp/unit_test/hikyuu/indicator/test_SPEARMAN.cpp
Normal file
194
hikyuu_cpp/unit_test/hikyuu/indicator/test_SPEARMAN.cpp
Normal file
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* test_COS.cpp
|
||||
*
|
||||
* Copyright (c) 2019 hikyuu.org
|
||||
*
|
||||
* Created on: 2019-5-1
|
||||
* Author: fasiondog
|
||||
*/
|
||||
|
||||
#include "../test_config.h"
|
||||
#include <fstream>
|
||||
#include <hikyuu/StockManager.h>
|
||||
#include <hikyuu/indicator/crt/KDATA.h>
|
||||
#include <hikyuu/indicator/crt/PRICELIST.h>
|
||||
|
||||
using namespace hku;
|
||||
|
||||
/**
|
||||
* @defgroup test_indicator_COS test_indicator_CORR
|
||||
* @ingroup test_hikyuu_indicator_suite
|
||||
* @{
|
||||
*/
|
||||
|
||||
static void spearmanLevel(const IndicatorImp::value_t *data, IndicatorImp::value_t *level,
|
||||
size_t total) {
|
||||
std::vector<std::pair<IndicatorImp::value_t, size_t>> data_index(total);
|
||||
for (size_t i = 0; i < total; i++) {
|
||||
data_index[i].first = data[i];
|
||||
data_index[i].second = i;
|
||||
}
|
||||
|
||||
std::sort(
|
||||
data_index.begin(), data_index.end(),
|
||||
std::bind(
|
||||
std::less<IndicatorImp::value_t>(),
|
||||
std::bind(&std::pair<IndicatorImp::value_t, size_t>::first, std::placeholders::_1),
|
||||
std::bind(&std::pair<IndicatorImp::value_t, size_t>::first, std::placeholders::_2)));
|
||||
|
||||
size_t i = 0;
|
||||
while (i < total) {
|
||||
size_t count = 1;
|
||||
IndicatorImp::value_t score = i + 1.0;
|
||||
for (size_t j = i + 1; j < total; j++) {
|
||||
if (data_index[i].first != data_index[j].first) {
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
score += j + 1;
|
||||
}
|
||||
score = score / count;
|
||||
for (size_t j = 0; j < count; j++) {
|
||||
level[data_index[i + j].second] = score;
|
||||
}
|
||||
i += count;
|
||||
}
|
||||
}
|
||||
|
||||
/** @par 检测点 */
|
||||
TEST_CASE("test_spearmanLevel") {
|
||||
std::vector<IndicatorImp::value_t> a{3., 8., 4., 7., 2.};
|
||||
size_t totala = a.size();
|
||||
auto levela = std::make_unique<IndicatorImp::value_t[]>(totala);
|
||||
auto *ptra = levela.get();
|
||||
spearmanLevel(a.data(), levela.get(), totala);
|
||||
|
||||
std::vector<IndicatorImp::value_t> expecta = {2., 5., 3., 4., 1.};
|
||||
for (size_t i = 0; i < totala; i++) {
|
||||
CHECK_EQ(ptra[i], doctest::Approx(expecta[i]));
|
||||
}
|
||||
|
||||
std::vector<IndicatorImp::value_t> b{5., 10., 8., 10., 6.};
|
||||
size_t totalb = b.size();
|
||||
auto levelb = std::make_unique<IndicatorImp::value_t[]>(totalb);
|
||||
auto *ptrb = levelb.get();
|
||||
spearmanLevel(b.data(), levelb.get(), totalb);
|
||||
|
||||
std::vector<IndicatorImp::value_t> expectb = {1., 4.5, 3., 4.5, 2.};
|
||||
for (size_t i = 0; i < totalb; i++) {
|
||||
CHECK_EQ(ptrb[i], doctest::Approx(expectb[i]));
|
||||
}
|
||||
}
|
||||
|
||||
/** @par 检测点 */
|
||||
TEST_CASE("test_SPEARMAN") {
|
||||
Indicator result;
|
||||
|
||||
// 空指标
|
||||
result = SPEARMAN(Indicator(), Indicator(), 10);
|
||||
CHECK_UNARY(result.empty());
|
||||
|
||||
PriceList a{3., 8., 4., 7., 2.};
|
||||
PriceList b{5., 10., 8., 10., 6.};
|
||||
|
||||
Indicator x = PRICELIST(a);
|
||||
Indicator y = PRICELIST(b);
|
||||
|
||||
// 非法参数 n
|
||||
result = SPEARMAN(x, y, 0);
|
||||
CHECK_UNARY(result.empty());
|
||||
result = SPEARMAN(x, y, 1);
|
||||
CHECK_UNARY(result.empty());
|
||||
|
||||
// 正常情况
|
||||
PriceList expect{Null<price_t>(), 1., 1., 0.95, 0.875};
|
||||
result = SPEARMAN(x, y, a.size());
|
||||
CHECK_EQ(result.name(), "SPEARMAN");
|
||||
CHECK_EQ(result.discard(), 1);
|
||||
CHECK_EQ(result.size(), a.size());
|
||||
|
||||
for (size_t i = result.discard(); i < result.size(); i++) {
|
||||
CHECK_EQ(result[i], doctest::Approx(expect[i]));
|
||||
}
|
||||
|
||||
result = SPEARMAN(x, y, 4);
|
||||
CHECK_EQ(result.name(), "SPEARMAN");
|
||||
CHECK_EQ(result.discard(), 1);
|
||||
CHECK_EQ(result.size(), a.size());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// benchmark
|
||||
//-----------------------------------------------------------------------------
|
||||
#if ENABLE_BENCHMARK_TEST
|
||||
TEST_CASE("test_SPEARMAN_benchmark") {
|
||||
// Stock stock = getStock("sh000001");
|
||||
// KData kdata = stock.getKData(KQuery(0));
|
||||
// Indicator c = kdata.close();
|
||||
// int cycle = 1000; // 测试循环次数
|
||||
|
||||
// {
|
||||
// BENCHMARK_TIME_MSG(test_SPEARMAN_benchmark, cycle, fmt::format("data len: {}",
|
||||
// c.size())); SPEND_TIME_CONTROL(false); for (int i = 0; i < cycle; i++) {
|
||||
// Indicator ind = ABS();
|
||||
// Indicator result = ind(c);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// test export
|
||||
//-----------------------------------------------------------------------------
|
||||
#if HKU_SUPPORT_SERIALIZATION
|
||||
|
||||
/** @par 检测点 */
|
||||
TEST_CASE("test_CORR_export") {
|
||||
StockManager &sm = StockManager::instance();
|
||||
string filename(sm.tmpdir());
|
||||
filename += "/COS.xml";
|
||||
|
||||
Stock stock = sm.getStock("sh000001");
|
||||
KData kdata = stock.getKData(KQuery(-20));
|
||||
Indicator x1 = CORR(CLOSE(kdata), OPEN(kdata), 10);
|
||||
{
|
||||
std::ofstream ofs(filename);
|
||||
boost::archive::xml_oarchive oa(ofs);
|
||||
oa << BOOST_SERIALIZATION_NVP(x1);
|
||||
}
|
||||
|
||||
Indicator x2;
|
||||
{
|
||||
std::ifstream ifs(filename);
|
||||
boost::archive::xml_iarchive ia(ifs);
|
||||
ia >> BOOST_SERIALIZATION_NVP(x2);
|
||||
}
|
||||
|
||||
CHECK_EQ(x2.name(), "CORR");
|
||||
CHECK_EQ(x1.size(), x2.size());
|
||||
CHECK_EQ(x1.discard(), x2.discard());
|
||||
CHECK_EQ(x1.getResultNumber(), x2.getResultNumber());
|
||||
for (size_t i = x1.discard(); i < x1.size(); ++i) {
|
||||
if (std::isnan(x1[i])) {
|
||||
CHECK_UNARY(std::isnan(x2[i]));
|
||||
} else {
|
||||
CHECK_EQ(x1[i], doctest::Approx(x2[i]));
|
||||
}
|
||||
}
|
||||
|
||||
Indicator x11 = x1.getResult(1);
|
||||
Indicator x21 = x2.getResult(1);
|
||||
CHECK_EQ(x11.size(), x21.size());
|
||||
CHECK_EQ(x11.discard(), x21.discard());
|
||||
CHECK_EQ(x11.getResultNumber(), x21.getResultNumber());
|
||||
for (size_t i = x11.discard(); i < x21.size(); ++i) {
|
||||
if (std::isnan(x11[i])) {
|
||||
CHECK_UNARY(std::isnan(x21[i]));
|
||||
} else {
|
||||
CHECK_EQ(x11[i], doctest::Approx(x21[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* #if HKU_SUPPORT_SERIALIZATION */
|
||||
|
||||
/** @} */
|
Loading…
Reference in New Issue
Block a user