├── .github └── workflows │ └── test.yml ├── .gitignore ├── CMakeLists.txt ├── Examples ├── CMakeLists.txt ├── Data │ ├── BTC-USD.csv │ └── ^NSEMDCP50.csv ├── StreamingSupportResistance │ ├── CMakeLists.txt │ └── main.cpp └── SupportResistance │ ├── CMakeLists.txt │ ├── SupportResistance.h │ ├── main.cpp │ └── readme.txt ├── LICENSE ├── README.md └── include └── backtest ├── Data.h ├── Engine.h ├── FileIterator.h ├── Indicators.h └── Strategy.h /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Backtest-Cpp CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - 'v*' 8 | pull_request: 9 | branches: 10 | - main 11 | - 'v*' 12 | 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Checkout code 18 | uses: actions/checkout@v2 19 | 20 | - name: Set up CMake 21 | uses: jwlawson/actions-setup-cmake@v2 22 | with: 23 | cmake-version: '3.22.1' 24 | 25 | - name: Build and test 26 | run: | 27 | mkdir build 28 | cd build 29 | cmake .. 30 | make -j4 31 | cd Examples/SupportResistance 32 | ./SupportResistance 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | main 34 | out 35 | 36 | # Build files 37 | build/ -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | 3 | project(BackTest-Cpp LANGUAGES CXX) 4 | 5 | set(CMAKE_CXX_STANDARD 17) 6 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 7 | set(CMAKE_CXX_EXTENSIONS OFF) 8 | 9 | # Header-only backtest core 10 | add_library(backtest INTERFACE) 11 | target_include_directories(backtest INTERFACE 12 | $ 13 | $ 14 | ) 15 | 16 | # Build example projects 17 | add_subdirectory(Examples) 18 | -------------------------------------------------------------------------------- /Examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(SupportResistance) 2 | add_subdirectory(StreamingSupportResistance) 3 | -------------------------------------------------------------------------------- /Examples/Data/BTC-USD.csv: -------------------------------------------------------------------------------- 1 | Date,Open,High,Low,Close,Adj Close,Volume 2 | 2023-07-05,30778.724609,30877.330078,30225.613281,30514.166016,30514.166016,12481622280 3 | 2023-07-06,30507.150391,31460.052734,29892.226563,29909.337891,29909.337891,21129219509 4 | 2023-07-07,29907.998047,30434.644531,29777.285156,30342.265625,30342.265625,13384770155 5 | 2023-07-08,30346.921875,30374.437500,30080.160156,30292.541016,30292.541016,7509378699 6 | 2023-07-09,30291.611328,30427.589844,30085.591797,30171.234375,30171.234375,7903327692 7 | 2023-07-10,30172.423828,31026.083984,29985.394531,30414.470703,30414.470703,14828209155 8 | 2023-07-11,30417.632813,30788.314453,30358.097656,30620.951172,30620.951172,12151839152 9 | 2023-07-12,30622.246094,30959.964844,30228.835938,30391.646484,30391.646484,14805659717 10 | 2023-07-13,30387.488281,31814.515625,30268.351563,31476.048828,31476.048828,23686079548 11 | 2023-07-14,31474.720703,31582.253906,29966.386719,30334.068359,30334.068359,20917902660 12 | 2023-07-15,30331.783203,30407.781250,30263.462891,30295.806641,30295.806641,8011667756 13 | 2023-07-16,30297.472656,30437.560547,30089.669922,30249.132813,30249.132813,8516564470 14 | 2023-07-17,30249.626953,30336.400391,29685.783203,30145.888672,30145.888672,13240156074 15 | 2023-07-18,30147.070313,30233.656250,29556.427734,29856.562500,29856.562500,13138897269 16 | 2023-07-19,29862.046875,30184.181641,29794.269531,29913.923828,29913.923828,12128602812 17 | 2023-07-20,29915.250000,30195.531250,29638.095703,29792.015625,29792.015625,14655207121 18 | 2023-07-21,29805.111328,30045.998047,29733.851563,29908.744141,29908.744141,10972789818 19 | 2023-07-22,29908.697266,29991.615234,29664.121094,29771.802734,29771.802734,7873300598 20 | 2023-07-23,29790.111328,30330.640625,29741.527344,30084.539063,30084.539063,9220145050 21 | 2023-07-24,30081.662109,30093.394531,28934.294922,29176.916016,29176.916016,15395817395 22 | 2023-07-25,29178.970703,29353.160156,29062.433594,29227.390625,29227.390625,10266772793 23 | 2023-07-26,29225.759766,29675.552734,29113.912109,29354.972656,29354.972656,13497554655 24 | 2023-07-27,29353.798828,29560.966797,29099.351563,29210.689453,29210.689453,10770779217 25 | 2023-07-28,29212.164063,29521.513672,29125.845703,29319.246094,29319.246094,11218474952 26 | 2023-07-29,29319.445313,29396.843750,29264.166016,29356.917969,29356.917969,6481775959 27 | 2023-07-30,29357.093750,29443.169922,29059.501953,29275.308594,29275.308594,8678454527 28 | 2023-07-31,29278.314453,29489.873047,29131.578125,29230.111328,29230.111328,11656781982 29 | 2023-08-01,29230.873047,29675.732422,28657.023438,29675.732422,29675.732422,18272392391 30 | 2023-08-02,29704.146484,29987.998047,28946.509766,29151.958984,29151.958984,19212655598 31 | 2023-08-03,29161.812500,29375.707031,28959.488281,29178.679688,29178.679688,12780357746 32 | 2023-08-04,29174.382813,29302.078125,28885.335938,29074.091797,29074.091797,12036639988 33 | 2023-08-05,29075.388672,29102.464844,28957.796875,29042.126953,29042.126953,6598366353 34 | 2023-08-06,29043.701172,29160.822266,28963.833984,29041.855469,29041.855469,7269806994 35 | 2023-08-07,29038.513672,29244.281250,28724.140625,29180.578125,29180.578125,13618163710 36 | 2023-08-08,29180.019531,30176.796875,29113.814453,29765.492188,29765.492188,17570561357 37 | 2023-08-09,29766.695313,30093.435547,29376.800781,29561.494141,29561.494141,18379521213 38 | 2023-08-10,29563.972656,29688.564453,29354.447266,29429.591797,29429.591797,11865344789 39 | 2023-08-11,29424.902344,29517.773438,29253.517578,29397.714844,29397.714844,10195168197 40 | 2023-08-12,29399.787109,29465.113281,29357.587891,29415.964844,29415.964844,6194358008 41 | 2023-08-13,29416.593750,29441.433594,29265.806641,29282.914063,29282.914063,7329897180 42 | 2023-08-14,29283.263672,29660.253906,29124.105469,29408.443359,29408.443359,14013695304 43 | 2023-08-15,29408.048828,29439.121094,29088.853516,29170.347656,29170.347656,12640195779 44 | 2023-08-16,29169.074219,29221.976563,28701.779297,28701.779297,28701.779297,14949271904 45 | 2023-08-17,28699.802734,28745.947266,25409.111328,26664.550781,26664.550781,31120851211 46 | 2023-08-18,26636.078125,26808.195313,25668.921875,26049.556641,26049.556641,24026236529 47 | 2023-08-19,26047.832031,26249.449219,25802.408203,26096.205078,26096.205078,10631443812 48 | 2023-08-20,26096.861328,26260.681641,26004.314453,26189.583984,26189.583984,9036580420 49 | 2023-08-21,26188.691406,26220.201172,25846.087891,26124.140625,26124.140625,13371557893 50 | 2023-08-22,26130.748047,26135.507813,25520.728516,26031.656250,26031.656250,14503820706 51 | 2023-08-23,26040.474609,26786.898438,25804.998047,26431.640625,26431.640625,16985265785 52 | 2023-08-24,26431.519531,26554.910156,25914.925781,26162.373047,26162.373047,12871532023 53 | 2023-08-25,26163.679688,26248.103516,25786.812500,26047.667969,26047.667969,12406045118 54 | 2023-08-26,26047.234375,26107.384766,25983.878906,26008.462891,26008.462891,6034817316 55 | 2023-08-27,26008.242188,26165.373047,25965.097656,26089.693359,26089.693359,6913768611 56 | 2023-08-28,26089.615234,26198.578125,25880.599609,26106.150391,26106.150391,11002805166 57 | 2023-08-29,26102.486328,28089.337891,25912.628906,27727.392578,27727.392578,29368391712 58 | 2023-08-30,27726.083984,27760.160156,27069.207031,27297.265625,27297.265625,16343655235 59 | 2023-08-31,27301.929688,27456.078125,25752.929688,25931.472656,25931.472656,20181001451 60 | 2023-09-01,25934.021484,26125.869141,25362.609375,25800.724609,25800.724609,17202862221 61 | 2023-09-02,25800.910156,25970.285156,25753.093750,25868.798828,25868.798828,10100387473 62 | 2023-09-03,25869.472656,26087.148438,25817.031250,25969.566406,25969.566406,8962524523 63 | 2023-09-04,25968.169922,26081.525391,25657.025391,25812.416016,25812.416016,10680635106 64 | 2023-09-05,25814.957031,25858.375000,25589.988281,25779.982422,25779.982422,11094740040 65 | 2023-09-06,25783.931641,25953.015625,25404.359375,25753.236328,25753.236328,12752705327 66 | 2023-09-07,25748.312500,26409.302734,25608.201172,26240.195313,26240.195313,11088307100 67 | 2023-09-08,26245.208984,26414.005859,25677.480469,25905.654297,25905.654297,10817356400 68 | 2023-09-09,25905.425781,25921.976563,25810.494141,25895.677734,25895.677734,5481314132 69 | 2023-09-10,25895.210938,25978.130859,25640.261719,25832.226563,25832.226563,7899553047 70 | 2023-09-11,25831.714844,25883.947266,24930.296875,25162.654297,25162.654297,14600006467 71 | 2023-09-12,25160.658203,26451.939453,25133.078125,25833.343750,25833.343750,18657279324 72 | 2023-09-13,25837.554688,26376.113281,25781.123047,26228.324219,26228.324219,13072077070 73 | 2023-09-14,26228.277344,26774.623047,26171.451172,26539.673828,26539.673828,13811359124 74 | 2023-09-15,26533.818359,26840.498047,26240.701172,26608.693359,26608.693359,11479735788 75 | 2023-09-16,26606.199219,26754.769531,26473.890625,26568.281250,26568.281250,7402031417 76 | 2023-09-17,26567.927734,26617.998047,26445.074219,26534.187500,26534.187500,6774210670 77 | 2023-09-18,26532.994141,27414.734375,26415.515625,26754.281250,26754.281250,15615339655 78 | 2023-09-19,26760.851563,27488.763672,26681.605469,27211.117188,27211.117188,13807690550 79 | 2023-09-20,27210.228516,27379.505859,26864.082031,27132.007813,27132.007813,13281116604 80 | 2023-09-21,27129.839844,27152.939453,26389.300781,26567.632813,26567.632813,13371443708 81 | 2023-09-22,26564.056641,26726.078125,26495.533203,26579.568359,26579.568359,10578746709 82 | 2023-09-23,26578.556641,26634.185547,26520.519531,26579.390625,26579.390625,7404700301 83 | 2023-09-24,26579.373047,26716.058594,26221.050781,26256.826172,26256.826172,8192867686 84 | 2023-09-25,26253.775391,26421.507813,26011.468750,26298.480469,26298.480469,11997833257 85 | 2023-09-26,26294.757813,26389.884766,26090.712891,26217.250000,26217.250000,9985498161 86 | 2023-09-27,26209.498047,26817.841797,26111.464844,26352.716797,26352.716797,11718380997 87 | 2023-09-28,26355.812500,27259.500000,26327.322266,27021.546875,27021.546875,14079002707 88 | 2023-09-29,27024.841797,27225.937500,26721.763672,26911.720703,26911.720703,10396435377 89 | 2023-09-30,26911.689453,27091.794922,26888.968750,26967.916016,26967.916016,5331172801 90 | 2023-10-01,26967.396484,28047.238281,26965.093750,27983.750000,27983.750000,9503917434 91 | 2023-10-02,27976.798828,28494.458984,27347.787109,27530.785156,27530.785156,19793041322 92 | 2023-10-03,27508.251953,27667.191406,27216.001953,27429.978516,27429.978516,11407814187 93 | 2023-10-04,27429.074219,27826.658203,27248.105469,27799.394531,27799.394531,11143355314 94 | 2023-10-05,27798.646484,28091.861328,27375.601563,27415.912109,27415.912109,11877253670 95 | 2023-10-06,27412.123047,28252.537109,27215.552734,27946.597656,27946.597656,13492391599 96 | 2023-10-07,27946.781250,28028.091797,27870.423828,27968.839844,27968.839844,6553044316 97 | 2023-10-08,27971.677734,28102.169922,27740.662109,27935.089844,27935.089844,7916875290 98 | 2023-10-09,27934.472656,27989.470703,27302.562500,27583.677734,27583.677734,12007668568 99 | 2023-10-10,27589.201172,27715.847656,27301.654297,27391.019531,27391.019531,9973350678 100 | 2023-10-11,27392.076172,27474.115234,26561.099609,26873.320313,26873.320313,13648094333 101 | 2023-10-12,26873.292969,26921.439453,26558.320313,26756.798828,26756.798828,9392909295 102 | 2023-10-13,26752.878906,27092.697266,26686.322266,26862.375000,26862.375000,15165312851 103 | 2023-10-14,26866.203125,26969.000000,26814.585938,26861.707031,26861.707031,5388116782 104 | 2023-10-15,26858.011719,27289.169922,26817.894531,27159.652344,27159.652344,7098201980 105 | 2023-10-16,27162.628906,29448.138672,27130.472656,28519.466797,28519.466797,27833876539 106 | 2023-10-17,28522.097656,28618.751953,28110.185547,28415.748047,28415.748047,14872527508 107 | 2023-10-18,28413.531250,28889.009766,28174.251953,28328.341797,28328.341797,12724128586 108 | 2023-10-19,28332.416016,28892.474609,28177.988281,28719.806641,28719.806641,14448058195 109 | 2023-10-20,28732.812500,30104.085938,28601.669922,29682.949219,29682.949219,21536125230 110 | 2023-10-21,29683.380859,30287.482422,29481.751953,29918.412109,29918.412109,11541146996 111 | 2023-10-22,29918.654297,30199.433594,29720.312500,29993.896484,29993.896484,10446520040 112 | 2023-10-23,30140.685547,34370.437500,30097.828125,33086.234375,33086.234375,38363572311 113 | 2023-10-24,33077.304688,35150.433594,32880.761719,33901.527344,33901.527344,44934999645 114 | 2023-10-25,33916.042969,35133.757813,33709.109375,34502.820313,34502.820313,25254318008 115 | 2023-10-26,34504.289063,34832.910156,33762.324219,34156.648438,34156.648438,19427195376 116 | 2023-10-27,34156.500000,34238.210938,33416.886719,33909.800781,33909.800781,16418032871 117 | 2023-10-28,33907.722656,34399.390625,33874.804688,34089.574219,34089.574219,10160330825 118 | 2023-10-29,34089.371094,34743.261719,33947.566406,34538.480469,34538.480469,11160323986 119 | 2023-10-30,34531.742188,34843.933594,34110.972656,34502.363281,34502.363281,17184860315 120 | 2023-10-31,34500.078125,34719.253906,34083.308594,34667.781250,34667.781250,15758270810 121 | 2023-11-01,34657.273438,35527.929688,34170.691406,35437.253906,35437.253906,22446272005 122 | 2023-11-02,35441.578125,35919.843750,34401.574219,34938.242188,34938.242188,20998158544 123 | 2023-11-03,34942.472656,34942.472656,34133.441406,34732.324219,34732.324219,17158456701 124 | 2023-11-04,34736.324219,35256.031250,34616.691406,35082.195313,35082.195313,9561294264 125 | 2023-11-05,35090.011719,35340.339844,34594.242188,35049.355469,35049.355469,12412743996 126 | 2023-11-06,35044.789063,35286.027344,34765.363281,35037.371094,35037.371094,12693436420 127 | 2023-11-07,35047.792969,35892.417969,34545.816406,35443.562500,35443.562500,18834737789 128 | 2023-11-08,35419.476563,35994.417969,35147.800781,35655.277344,35655.277344,17295394918 129 | 2023-11-09,35633.632813,37926.257813,35592.101563,36693.125000,36693.125000,37762672382 130 | 2023-11-10,36702.250000,37493.800781,36362.753906,37313.968750,37313.968750,22711265155 131 | 2023-11-11,37310.070313,37407.093750,36773.667969,37138.050781,37138.050781,13924272142 132 | 2023-11-12,37133.992188,37227.691406,36779.117188,37054.519531,37054.519531,11545715999 133 | 2023-11-13,37070.304688,37405.117188,36399.605469,36502.355469,36502.355469,19057712790 134 | 2023-11-14,36491.789063,36753.351563,34948.500000,35537.640625,35537.640625,23857403554 135 | 2023-11-15,35548.113281,37964.894531,35383.781250,37880.582031,37880.582031,27365821679 136 | 2023-11-16,37879.980469,37934.625000,35545.472656,36154.769531,36154.769531,26007385366 137 | 2023-11-17,36164.824219,36704.484375,35901.234375,36596.683594,36596.683594,22445028430 138 | 2023-11-18,36625.371094,36839.281250,36233.312500,36585.703125,36585.703125,11886022717 139 | 2023-11-19,36585.765625,37509.355469,36414.597656,37386.546875,37386.546875,12915986553 140 | 2023-11-20,37374.074219,37756.820313,36882.531250,37476.957031,37476.957031,20888209068 141 | 2023-11-21,37469.160156,37631.140625,35813.812500,35813.812500,35813.812500,25172163756 142 | 2023-11-22,35756.554688,37856.980469,35670.972656,37432.339844,37432.339844,24397247860 143 | 2023-11-23,37420.433594,37643.917969,36923.863281,37289.621094,37289.621094,14214948217 144 | 2023-11-24,37296.316406,38415.339844,37261.605469,37720.281250,37720.281250,22922957823 145 | 2023-11-25,37721.414063,37892.429688,37617.417969,37796.792969,37796.792969,9099571165 146 | 2023-11-26,37796.828125,37820.300781,37162.750000,37479.121094,37479.121094,13744796068 147 | 2023-11-27,37454.191406,37559.355469,36750.128906,37254.167969,37254.167969,19002925720 148 | 2023-11-28,37247.992188,38368.480469,36891.089844,37831.085938,37831.085938,21696137014 149 | 2023-11-29,37826.105469,38366.113281,37612.632813,37858.492188,37858.492188,20728546658 150 | 2023-11-30,37861.117188,38141.753906,37531.140625,37712.746094,37712.746094,18115982627 151 | 2023-12-01,37718.007813,38954.109375,37629.359375,38688.750000,38688.750000,23512784002 152 | 2023-12-02,38689.277344,39678.937500,38652.593750,39476.332031,39476.332031,15534035612 153 | 2023-12-03,39472.207031,40135.605469,39298.164063,39978.390625,39978.390625,15769696322 154 | 2023-12-04,39978.628906,42371.750000,39978.628906,41980.097656,41980.097656,39856129827 155 | 2023-12-05,41986.265625,44408.664063,41421.148438,44080.648438,44080.648438,36312154535 156 | 2023-12-06,44080.023438,44265.769531,43478.082031,43746.445313,43746.445313,29909761586 157 | 2023-12-07,43769.132813,44042.589844,42880.648438,43292.664063,43292.664063,27635760671 158 | 2023-12-08,43293.136719,44705.515625,43125.296875,44166.601563,44166.601563,24421116687 159 | 2023-12-09,44180.019531,44361.257813,43627.597656,43725.984375,43725.984375,17368210171 160 | 2023-12-10,43728.382813,44034.625000,43593.285156,43779.699219,43779.699219,13000481418 161 | 2023-12-11,43792.019531,43808.375000,40234.578125,41243.832031,41243.832031,40632672038 162 | 2023-12-12,41238.734375,42048.304688,40667.562500,41450.222656,41450.222656,24779520132 163 | 2023-12-13,41468.464844,43429.781250,40676.867188,42890.742188,42890.742188,26797884674 164 | 2023-12-14,42884.261719,43390.859375,41767.089844,43023.972656,43023.972656,25578530178 165 | 2023-12-15,43028.250000,43087.824219,41692.968750,41929.757813,41929.757813,19639442462 166 | 2023-12-16,41937.742188,42664.945313,41723.113281,42240.117188,42240.117188,14386729590 167 | 2023-12-17,42236.109375,42359.496094,41274.542969,41364.664063,41364.664063,16678702876 168 | 2023-12-18,41348.203125,42720.296875,40530.257813,42623.539063,42623.539063,25224642008 169 | 2023-12-19,42641.511719,43354.296875,41826.335938,42270.527344,42270.527344,23171001281 170 | 2023-12-20,42261.300781,44275.585938,42223.816406,43652.250000,43652.250000,27868908174 171 | 2023-12-21,43648.125000,44240.667969,43330.050781,43869.152344,43869.152344,22452766169 172 | 2023-12-22,43868.988281,44367.957031,43441.968750,43997.902344,43997.902344,21028503216 173 | 2023-12-23,44012.199219,44015.699219,43351.355469,43739.542969,43739.542969,13507796558 174 | 2023-12-24,43728.367188,43945.523438,42786.917969,43016.117188,43016.117188,18830554085 175 | 2023-12-25,43010.574219,43765.093750,42765.769531,43613.140625,43613.140625,21115795370 176 | 2023-12-26,43599.847656,43603.175781,41676.488281,42520.402344,42520.402344,30026850982 177 | 2023-12-27,42518.468750,43683.160156,42167.582031,43442.855469,43442.855469,25260941032 178 | 2023-12-28,43468.199219,43804.781250,42318.550781,42627.855469,42627.855469,22992093014 179 | 2023-12-29,42614.644531,43124.324219,41424.062500,42099.402344,42099.402344,26000021055 180 | 2023-12-30,42091.753906,42584.125000,41556.226563,42156.902344,42156.902344,16013925945 181 | 2023-12-31,42152.097656,42860.937500,41998.253906,42265.187500,42265.187500,16397498810 182 | 2024-01-01,42280.234375,44175.437500,42214.976563,44167.332031,44167.332031,18426978443 183 | 2024-01-02,44187.140625,45899.707031,44176.949219,44957.968750,44957.968750,39335274536 184 | 2024-01-03,44961.601563,45503.242188,40813.535156,42848.175781,42848.175781,46342323118 185 | 2024-01-04,42855.816406,44770.023438,42675.175781,44179.921875,44179.921875,30448091210 186 | 2024-01-05,44192.980469,44353.285156,42784.718750,44162.691406,44162.691406,32336029347 187 | 2024-01-06,44178.953125,44227.632813,43475.156250,43989.195313,43989.195313,16092503468 188 | 2024-01-07,43998.464844,44495.570313,43662.230469,43943.097656,43943.097656,19330573863 189 | 2024-01-08,43948.707031,47218.000000,43244.082031,46970.503906,46970.503906,42746192015 190 | 2024-01-09,46987.640625,47893.699219,45244.714844,46139.730469,46139.730469,39821290992 191 | 2024-01-10,46121.539063,47647.222656,44483.152344,46627.777344,46627.777344,50114613298 192 | 2024-01-11,46656.074219,48969.371094,45678.644531,46368.585938,46368.585938,45833734549 193 | 2024-01-12,46354.792969,46498.136719,41903.769531,42853.167969,42853.167969,43332698900 194 | 2024-01-13,42799.445313,43234.660156,42464.144531,42842.382813,42842.382813,20601860469 195 | 2024-01-14,42842.261719,43065.597656,41724.613281,41796.269531,41796.269531,17521429522 196 | 2024-01-15,41715.066406,43319.722656,41705.417969,42511.968750,42511.968750,22320220558 197 | 2024-01-16,42499.335938,43566.273438,42085.996094,43154.945313,43154.945313,24062872740 198 | 2024-01-17,43132.101563,43189.890625,42189.308594,42742.652344,42742.652344,20851232595 199 | 2024-01-18,42742.312500,42876.347656,40631.171875,41262.058594,41262.058594,25218357242 200 | 2024-01-19,41278.460938,42134.160156,40297.457031,41618.406250,41618.406250,25752407154 201 | 2024-01-20,41624.589844,41877.894531,41446.824219,41665.585938,41665.585938,11586690904 202 | 2024-01-21,41671.488281,41855.367188,41497.007813,41545.785156,41545.785156,9344043642 203 | 2024-01-22,41553.652344,41651.207031,39450.117188,39507.367188,39507.367188,31338708143 204 | 2024-01-23,39518.714844,40127.351563,38521.894531,39845.550781,39845.550781,29244553045 205 | 2024-01-24,39877.593750,40483.785156,39508.796875,40077.074219,40077.074219,22359526178 206 | 2024-01-25,40075.550781,40254.480469,39545.664063,39933.808594,39933.808594,18491782013 207 | 2024-01-26,39936.816406,42209.386719,39825.691406,41816.871094,41816.871094,25598119893 208 | 2024-01-27,41815.625000,42195.632813,41431.281250,42120.054688,42120.054688,11422941934 209 | 2024-01-28,42126.125000,42797.175781,41696.910156,42035.593750,42035.593750,16858971687 210 | 2024-01-29,42030.914063,43305.867188,41818.332031,43288.246094,43288.246094,20668476578 211 | 2024-01-30,43300.226563,43838.945313,42711.371094,42952.609375,42952.609375,23842814518 212 | 2024-01-31,42946.250000,43717.406250,42298.945313,42582.605469,42582.605469,24673628793 213 | 2024-02-01,42569.761719,43243.167969,41879.191406,43075.773438,43075.773438,21423953779 214 | 2024-02-02,43077.640625,43422.488281,42584.335938,43185.859375,43185.859375,18603843039 215 | 2024-02-03,43184.964844,43359.941406,42890.808594,42992.250000,42992.250000,11169245236 216 | 2024-02-04,42994.941406,43097.644531,42374.832031,42583.582031,42583.582031,14802225490 217 | 2024-02-05,42577.621094,43494.250000,42264.816406,42658.667969,42658.667969,18715487317 218 | 2024-02-06,42657.390625,43344.148438,42529.019531,43084.671875,43084.671875,16798476726 219 | 2024-02-07,43090.019531,44341.949219,42775.957031,44318.222656,44318.222656,21126587775 220 | 2024-02-08,44332.125000,45575.839844,44332.125000,45301.566406,45301.566406,26154524080 221 | 2024-02-09,45297.382813,48152.496094,45260.824219,47147.199219,47147.199219,39316770844 222 | 2024-02-10,47153.527344,48146.171875,46905.320313,47771.277344,47771.277344,16398681570 223 | 2024-02-11,47768.968750,48535.937500,47617.406250,48293.917969,48293.917969,19315867136 224 | 2024-02-12,48296.386719,50280.476563,47745.761719,49958.222656,49958.222656,34511985805 225 | 2024-02-13,49941.359375,50358.390625,48406.496094,49742.441406,49742.441406,35593051468 226 | 2024-02-14,49733.445313,52021.371094,49296.832031,51826.695313,51826.695313,39105608050 227 | 2024-02-15,51836.785156,52820.066406,51371.628906,51938.554688,51938.554688,38564360533 228 | 2024-02-16,51937.726563,52537.968750,51641.367188,52160.203125,52160.203125,28180567298 229 | 2024-02-17,52161.675781,52191.914063,50669.667969,51662.996094,51662.996094,20009091006 230 | 2024-02-18,51661.968750,52356.964844,51233.707031,52122.546875,52122.546875,17595377311 231 | 2024-02-19,52134.812500,52483.324219,51711.820313,51779.144531,51779.144531,21362184346 232 | 2024-02-20,51777.726563,52945.050781,50792.312500,52284.875000,52284.875000,33353758256 233 | 2024-02-21,52273.535156,52368.816406,50671.757813,51839.179688,51839.179688,28624907020 234 | 2024-02-22,51854.644531,52009.613281,50926.292969,51304.972656,51304.972656,25413900611 235 | 2024-02-23,51283.906250,51497.933594,50561.777344,50731.949219,50731.949219,21427078270 236 | 2024-02-24,50736.371094,51684.195313,50585.445313,51571.101563,51571.101563,15174077879 237 | 2024-02-25,51565.214844,51950.027344,51306.171875,51733.238281,51733.238281,15413239245 238 | 2024-02-26,51730.539063,54938.175781,50931.031250,54522.402344,54522.402344,34074411896 239 | 2024-02-27,54519.363281,57537.839844,54484.199219,57085.371094,57085.371094,49756832031 240 | 2024-02-28,57071.097656,63913.132813,56738.425781,62504.789063,62504.789063,83239156760 241 | 2024-02-29,62499.183594,63585.644531,60498.730469,61198.382813,61198.382813,65496611844 242 | 2024-03-01,61168.062500,63155.101563,60802.527344,62440.632813,62440.632813,40186368423 243 | 2024-03-02,62431.652344,62458.699219,61657.289063,62029.847656,62029.847656,23888473685 244 | 2024-03-03,62031.578125,63230.210938,61435.023438,63167.371094,63167.371094,26253811450 245 | 2024-03-04,63137.003906,68537.031250,62386.519531,68330.414063,68330.414063,70670471105 246 | 2024-03-05,68341.054688,69170.625000,59323.910156,63801.199219,63801.199219,102802940877 247 | 2024-03-06,63776.050781,67637.929688,62848.671875,66106.804688,66106.804688,68750229073 248 | 2024-03-07,66099.742188,68029.921875,65655.531250,66925.484375,66925.484375,46989543159 249 | 2024-03-08,66938.093750,70083.054688,66230.453125,68300.093750,68300.093750,59202881172 250 | 2024-03-09,68299.257813,68673.054688,68053.125000,68498.882813,68498.882813,21609650379 251 | 2024-03-10,68500.257813,70005.203125,68239.976563,69019.789063,69019.789063,35683977532 252 | 2024-03-11,69020.546875,72850.710938,67194.882813,72123.906250,72123.906250,65716656765 253 | 2024-03-12,72125.125000,72825.656250,68728.851563,71481.289063,71481.289063,62554434520 254 | 2024-03-13,71482.117188,73637.476563,71334.093750,73083.500000,73083.500000,48212536929 255 | 2024-03-14,73079.375000,73750.070313,68563.023438,71396.593750,71396.593750,59594605698 256 | 2024-03-15,71387.875000,72357.132813,65630.695313,69403.773438,69403.773438,78320453976 257 | 2024-03-16,69392.484375,70046.273438,64801.394531,65315.117188,65315.117188,46842198371 258 | 2024-03-17,65316.343750,68845.718750,64545.316406,68390.625000,68390.625000,44716864318 259 | 2024-03-18,68371.304688,68897.132813,66594.226563,67548.593750,67548.593750,49261579492 260 | 2024-03-19,67556.132813,68106.929688,61536.179688,61912.773438,61912.773438,74215844794 261 | 2024-03-20,61930.156250,68115.257813,60807.785156,67913.671875,67913.671875,66792634382 262 | 2024-03-21,67911.585938,68199.992188,64580.917969,65491.390625,65491.390625,44480350565 263 | 2024-03-22,65489.929688,66623.750000,62355.371094,63778.761719,63778.761719,41401116964 264 | 2024-03-23,63802.722656,65976.398438,63038.492188,64062.203125,64062.203125,24738964812 265 | 2024-03-24,64070.753906,67622.757813,63825.851563,67234.171875,67234.171875,27206630673 266 | 2024-03-25,67234.093750,71162.593750,66414.835938,69958.812500,69958.812500,42700139523 267 | 2024-03-26,69931.328125,71535.742188,69335.609375,69987.835938,69987.835938,36010437368 268 | 2024-03-27,69991.898438,71727.687500,68381.929688,69455.343750,69455.343750,40827113309 269 | 2024-03-28,69452.773438,71546.023438,68895.507813,70744.953125,70744.953125,34374900617 270 | 2024-03-29,70744.796875,70913.093750,69076.656250,69892.828125,69892.828125,25230851763 271 | 2024-03-30,69893.445313,70355.492188,69601.062500,69645.304688,69645.304688,17130241883 272 | 2024-03-31,69647.781250,71377.781250,69624.867188,71333.648438,71333.648438,20050941373 273 | 2024-04-01,71333.484375,71342.093750,68110.695313,69702.148438,69702.148438,34873527352 274 | 2024-04-02,69705.023438,69708.382813,64586.593750,65446.972656,65446.972656,50705240709 275 | 2024-04-03,65446.671875,66914.320313,64559.898438,65980.812500,65980.812500,34488018367 276 | 2024-04-04,65975.695313,69291.257813,65113.796875,68508.843750,68508.843750,34439527442 277 | 2024-04-05,68515.757813,68725.757813,66011.476563,67837.640625,67837.640625,33748230056 278 | 2024-04-06,67840.570313,69629.601563,67491.718750,68896.109375,68896.109375,19967785809 279 | 2024-04-07,68897.109375,70284.429688,68851.632813,69362.554688,69362.554688,21204930369 280 | 2024-04-08,69362.554688,72715.359375,69064.242188,71631.359375,71631.359375,37261432669 281 | 2024-04-09,71632.500000,71742.507813,68212.921875,69139.015625,69139.015625,36426900409 282 | 2024-04-10,69140.242188,71093.429688,67503.562500,70587.882813,70587.882813,38318601774 283 | 2024-04-11,70575.734375,71256.234375,69571.812500,70060.609375,70060.609375,30153382941 284 | 2024-04-12,70061.382813,71222.742188,65254.835938,67195.867188,67195.867188,44129299406 285 | 2024-04-13,67188.375000,67931.429688,60919.105469,63821.472656,63821.472656,52869738185 286 | 2024-04-14,63836.230469,65824.429688,62205.851563,65738.726563,65738.726563,49084320047 287 | 2024-04-15,65739.648438,66878.648438,62332.070313,63426.210938,63426.210938,43595917654 288 | 2024-04-16,63419.296875,64355.667969,61716.402344,63811.863281,63811.863281,42847528078 289 | 2024-04-17,63831.847656,64486.363281,59768.585938,61276.691406,61276.691406,41915247049 290 | 2024-04-18,61275.316406,64125.687500,60833.480469,63512.753906,63512.753906,36006307335 291 | 2024-04-19,63510.750000,65481.597656,59651.390625,63843.570313,63843.570313,49920425401 292 | 2024-04-20,63851.101563,65442.457031,63172.402344,64994.441406,64994.441406,23097485495 293 | 2024-04-21,64992.816406,65723.242188,64277.722656,64926.644531,64926.644531,20506644853 294 | 2024-04-22,64935.632813,67233.960938,64548.179688,66837.679688,66837.679688,28282686673 295 | 2024-04-23,66839.890625,67199.242188,65864.867188,66407.273438,66407.273438,24310975583 296 | 2024-04-24,66408.718750,67075.367188,63589.871094,64276.898438,64276.898438,30276655120 297 | 2024-04-25,64275.019531,65275.207031,62783.632813,64481.707031,64481.707031,32155786816 298 | 2024-04-26,64485.371094,64789.656250,63322.398438,63755.320313,63755.320313,24139372950 299 | 2024-04-27,63750.988281,63898.363281,62424.718750,63419.140625,63419.140625,19530783039 300 | 2024-04-28,63423.515625,64321.484375,62793.597656,63113.230469,63113.230469,17334827993 301 | 2024-04-29,63106.363281,64174.878906,61795.457031,63841.121094,63841.121094,26635912073 302 | 2024-04-30,63839.417969,64703.332031,59120.066406,60636.855469,60636.855469,37840840057 303 | 2024-05-01,60609.496094,60780.500000,56555.292969,58254.011719,58254.011719,48439780271 304 | 2024-05-02,58253.703125,59602.296875,56937.203125,59123.433594,59123.433594,32711813559 305 | 2024-05-03,59122.300781,63320.503906,58848.312500,62889.835938,62889.835938,33172023048 306 | 2024-05-04,62891.031250,64494.957031,62599.351563,63891.472656,63891.472656,20620477992 307 | 2024-05-05,63892.453125,64610.890625,62955.304688,64031.132813,64031.132813,18296164805 308 | 2024-05-06,64038.312500,65494.902344,62746.238281,63161.949219,63161.949219,28697928697 309 | 2024-05-07,63162.761719,64390.457031,62285.980469,62334.816406,62334.816406,25930730982 310 | 2024-05-08,62332.640625,62986.085938,60877.128906,61187.941406,61187.941406,26088172222 311 | 2024-05-09,61191.199219,63404.914063,60648.074219,63049.960938,63049.960938,25453338161 312 | 2024-05-10,63055.191406,63446.742188,60208.781250,60792.777344,60792.777344,27804954694 313 | 2024-05-11,60793.355469,61451.152344,60492.625000,60793.710938,60793.710938,13842272968 314 | 2024-05-12,60793.503906,61818.156250,60632.601563,61448.394531,61448.394531,13800459405 315 | 2024-05-13,61451.218750,63422.660156,60769.839844,62901.449219,62901.449219,27889181179 316 | 2024-05-14,62900.773438,63092.125000,61123.765625,61552.789063,61552.789063,28186271527 317 | 2024-05-15,61553.988281,66454.453125,61330.410156,66267.492188,66267.492188,39815167074 318 | 2024-05-16,66256.109375,66712.429688,64613.054688,65231.582031,65231.582031,31573077994 319 | 2024-05-17,65231.296875,67459.460938,65119.316406,67051.875000,67051.875000,28031279310 320 | 2024-05-18,67066.210938,67387.328125,66663.500000,66940.804688,66940.804688,16712277406 321 | 2024-05-19,66937.929688,67694.296875,65937.179688,66278.367188,66278.367188,19249094538 322 | 2024-05-20,66278.742188,71483.562500,66086.171875,71448.195313,71448.195313,43850655717 323 | 2024-05-21,71443.062500,71946.460938,69191.125000,70136.531250,70136.531250,46932005990 324 | 2024-05-22,70135.320313,70623.695313,68977.695313,69122.335938,69122.335938,32802561717 325 | 2024-05-23,69121.304688,70041.273438,66356.953125,67929.562500,67929.562500,41895680979 326 | 2024-05-24,67928.132813,69220.296875,66622.671875,68526.101563,68526.101563,29197308153 327 | 2024-05-25,68526.921875,69579.320313,68515.820313,69265.945313,69265.945313,15473071741 328 | 2024-05-26,69264.289063,69506.226563,68183.890625,68518.093750,68518.093750,15628433737 329 | 2024-05-27,68512.179688,70597.882813,68232.500000,69394.554688,69394.554688,25870990717 330 | 2024-05-28,69392.195313,69514.640625,67227.156250,68296.218750,68296.218750,32722265965 331 | 2024-05-29,68296.351563,68852.460938,67101.492188,67578.093750,67578.093750,26707072906 332 | 2024-05-30,67576.085938,69500.539063,67118.078125,68364.992188,68364.992188,29509712534 333 | 2024-05-31,68362.515625,68999.562500,66633.421875,67491.414063,67491.414063,27387283769 334 | 2024-06-01,67489.609375,67839.765625,67386.195313,67706.937500,67706.937500,11641495604 335 | 2024-06-02,67710.273438,68409.164063,67315.523438,67751.601563,67751.601563,17110588415 336 | 2024-06-03,67753.898438,70230.820313,67589.835938,68804.781250,68804.781250,32401285324 337 | 2024-06-04,68804.570313,71047.406250,68564.640625,70567.765625,70567.765625,33149696545 338 | 2024-06-05,70568.351563,71735.414063,70390.710938,71082.820313,71082.820313,32810771409 339 | 2024-06-06,71082.843750,71625.734375,70119.125000,70757.164063,70757.164063,25223152007 340 | 2024-06-07,70759.187500,71907.851563,68507.257813,69342.585938,69342.585938,36188381096 341 | 2024-06-08,69324.179688,69533.320313,69210.742188,69305.773438,69305.773438,14262185861 342 | 2024-06-09,69297.492188,69817.523438,69160.843750,69647.992188,69647.992188,13534028500 343 | 2024-06-10,69644.312500,70146.070313,69232.421875,69512.281250,69512.281250,20597699541 344 | 2024-06-11,69508.078125,69549.414063,66123.601563,67332.031250,67332.031250,37116136345 345 | 2024-06-12,67321.375000,69977.890625,66902.453125,68241.187500,68241.187500,34497940694 346 | 2024-06-13,68243.101563,68365.781250,66304.562500,66756.398438,66756.398438,28955204146 347 | 2024-06-14,66747.570313,67294.648438,65056.894531,66011.093750,66011.093750,27403884779 348 | 2024-06-15,66006.742188,66402.187500,65871.773438,66191.000000,66191.000000,14121265576 349 | 2024-06-16,66189.359375,66894.843750,66018.250000,66639.046875,66639.046875,13281140541 350 | 2024-06-17,66636.515625,67188.320313,65094.964844,66490.296875,66490.296875,30006354476 351 | 2024-06-18,66490.976563,66556.703125,64066.957031,65140.746094,65140.746094,39481285950 352 | 2024-06-19,65146.660156,65695.351563,64693.300781,64960.296875,64960.296875,21103423504 353 | 2024-06-20,64960.296875,66438.960938,64547.847656,64828.656250,64828.656250,25641109124 354 | 2024-06-21,64837.988281,65007.546875,63378.894531,64096.199219,64096.199219,26188171739 355 | 2024-06-22,64113.863281,64475.468750,63929.757813,64252.578125,64252.578125,9858198793 356 | 2024-06-23,64248.964844,64491.703125,63180.796875,63180.796875,63180.796875,11170471802 357 | 2024-06-24,63173.351563,63292.527344,58601.699219,60277.414063,60277.414063,43152133651 358 | 2024-06-25,60266.281250,62258.261719,60239.750000,61804.640625,61804.640625,29201215431 359 | 2024-06-26,61789.675781,62434.136719,60695.187500,60811.277344,60811.277344,22506003064 360 | 2024-06-27,60811.226563,62293.863281,60585.332031,61604.800781,61604.800781,21231745045 361 | 2024-06-28,61612.804688,62126.097656,59985.402344,60320.136719,60320.136719,24952866877 362 | 2024-06-29,60319.875000,61097.621094,60300.964844,60887.378906,60887.378906,12652903396 363 | 2024-06-30,60888.445313,62892.828125,60632.949219,62678.292969,62678.292969,17333226409 364 | 2024-07-01,62673.605469,63777.226563,62495.511719,62851.980469,62851.980469,25468379421 365 | 2024-07-02,62844.410156,63203.359375,61752.746094,62029.015625,62029.015625,20151616992 366 | 2024-07-03,62034.332031,62187.703125,59419.386719,60173.921875,60173.921875,29756701685 367 | 2024-07-04,60147.136719,60399.675781,56777.804688,56977.703125,56977.703125,41149609230 368 | 2024-07-05,57022.808594,57400.679688,53717.375000,56350.566406,56350.566406,57080098816 -------------------------------------------------------------------------------- /Examples/Data/^NSEMDCP50.csv: -------------------------------------------------------------------------------- 1 | Date,Open,High,Low,Close,Adj Close,Volume 2 | 2023-03-29,8225.200195,8390.450195,8225.049805,8373.500000,8373.500000,278300 3 | 2023-03-31,8413.299805,8490.900391,8410.750000,8466.799805,8466.799805,267400 4 | 2023-04-03,8513.299805,8515.099609,8465.400391,8497.750000,8497.750000,264600 5 | 2023-04-05,8500.700195,8501.450195,8451.799805,8495.549805,8495.549805,270300 6 | 2023-04-06,8490.349609,8559.150391,8466.700195,8550.650391,8550.650391,243400 7 | 2023-04-10,8573.849609,8591.500000,8537.450195,8581.950195,8581.950195,182900 8 | 2023-04-11,8606.049805,8634.799805,8570.099609,8607.849609,8607.849609,197200 9 | 2023-04-12,8621.049805,8661.250000,8615.849609,8646.400391,8646.400391,185400 10 | 2023-04-13,8671.750000,8699.049805,8626.450195,8677.349609,8677.349609,226200 11 | 2023-04-17,8647.950195,8707.849609,8610.400391,8699.200195,8699.200195,208600 12 | 2023-04-18,8723.150391,8781.750000,8705.799805,8771.700195,8771.700195,233200 13 | 2023-04-19,8789.549805,8805.250000,8741.500000,8753.450195,8753.450195,187900 14 | 2023-04-20,8773.650391,8792.400391,8752.450195,8767.099609,8767.099609,181400 15 | 2023-04-21,8780.700195,8782.150391,8700.150391,8731.299805,8731.299805,470900 16 | 2023-04-24,8743.099609,8794.599609,8721.950195,8790.299805,8790.299805,239700 17 | 2023-04-25,8806.299805,8846.400391,8791.299805,8815.099609,8815.099609,220400 18 | 2023-04-26,8800.500000,8839.450195,8770.849609,8834.200195,8834.200195,323300 19 | 2023-04-27,8835.900391,8874.900391,8834.650391,8865.150391,8865.150391,479900 20 | 2023-04-28,8878.849609,8970.150391,8861.400391,8962.849609,8962.849609,393800 21 | 2023-05-02,9010.750000,9080.700195,8996.950195,9062.200195,9062.200195,395400 22 | 2023-05-03,9046.650391,9099.849609,9032.150391,9065.849609,9065.849609,276300 23 | 2023-05-04,9080.650391,9132.150391,9071.400391,9122.900391,9122.900391,293300 24 | 2023-05-05,9130.450195,9155.299805,9027.250000,9036.799805,9036.799805,305300 25 | 2023-05-08,9069.400391,9156.250000,9062.200195,9149.150391,9149.150391,256200 26 | 2023-05-09,9174.250000,9222.150391,9132.599609,9152.799805,9152.799805,251800 27 | 2023-05-10,9184.750000,9184.750000,9101.250000,9158.000000,9158.000000,320700 28 | 2023-05-11,9191.849609,9221.799805,9169.099609,9194.650391,9194.650391,383000 29 | 2023-05-12,9186.400391,9194.599609,9125.250000,9149.599609,9149.599609,270400 30 | 2023-05-15,9162.000000,9255.549805,9133.950195,9239.250000,9239.250000,259600 31 | 2023-05-16,9279.250000,9331.599609,9261.200195,9269.700195,9269.700195,404500 32 | 2023-05-17,9271.150391,9274.200195,9171.700195,9244.650391,9244.650391,323000 33 | 2023-05-18,9280.299805,9287.200195,9166.000000,9176.549805,9176.549805,221700 34 | 2023-05-19,9199.150391,9200.299805,9095.049805,9176.099609,9176.099609,229900 35 | 2023-05-22,9162.650391,9241.250000,9140.900391,9235.900391,9235.900391,205500 36 | 2023-05-23,9255.750000,9304.500000,9247.900391,9286.150391,9286.150391,184300 37 | 2023-05-24,9290.049805,9319.049805,9248.049805,9267.599609,9267.599609,250600 38 | 2023-05-25,9264.799805,9342.000000,9254.950195,9332.000000,9332.000000,349300 39 | 2023-05-26,9342.150391,9435.299805,9340.450195,9428.599609,9428.599609,297300 40 | 2023-05-29,9468.599609,9478.700195,9419.900391,9470.349609,9470.349609,275000 41 | 2023-05-30,9480.799805,9514.950195,9459.599609,9506.400391,9506.400391,225300 42 | 2023-05-31,9496.849609,9547.400391,9485.650391,9539.900391,9539.900391,321400 43 | 2023-06-01,9547.299805,9603.400391,9541.099609,9559.500000,9559.500000,219300 44 | 2023-06-02,9590.250000,9637.799805,9587.000000,9629.650391,9629.650391,204700 45 | 2023-06-05,9669.200195,9684.900391,9629.500000,9638.150391,9638.150391,209600 46 | 2023-06-06,9643.299805,9644.599609,9571.650391,9628.150391,9628.150391,172000 47 | 2023-06-07,9658.549805,9710.250000,9644.150391,9704.750000,9704.750000,356600 48 | 2023-06-08,9723.950195,9725.150391,9599.400391,9609.599609,9609.599609,313200 49 | 2023-06-09,9637.599609,9650.049805,9590.250000,9598.849609,9598.849609,229500 50 | 2023-06-12,9628.450195,9685.799805,9592.549805,9675.650391,9675.650391,221400 51 | 2023-06-13,9696.150391,9801.299805,9694.349609,9795.500000,9795.500000,398100 52 | 2023-06-14,9825.799805,9833.000000,9793.400391,9819.650391,9819.650391,543800 53 | 2023-06-15,9835.250000,9864.299805,9796.049805,9803.349609,9803.349609,347400 54 | 2023-06-16,9831.750000,9906.349609,9817.349609,9884.200195,9884.200195,386500 55 | 2023-06-19,9926.799805,9950.250000,9880.000000,9891.549805,9891.549805,315400 56 | 2023-06-20,9900.000000,9968.200195,9871.549805,9957.549805,9957.549805,306200 57 | 2023-06-21,10033.799805,10081.299805,10003.900391,10032.400391,10032.400391,506600 58 | 2023-06-22,10047.500000,10047.700195,9872.750000,9911.450195,9911.450195,460100 59 | 2023-06-23,9901.000000,9905.400391,9780.299805,9807.250000,9807.250000,329800 60 | 2023-06-26,9809.400391,9894.000000,9762.650391,9883.799805,9883.799805,275500 61 | 2023-06-27,9910.799805,9957.549805,9900.799805,9945.099609,9945.099609,318700 62 | 2023-06-28,9994.000000,10062.250000,9966.000000,10040.049805,10040.049805,434300 63 | 2023-06-30,10072.849609,10133.250000,10060.400391,10126.849609,10126.849609,316900 64 | 2023-07-03,10189.750000,10199.200195,10126.000000,10142.950195,10142.950195,389700 65 | 2023-07-04,10182.799805,10184.500000,10095.799805,10119.599609,10119.599609,585800 66 | 2023-07-05,10137.049805,10205.049805,10113.450195,10194.150391,10194.150391,434800 67 | 2023-07-06,10200.799805,10271.900391,10182.400391,10267.400391,10267.400391,321700 68 | 2023-07-07,10255.750000,10266.500000,10117.900391,10169.950195,10169.950195,340800 69 | 2023-07-10,10203.599609,10203.950195,10099.099609,10141.849609,10141.849609,356200 70 | 2023-07-11,10173.200195,10275.150391,10169.099609,10249.250000,10249.250000,291100 71 | 2023-07-12,10282.250000,10306.049805,10244.900391,10286.000000,10286.000000,301100 72 | 2023-07-13,10321.599609,10327.700195,10161.450195,10193.950195,10193.950195,393700 73 | 2023-07-14,10241.849609,10356.849609,10218.750000,10350.950195,10350.950195,275300 74 | 2023-07-17,10382.750000,10423.049805,10361.549805,10373.750000,10373.750000,471100 75 | 2023-07-18,10411.849609,10416.349609,10314.299805,10368.599609,10368.599609,503100 76 | 2023-07-19,10396.500000,10460.000000,10384.549805,10454.900391,10454.900391,480500 77 | 2023-07-20,10481.299805,10483.299805,10447.450195,10476.250000,10476.250000,340700 78 | 2023-07-21,10428.799805,10479.299805,10411.950195,10446.549805,10446.549805,460000 79 | 2023-07-24,10461.049805,10522.299805,10437.700195,10461.200195,10461.200195,498300 80 | 2023-07-25,10515.099609,10515.799805,10428.450195,10503.450195,10503.450195,335500 81 | 2023-07-26,10530.849609,10585.799805,10519.450195,10562.150391,10562.150391,780200 82 | 2023-07-27,10615.349609,10656.450195,10583.099609,10624.500000,10624.500000,719700 83 | 2023-07-28,10644.799805,10694.750000,10623.750000,10686.299805,10686.299805,397700 84 | 2023-07-31,10704.200195,10831.500000,10689.450195,10822.500000,10822.500000,506500 85 | 2023-08-01,10854.500000,10864.150391,10772.400391,10793.950195,10793.950195,277000 86 | 2023-08-02,10781.650391,10784.900391,10548.849609,10643.200195,10643.200195,434500 87 | 2023-08-03,10628.200195,10696.549805,10581.900391,10657.549805,10657.549805,322300 88 | 2023-08-04,10705.799805,10780.349609,10666.000000,10741.900391,10741.900391,388700 89 | 2023-08-07,10761.900391,10795.349609,10739.549805,10787.799805,10787.799805,366500 90 | 2023-08-08,10818.849609,10840.650391,10708.799805,10803.400391,10803.400391,505500 91 | 2023-08-09,10834.549805,10865.950195,10744.500000,10855.900391,10855.900391,303700 92 | 2023-08-10,10875.000000,10900.750000,10803.150391,10868.150391,10868.150391,469400 93 | 2023-08-11,10909.549805,10913.400391,10807.200195,10821.849609,10821.849609,411100 94 | 2023-08-14,10805.900391,10849.000000,10674.150391,10827.450195,10827.450195,329500 95 | 2023-08-16,10804.950195,10851.849609,10743.200195,10837.549805,10837.549805,0 96 | 2023-08-17,10858.250000,10903.549805,10839.299805,10872.750000,10872.750000,422200 97 | 2023-08-18,10878.900391,10896.099609,10794.150391,10824.299805,10824.299805,274800 98 | 2023-08-21,10847.299805,10922.700195,10818.299805,10904.000000,10904.000000,230700 99 | 2023-08-22,10934.099609,11015.000000,10918.900391,11009.200195,11009.200195,412700 100 | 2023-08-23,11038.400391,11106.450195,11026.900391,11081.700195,11081.700195,306300 101 | 2023-08-24,11142.299805,11185.650391,11118.650391,11131.049805,11131.049805,327300 102 | 2023-08-25,11098.900391,11132.349609,11003.250000,11021.599609,11021.599609,656600 103 | 2023-08-28,11052.049805,11093.000000,11031.650391,11073.049805,11073.049805,711300 104 | 2023-08-29,11105.849609,11129.099609,11085.950195,11109.349609,11109.349609,552900 105 | 2023-08-30,11159.900391,11235.049805,11150.200195,11205.349609,11205.349609,439100 106 | 2023-08-31,11249.500000,11261.400391,11140.200195,11182.650391,11182.650391,1366100 107 | 2023-09-01,11187.349609,11274.750000,11154.250000,11260.599609,11260.599609,1159000 108 | 2023-09-04,11310.349609,11349.650391,11260.599609,11327.049805,11327.049805,0 109 | 2023-09-05,11361.599609,11448.700195,11327.049805,11437.650391,11437.650391,467000 110 | 2023-09-06,11467.150391,11489.099609,11418.849609,11469.650391,11469.650391,663700 111 | 2023-09-07,11487.599609,11530.700195,11458.150391,11520.799805,11520.799805,513500 112 | 2023-09-08,11559.250000,11656.849609,11520.799805,11647.150391,11647.150391,678100 113 | 2023-09-11,11714.450195,11736.150391,11685.650391,11725.650391,11725.650391,939100 114 | 2023-09-12,11789.950195,11789.950195,11371.500000,11386.500000,11386.500000,862100 115 | 2023-09-13,11381.150391,11463.099609,11271.349609,11454.950195,11454.950195,727400 116 | 2023-09-14,11508.049805,11589.200195,11497.049805,11582.799805,11582.799805,435700 117 | 2023-09-15,11638.349609,11654.099609,11585.950195,11635.900391,11635.900391,834700 118 | 2023-09-18,11652.500000,11654.750000,11579.500000,11595.500000,11595.500000,817700 119 | 2023-09-20,11568.549805,11648.549805,11509.150391,11594.700195,11594.700195,468300 120 | 2023-09-21,11577.299805,11634.099609,11473.150391,11502.500000,11502.500000,452000 121 | 2023-09-22,11513.900391,11570.250000,11427.849609,11494.900391,11494.900391,558200 122 | 2023-09-25,11513.299805,11618.500000,11414.099609,11600.650391,11600.650391,471100 123 | 2023-09-26,11602.150391,11639.450195,11543.849609,11554.700195,11554.700195,742600 124 | 2023-09-27,11574.950195,11672.400391,11544.400391,11655.000000,11655.000000,674500 125 | 2023-09-28,11674.799805,11680.650391,11432.500000,11453.650391,11453.650391,679400 -------------------------------------------------------------------------------- /Examples/StreamingSupportResistance/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | project(StreamingSupportResistance) 3 | 4 | add_executable(StreamingSupportResistance 5 | main.cpp 6 | ) 7 | target_link_libraries(StreamingSupportResistance PRIVATE backtest) 8 | target_include_directories(StreamingSupportResistance PRIVATE 9 | 10 | ${CMAKE_SOURCE_DIR}/include 11 | ${CMAKE_SOURCE_DIR}/Examples/SupportResistance 12 | ) -------------------------------------------------------------------------------- /Examples/StreamingSupportResistance/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "backtest/Data.h" 6 | #include "SupportResistance.h" 7 | 8 | 9 | inline std::filesystem::path get_directory() { 10 | std::filesystem::path dir = __FILE__; 11 | dir = dir.parent_path().parent_path(); 12 | return dir; 13 | } 14 | 15 | int main(int argc, char** argv) { 16 | std::filesystem::path dir = get_directory(); 17 | const std::string csvname = "Data/^NSEMDCP50.csv"; 18 | std::filesystem::path filePath = dir / csvname; 19 | const std::string filename = (argc > 1 ? argv[1] : filePath); 20 | const std::size_t batchSize = (argc > 2 ? std::stoul(argv[2]) : 1024); 21 | 22 | data::CSVDataFeed feed(filename, batchSize); 23 | SupportResistance strat(feed); 24 | strat.run(); 25 | return 0; 26 | } -------------------------------------------------------------------------------- /Examples/SupportResistance/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(SupportResistance main.cpp) 2 | target_link_libraries(SupportResistance PRIVATE backtest) 3 | target_include_directories(SupportResistance PRIVATE 4 | ${CMAKE_SOURCE_DIR}/include 5 | ) 6 | -------------------------------------------------------------------------------- /Examples/SupportResistance/SupportResistance.h: -------------------------------------------------------------------------------- 1 | #ifndef SUPPORTRESISTANCE_H 2 | #define SUPPORTRESISTANCE_H 3 | 4 | #include "backtest/Strategy.h" 5 | #include "backtest/Data.h" 6 | #include 7 | 8 | class SupportResistance : public backtest::Strategy { 9 | public: 10 | explicit SupportResistance(data::CSVDataFeed& feed) noexcept 11 | : Strategy(feed) {} 12 | 13 | void onStart() noexcept { 14 | setCash(100000.0); 15 | setCommission(0.001); 16 | setSlippage(0.0); 17 | isLong_ = false; 18 | isShort_ = false; 19 | longQty_ = 0; 20 | shortQty_ = 0; 21 | balance_ = initialCash_; 22 | totalCommission_ = 0.0; 23 | totalSlippage_ = 0.0; 24 | std::cout << "========================= Starting Backtest =========================\n"; 25 | } 26 | 27 | void onBar(const data::OHLCBatch& batch, std::size_t idx) noexcept { 28 | if (idx == 0) return; 29 | double prevPivot = (batch.high[idx-1] + batch.low[idx-1] + batch.close[idx-1]) / 3.0; 30 | double support = 2.0 * prevPivot - batch.high[idx-1]; 31 | double resistance= 2.0 * prevPivot - batch.low[idx-1]; 32 | double price = batch.open[idx]; 33 | const std::string& date = batch.date[idx]; 34 | int quantity = 1; 35 | quantity = static_cast((balance_ * 0.85) / price); 36 | if (price > prevPivot && !isLong_) { 37 | buy(date, price, quantity); 38 | } else if (isLong_ && price >= resistance) { 39 | close(date, price, longQty_); 40 | } else if (price < prevPivot && !isShort_) { 41 | sell(date, price, quantity); 42 | } else if (isShort_ && price <= support) { 43 | close(date, price, shortQty_); 44 | } 45 | } 46 | 47 | void onEnd() noexcept { 48 | std::cout << "========================= Ending Backtest =========================\n"; 49 | stats(); 50 | } 51 | }; 52 | 53 | #endif // SUPPORTRESISTANCE_H 54 | -------------------------------------------------------------------------------- /Examples/SupportResistance/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "SupportResistance.h" 6 | #include "backtest/Data.h" 7 | 8 | inline std::filesystem::path get_directory() { 9 | std::filesystem::path dir = __FILE__; 10 | dir = dir.parent_path().parent_path(); 11 | return dir; 12 | } 13 | 14 | 15 | int main(){ 16 | std::filesystem::path dir = get_directory(); 17 | const std::string filename = "Data/^NSEMDCP50.csv"; 18 | std::filesystem::path filePath = dir / filename; 19 | std::cout << "File Path: " << filePath << std::endl; 20 | const std::size_t batchSize = 1024; 21 | data::CSVDataFeed feed(filePath, batchSize); 22 | 23 | SupportResistance strat(feed); 24 | strat.run(); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /Examples/SupportResistance/readme.txt: -------------------------------------------------------------------------------- 1 | To compile : g++ main.cpp SupportResistance.cpp ../../BacktestEngine.cpp ../../Data.cpp ../../Indicator.cpp ../../Strategy.cpp -o out 2 | on sucessful compilation: .\out.exe 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BackTest-Cpp 2 | 3 | A header-only, high-throughput backtesting engine in C++17. Supports CSV data feeds, built-in technical indicators (SMA, EMA, RSI), and simple strategy templates. Includes example projects demonstrating support/resistance breakout strategies in both batch and streaming modes. 4 | 5 | ## Features 6 | - **Core library** (header-only, under `include/backtest`): 7 | - `Engine`: CRTP-driven backtest engine with cash, commission, slippage, and position management. 8 | - `Strategy`: Base class for user-defined strategies. 9 | - `data::CSVDataFeed` & `data::OHLCBatch`: Batch reader and container for OHLC CSV data. 10 | - `indicators`: Header-only SMA, EMA, and RSI functions. 11 | - **Examples**: 12 | - **SupportResistance**: Pivot-based support/resistance strategy (batch mode). 13 | - **StreamingSupportResistance**: Streaming example using the same strategy on live data feed. 14 | 15 | ## Requirements 16 | - C++17 compiler (GCC, Clang, MSVC) 17 | - CMake ≥ 3.10 18 | - Standard C++ library 19 | 20 | ## Building 21 | ```bash 22 | # From project root 23 | mkdir build && cd build 24 | cmake .. 25 | make -j4 26 | ``` 27 | 28 | Executables are generated under: 29 | - `build/Examples/SupportResistance/SupportResistance` 30 | - `build/Examples/StreamingSupportResistance/StreamingSupportResistance` 31 | 32 | ## Usage 33 | 34 | ### SupportResistance (batch mode) 35 | ```bash 36 | build/Examples/SupportResistance/SupportResistance 37 | ``` 38 | 39 | ### StreamingSupportResistance (streaming mode) 40 | ```bash 41 | # Provide CSV path and optional batch size 42 | build/Examples/StreamingSupportResistance/StreamingSupportResistance \ 43 | ../Examples/Data/^NSEMDCP50.csv [batch_size] 44 | ``` 45 | 46 | ## Core API Overview 47 | - **Engine** (`backtest::Engine`): 48 | - `setCash(double)`, `setCommission(double)`, `setSlippage(double)` 49 | - `run()`: invokes `onStart()`, `onBar(batch, idx)`, `onEnd()` on the derived strategy. 50 | - `buy()`, `sell()`, `close()`: position operations with commission tracking. 51 | - **Data Feed**: 52 | - `data::CSVDataFeed(filePath, batchSize)`: loads CSV in batches. 53 | - `data::OHLCBatch`: columnar storage for date, open, high, low, close, adjClose, volume. 54 | - **Indicators** (`backtest::indicators`): 55 | - `SMA(data, period)`, `EMA(data, period)`, `RSI(data, period)` 56 | 57 | ## Directory Structure 58 | ``` 59 | . # Project root 60 | ├── CMakeLists.txt # Top-level CMake configuration 61 | ├── include/ # Header-only backtest core 62 | │ └── backtest/ 63 | ├── Examples/ # Example strategies and data 64 | │ ├── SupportResistance/ 65 | │ └── StreamingSupportResistance/ 66 | └── build/ # Build output (CMake / Makefiles) 67 | ``` 68 | 69 | ## Contributing 70 | Contributions are welcome! Please open issues or pull requests for enhancements or bug fixes. -------------------------------------------------------------------------------- /include/backtest/Data.h: -------------------------------------------------------------------------------- 1 | #ifndef BACKTEST_DATA_H 2 | #define BACKTEST_DATA_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "backtest/FileIterator.h" 8 | 9 | namespace data { 10 | 11 | 12 | class DataFeed { 13 | public: 14 | virtual ~DataFeed() = default; 15 | virtual bool nextBatch() = 0; 16 | virtual const OHLCBatch& currentBatch() const = 0; 17 | }; 18 | 19 | class CSVDataFeed : public DataFeed { 20 | public: 21 | CSVDataFeed(const std::string& filePath, std::size_t batchSize) noexcept 22 | : fileIterator_(filePath, batchSize) {} 23 | bool nextBatch() override { 24 | return fileIterator_.nextBatch(); 25 | } 26 | const OHLCBatch& currentBatch() const override { 27 | return fileIterator_.batch(); 28 | } 29 | private: 30 | FileIterator fileIterator_; 31 | }; 32 | 33 | } 34 | #endif // BACKTEST_DATA_H -------------------------------------------------------------------------------- /include/backtest/Engine.h: -------------------------------------------------------------------------------- 1 | // Engine.h - high-throughput, template-driven backtest engine 2 | #ifndef BACKTEST_ENGINE_H 3 | #define BACKTEST_ENGINE_H 4 | 5 | #include "backtest/Data.h" 6 | #include 7 | #include 8 | #include 9 | 10 | namespace backtest { 11 | 12 | template 13 | class Engine { 14 | public: 15 | using Batch = data::OHLCBatch; 16 | 17 | explicit Engine(Feed& feed) noexcept 18 | : feed_(feed), balance_(0.0), initialCash_(0.0), commissionRate_(0.0), totalCommission_(0.0), slippage_(0.0) {} 19 | 20 | void setCash(double cash) noexcept { balance_ = initialCash_ = cash; } 21 | void setCommission(double rate) noexcept { commissionRate_ = rate; totalCommission_ = 0.0; } 22 | void setSlippage(double slip) noexcept { slippage_ = slip; } 23 | 24 | void run() { 25 | static_cast(this)->onStart(); 26 | while (feed_.nextBatch()) { 27 | const Batch& batch = feed_.currentBatch(); 28 | for (std::size_t i = 0, n = batch.size(); i < n; ++i) { 29 | static_cast(this)->onBar(batch, i); 30 | } 31 | } 32 | static_cast(this)->onEnd(); 33 | } 34 | 35 | void stats() const noexcept { 36 | double pnl = balance_ - initialCash_; 37 | std::cout << "Final Balance: " << balance_ << " (P&L " << pnl << ")\n"; 38 | std::cout << "Return: " << (pnl / initialCash_) * 100 << "%\n"; 39 | std::cout << "Total Commission: " << totalCommission_ << "\n"; 40 | } 41 | 42 | protected: 43 | void onStart() {} 44 | void onEnd() {} 45 | void onBar(const Batch& batch, std::size_t idx) {} 46 | 47 | void buy(const std::string& date, double price, std::size_t qty) noexcept { 48 | double fee = commissionRate_ * price * qty; 49 | totalCommission_ += fee; 50 | if (!isLong_ && !isShort_) { 51 | isLong_ = true; longQty_ = qty; 52 | balance_ -= price * qty + fee; 53 | } else if (isLong_) { 54 | longQty_ += qty; 55 | balance_ -= price * qty + fee; 56 | } else if (isShort_) { 57 | if (qty > shortQty_) { 58 | std::size_t diff = qty - shortQty_; 59 | isShort_ = false; isLong_ = true; longQty_ = diff; shortQty_ = 0; 60 | balance_ -= diff * price + fee; 61 | } else { 62 | shortQty_ -= qty; 63 | balance_ -= -(price * qty) + fee; 64 | } 65 | } 66 | std::cout << date << "\tBUY\t" << "- " << price << " \t-\t " << qty << "\n"; 67 | } 68 | 69 | void sell(const std::string& date, double price, std::size_t qty) noexcept { 70 | double fee = commissionRate_ * price * qty; 71 | totalCommission_ += fee; 72 | if (!isLong_ && !isShort_) { 73 | isShort_ = true; shortQty_ = qty; 74 | balance_ += price * qty - fee; 75 | } else if (isShort_) { 76 | shortQty_ += qty; 77 | balance_ += price * qty - fee; 78 | } else if (isLong_) { 79 | if (qty > longQty_) { 80 | std::size_t diff = qty - longQty_; 81 | isLong_ = false; isShort_ = true; shortQty_ = diff; longQty_ = 0; 82 | balance_ += diff * price - fee; 83 | } else { 84 | longQty_ -= qty; 85 | balance_ += price * qty - fee; 86 | } 87 | } 88 | std::cout << date << "\tSELL\t" << "- " << price << " \t-\t " << qty << "\n"; 89 | } 90 | 91 | void close(const std::string& date, double price, std::size_t qty) noexcept { 92 | double fee = commissionRate_ * price * qty; 93 | totalCommission_ += fee; 94 | if (isLong_) { 95 | balance_ += price * qty - fee; 96 | longQty_ -= qty; 97 | if (longQty_ == 0) isLong_ = false; 98 | } else if (isShort_) { 99 | balance_ -= price * qty + fee; 100 | shortQty_ -= qty; 101 | if (shortQty_ == 0) isShort_ = false; 102 | } 103 | std::cout << date << "\tCLOSE\t" << "- " << price << " \t-\t " << qty << "\n"; 104 | } 105 | 106 | Feed& feed_; 107 | bool isLong_ = false; 108 | bool isShort_ = false; 109 | std::size_t longQty_ = 0; 110 | std::size_t shortQty_ = 0; 111 | double balance_; 112 | double initialCash_; 113 | double commissionRate_; 114 | double totalCommission_; 115 | double slippage_; 116 | double totalSlippage_; 117 | }; 118 | 119 | } 120 | #endif // BACKTEST_ENGINE_H -------------------------------------------------------------------------------- /include/backtest/FileIterator.h: -------------------------------------------------------------------------------- 1 | // FileIterator: reads CSV in batches, storing columnar OHLCBatch 2 | #ifndef BACKTEST_FILEITERATOR_H 3 | #define BACKTEST_FILEITERATOR_H 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace data { 13 | 14 | struct OHLCBatch { 15 | std::vector date; 16 | std::vector open; 17 | std::vector high; 18 | std::vector low; 19 | std::vector close; 20 | std::vector adjClose; 21 | std::vector volume; 22 | void clear() { 23 | date.clear(); open.clear(); high.clear(); low.clear(); 24 | close.clear(); adjClose.clear(); volume.clear(); 25 | } 26 | std::size_t size() const { return date.size(); } 27 | }; 28 | 29 | class FileIterator { 30 | public: 31 | FileIterator(const std::string& filename, std::size_t batchSize = 1024) 32 | : file_(filename), batchSize_(batchSize) { 33 | if (!file_.is_open()) throw std::runtime_error("Cannot open file " + filename); 34 | std::string header; 35 | if (!std::getline(file_, header)) throw std::runtime_error("Empty file " + filename); 36 | batch_.date.reserve(batchSize_); 37 | batch_.open.reserve(batchSize_); 38 | batch_.high.reserve(batchSize_); 39 | batch_.low.reserve(batchSize_); 40 | batch_.close.reserve(batchSize_); 41 | batch_.adjClose.reserve(batchSize_); 42 | batch_.volume.reserve(batchSize_); 43 | } 44 | 45 | bool nextBatch() { 46 | batch_.clear(); 47 | std::string line; 48 | while (batch_.date.size() < batchSize_ && std::getline(file_, line)) { 49 | if (line.empty()) continue; 50 | std::stringstream ss(line); 51 | std::string token; 52 | std::getline(ss, token, ','); batch_.date.push_back(token); 53 | std::getline(ss, token, ','); batch_.open.push_back(std::stod(token)); 54 | std::getline(ss, token, ','); batch_.high.push_back(std::stod(token)); 55 | std::getline(ss, token, ','); batch_.low.push_back(std::stod(token)); 56 | std::getline(ss, token, ','); batch_.close.push_back(std::stod(token)); 57 | std::getline(ss, token, ','); batch_.adjClose.push_back(std::stod(token)); 58 | std::getline(ss, token, ','); batch_.volume.push_back(std::stod(token)); 59 | } 60 | return !batch_.date.empty(); 61 | } 62 | 63 | const OHLCBatch& batch() const noexcept { return batch_; } 64 | 65 | void reset() { 66 | file_.clear(); file_.seekg(0); 67 | std::string header; std::getline(file_, header); 68 | } 69 | 70 | private: 71 | std::ifstream file_; 72 | std::size_t batchSize_; 73 | OHLCBatch batch_; 74 | }; 75 | 76 | } 77 | #endif // BACKTEST_FILEITERATOR_H -------------------------------------------------------------------------------- /include/backtest/Indicators.h: -------------------------------------------------------------------------------- 1 | // Indicators.h: header-only technical indicators 2 | #ifndef BACKTEST_INDICATORS_H 3 | #define BACKTEST_INDICATORS_H 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace backtest { 11 | namespace indicators { 12 | 13 | // Simple Moving Average 14 | inline std::vector SMA(const std::vector& data, std::size_t period) { 15 | std::vector sma(data.size(), 0.0); 16 | if (data.size() < period || period == 0) return sma; 17 | double sum = std::accumulate(data.begin(), data.begin() + period, 0.0); 18 | sma[period - 1] = sum / period; 19 | for (std::size_t i = period; i < data.size(); ++i) { 20 | sum += data[i] - data[i - period]; 21 | sma[i] = sum / period; 22 | } 23 | return sma; 24 | } 25 | 26 | // Exponential Moving Average 27 | inline std::vector EMA(const std::vector& data, std::size_t period) { 28 | std::vector ema(data.size(), 0.0); 29 | if (data.size() < period || period == 0) return ema; 30 | // Start EMA with SMA for first period 31 | double sum = std::accumulate(data.begin(), data.begin() + period, 0.0); 32 | double prev = sum / period; 33 | ema[period - 1] = prev; 34 | double alpha = 2.0 / (period + 1); 35 | for (std::size_t i = period; i < data.size(); ++i) { 36 | prev = alpha * (data[i] - prev) + prev; 37 | ema[i] = prev; 38 | } 39 | return ema; 40 | } 41 | 42 | // Relative Strength Index 43 | inline std::vector RSI(const std::vector& data, std::size_t period) { 44 | std::vector rsi(data.size(), 0.0); 45 | if (data.size() <= period || period == 0) return rsi; 46 | double gain = 0.0, loss = 0.0; 47 | for (std::size_t i = 1; i <= period; ++i) { 48 | double delta = data[i] - data[i - 1]; 49 | if (delta >= 0) gain += delta; 50 | else loss += -delta; 51 | } 52 | gain /= period; 53 | loss /= period; 54 | if (loss == 0) rsi[period] = 100.0; 55 | else { 56 | double rs = gain / loss; 57 | rsi[period] = 100.0 - 100.0 / (1 + rs); 58 | } 59 | for (std::size_t i = period + 1; i < data.size(); ++i) { 60 | double delta = data[i] - data[i - 1]; 61 | double g = (delta > 0) ? delta : 0.0; 62 | double l = (delta < 0) ? -delta : 0.0; 63 | gain = (gain * (period - 1) + g) / period; 64 | loss = (loss * (period - 1) + l) / period; 65 | if (loss == 0) rsi[i] = 100.0; 66 | else { 67 | double rs = gain / loss; 68 | rsi[i] = 100.0 - 100.0 / (1 + rs); 69 | } 70 | } 71 | return rsi; 72 | } 73 | 74 | } // namespace indicators 75 | } // namespace backtest 76 | #endif // BACKTEST_INDICATORS_H -------------------------------------------------------------------------------- /include/backtest/Strategy.h: -------------------------------------------------------------------------------- 1 | #ifndef BACKTEST_STRATEGY_H 2 | #define BACKTEST_STRATEGY_H 3 | 4 | #include "backtest/Engine.h" 5 | 6 | namespace backtest { 7 | 8 | template 9 | class Strategy : public Engine { 10 | public: 11 | using Engine::Engine; 12 | }; 13 | 14 | } // namespace backtest 15 | #endif // BACKTEST_STRATEGY_H --------------------------------------------------------------------------------