Skip to content

Commit

Permalink
abqindexday lib, pyindexday
Browse files Browse the repository at this point in the history
  • Loading branch information
yssource committed Sep 7, 2020
1 parent 7be577d commit 9f2cf40
Show file tree
Hide file tree
Showing 4 changed files with 262 additions and 0 deletions.
1 change: 1 addition & 0 deletions bind11/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
add_subdirectory(abquant)
add_subdirectory(indexday)
add_subdirectory(stockday)
add_subdirectory(stockmin)
add_subdirectory(test)
121 changes: 121 additions & 0 deletions bind11/indexday/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# ================================ General configuration ======================================

# keywords signals
# add_definitions(-DQT_NO_KEYWORDS)

# The sample library for which we will create bindings. You can change the name to something
# relevant for your project.

# The name of the generated bindings module (as imported in Python). You can change the name
# to something relevant for your project.
set(bindings_library "abqindexday")

# set(CMAKE_CXX_FLAGS_RELEASE "-O0")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DQT_SQL_LIB")

set(abqindexday_include_dir ${CMAKE_CURRENT_SOURCE_DIR}/../../cxx/include)
set(tree_includes "/usr/include/treefrog/")
# set(tree_lib "/usr/lib/libtreefrog.so")
set(abqindexday_lib_dir ${CMAKE_CURRENT_SOURCE_DIR}/../../lib)

set(sample_library "${abqindexday_lib_dir}/libabqcontroller.so;${abqindexday_lib_dir}/libabqhelper.so;${abqindexday_lib_dir}/libabqmodel.so;${abqindexday_lib_dir}/libabqaction.so")
set(bindings_library_dir ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/)


# ==================================== RPATH configuration ====================================


# =============================================================================================
# !!! (The section below is deployment related, so in a real world application you will want to
# take care of this properly with some custom script or tool).
# =============================================================================================
# Enable rpaths so that the built shared libraries find their dependencies.
set(CMAKE_SKIP_BUILD_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
set(CMAKE_INSTALL_RPATH ${CMAKE_CURRENT_SOURCE_DIR} ${QtCore_libdir})
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
# =============================================================================================
# !!! End of dubious section.
# =============================================================================================


# # ====================== Shiboken target for generating binding C++ files ====================
# get_target_property(qtcore_M_QT5_INCLUDES Qt5::Core INTERFACE_INCLUDE_DIRECTORIES)
set(qtcore_M_QT5_INCLUDES ${Qt5Core_INCLUDE_DIRS})

list(JOIN qtcore_M_QT5_INCLUDES ";-I" M_QT5_INCLUDES)

message(STATUS "${M_QT5_INCLUDES}")
set(M_QT5_INCLUDES ${M_QT5_INCLUDES})


# =============================== CMake target - bindings_library =============================

# Set the cpp files which will be used for the bindings library.
set(${bindings_library}_sources main.cpp)

# Define and build the bindings library.
# add_library(${bindings_library} MODULE ${${bindings_library}_sources})
pybind11_add_module(${bindings_library} SHARED ${${bindings_library}_sources} NO_EXTRAS)

# target_include_directories(${bindings_library} PRIVATE ${CONAN_INCLUDE_DIRS})

# Apply relevant include and link flags.
target_include_directories(${bindings_library} PRIVATE ${python_include_dir})
target_include_directories(${bindings_library} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(${bindings_library} PRIVATE ${abqindexday_include_dir})
target_include_directories(${bindings_library} PRIVATE ${tree_includes})

target_include_directories(${bindings_library} PRIVATE "${Qt5Core_INCLUDE_DIRS}")
target_include_directories(${bindings_library} PRIVATE "${Qt5Network_INCLUDE_DIRS}")
target_include_directories(${bindings_library} PRIVATE "${Qt5Sql_INCLUDE_DIRS}")
target_include_directories(${bindings_library} PRIVATE "${Qt5Xml_INCLUDE_DIRS}")
target_include_directories(${bindings_library} PRIVATE "${Qt5Qml_INCLUDE_DIRS}")
# target_include_directories(${bindings_library} PRIVATE "${QtTest_INCLUDE_DIRS}")
target_include_directories(${bindings_library} PRIVATE ${pybind11_INCLUDE_DIRS})

target_link_libraries(${bindings_library} PRIVATE ${sample_library} ${CONAN_LIBS})
set_property(TARGET ${bindings_library} PROPERTY CXX_STANDARD 17)

# Adjust the name of generated module.
set_property(TARGET ${bindings_library} PROPERTY PREFIX "")
set_property(TARGET ${bindings_library} PROPERTY OUTPUT_NAME
"${bindings_library}${PYTHON_EXTENSION_SUFFIX}")
if(WIN32)
set_property(TARGET ${bindings_library} PROPERTY SUFFIX ".pyd")
endif()

# Make sure the linker doesn't complain about not finding Python symbols on macOS.
if(APPLE)
set_target_properties(${bindings_library} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
endif(APPLE)

# Find and link to the python import library only on Windows.
# On Linux and macOS, the undefined symbols will get resolved by the dynamic linker
# (the symbols will be picked up in the Python executable).
if (WIN32)
list(GET python_linking_data 0 python_libdir)
list(GET python_linking_data 1 python_lib)
find_library(python_link_flags ${python_lib} PATHS ${python_libdir} HINTS ${python_libdir})
target_link_libraries(${bindings_library} PRIVATE ${python_link_flags})
endif()


# =============================================================================================
# !!! (The section below is deployment related, so in a real world application you will want to
# take care of this properly with some custom script or tool).
# =============================================================================================
# Install the library and the bindings module into the source folder near the main.py file, so
# that the Python interpeter successfully imports the used module.
# install(TARGETS ${bindings_library} ${sample_library}
# LIBRARY DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}
# RUNTIME DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}
# )
install(TARGETS ${bindings_library}
LIBRARY DESTINATION ${bindings_library_dir}
RUNTIME DESTINATION ${bindings_library_dir}
)

add_custom_command(TARGET ${bindings_library} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
$<TARGET_FILE:${bindings_library}> ${abqindexday_lib_dir})
82 changes: 82 additions & 0 deletions bind11/indexday/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#include <pybind11/numpy.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

#include <QtCore/QObject>
#include <cstring>
#include <iostream>
#include <string>
#include <typeinfo>
#include <vector>

#include "abquant/actions/abquant.hpp"
#include "abquant/actions/indexday.hpp"
#include "abquant/actions/utils.hpp"

// using namespace std;
namespace abq
{
class PyIndexDay
{
public:
PyIndexDay(std::vector<std::string> codes, const string& start, const string& end)
: m_codes{codes}, m_start{start}, m_end{end}
{
QStringList qcodes;
for (auto c : codes) {
qcodes << QString::fromStdString(c);
}
m_ida = IndexDayAction(qcodes, m_start.c_str(), m_end.c_str());
m_ida.setDataFrame();
};

template <class T>
std::vector<T> toSeries(const string& col) const noexcept
{
if constexpr (std::is_same_v<T, double>) {
auto series = m_ida.get_pyseries(col.c_str());
return series;
}

auto series = m_ida.toSeries<T>(col.c_str());
return series.toStdVector();
}
~PyIndexDay() = default;

private:
std::vector<std::string> m_codes{};
const string m_start{};
const string m_end{};
IndexDayAction m_ida{};
};

namespace py = pybind11;

PYBIND11_MODULE(abqindexday, m)
{
m.doc() = R"pbdoc(
Pybind11 IndexDay plugin
-----------------------
.. abqindexday:: currentmodule_exmaple
.. autosummary::
:indexday: toSeries
toSeries
)pbdoc";

py::class_<PyIndexDay> sm_class(m, "PyIndexDay");
sm_class.def(py::init<std::vector<std::string>, const string, const string>())
.def("toSeries", &PyIndexDay::toSeries<double>, R"pbdoc(toSeries double toSeries double function.)pbdoc")
.def("toSeries_string", &PyIndexDay::toSeries<std::string>,
R"pbdoc(toSeries string toSeries string function.)pbdoc");

#ifdef VERSION_INFO
m.attr("__version__") = VERSION_INFO;
#else
m.attr("__version__") = "dev";
#endif
}

} // namespace abq
58 changes: 58 additions & 0 deletions bind11/test/test_indexday.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# -*- coding: utf-8 -*-

import unittest

import pandas as pd

from abqindexday import PyIndexDay as indexday
from pyabquant import PyAbquant

pd.set_option("display.max_rows", None)
pd.set_option("display.max_columns", None)
pd.set_option("display.width", None)


class MainTest(unittest.TestCase):
def testDay(self):
codes = ["000001"]
start = "2019-01-01"
end = "2019-12-01"
sd = indexday(codes, start, end)

open_ = sd.toSeries("open")
close = sd.toSeries("close")
high = sd.toSeries("high")
low = sd.toSeries("low")
vol = sd.toSeries("vol")
amount = sd.toSeries("amount")
date = sd.toSeries_string("date")
code = sd.toSeries_string("code")
print(date[:10])
print(code[:10])
date_stamp = sd.toSeries("date_stamp")

df = pd.DataFrame(
{
"open": open_,
"close": close,
"high": high,
"low": low,
"vol": vol,
"amount": amount,
"date": date,
"code": code,
"date_stamp": date_stamp,
}
)
df.set_index(["code", "date"], inplace=True)

print(df[:10])

self.assertTrue(len(open_) > 0)
self.assertAlmostEqual(open_[0], 2497.88, delta=0.001)


if __name__ == "__main__":
PyAbquant.start()
unittest.main()
PyAbquant.finish()

0 comments on commit 9f2cf40

Please sign in to comment.