diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..75a203b --- /dev/null +++ b/.clang-format @@ -0,0 +1,3 @@ +BasedOnStyle: LLVM +IndentWidth: 4 +ColumnLimit: 100 diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..d458fd2 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,13 @@ +--- +name: Bug Report +about: Create a bug report to help us improve +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior. + +**Expected behavior** +A clear and concise description of what you expected to happen. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..4278722 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,5 @@ +## Summary +- Provide a concise description of changes. + +## Testing +- `ctest -V` diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..d2d6cd6 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,15 @@ +name: CI + +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Configure + run: cmake -S . -B build + - name: Build + run: cmake --build build + - name: Test + run: ctest --test-dir build --output-on-failure diff --git a/CMakeLists.txt b/CMakeLists.txt index a9f2f27..ff55b46 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,6 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) -include_directories(${PROJECT_SOURCE_DIR}/include) add_subdirectory(src) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..d865d5a --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,3 @@ +# Code of Conduct + +Be respectful and considerate in all interactions. Harassment or abusive behavior will not be tolerated. If you encounter any issues, please contact the maintainers. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..c13500c --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,8 @@ +# Contributing + +Thank you for considering contributing to this project! Please open an issue first to discuss any major changes. Pull requests should: + +1. Build successfully with CMake. +2. Run `ctest` and pass all tests. + +Feel free to propose enhancements and bug fixes. diff --git a/README.md b/README.md index 0446f61..45cab46 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,11 @@ Bootstrap for implementing code snippets from Duffy's *Financial Instrument Pricing Using C++*. +### Quick Start +1. `mkdir build && cd build` +2. `cmake .. && cmake --build .` +3. `ctest -V` + ## Requirements - CMake >= 3.15 @@ -107,76 +112,8 @@ ctest -V This will execute the `option_pricing` unit tests (normal PDF/CDF checks and basic call/put pricing validations). -## Getting Started Guide for Java Developers - -If you come from a Java background and haven’t touched C++ in a while (or ever), this section will help you: - -- Understand the C++ project layout and how it compares to a typical Java project -- Learn the CMake build workflow (analogy to Maven/Gradle) -- Pick up the core C++ language features used in this codebase - -### 1. Project Layout Comparison - -```text -Java: C++ (this project): -src/main/java/... include/sud.hpp, include/option_pricing.hpp -src/main/resources/... src/main.cpp -pom.xml / build.gradle CMakeLists.txt (root & src) -``` - -• **Headers (`.hpp`)** declare interfaces and templates (like Java interfaces or class declarations). -• **Sources (`.cpp`)** contain implementations (like Java classes with method bodies). -• **`CMakeLists.txt`** serves as the build spec (similar to `pom.xml` or `build.gradle`). - -### 2. CMake vs. Maven/Gradle - -| Step | Java (Maven) | C++ (CMake) | -|:-----------------------|:--------------------------|:-------------------------------------| -| Configure/dependencies | `mvn compile` | `cmake ..` | -| Compile & link | `mvn package` | `cmake --build .` | -| Run tests | `mvn test` | (CTest or manual test executable) | -| Execute application | `java -jar target/app.jar`| `./option_pricing` | - -### 3. Essential C++ Constructs - -1. **Templates** (generic code): - ```cpp - template - using OptionData = std::tuple; - ``` - -2. **Type aliases** (`using`): - ```cpp - using ComputedData = std::tuple; - ``` - -3. **Tuples** (multiple return values): - ```cpp - return std::make_tuple(price, delta, gamma); - ``` - -4. **Lambdas & callbacks** (`std::function`): - ```cpp - IAlgorithm bs = [](auto od, double S) { /* ... */ }; - ``` - -5. **Inline/free functions** for small utilities: - ```cpp - inline double N(double x) { return 0.5*(1-std::erf(-x/√2)); } - ``` - -6. **Thread safety** with `std::mutex` + `std::lock_guard` (vs Java `synchronized`): - ```cpp - static std::mutex m; - std::lock_guard lock(m); - ``` - -### 4. IDE & Tooling - -- **CLion**: IntelliJ-like C++ IDE—open the root folder, and it imports the CMake project automatically. -- **Command-line**: requires a C++17 compiler (`g++`/`clang++`) and CMake installed in your PATH. -- **.gitignore**: filters build artifacts, IDE settings, and temporary files so your repo stays clean. +For a detailed introduction, see [docs/JavaGuide.md](docs/JavaGuide.md). -With these points in mind, you’ll feel right at home extending and navigating this C++ project using patterns and workflows you already know from Java. +## License -Happy coding! \ No newline at end of file +This project is licensed under the MIT License. Pricing formulas are provided for educational purposes only and should not be used in production without proper validation. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..ba0336d --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,3 @@ +# Security Policy + +Please report any security vulnerabilities by opening an issue or contacting the maintainers privately. We will respond as soon as possible. diff --git a/docs/JavaGuide.md b/docs/JavaGuide.md new file mode 100644 index 0000000..a802624 --- /dev/null +++ b/docs/JavaGuide.md @@ -0,0 +1,73 @@ +## Getting Started Guide for Java Developers + +If you come from a Java background and haven’t touched C++ in a while (or ever), this section will help you: + +- Understand the C++ project layout and how it compares to a typical Java project +- Learn the CMake build workflow (analogy to Maven/Gradle) +- Pick up the core C++ language features used in this codebase + +### 1. Project Layout Comparison + +```text +Java: C++ (this project): +src/main/java/... include/sud.hpp, include/option_pricing.hpp +src/main/resources/... src/main.cpp +pom.xml / build.gradle CMakeLists.txt (root & src) +``` + +• **Headers (`.hpp`)** declare interfaces and templates (like Java interfaces or class declarations). +• **Sources (`.cpp`)** contain implementations (like Java classes with method bodies). +• **`CMakeLists.txt`** serves as the build spec (similar to `pom.xml` or `build.gradle`). + +### 2. CMake vs. Maven/Gradle + +| Step | Java (Maven) | C++ (CMake) | +|:-----------------------|:--------------------------|:-------------------------------------| +| Configure/dependencies | `mvn compile` | `cmake ..` | +| Compile & link | `mvn package` | `cmake --build .` | +| Run tests | `mvn test` | (CTest or manual test executable) | +| Execute application | `java -jar target/app.jar`| `./option_pricing` | + +### 3. Essential C++ Constructs + +1. **Templates** (generic code): + ```cpp + template + using OptionData = std::tuple; + ``` + +2. **Type aliases** (`using`): + ```cpp + using ComputedData = std::tuple; + ``` + +3. **Tuples** (multiple return values): + ```cpp + return std::make_tuple(price, delta, gamma); + ``` + +4. **Lambdas & callbacks** (`std::function`): + ```cpp + IAlgorithm bs = [](auto od, double S) { /* ... */ }; + ``` + +5. **Inline/free functions** for small utilities: + ```cpp + inline double N(double x) { return 0.5*(1-std::erf(-x/√2)); } + ``` + +6. **Thread safety** with `std::mutex` + `std::lock_guard` (vs Java `synchronized`): + ```cpp + static std::mutex m; + std::lock_guard lock(m); + ``` + +### 4. IDE & Tooling + +- **CLion**: IntelliJ-like C++ IDE—open the root folder, and it imports the CMake project automatically. +- **Command-line**: requires a C++17 compiler (`g++`/`clang++`) and CMake installed in your PATH. +- **.gitignore**: filters build artifacts, IDE settings, and temporary files so your repo stays clean. + +With these points in mind, you’ll feel right at home extending and navigating this C++ project using patterns and workflows you already know from Java. + +Happy coding! diff --git a/include/option_pricing.hpp b/include/option_pricing.hpp index b965027..40bd439 100644 --- a/include/option_pricing.hpp +++ b/include/option_pricing.hpp @@ -13,17 +13,21 @@ #include "sud.hpp" +namespace op { + // Standard normal density function inline double n(double x) { - const double A = 1.0 / std::sqrt(2.0 * 3.14159265358979323846); + constexpr double PI = 3.14159265358979323846; + const double A = 1.0 / std::sqrt(2.0 * PI); return A * std::exp(-x * x * 0.5); } // Cumulative normal distribution using error function -static inline auto cndN = [](double x) { +inline double cndN(double x) +{ return 0.5 * (1.0 - std::erf(-x / std::sqrt(2.0))); -}; +} inline double N(double x) { @@ -155,4 +159,6 @@ class ProcessingII { return PutValues(optData, S); } -}; \ No newline at end of file +}; + +} // namespace op diff --git a/include/sud.hpp b/include/sud.hpp index 846c643..3e3b05b 100644 --- a/include/sud.hpp +++ b/include/sud.hpp @@ -8,6 +8,8 @@ #include #include +namespace op { + template using OptionData = std::tuple; @@ -36,4 +38,7 @@ class SUD : private Source, private Sink SendData(t2); end(); } -}; \ No newline at end of file +}; + +} // namespace op + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2e67226..714e744 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,10 +1,10 @@ -file(GLOB SOURCES *.cpp) - -add_executable(option_pricing ${SOURCES}) +add_executable(option_pricing + main.cpp +) # Place the executable in the top-level build directory for ease of use set_target_properties(option_pricing PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} ) -target_include_directories(option_pricing PUBLIC ${PROJECT_SOURCE_DIR}/include) \ No newline at end of file +target_include_directories(option_pricing PUBLIC ${PROJECT_SOURCE_DIR}/include) diff --git a/src/main.cpp b/src/main.cpp index f452912..e718701 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,18 +4,18 @@ int main() { using value_type = double; // Instantiate call and put processing policies - Processing converter; - ProcessingII converter2; + op::Processing converter; + op::ProcessingII converter2; // Pricing calls - SUD callPricer(converter); + op::SUD callPricer(converter); value_type S = 60.0; callPricer.run(S); // Pricing puts - SUD putPricer(converter2); + op::SUD putPricer(converter2); value_type S2 = 60.0; putPricer.run(S2); return 0; -} \ No newline at end of file +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 91b3a91..da70181 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,7 +1,6 @@ -file(GLOB TEST_SOURCES *.cpp) +add_executable(test_option_pricing test_option_pricing.cpp) -add_executable(test_option_pricing ${TEST_SOURCES}) target_include_directories(test_option_pricing PRIVATE ${PROJECT_SOURCE_DIR}/include) # Register with CTest -add_test(NAME option_pricing_unit_tests COMMAND test_option_pricing) \ No newline at end of file +add_test(NAME option_pricing_unit_tests COMMAND test_option_pricing) diff --git a/tests/test_option_pricing.cpp b/tests/test_option_pricing.cpp index c462265..285d558 100644 --- a/tests/test_option_pricing.cpp +++ b/tests/test_option_pricing.cpp @@ -8,18 +8,18 @@ int main() { // Test standard normal PDF at 0: n(0) = 1/sqrt(2*pi) const double PI = 3.14159265358979323846; - double pdf0 = n(0.0); + double pdf0 = op::n(0.0); assert(std::abs(pdf0 - (1.0 / std::sqrt(2.0 * PI))) < 1e-12); // Test cumulative normal CDF at 0: N(0) = 0.5 - double cdf0 = N(0.0); + double cdf0 = op::N(0.0); assert(std::abs(cdf0 - 0.5) < 1e-12); // Prepare option data: K=100, T=1, r=0, v=0.2 - OptionData data(100.0, 1.0, 0.0, 0.2); + op::OptionData data(100.0, 1.0, 0.0, 0.2); // Test call values: price>0, 00 - auto call = CallValues(data, 100.0); + auto call = op::CallValues(data, 100.0); double price = std::get<0>(call); double delta = std::get<1>(call); double gamma = std::get<2>(call); @@ -28,7 +28,7 @@ int main() assert(gamma > 0.0); // Test put values: price>0, delta<0, gamma>0 - auto put = PutValues(data, 100.0); + auto put = op::PutValues(data, 100.0); double price2 = std::get<0>(put); double delta2 = std::get<1>(put); double gamma2 = std::get<2>(put); @@ -38,4 +38,4 @@ int main() std::cout << "All unit tests passed." << std::endl; return 0; -} \ No newline at end of file +}