├── .gitattributes
├── .gitignore
├── .gitmodules
├── AgisCorePy
├── AgisCorePy.vcxproj
├── AgisCorePy.vcxproj.filters
├── dllmain.cpp
├── framework.h
├── module.cpp
├── pch.cpp
└── pch.h
├── LICENSE
├── MainWindow.qrc
├── MainWindow.ui
├── Nexus.sln
├── Nexus.vcxproj
├── Nexus.vcxproj.filters
├── README.md
├── example
├── holidays
│ └── us_trading_holidays.csv
└── io
│ └── futures_hdf5.ipynb
├── external
└── QCustomPlot
│ ├── qcustomplot.cpp
│ └── qcustomplot.h
├── github
├── Nexus.png
├── codegen.png
├── perf.png
└── pybind11.png
├── images
├── ads_tile_blue_light.svg
├── ads_tile_green.svg
├── ads_tile_orange.svg
├── branch-closed.png
├── branch-end.png
├── branch-more.png
├── broker.png
├── color_lens.svg
├── console.png
├── create_floating_editor.svg
├── create_floating_table.svg
├── crop_original.svg
├── custom-menu-button.svg
├── date_range.svg
├── docked_editor.svg
├── edit.svg
├── exchange.png
├── find_in_page.svg
├── flow.png
├── folder.svg
├── folder_open.svg
├── font_download.svg
├── fullscreen.svg
├── grid_on.svg
├── help_outline.svg
├── json.png
├── link.png
├── material_icons_license.txt
├── note_add.svg
├── panorama.svg
├── perm_media.svg
├── photo.svg
├── picture_in_picture.svg
├── piechart.png
├── plus.svg
├── restore.svg
├── run.png
├── save.svg
├── settings.png
├── stock.png
├── tab.svg
├── vline.png
├── win
│ ├── checkbox-checked.png
│ ├── checkbox.png
│ ├── editcopy.png
│ ├── editcut.png
│ ├── editpaste.png
│ ├── editredo.png
│ ├── exportpdf.png
│ ├── filenew.png
│ ├── fileopen.png
│ ├── fileprint.png
│ ├── filesave.png
│ ├── format-indent-less.png
│ ├── format-indent-more.png
│ ├── textbold.png
│ ├── textcenter.png
│ ├── textitalic.png
│ ├── textjustify.png
│ ├── textleft.png
│ ├── textright.png
│ ├── textunder.png
│ ├── textundercolor.png
│ ├── zoomin.png
│ └── zoomout.png
├── zoom_in.svg
├── zoom_out.svg
└── zoom_out_map.svg
├── include
├── MainWindow.h
├── NexusAsset.h
├── NexusBroker.h
├── NexusDockManager.h
├── NexusEnv.h
├── NexusErrors.h
├── NexusHelpers.h
├── NexusNode.h
├── NexusNodeModel.h
├── NexusNodeWidget.h
├── NexusPch.h
├── NexusPlot.h
├── NexusPopups.h
├── NexusPortfolio.h
├── NexusTree.h
├── NexusWidgetFactory.h
├── QScintillaEditor.h
├── QTerminal.h
└── QTerminalImpl.h
├── src
├── MainWindow.cpp
├── NexusAsset.cpp
├── NexusBroker.cpp
├── NexusDockManager.cpp
├── NexusEnv.cpp
├── NexusNode.cpp
├── NexusNodeModel.cpp
├── NexusNodeWidget.cpp
├── NexusPlot.cpp
├── NexusPopups.cpp
├── NexusPortfolio.cpp
├── NexusTree.cpp
├── NexusWidgetFactory.cpp
├── QScintillaEditor.cpp
├── QTerminal.cpp
├── QTerminalImpl.cpp
└── main.cpp
├── style
├── NexusTree.qss
└── vs_light.qss
└── ui
├── ExchangesPopup.ui
├── NewExchangePopup.ui
├── NewPortfolioPopup.ui
├── NewStrategyPopup.ui
├── NexusAsset.ui
├── NexusBroker.qml
├── NexusBroker.ui
├── NexusNodeEditor.ui
├── NexusPortfolio.ui
└── NexusSettings.ui
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Mono auto generated files
17 | mono_crash.*
18 |
19 | # Build results
20 | [Dd]ebug/
21 | [Dd]ebugPublic/
22 | [Rr]elease/
23 | [Rr]eleases/
24 | x64/
25 | x86/
26 | [Ww][Ii][Nn]32/
27 | [Aa][Rr][Mm]/
28 | [Aa][Rr][Mm]64/
29 | bld/
30 | [Bb]in/
31 | [Oo]bj/
32 | [Oo]ut/
33 | [Ll]og/
34 | [Ll]ogs/
35 |
36 | # Visual Studio 2015/2017 cache/options directory
37 | .vs/
38 | # Uncomment if you have tasks that create the project's static files in wwwroot
39 | #wwwroot/
40 |
41 | # Visual Studio 2017 auto generated files
42 | Generated\ Files/
43 |
44 | # MSTest test Results
45 | [Tt]est[Rr]esult*/
46 | [Bb]uild[Ll]og.*
47 |
48 | # NUnit
49 | *.VisualState.xml
50 | TestResult.xml
51 | nunit-*.xml
52 |
53 | # Build Results of an ATL Project
54 | [Dd]ebugPS/
55 | [Rr]eleasePS/
56 | dlldata.c
57 |
58 | # Benchmark Results
59 | BenchmarkDotNet.Artifacts/
60 |
61 | # .NET Core
62 | project.lock.json
63 | project.fragment.lock.json
64 | artifacts/
65 |
66 | # ASP.NET Scaffolding
67 | ScaffoldingReadMe.txt
68 |
69 | # StyleCop
70 | StyleCopReport.xml
71 |
72 | # Files built by Visual Studio
73 | *_i.c
74 | *_p.c
75 | *_h.h
76 | *.ilk
77 | *.meta
78 | *.obj
79 | *.iobj
80 | *.pch
81 | *.pdb
82 | *.ipdb
83 | *.pgc
84 | *.pgd
85 | *.rsp
86 | *.sbr
87 | *.tlb
88 | *.tli
89 | *.tlh
90 | *.tmp
91 | *.tmp_proj
92 | *_wpftmp.csproj
93 | *.log
94 | *.vspscc
95 | *.vssscc
96 | .builds
97 | *.pidb
98 | *.svclog
99 | *.scc
100 |
101 | # Chutzpah Test files
102 | _Chutzpah*
103 |
104 | # Visual C++ cache files
105 | ipch/
106 | *.aps
107 | *.ncb
108 | *.opendb
109 | *.opensdf
110 | *.sdf
111 | *.cachefile
112 | *.VC.db
113 | *.VC.VC.opendb
114 |
115 | # Visual Studio profiler
116 | *.psess
117 | *.vsp
118 | *.vspx
119 | *.sap
120 |
121 | # Visual Studio Trace Files
122 | *.e2e
123 |
124 | # TFS 2012 Local Workspace
125 | $tf/
126 |
127 | # Guidance Automation Toolkit
128 | *.gpState
129 |
130 | # ReSharper is a .NET coding add-in
131 | _ReSharper*/
132 | *.[Rr]e[Ss]harper
133 | *.DotSettings.user
134 |
135 | # TeamCity is a build add-in
136 | _TeamCity*
137 |
138 | # DotCover is a Code Coverage Tool
139 | *.dotCover
140 |
141 | # AxoCover is a Code Coverage Tool
142 | .axoCover/*
143 | !.axoCover/settings.json
144 |
145 | # Coverlet is a free, cross platform Code Coverage Tool
146 | coverage*.json
147 | coverage*.xml
148 | coverage*.info
149 |
150 | # Visual Studio code coverage results
151 | *.coverage
152 | *.coveragexml
153 |
154 | # NCrunch
155 | _NCrunch_*
156 | .*crunch*.local.xml
157 | nCrunchTemp_*
158 |
159 | # MightyMoose
160 | *.mm.*
161 | AutoTest.Net/
162 |
163 | # Web workbench (sass)
164 | .sass-cache/
165 |
166 | # Installshield output folder
167 | [Ee]xpress/
168 |
169 | # DocProject is a documentation generator add-in
170 | DocProject/buildhelp/
171 | DocProject/Help/*.HxT
172 | DocProject/Help/*.HxC
173 | DocProject/Help/*.hhc
174 | DocProject/Help/*.hhk
175 | DocProject/Help/*.hhp
176 | DocProject/Help/Html2
177 | DocProject/Help/html
178 |
179 | # Click-Once directory
180 | publish/
181 |
182 | # Publish Web Output
183 | *.[Pp]ublish.xml
184 | *.azurePubxml
185 | # Note: Comment the next line if you want to checkin your web deploy settings,
186 | # but database connection strings (with potential passwords) will be unencrypted
187 | *.pubxml
188 | *.publishproj
189 |
190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
191 | # checkin your Azure Web App publish settings, but sensitive information contained
192 | # in these scripts will be unencrypted
193 | PublishScripts/
194 |
195 | # NuGet Packages
196 | *.nupkg
197 | # NuGet Symbol Packages
198 | *.snupkg
199 | # The packages folder can be ignored because of Package Restore
200 | **/[Pp]ackages/*
201 | # except build/, which is used as an MSBuild target.
202 | !**/[Pp]ackages/build/
203 | # Uncomment if necessary however generally it will be regenerated when needed
204 | #!**/[Pp]ackages/repositories.config
205 | # NuGet v3's project.json files produces more ignorable files
206 | *.nuget.props
207 | *.nuget.targets
208 |
209 | # Microsoft Azure Build Output
210 | csx/
211 | *.build.csdef
212 |
213 | # Microsoft Azure Emulator
214 | ecf/
215 | rcf/
216 |
217 | # Windows Store app package directories and files
218 | AppPackages/
219 | BundleArtifacts/
220 | Package.StoreAssociation.xml
221 | _pkginfo.txt
222 | *.appx
223 | *.appxbundle
224 | *.appxupload
225 |
226 | # Visual Studio cache files
227 | # files ending in .cache can be ignored
228 | *.[Cc]ache
229 | # but keep track of directories ending in .cache
230 | !?*.[Cc]ache/
231 |
232 | # Others
233 | ClientBin/
234 | ~$*
235 | *~
236 | *.dbmdl
237 | *.dbproj.schemaview
238 | *.jfm
239 | *.pfx
240 | *.publishsettings
241 | orleans.codegen.cs
242 |
243 | # Including strong name files can present a security risk
244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
245 | #*.snk
246 |
247 | # Since there are multiple workflows, uncomment next line to ignore bower_components
248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
249 | #bower_components/
250 |
251 | # RIA/Silverlight projects
252 | Generated_Code/
253 |
254 | # Backup & report files from converting an old project file
255 | # to a newer Visual Studio version. Backup files are not needed,
256 | # because we have git ;-)
257 | _UpgradeReport_Files/
258 | Backup*/
259 | UpgradeLog*.XML
260 | UpgradeLog*.htm
261 | ServiceFabricBackup/
262 | *.rptproj.bak
263 |
264 | # SQL Server files
265 | *.mdf
266 | *.ldf
267 | *.ndf
268 |
269 | # Business Intelligence projects
270 | *.rdl.data
271 | *.bim.layout
272 | *.bim_*.settings
273 | *.rptproj.rsuser
274 | *- [Bb]ackup.rdl
275 | *- [Bb]ackup ([0-9]).rdl
276 | *- [Bb]ackup ([0-9][0-9]).rdl
277 |
278 | # Microsoft Fakes
279 | FakesAssemblies/
280 |
281 | # GhostDoc plugin setting file
282 | *.GhostDoc.xml
283 |
284 | # Node.js Tools for Visual Studio
285 | .ntvs_analysis.dat
286 | node_modules/
287 |
288 | # Visual Studio 6 build log
289 | *.plg
290 |
291 | # Visual Studio 6 workspace options file
292 | *.opt
293 |
294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
295 | *.vbw
296 |
297 | # Visual Studio LightSwitch build output
298 | **/*.HTMLClient/GeneratedArtifacts
299 | **/*.DesktopClient/GeneratedArtifacts
300 | **/*.DesktopClient/ModelManifest.xml
301 | **/*.Server/GeneratedArtifacts
302 | **/*.Server/ModelManifest.xml
303 | _Pvt_Extensions
304 |
305 | # Paket dependency manager
306 | .paket/paket.exe
307 | paket-files/
308 |
309 | # FAKE - F# Make
310 | .fake/
311 |
312 | # CodeRush personal settings
313 | .cr/personal
314 |
315 | # Python Tools for Visual Studio (PTVS)
316 | __pycache__/
317 | *.pyc
318 |
319 | # Cake - Uncomment if you are using it
320 | # tools/**
321 | # !tools/packages.config
322 |
323 | # Tabs Studio
324 | *.tss
325 |
326 | # Telerik's JustMock configuration file
327 | *.jmconfig
328 |
329 | # BizTalk build output
330 | *.btp.cs
331 | *.btm.cs
332 | *.odx.cs
333 | *.xsd.cs
334 |
335 | # OpenCover UI analysis results
336 | OpenCover/
337 |
338 | # Azure Stream Analytics local run output
339 | ASALocalRun/
340 |
341 | # MSBuild Binary and Structured Log
342 | *.binlog
343 |
344 | # NVidia Nsight GPU debugger configuration file
345 | *.nvuser
346 |
347 | # MFractors (Xamarin productivity tool) working folder
348 | .mfractor/
349 |
350 | # Local History for Visual Studio
351 | .localhistory/
352 |
353 | # BeatPulse healthcheck temp database
354 | healthchecksdb
355 |
356 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
357 | MigrationBackup/
358 |
359 | # Ionide (cross platform F# VS Code tools) working folder
360 | .ionide/
361 |
362 | # Fody - auto-generated XML schema
363 | FodyWeavers.xsd
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "AgisCore"]
2 | path = AgisCore
3 | url = https://github.com/ntorm1/AgisCore
4 | [submodule "AgisCoreTest"]
5 | path = AgisCoreTest
6 | url = https://github.com/ntorm1/AgisCoreTest.git
7 | [submodule "Qt-Advanced-Docking-System"]
8 | path = Qt-Advanced-Docking-System
9 | url = https://github.com/ntorm1/Qt-Advanced-Docking-System.git
10 | [submodule "nodeeditor"]
11 | path = nodeeditor
12 | url = https://github.com/paceholder/nodeeditor.git
13 | [submodule "external/QScintilla"]
14 | path = external/QScintilla
15 | url = https://github.com/ntorm1/QScintilla.git
16 |
--------------------------------------------------------------------------------
/AgisCorePy/AgisCorePy.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 | Debug
14 | x64
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | 16.0
23 | Win32Proj
24 | {ab689656-df19-4960-b465-5572eaf6f709}
25 | AgisCorePy
26 | 10.0
27 |
28 |
29 |
30 | DynamicLibrary
31 | true
32 | v143
33 | Unicode
34 |
35 |
36 | DynamicLibrary
37 | false
38 | v143
39 | true
40 | Unicode
41 |
42 |
43 | DynamicLibrary
44 | true
45 | v143
46 | Unicode
47 |
48 |
49 | DynamicLibrary
50 | false
51 | v143
52 | true
53 | Unicode
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);C:\Program Files\Python310\libs
75 | .pyd
76 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)AgisCore\external\include
77 |
78 |
79 | $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);
80 | .pyd
81 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)AgisCore\external\include
82 |
83 |
84 |
85 | Level3
86 | true
87 | WIN32;_DEBUG;AGISCOREPY_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
88 | true
89 | Use
90 | pch.h
91 |
92 |
93 | Windows
94 | true
95 | false
96 |
97 |
98 |
99 |
100 | Level3
101 | true
102 | true
103 | true
104 | WIN32;NDEBUG;AGISCOREPY_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
105 | true
106 | Use
107 | pch.h
108 |
109 |
110 | Windows
111 | true
112 | true
113 | true
114 | false
115 |
116 |
117 |
118 |
119 | Level3
120 | true
121 | _DEBUG;AGISCOREPY_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
122 | true
123 | Use
124 | pch.h
125 | C:\Program Files\Python310\include;$(SolutionDir)AgisCore\include;
126 | stdcpplatest
127 | true
128 | true
129 | $(SolutionDir)AgisCore\$(Platform)\$(Configuration)\Broker.ixx.ifc;$(SolutionDir)AgisCore\$(Platform)\$(Configuration)\Broker.Dummy.ixx.ifc;$(SolutionDir)AgisCore\$(Platform)\$(Configuration)\Broker.Base.ixx.ifc;%(AdditionalModuleDependencies)
130 |
131 |
132 | Windows
133 | true
134 | false
135 | python310_d.lib;$(SolutionDir)$(Platform)\$(Configuration)\AgisCore.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)
136 |
137 |
138 |
139 |
140 | Level3
141 | true
142 | true
143 | true
144 | NDEBUG;AGISCOREPY_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
145 | true
146 | Use
147 | pch.h
148 | stdcpp20
149 | C:\Program Files\Python310\include;$(SolutionDir)AgisCore
150 |
151 |
152 | Windows
153 | true
154 | true
155 | true
156 | false
157 | $(CoreLibraryDependencies);%(AdditionalDependencies);$(SolutionDir)$(Platform)\$(Configuration)\AgisCore.lib;python310.lib
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 | Create
169 | Create
170 | Create
171 | Create
172 |
173 |
174 |
175 |
176 |
177 |
--------------------------------------------------------------------------------
/AgisCorePy/AgisCorePy.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Header Files
20 |
21 |
22 | Header Files
23 |
24 |
25 |
26 |
27 | Source Files
28 |
29 |
30 | Source Files
31 |
32 |
33 | Source Files
34 |
35 |
36 |
--------------------------------------------------------------------------------
/AgisCorePy/dllmain.cpp:
--------------------------------------------------------------------------------
1 | // dllmain.cpp : Defines the entry point for the DLL application.
2 | #include "pch.h"
3 |
4 | BOOL APIENTRY DllMain( HMODULE hModule,
5 | DWORD ul_reason_for_call,
6 | LPVOID lpReserved
7 | )
8 | {
9 | switch (ul_reason_for_call)
10 | {
11 | case DLL_PROCESS_ATTACH:
12 | case DLL_THREAD_ATTACH:
13 | case DLL_THREAD_DETACH:
14 | case DLL_PROCESS_DETACH:
15 | break;
16 | }
17 | return TRUE;
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/AgisCorePy/framework.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
4 | // Windows Header Files
5 | #include
6 |
--------------------------------------------------------------------------------
/AgisCorePy/module.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | #include "Hydra.h"
8 |
9 | import Broker;
10 |
11 |
12 | namespace py = pybind11;
13 | using namespace std;
14 |
15 |
16 | class PyAgisStrategy : public AgisStrategy {
17 | public:
18 | /* inherit the constructors */
19 | using AgisStrategy::AgisStrategy;
20 |
21 | ///
22 | /// Trampoline function for pure virtual method: next
23 | ///
24 | void next() override {
25 | PYBIND11_OVERRIDE_PURE(
26 | void,
27 | AgisStrategy,
28 | next
29 | );
30 | }
31 |
32 | ///
33 | /// Trampoline function for pure virtual method: reset
34 | ///
35 | void reset() override {
36 | PYBIND11_OVERRIDE_PURE(
37 | void,
38 | AgisStrategy,
39 | reset
40 | );
41 | }
42 |
43 | ///
44 | /// Trampoline function for pure virtual method: build
45 | ///
46 | void build() override {
47 | PYBIND11_OVERRIDE_PURE(
48 | void,
49 | AgisStrategy,
50 | build
51 | );
52 | }
53 | };
54 |
55 |
56 | class PyTradeExit : public TradeExit {
57 | public:
58 | using TradeExit::TradeExit;
59 |
60 | ///
61 | /// Trampoline function for pure virtual method: exit
62 | ///
63 | bool exit() override {
64 | PYBIND11_OVERRIDE_PURE(
65 | bool,
66 | TradeExit,
67 | exit
68 | );
69 | }
70 | };
71 |
72 |
73 | void init_agis_broker(py::module& m)
74 | {
75 | py::class_>(m, "Broker");
76 | }
77 |
78 |
79 | void init_agis_strategy(py::module& m)
80 | {
81 | py::enum_(m, "AllocType")
82 | .value("UNITS", AllocType::UNITS)
83 | .value("DOLLARS", AllocType::DOLLARS)
84 | .value("PCT", AllocType::PCT)
85 | .export_values();
86 |
87 | py::class_(m, "AgisStrategy")
88 | .def(py::init, std::shared_ptr, double>())
89 | .def("next", &AgisStrategy::next)
90 | .def("reset", &AgisStrategy::reset)
91 | .def("build", &AgisStrategy::build)
92 | .def("get_nlv", &AgisStrategy::get_nlv, "Get net liquidation value")
93 | .def("exchange_subscribe", &AgisStrategy::exchange_subscribe, "Subscribe to an exchange")
94 | .def("get_allocation", &AgisStrategy::get_allocation, "Get portfolio allocation")
95 | .def("get_strategy_index", &AgisStrategy::get_strategy_index, "Get unique strategy index")
96 | .def("get_strategy_id", &AgisStrategy::get_strategy_id, "Get unique strategy id")
97 | .def("get_portfolio_index", &AgisStrategy::get_portfolio_index, "Get portfolio index")
98 | .def("get_portfolio_id", &AgisStrategy::get_portfolio_id, "Get portfolio id")
99 | .def("get_exchange", &AgisStrategy::get_exchange, "Get an exchange by id")
100 | .def("strategy_allocate",
101 | &AgisStrategy::strategy_allocate,
102 | py::arg("allocation"),
103 | py::arg("epsilon"),
104 | py::arg("clear_missing") = true,
105 | py::arg("exit") = py::none(),
106 | py::arg("alloc_type") = AllocType::UNITS);
107 | }
108 |
109 | void init_exchange(py::module& m)
110 | {
111 | py::enum_(m, "ExchangeQueryType")
112 | .value("Default", ExchangeQueryType::Default)
113 | .value("NExtreme", ExchangeQueryType::NExtreme)
114 | .value("NLargest", ExchangeQueryType::NLargest)
115 | .value("NSmallest", ExchangeQueryType::NSmallest)
116 | .export_values();
117 |
118 | py::class_>(m, "Exchange")
119 | .def("get_exchange_id", &Exchange::get_exchange_id)
120 | .def("get_exchange_view",
121 | py::overload_cast<
122 | const std::string&,
123 | int,
124 | ExchangeQueryType,
125 | int,
126 | bool>
127 | (&Exchange::get_exchange_view),
128 | "Get ExchangeView with specified parameters",
129 | py::arg("col"),
130 | py::arg("row") = 0,
131 | py::arg("query_type") = ExchangeQueryType::Default,
132 | py::arg("N") = -1,
133 | py::arg("panic") = false
134 | );
135 |
136 | py::class_(m, "ExchangeView")
137 | .def(py::init<>())
138 | .def_readwrite("view", &ExchangeView::view)
139 | .def("apply_weights", &ExchangeView::apply_weights)
140 | .def("apply_weights",
141 | &ExchangeView::apply_weights,
142 | py::arg("type"),
143 | py::arg("c"),
144 | py::arg("x") = py::none())
145 | .def("__len__", &ExchangeView::size)
146 | .def("__sub__", &ExchangeView::operator-, py::is_operator()) // Wrap the subtraction operator
147 | .def("__add__", &ExchangeView::operator+, py::is_operator()) // Wrap the subtraction operator
148 | .def("__div__", &ExchangeView::operator/, py::is_operator()) // Wrap the subtraction operator
149 | .def("__mul__", &ExchangeView::operator*, py::is_operator()); // Wrap the subtraction operator
150 |
151 | }
152 |
153 | void init_portfolio(py::module& m)
154 | {
155 | py::class_(m, "TradeExit")
156 | .def(py::init<>())
157 | .def("build", &TradeExit::build)
158 | .def("exit", &TradeExit::exit);
159 |
160 | //py::class_>(m, "Portfolio")
161 | // .def(py::init());
162 | }
163 |
164 | PYBIND11_MODULE(AgisCorePy, m) {
165 | // build python bindings for broker class
166 | init_agis_broker(m);
167 |
168 | // build python bindings for Agis strategy class
169 | init_agis_strategy(m);
170 |
171 | // build python bindings for exchange class
172 | init_exchange(m);
173 |
174 | // build python bindings for portfolio class
175 | init_portfolio(m);
176 | }
--------------------------------------------------------------------------------
/AgisCorePy/pch.cpp:
--------------------------------------------------------------------------------
1 | // pch.cpp: source file corresponding to the pre-compiled header
2 |
3 | #include "pch.h"
4 |
5 | // When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
6 |
--------------------------------------------------------------------------------
/AgisCorePy/pch.h:
--------------------------------------------------------------------------------
1 | // pch.h: This is a precompiled header file.
2 | // Files listed below are compiled only once, improving build performance for future builds.
3 | // This also affects IntelliSense performance, including code completion and many code browsing features.
4 | // However, files listed here are ALL re-compiled if any one of them is updated between builds.
5 | // Do not add files here that you will be updating frequently as this negates the performance advantage.
6 | #define NOMINMAX
7 | #ifndef PCH_H
8 | #define PCH_H
9 | #define _SILENCE_CXX23_ALIGNED_STORAGE_DEPRECATION_WARNING
10 | #define _SILENCE_CXX23_DENORM_DEPRECATION_WARNING
11 |
12 | // add headers that you want to pre-compile here
13 | #include "framework.h"
14 | #include
15 |
16 | #endif //PCH_H
17 |
--------------------------------------------------------------------------------
/MainWindow.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/MainWindow.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | MainWindow
4 |
5 |
6 |
7 | 0
8 | 0
9 | 1131
10 | 757
11 |
12 |
13 |
14 | MainWindow
15 |
16 |
17 |
33 |
34 |
35 | toolBar
36 |
37 |
38 | TopToolBarArea
39 |
40 |
41 | false
42 |
43 |
44 |
45 | Save State
46 |
47 |
48 |
49 |
50 | Restore State
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/Nexus.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.5.33627.172
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AgisCore", "AgisCore\AgisCore.vcxproj", "{580F9CB3-A7BA-418F-ABE1-5865B3071D6A}"
7 | EndProject
8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AgisCoreTest", "..\AgisCoreTest\AgisCoreTest.vcxproj", "{939DA327-5AE8-4499-B79F-69F041B085FF}"
9 | ProjectSection(ProjectDependencies) = postProject
10 | {580F9CB3-A7BA-418F-ABE1-5865B3071D6A} = {580F9CB3-A7BA-418F-ABE1-5865B3071D6A}
11 | EndProjectSection
12 | EndProject
13 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Nexus", "Nexus.vcxproj", "{4B2D8569-2184-4357-96E2-6D97BD658FD9}"
14 | ProjectSection(ProjectDependencies) = postProject
15 | {580F9CB3-A7BA-418F-ABE1-5865B3071D6A} = {580F9CB3-A7BA-418F-ABE1-5865B3071D6A}
16 | EndProjectSection
17 | EndProject
18 | Global
19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
20 | Debug|x64 = Debug|x64
21 | Debug|x86 = Debug|x86
22 | Release|x64 = Release|x64
23 | Release|x86 = Release|x86
24 | EndGlobalSection
25 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
26 | {580F9CB3-A7BA-418F-ABE1-5865B3071D6A}.Debug|x64.ActiveCfg = Debug|x64
27 | {580F9CB3-A7BA-418F-ABE1-5865B3071D6A}.Debug|x64.Build.0 = Debug|x64
28 | {580F9CB3-A7BA-418F-ABE1-5865B3071D6A}.Debug|x86.ActiveCfg = Debug|Win32
29 | {580F9CB3-A7BA-418F-ABE1-5865B3071D6A}.Debug|x86.Build.0 = Debug|Win32
30 | {580F9CB3-A7BA-418F-ABE1-5865B3071D6A}.Release|x64.ActiveCfg = Release|x64
31 | {580F9CB3-A7BA-418F-ABE1-5865B3071D6A}.Release|x64.Build.0 = Release|x64
32 | {580F9CB3-A7BA-418F-ABE1-5865B3071D6A}.Release|x86.ActiveCfg = Release|Win32
33 | {580F9CB3-A7BA-418F-ABE1-5865B3071D6A}.Release|x86.Build.0 = Release|Win32
34 | {939DA327-5AE8-4499-B79F-69F041B085FF}.Debug|x64.ActiveCfg = Debug|x64
35 | {939DA327-5AE8-4499-B79F-69F041B085FF}.Debug|x64.Build.0 = Debug|x64
36 | {939DA327-5AE8-4499-B79F-69F041B085FF}.Debug|x86.ActiveCfg = Debug|Win32
37 | {939DA327-5AE8-4499-B79F-69F041B085FF}.Debug|x86.Build.0 = Debug|Win32
38 | {939DA327-5AE8-4499-B79F-69F041B085FF}.Release|x64.ActiveCfg = Release|x64
39 | {939DA327-5AE8-4499-B79F-69F041B085FF}.Release|x64.Build.0 = Release|x64
40 | {939DA327-5AE8-4499-B79F-69F041B085FF}.Release|x86.ActiveCfg = Release|Win32
41 | {939DA327-5AE8-4499-B79F-69F041B085FF}.Release|x86.Build.0 = Release|Win32
42 | {4B2D8569-2184-4357-96E2-6D97BD658FD9}.Debug|x64.ActiveCfg = Debug|x64
43 | {4B2D8569-2184-4357-96E2-6D97BD658FD9}.Debug|x64.Build.0 = Debug|x64
44 | {4B2D8569-2184-4357-96E2-6D97BD658FD9}.Debug|x86.ActiveCfg = Debug|x64
45 | {4B2D8569-2184-4357-96E2-6D97BD658FD9}.Debug|x86.Build.0 = Debug|x64
46 | {4B2D8569-2184-4357-96E2-6D97BD658FD9}.Release|x64.ActiveCfg = Release|x64
47 | {4B2D8569-2184-4357-96E2-6D97BD658FD9}.Release|x64.Build.0 = Release|x64
48 | {4B2D8569-2184-4357-96E2-6D97BD658FD9}.Release|x86.ActiveCfg = Release|x64
49 | {4B2D8569-2184-4357-96E2-6D97BD658FD9}.Release|x86.Build.0 = Release|x64
50 | EndGlobalSection
51 | GlobalSection(SolutionProperties) = preSolution
52 | HideSolutionNode = FALSE
53 | EndGlobalSection
54 | GlobalSection(ExtensibilityGlobals) = postSolution
55 | SolutionGuid = {46445AB8-45BA-4A90-866E-20049C320F87}
56 | EndGlobalSection
57 | EndGlobal
58 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Nexus
2 | Algoirthmic trading IDE and framework
3 | 
4 |
5 | ### Features
6 | - Multi window based UI that allows for the devolpment of Algorithmic trading strategies.
7 | - Allows for multipule strategies to be executed at the same time using different frequencies, logic, portfolios, etc...
8 | - Create abstract strategies using the node editor to adjust strategies and observe changes without having to recompile.
9 | - Generate code for an abstract strategy and compile it into a seperate dll which can be linked at run time to allow for customized and more complex strategies.
10 |
11 | ### Build
12 | - Notes: only supported setup is Windows with MSVC compiler, supporting c++20, using Visual Studio build system. Dependancies are manged using vcpkg.
13 | - To build you may have to update the solution properties for include or lib directories, the default vcpkg dir is at C:\dev\vcpkg\installed\x64-windows\bin
14 | Ex:
15 | - run: git clone https://github.com/ntorm1/Nexus
16 | - run: cd Nexus
17 | - run: git submodule update --init --recursive
18 | - Open nodeeditor/CMakeLists.txt in Visual Studio, build and copy QtNodes.dll to x64/debug and release folders of the Nexus Solution.
19 | - cd to external/QScintilla/src. Open x64 Native Tools Command Prompt
20 | - run qmake
21 | - run nmake /f Makefile.Debug (and release), then copy dll files to x64/debug and release
22 | - Open Nexus.sln and build.
23 |
24 | To get AgisCoreTest running you will need [Google Test](https://learn.microsoft.com/en-us/visualstudio/test/how-to-use-google-test-for-cpp?view=vs-2022)
25 |
26 |
27 | ### Scripting
28 | - AgisCore uses LuaJIT for scripting allowing for easy creation of strategies with almost no overhead. You can create abstract strategy trees using the
29 | AgisCore Lua API which evaluates to a C++ strategy tree at run time with comparable time to abstract strategies made using the node editor.
30 | - To use Lua you need to download LuaJIT, see below, and add the Lua header files and lib files to the Visual Studio Nexus project settings. Make sure the
31 | Lua DLL is available in the system path or is copied/output to the Nexus x64 build folder.
32 |
33 |
34 | ### Dependencies
35 | There are a lot, some are nessecary like Qt and AgisCore, others like One Intel TBB could be removed with some modifications to the code, some of which I have provided but working around this would not be recomended.
36 | - One Intel API and Thread Building Blocks, used for parralell execution
37 | - Qt
38 | - (vcpkg) Apache Arrow C++ (for data io)
39 | - (vcpkg) rapidjson (serialization)
40 | - (vcpkg) HDF5 C++ (for data io)
41 | - (vcpkg) Eigen3 (linear algebra)
42 | - (vcpkg) pybind11 (for python wrapper)
43 | - (git submodule) Qt advance docking system (for main docking ui)
44 | - (git submodule) nodeeditor (strategy nodeeditor )
45 | - (git submodule) AgisCore (backtesting framework)
46 | - (git submdoule) QScintilla (text editor)
47 | - LuaJIT see: https://luajit.org/download.html (optional lua scripting)
48 |
49 | #### Performance
50 | 
51 |
52 |
53 | #### Codegen
54 | 
55 |
56 | #### Python Support
57 | 
58 |
--------------------------------------------------------------------------------
/github/Nexus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/github/Nexus.png
--------------------------------------------------------------------------------
/github/codegen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/github/codegen.png
--------------------------------------------------------------------------------
/github/perf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/github/perf.png
--------------------------------------------------------------------------------
/github/pybind11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/github/pybind11.png
--------------------------------------------------------------------------------
/images/ads_tile_green.svg:
--------------------------------------------------------------------------------
1 |
2 |
34 |
--------------------------------------------------------------------------------
/images/ads_tile_orange.svg:
--------------------------------------------------------------------------------
1 |
2 |
34 |
--------------------------------------------------------------------------------
/images/branch-closed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/branch-closed.png
--------------------------------------------------------------------------------
/images/branch-end.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/branch-end.png
--------------------------------------------------------------------------------
/images/branch-more.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/branch-more.png
--------------------------------------------------------------------------------
/images/broker.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/broker.png
--------------------------------------------------------------------------------
/images/color_lens.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/console.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/console.png
--------------------------------------------------------------------------------
/images/create_floating_editor.svg:
--------------------------------------------------------------------------------
1 |
2 |
81 |
--------------------------------------------------------------------------------
/images/create_floating_table.svg:
--------------------------------------------------------------------------------
1 |
2 |
81 |
--------------------------------------------------------------------------------
/images/crop_original.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/custom-menu-button.svg:
--------------------------------------------------------------------------------
1 |
2 |
33 |
--------------------------------------------------------------------------------
/images/date_range.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/docked_editor.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/edit.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/exchange.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/exchange.png
--------------------------------------------------------------------------------
/images/find_in_page.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/flow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/flow.png
--------------------------------------------------------------------------------
/images/folder.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/folder_open.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/font_download.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/fullscreen.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/grid_on.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/help_outline.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/json.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/json.png
--------------------------------------------------------------------------------
/images/link.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/link.png
--------------------------------------------------------------------------------
/images/note_add.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/panorama.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/perm_media.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/photo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/picture_in_picture.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/piechart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/piechart.png
--------------------------------------------------------------------------------
/images/plus.svg:
--------------------------------------------------------------------------------
1 |
2 |
124 |
--------------------------------------------------------------------------------
/images/restore.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/run.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/run.png
--------------------------------------------------------------------------------
/images/save.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/settings.png
--------------------------------------------------------------------------------
/images/stock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/stock.png
--------------------------------------------------------------------------------
/images/tab.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/vline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/vline.png
--------------------------------------------------------------------------------
/images/win/checkbox-checked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/win/checkbox-checked.png
--------------------------------------------------------------------------------
/images/win/checkbox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/win/checkbox.png
--------------------------------------------------------------------------------
/images/win/editcopy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/win/editcopy.png
--------------------------------------------------------------------------------
/images/win/editcut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/win/editcut.png
--------------------------------------------------------------------------------
/images/win/editpaste.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/win/editpaste.png
--------------------------------------------------------------------------------
/images/win/editredo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/win/editredo.png
--------------------------------------------------------------------------------
/images/win/exportpdf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/win/exportpdf.png
--------------------------------------------------------------------------------
/images/win/filenew.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/win/filenew.png
--------------------------------------------------------------------------------
/images/win/fileopen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/win/fileopen.png
--------------------------------------------------------------------------------
/images/win/fileprint.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/win/fileprint.png
--------------------------------------------------------------------------------
/images/win/filesave.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/win/filesave.png
--------------------------------------------------------------------------------
/images/win/format-indent-less.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/win/format-indent-less.png
--------------------------------------------------------------------------------
/images/win/format-indent-more.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/win/format-indent-more.png
--------------------------------------------------------------------------------
/images/win/textbold.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/win/textbold.png
--------------------------------------------------------------------------------
/images/win/textcenter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/win/textcenter.png
--------------------------------------------------------------------------------
/images/win/textitalic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/win/textitalic.png
--------------------------------------------------------------------------------
/images/win/textjustify.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/win/textjustify.png
--------------------------------------------------------------------------------
/images/win/textleft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/win/textleft.png
--------------------------------------------------------------------------------
/images/win/textright.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/win/textright.png
--------------------------------------------------------------------------------
/images/win/textunder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/win/textunder.png
--------------------------------------------------------------------------------
/images/win/textundercolor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/win/textundercolor.png
--------------------------------------------------------------------------------
/images/win/zoomin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/win/zoomin.png
--------------------------------------------------------------------------------
/images/win/zoomout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntorm1/Nexus/98a777f0ea14664490e1f1ccfec88b26725cd164/images/win/zoomout.png
--------------------------------------------------------------------------------
/images/zoom_in.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/zoom_out.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/zoom_out_map.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/include/MainWindow.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "NexusPch.h"
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | #include "DockManager.h"
16 | #include "DockAreaWidget.h"
17 | #include "DockWidget.h"
18 |
19 | #include "QScintillaEditor.h"
20 | #include "NexusEnv.h"
21 | #include "NexusAsset.h"
22 | #include "NexusNode.h"
23 |
24 |
25 | class NexusDockManager;
26 | class NexusSettings;
27 | class NewExchangePopup;
28 | class NexusWidgetFactory;
29 |
30 | QT_BEGIN_NAMESPACE
31 | namespace Ui {
32 | class MainWindow;
33 | }
34 | QT_END_NAMESPACE
35 |
36 | class MainWindow : public QMainWindow
37 | {
38 | Q_OBJECT
39 | friend class NexusWidgetFactory;
40 | public:
41 | MainWindow(QWidget* parent = 0);
42 | ~MainWindow();
43 |
44 | public slots:
45 | void about();
46 |
47 | void showErrorMessageBox(const QString& errorMessage)
48 | {
49 |
50 | }
51 |
52 |
53 | signals:
54 | void new_hydra_run();
55 | void new_exchange_accepted(const QModelIndex& parentIndex, const QString name);
56 | void new_portfolio_accepeted(const QModelIndex& parentIndex, const QString name);
57 | void new_strategy_accepeted(const QModelIndex& parentIndex, const QString name);
58 | void remove_strategy_accepted(const QModelIndex& parentIndex);
59 | void remove_exchange_accepted(const QModelIndex& parentIndex);
60 | void remove_portfolio_accepted(const QModelIndex& parentIndex);
61 |
62 |
63 | private slots:
64 | void save_perspective();
65 | void create_editor();
66 | void on_editor_close_requested();
67 | void on_node_editor_close_request();
68 | void on_widget_focus(ads::CDockWidget* old, ads::CDockWidget* now);
69 | void on_actionSaveState_triggered(bool);
70 | void on_actionRestoreState_triggered(bool);
71 |
72 | void on_new_portfolio_request(const QModelIndex& parentIndex,
73 | const QString& portfolio_id,
74 | const QString& starting_casj
75 | );
76 | void on_new_strategy_requested(const QModelIndex& parentIndex,
77 | const QString& portfolio_id,
78 | const QString& strategy_id,
79 | const QString& allocation,
80 | AgisStrategyType type
81 | );
82 | void on_strategy_remove_requested(const QModelIndex& parentIndex,
83 | const QString& strategy_id
84 | );
85 | void on_new_exchange_request(const QModelIndex& parentIndex,
86 | NewExchangePopup* popup
87 | );
88 |
89 | void on_remove_portfolio_request(const QString& name, const QModelIndex& parentIndex);
90 | void on_remove_exchange_request(const QString& name, const QModelIndex& parentIndex);
91 | void on_new_asset_window_request(const QString& name);
92 | void on_new_portfolio_window_request(const QString& name);
93 | void on_new_node_editor_request(const QString& name);
94 | void on_strategy_toggle(const QString& name, bool toggle);
95 | void on_settings_change(NexusSettings* settings);
96 |
97 | protected:
98 | virtual void closeEvent(QCloseEvent* event) override;
99 |
100 | private:
101 | void restore_state();
102 | AgisResult restore_editors(rapidjson::Document const& j);
103 | std::expected restore_exchanges(rapidjson::Document const& j);
104 | std::expected restore_portfolios(rapidjson::Document const& j);
105 |
106 | AgisResult save_state();
107 |
108 | void setup_toolbar();
109 | void setup_help_menu();
110 | void setup_command_bar();
111 | void create_perspective_ui();
112 |
113 | void place_widget(ads::CDockWidget* docket_widget, QObject* Sender);
114 | void place_widget(ads::CDockWidget* docket_widget, ads::CDockAreaWidget* dock_area);
115 | void on_settings_window_request();
116 |
117 | void onViewVisibilityChanged(bool open);
118 | void onViewToggled(bool open);
119 | void onFileDoubleClicked(const QModelIndex& index);
120 | void extract_flow_graphs();
121 | void applyVsStyle();
122 |
123 | QAction* SavePerspectiveAction = nullptr;
124 | QWidgetAction* PerspectiveListAction = nullptr;
125 | QComboBox* PerspectiveComboBox = nullptr;
126 | QProgressBar* ProgressBar = nullptr;
127 |
128 | QPointer LastDockedEditor;
129 | QPointer LastCreatedFloatingEditor;
130 |
131 | NexusEnv nexus_env;
132 | Ui::MainWindow* ui;
133 | ExchangeTree* exchange_tree;
134 | PortfolioTree* portfolio_tree;
135 |
136 | NexusDockManager* DockManager;
137 | ads::CDockAreaWidget* StatusDockArea;
138 | ads::CDockWidget* TimelineDockWidget;
139 |
140 | void __run();
141 | void __run_lambda();
142 | void __run_compile();
143 | void __run_link();
144 |
145 | public:
146 | ads::CDockWidget* create_console_widget();
147 | ads::CDockWidget* create_editor_widget();
148 | ads::CDockWidget* create_asset_widget(const QString& asset_id);
149 | ads::CDockWidget* create_portfolio_widget(const QString& portfolio_id);
150 | ads::CDockWidget* create_node_editor_widget(const QString& strategy_id);
151 | };
152 |
--------------------------------------------------------------------------------
/include/NexusAsset.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "NexusPch.h"
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | #include "DockWidget.h"
10 | #include "NexusHelpers.h"
11 | #include "NexusEnv.h"
12 | #include "NexusPlot.h"
13 | #include "Order.h"
14 |
15 | namespace Agis {
16 | class Asset;
17 | }
18 |
19 | typedef std::shared_ptr AssetPtr;
20 |
21 | namespace Ui {
22 | class NexusAsset;
23 | }
24 |
25 | class NexusAsset;
26 |
27 | class NexusAssetPlot : public NexusPlot
28 | {
29 | Q_OBJECT
30 | friend class NexusAsset;
31 | public:
32 | explicit NexusAssetPlot(QWidget* parent);
33 | ~NexusAssetPlot() = default;
34 |
35 | void load_asset(NexusAsset* asset);
36 |
37 | void add_plot(std::string plot_name);
38 | void plot_trades(std::vector const& trades);
39 | void plot_orders(std::vector const& orders);
40 |
41 | ///
42 | /// List of columns currently plotted
43 | ///
44 | std::vector plotted_graphs;
45 |
46 | ///
47 | /// Vector of QCPGraphs that are used to plot the trades
48 | ///
49 | std::vector trade_segments;
50 |
51 | protected slots:
52 | void removeSelectedGraph() override;
53 | void removeAllGraphs() override;
54 |
55 | private slots:
56 | void contextMenuRequest(QPoint pos) override;
57 | void new_plot(QString name);
58 |
59 | private:
60 | NexusAsset* nexus_asset;
61 | };
62 |
63 | class NexusAsset : public QMainWindow
64 | {
65 | Q_OBJECT
66 |
67 | public slots:
68 | void on_new_hydra_run();
69 |
70 | public:
71 | NexusAsset(
72 | NexusEnv const* nexus_env,
73 | ads::CDockWidget* DockWidget,
74 | AssetPtr asset,
75 | QWidget* parent = nullptr
76 | );
77 | void init_asset_selection();
78 | void load_asset_data();
79 | void load_asset_order_data();
80 | void load_asset_trade_data();
81 |
82 | void set_plotted_graphs(std::vector const& graphs);
83 | std::vector get_plotted_graphs() const { return this->nexus_plot->plotted_graphs; }
84 | std::string get_asset_id() const noexcept;
85 |
86 | Ui::NexusAsset* ui;
87 | ads::CDockWidget* DockWidget;
88 | NexusAssetPlot* nexus_plot;
89 | QComboBox* asset_selection;
90 | QTabWidget* table_container;
91 | QTableView* table_view;
92 | QTableView* orders_table_view;
93 | QTableView* trades_table_view;
94 | QTableView* positions_table_view;
95 |
96 | NexusEnv const* nexus_env;
97 | std::vector asset_ids;
98 | AssetPtr asset;
99 |
100 | std::vector trades;
101 | std::vector orders;
102 |
103 | std::vector column_names;
104 | std::vector dt_index_str;
105 | std::span dt_index;
106 | std::vector data;
107 | };
108 |
109 |
110 | //============================================================================
111 | template
112 | void event_data_loader(
113 | std::vector events,
114 | QStringList const& q_columns,
115 | QStandardItemModel* model,
116 | HydraPtr hydra
117 | )
118 | {
119 | model->setRowCount(events.size());
120 | model->setColumnCount(q_columns.size());
121 | model->setHorizontalHeaderLabels(q_columns);
122 |
123 | // Set the data in the model
124 | int row = 0;
125 | auto column_names = qlist_to_str_vec(q_columns);
126 | for (auto& new_event : events) {
127 | int col = 0;
128 | for (auto& column_name : column_names) {
129 | std::expected object_json_expected = new_event->serialize(hydra);
130 | if (!object_json_expected.has_value()) {
131 | AGIS_THROW(object_json_expected.error().what());
132 | }
133 | rapidjson::Document object_json = std::move(object_json_expected.value());
134 | const rapidjson::Value& value = object_json[column_name.c_str()];
135 | std::string str_value;
136 |
137 | // test if column_name is in nexus_datetime_columns
138 | if (std::find(nexus_datetime_columns.begin(), nexus_datetime_columns.end(), column_name) != nexus_datetime_columns.end()) {
139 | long long epoch_time = object_json[column_name.c_str()].GetUint64();
140 | auto res = epoch_to_str(epoch_time, NEXUS_DATETIME_FORMAT);
141 | if (res.is_exception())
142 | {
143 | AGIS_THROW(res.get_exception());
144 | }
145 | str_value = res.unwrap();
146 | }
147 | // parse any other value
148 | else {
149 | str_value = json_val_to_string(value);
150 | }
151 | QStandardItem* item = new QStandardItem(QString::fromStdString(str_value));
152 | model->setItem(row, col, item);
153 | col++;
154 | }
155 | row++;
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/include/NexusBroker.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include "NexusPch.h"
4 | #include "DockWidget.h"
5 |
6 | namespace Ui {
7 | class NexusBroker;
8 | }
9 |
10 | class NexusEnv;
11 |
12 | class NexusBroker : public QMainWindow
13 | {
14 | public:
15 | NexusBroker(
16 | NexusEnv const* nexus_env_,
17 | ads::CDockWidget* DockWidget,
18 | QWidget* parent = 0
19 | );
20 |
21 | ads::CDockWidget* DockWidget;
22 |
23 | private:
24 | Ui::NexusBroker* ui;
25 | NexusEnv const* nexus_env;
26 |
27 | };
--------------------------------------------------------------------------------
/include/NexusDockManager.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "NexusPch.h"
6 | #include "DockManager.h"
7 | #include
8 |
9 | //#include "MainWindow.h"
10 |
11 | class MainWindow;
12 |
13 |
14 | // Qt Advanced Docking System dock manager extension
15 | // because the Qt Advanced Docking System is not designed to e.g. regenerate closed widgets when restoring a perspective
16 | class NexusDockManager : public ads::CDockManager {
17 | public:
18 | NexusDockManager(MainWindow* main_window, QWidget* parent = nullptr);
19 |
20 | Document save_widgets();
21 | void restore_widgets(Document const& j);
22 |
23 | private:
24 | MainWindow* main_window;
25 | };
--------------------------------------------------------------------------------
/include/NexusEnv.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "NexusPch.h"
3 | #include
4 | #include
5 | #include
6 |
7 | #include "QScintillaEditor.h"
8 | #include "NexusTree.h"
9 |
10 | #include "AgisPointers.h"
11 | #include "AgisErrors.h"
12 | #include "ExchangeMap.h"
13 | #include "Portfolio.h"
14 |
15 | namespace fs = std::filesystem;
16 |
17 | ///
18 | /// Datetime format to use when displaying long long ns epoch times
19 | ///
20 | constexpr auto NEXUS_DATETIME_FORMAT = "%F %T";
21 |
22 | ///
23 | /// A list of columns to parse as datetime columns when loading ns epoch times
24 | ///
25 | extern const std::vector nexus_datetime_columns;
26 |
27 | class NexusSettings;
28 | class Position;
29 |
30 | typedef std::shared_ptr SharedPositionPtr;
31 |
32 | class NexusEnv
33 | {
34 | private:
35 |
36 | void remove_editors() { this->open_editors.clear(); }
37 |
38 | ///
39 | /// Vector of pointers to text editors currently open.
40 | ///
41 | std::vector open_editors;
42 |
43 | ///
44 | /// Vector of pointers to trees that are currently open
45 | ///
46 | std::vector open_trees;
47 |
48 | ///
49 | /// Vector of names of strategies whose node editors are currently open
50 | ///
51 | std::vector open_node_editors;
52 |
53 | ///
54 | /// Shared pointer to a hydra instance
55 | ///
56 | Hydra hydra;
57 |
58 | std::string agis_pyd_path = "";
59 | std::string agis_lib_path = "";
60 | std::string agis_include_path = "";
61 | std::string agis_build_method = "\"Visual Studio 17 2022\"";
62 | std::string env_name;
63 | fs::path env_path;
64 |
65 |
66 | ///
67 | /// AgisStrategy dll
68 | ///
69 | HINSTANCE AgisStrategyDLL;
70 | bool agis_strategy_dll_loaded = false;
71 |
72 | std::vector order_history;
73 | std::vector position_history;
74 | std::vector trade_history;
75 |
76 | public:
77 | NexusEnv();
78 | ~NexusEnv();
79 |
80 | [[nodiscard]] AgisResult __run();
81 | void __save_history();
82 | void __compile();
83 | void __link(bool assume_live = true);
84 | void __reset();
85 | void clear();
86 |
87 | AgisResult restore_strategies(rapidjson::Document const& j);
88 | AgisResult restore_settings(rapidjson::Document const& j);
89 | inline std::expected restore_portfolios(rapidjson::Document const& j) { return this->hydra.restore_portfolios(j); }
90 | inline std::expected restore_exchanges(rapidjson::Document const& j) { return this->hydra.restore_exchanges(j); }
91 |
92 | AgisResult init_covariance_matrix(size_t lookback, size_t step) { return this->hydra.init_covariance_matrix(lookback, step); }
93 |
94 | ///
95 | /// Take a Nexus settings popup window and load in the settings passes and validate them
96 | ///
97 | /// Pointer to a nexus settings window
98 | ///
99 | AgisResult set_settings(NexusSettings* nexus_settings);
100 |
101 | //============================================================================
102 | fs::path const& get_env_path() const { return this->env_path; }
103 | fs::path get_env_settings_path() const { return this->env_path / "env_settings.json"; }
104 | std::expected save_env(rapidjson::Document& j);
105 | void set_env_name(std::string const & exe_path, std::string const & env_name);
106 |
107 | //============================================================================
108 | [[nodiscard]] AgisResult new_node_editor(std::string strategy_id);
109 | void new_editor(QScintillaEditor* new_editor);
110 | std::optional get_editor(QString const & file_name) const;
111 | void remove_editor(QString const& file_name);
112 | void remove_node_editor(std::string const& id);
113 | bool editor_open(QString const & file_name);
114 |
115 | //============================================================================
116 | void new_tree(NexusTree* new_tree);
117 | void reset_trees();
118 |
119 | ///
120 | /// Return a pointer to the hydra instance
121 | ///
122 | ///
123 | HydraPtr get_hydra() const;
124 |
125 | ///
126 | /// Get an asset pointer by id
127 | ///
128 | /// the asset pointer if it exsists, otherwise Agis Result exception
129 | ///
130 | AgisResult const get_asset(std::string const& asset_id);
131 |
132 | ///
133 | /// Get a pointer to a strategy by id
134 | ///
135 | /// pointer to the strategy if it was found
136 | ///
137 | std::optional __get_strategy(std::string const& strategy_id);
138 |
139 | std::vector get_portfolio_ids();
140 | size_t get_candle_count() { return this->hydra.get_candle_count(); }
141 |
142 | [[nodiscard]] AgisResult new_exchange(
143 | const std::string& exchange_id,
144 | const std::string& source,
145 | const std::string& freq,
146 | const std::string& dt_format,
147 | std::optional> market_asset = std::nullopt
148 | );
149 | NexusStatusCode new_portfolio(
150 | const std::string& portfolio_id,
151 | const std::string& starting_cash
152 | );
153 | NexusStatusCode new_strategy(
154 | const std::string& portfolio_id,
155 | const std::string& strategy_id,
156 | const std::string& allocation,
157 | AgisStrategyType strategy_type = AgisStrategyType::FLOW
158 | );
159 |
160 | NexusStatusCode remove_exchange(const std::string& name);
161 | NexusStatusCode remove_portfolio(const std::string& name);
162 | NexusStatusCode remove_strategy(const std::string& name);
163 |
164 | auto const& get_order_history() const { return this->order_history; }
165 | auto const& get_trade_history() const { return this->trade_history; }
166 | auto const& get_position_history() const { return this->position_history; }
167 |
168 | std::string get_agis_include_path() const { return this->agis_include_path; }
169 | std::string get_agis_pyd_path() const { return this->agis_pyd_path; }
170 | std::string get_agis_dll_path() const { return this->agis_lib_path; }
171 | std::string get_agis_build_method() const { return this->agis_build_method; }
172 |
173 | [[nodiscard]] AgisResult set_market_asset(
174 | std::string const& exchange_id,
175 | std::string const& asset_id,
176 | bool disable,
177 | std::optional beta_lookback
178 | );
179 |
180 | //============================================================================
181 | template
182 | std::vector> const filter_event_history(
183 | std::vector> const& events,
184 | std::optional const& asset_id,
185 | std::optional const& strategy_id,
186 | std::optional const& portfolio_id) const
187 | {
188 | std::optional asset_index = std::nullopt;
189 | if (asset_id.has_value()) asset_index = this->hydra.get_exchanges().get_asset_index(asset_id.value());
190 |
191 | std::optional strategy_index = std::nullopt;
192 | if (strategy_id.has_value()) strategy_index = this->hydra.__get_strategy_map().__get_strategy_index(strategy_id.value());
193 |
194 | std::optional portfolio_index = std::nullopt;
195 | if (portfolio_id.has_value()) portfolio_index = this->hydra.get_portfolios().__get_portfolio_index(portfolio_id.value());
196 |
197 | std::vector> return_vec;
198 | auto it = events.begin();
199 | while (it != events.end())
200 | {
201 | if (asset_index.has_value() && (*it)->get_asset_index() != asset_index.value())
202 | {
203 | ++it;
204 | continue;
205 | }
206 | if (strategy_index.has_value() && (*it)->get_strategy_index() != strategy_index.value())
207 | {
208 | ++it;
209 | continue;
210 |
211 | }
212 | if (portfolio_index.has_value() && (*it)->get_portfolio_index() != portfolio_index.value())
213 | {
214 | ++it;
215 | continue;
216 | }
217 | return_vec.push_back(*it);
218 | ++it;
219 | }
220 | return return_vec;
221 | }
222 | };
223 |
224 | LPCWSTR StringToLPCWSTR(const std::string& str);
--------------------------------------------------------------------------------
/include/NexusErrors.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 |
4 | #define NEXUS_TRY(action) \
5 | try { \
6 | action; \
7 | } catch (const std::exception& e) { \
8 | QMessageBox::critical(nullptr, "Error", e.what());\
9 | }
10 |
11 |
12 | #define NEXUS_THROW(msg) \
13 | do { \
14 | std::ostringstream oss; \
15 | oss << "Error in " << __FILE__ \
16 | << " at line " << __LINE__ << ": " << msg; \
17 | throw std::runtime_error(oss.str()); \
18 | } while (false)
19 |
20 |
--------------------------------------------------------------------------------
/include/NexusHelpers.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "NexusPch.h"
3 | #include
4 |
5 | //============================================================================
6 | const QStringList q_order_columns_names = {
7 | "Order Fill Time","Asset Identifier","Strategy Identifier",
8 | "Order Type","Units","Average Price","Limit","Order State","Portfolio Identifier",
9 | "Order Create Time","Order Cancel Time", "Order ID",
10 | };
11 |
12 |
13 | //============================================================================
14 | const QStringList q_trade_column_names = {
15 | "Trade Open Time","Trade Close Time","Bars Held","Asset Identifier","Strategy Identifier",
16 | "Units","Average Price","Close Price","Unrealized PL",
17 | "Realized PL","Portfolio Identifier","Trade Identifier","Last Price","NLV",
18 | };
19 |
20 |
21 | //============================================================================
22 | inline std::vector qlist_to_str_vec(QStringList const& list) {
23 | std::vector order_columns_names;
24 | for (const auto& str : list) {
25 | order_columns_names.push_back(str.toStdString());
26 | }
27 | return order_columns_names;
28 | }
29 |
30 |
31 | //============================================================================
32 | static QIcon svgIcon(const QString& File)
33 | {
34 | // This is a workaround, because in item views SVG icons are not
35 | // properly scaled and look blurry or pixelate
36 | QIcon SvgIcon(File);
37 | SvgIcon.addPixmap(SvgIcon.pixmap(92));
38 | return SvgIcon;
39 | }
40 |
41 |
42 | //============================================================================
43 | inline QStringList str_vec_to_qlist(std::vector const& vec) {
44 | QStringList list;
45 | for (const auto& str : vec) {
46 | list.push_back(QString::fromStdString(str));
47 | }
48 | return list;
49 | }
50 |
51 |
52 | //============================================================================
53 | inline std::string json_val_to_string(const rapidjson::Value& j) {
54 | if (j.IsString()) {
55 | return j.GetString();
56 | }
57 | else if (j.IsInt()) {
58 | return std::to_string(j.GetInt());
59 | }
60 | else if (j.IsUint()) {
61 | return std::to_string(j.GetUint());
62 | }
63 | else if (j.IsDouble()) {
64 | return std::to_string(j.GetDouble());
65 | }
66 | else {
67 | throw std::runtime_error("unexpected type");
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/include/NexusNode.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | #include "DockWidget.h"
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 |
21 | #include "AgisStrategy.h"
22 | #include
23 |
24 | using QtNodes::NodeData;
25 | using QtNodes::NodeDataType;
26 | using QtNodes::NodeDelegateModel;
27 | using QtNodes::PortIndex;
28 | using QtNodes::PortType;
29 | using QtNodes::NodeDelegateModelRegistry;
30 | using QtNodes::DataFlowGraphModel;
31 | using QtNodes::GraphicsView;
32 | using QtNodes::BasicGraphicsScene;
33 |
34 | namespace fs = std::filesystem;
35 |
36 | class NexusEnv;
37 |
38 | namespace Ui {
39 | class NexusNodeEditor;
40 | }
41 |
42 | std::shared_ptr registerDataModels();
43 |
44 | class NexusNodeEditor : public QMainWindow
45 | {
46 | Q_OBJECT
47 |
48 |
49 | public:
50 |
51 | NexusNodeEditor(
52 | NexusEnv const* nexus_env,
53 | ads::CDockWidget* DockWidget,
54 | AgisStrategy* strategy,
55 | QWidget* parent = nullptr
56 | );
57 | ~NexusNodeEditor();
58 |
59 | void __set_strategy(AgisStrategy* strategy_);
60 | void __save();
61 | void __load(
62 | BasicGraphicsScene* scene,
63 | std::optional file_path = std::nullopt
64 | );
65 | static std::optional __extract_abstract_strategy(DataFlowGraphModel* dataFlowGraphModel);
66 |
67 | std::string get_strategy_id() { return this->strategy_id; }
68 |
69 | private:
70 | QMenuBar* createSaveRestoreMenu(BasicGraphicsScene* scene);
71 | void handleCheckBoxStateChange(QCheckBox* checkBox, std::function(bool)> setFunction);
72 | void create_strategy_tab(QVBoxLayout* l);
73 | void on_tw_change(int index);
74 |
75 | static size_t counter;
76 | size_t id;
77 |
78 | DataFlowGraphModel* dataFlowGraphModel;
79 | GraphicsView* view;
80 |
81 | NexusEnv const* nexus_env;
82 | AgisStrategy* strategy;
83 | std::string strategy_id;
84 | Ui::NexusNodeEditor* ui;
85 | ads::CDockWidget* DockWidget;
86 |
87 | QLineEdit* allocation;
88 | QLineEdit* max_leverage;
89 | QSpinBox* step_frequency;
90 | QComboBox* trading_window;
91 |
92 | QCheckBox* beta_trace; ///< Wether or not to store the net beta of the strategy every t
93 | QCheckBox* beta_scale; ///< Wether or not to scale the strategy allocation by the beta
94 | QCheckBox* beta_hedge; ///< Wether or not to hedge the beta of the strategy
95 | QCheckBox* net_leverage_trace; ///< Wether or not to store the net leverage of the strategy every t
96 | QCheckBox* vol_trace; ///< Wether or not to store the volatility of the strategy every t
97 |
98 | QMenuBar* menuBar;
99 | QMenu* fileMenu;
100 |
101 |
102 |
103 | signals:
104 | void on_close();
105 | };
106 |
107 |
108 | // Macro to run a function and display QMessageBox if an exception is thrown
109 | #define RUN_WITH_ERROR_DIALOG(function) \
110 | try { \
111 | function; \
112 | } \
113 | catch (const std::exception& e) { \
114 | QString errorMessage = "Error: " + QString(e.what()); \
115 | QMessageBox::critical(nullptr, "Critical Error", errorMessage, QMessageBox::Ok); \
116 | } \
117 | catch (...) { \
118 | QString errorMessage = "Unknown error occurred."; \
119 | QMessageBox::critical(nullptr, "Critical Error", errorMessage, QMessageBox::Ok); \
120 | }
--------------------------------------------------------------------------------
/include/NexusNodeWidget.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "NexusPch.h"
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | #include
15 | #include
16 |
17 | class Hydra;
18 |
19 | using QtNodes::NodeId;
20 | using QtNodes::PortIndex;
21 | using QtNodes::PortType;
22 |
23 |
24 |
25 | class ExchangeNode : public QWidget
26 | {
27 | Q_OBJECT
28 | public:
29 | ExchangeNode(
30 | HydraPtr hydra,
31 | QWidget* parent = nullptr);
32 |
33 | ~ExchangeNode() { delete layout; };
34 |
35 | HydraPtr hydra;
36 |
37 | QHBoxLayout* layout;
38 | QComboBox* exchange_id;
39 | };
40 |
41 | class AssetLambdaNode : public QWidget
42 | {
43 | Q_OBJECT
44 | public:
45 | AssetLambdaNode(
46 | QWidget* parent = nullptr);
47 |
48 | ~AssetLambdaNode() { delete layout; };
49 |
50 | QVBoxLayout* layout;
51 | QComboBox* opperation;
52 | QSpinBox* row;
53 | QLineEdit* column;
54 | QLineEdit* filter;
55 | };
56 |
57 | class ExchangeViewNode : public QWidget
58 | {
59 | Q_OBJECT
60 | public:
61 | ExchangeViewNode(
62 | QWidget* parent = nullptr);
63 |
64 | ~ExchangeViewNode() { delete layout; };
65 |
66 | QVBoxLayout* layout;
67 | QComboBox* query_type;
68 | QSpinBox* N;
69 | };
70 |
71 | class TradeExitNode : public QWidget
72 | {
73 | Q_OBJECT
74 | public:
75 | TradeExitNode(
76 | QWidget* parent = nullptr);
77 |
78 | ~TradeExitNode() { delete layout; };
79 |
80 | QVBoxLayout* layout;
81 | QComboBox* exit_type;
82 | QLineEdit* extra_param;
83 | };
84 |
85 | class StrategyAllocationNode : public QWidget
86 | {
87 | Q_OBJECT
88 | public:
89 | StrategyAllocationNode(
90 | QWidget* parent = nullptr);
91 |
92 | ~StrategyAllocationNode() { delete layout; };
93 |
94 | void update_ev_opp_param_state();
95 |
96 | QVBoxLayout* layout;
97 | QLineEdit* epsilon;
98 | QLineEdit* target_leverage;
99 | QCheckBox* clear_missing;
100 | QComboBox* alloc_type;
101 | QComboBox* ev_opp_type;
102 | QLineEdit* ev_opp_param;
103 |
104 | };
--------------------------------------------------------------------------------
/include/NexusPch.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #ifndef PCH_H
3 | #define PCH_H
4 | #define NOMINMAX
5 | #define USE_LUAJIT
6 | #include
7 | #include
8 | #include
9 |
10 | #include "AgisPointers.h"
11 |
12 | #include "Hydra.h"
13 |
14 | #include
15 |
16 | #include
17 | #include
18 | #include
19 |
20 |
21 | using namespace rapidjson;
22 |
23 | typedef const Hydra* HydraPtr;
24 |
25 | #define NEXUS_INTERUPT(msg) \
26 | do { \
27 | std::ostringstream oss; \
28 | oss << "Error in " << __FILE__ \
29 | << " at line " << __LINE__ << ": " << msg; \
30 | QMessageBox::critical(nullptr, "Critical Error", QString::fromStdString(oss.str()), QMessageBox::Ok); \
31 | return; \
32 | } while (false)
33 |
34 | #define NEXUS_DO_OR_INTERUPT(function) \
35 | do { \
36 | auto res = function; \
37 | if (!res.is_exception()) { \
38 | NEXUS_INTERUPT(res.get_exception()); \
39 | }\
40 | } while (false)
41 |
42 |
43 | #define NEXUS_ASSIGN_OR_INTERUPT (res, function) \
44 | auto res = function; \
45 | if (!res.has_value()) { \
46 | NEXUS_INTERUPT(res.error()); \
47 | }
48 |
49 |
50 | #endif
--------------------------------------------------------------------------------
/include/NexusPlot.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "NexusPch.h"
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | #include "qcustomplot.h"
12 |
13 | #include "Trade.h"
14 |
15 | struct Point
16 | {
17 | long long datetime_index;
18 | double value;
19 | };
20 |
21 |
22 | class NexusPlot : public QCustomPlot
23 | {
24 | Q_OBJECT
25 |
26 | public:
27 | explicit NexusPlot(QWidget* parent = 0);
28 | ~NexusPlot() = default;
29 |
30 | void set_title(std::string title);
31 | void plot(
32 | std::span x,
33 | std::span y,
34 | std::string name
35 | );
36 |
37 | //void scatter_plot();
38 |
39 | protected:
40 | std::optional selected_line = std::nullopt;
41 |
42 | protected slots:
43 | //void titleDoubleClick(QMouseEvent* event);
44 | //void axisLabelDoubleClick(QCPAxis* axis, QCPAxis::SelectablePart part);
45 | //void legendDoubleClick(QCPLegend* legend, QCPAbstractLegendItem* item);
46 | void addRandomGraph();
47 | void selectionChanged();
48 | void mousePress();
49 | void mouseWheel();
50 | virtual void removeSelectedGraph();
51 | virtual void remove_graph_by_name(std::string const& name);
52 | virtual void removeAllGraphs();
53 | virtual void contextMenuRequest(QPoint pos);
54 | void moveLegend();
55 | void graphClicked(QCPAbstractPlottable* plottable, int dataIndex);
56 | };
57 |
--------------------------------------------------------------------------------
/include/NexusPopups.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | class Exchange;
14 | class NexusEnv;
15 | class Hydra;
16 | typedef std::shared_ptr ExchangePtr;
17 | typedef const Hydra * HydraPtr;
18 |
19 | QT_BEGIN_NAMESPACE
20 | namespace Ui {
21 | class NewExchangePopup;
22 | class NewPortfolioPopup;
23 | class NewStrategyPopup;
24 | class NexusSettings;
25 | class ExchangesPopup;
26 | }
27 | QT_END_NAMESPACE
28 |
29 |
30 | ///
31 | /// Poppup window when a new portfolio is requested.
32 | ///
33 | class NewPortfolioPopup : public QDialog
34 | {
35 | Q_OBJECT
36 | public:
37 | explicit NewPortfolioPopup(QWidget* parent = nullptr);
38 | ~NewPortfolioPopup();
39 |
40 | QString get_portfolio_id() const;
41 | QString get_starting_cash() const;
42 |
43 | private:
44 | void on_submit();
45 | Ui::NewPortfolioPopup* ui;
46 |
47 | };
48 |
49 |
50 | ///
51 | /// Popup window when a new strategy is requested.
52 | ///
53 | class NewStrategyPopup : public QDialog
54 | {
55 | Q_OBJECT
56 | public:
57 | explicit NewStrategyPopup(QWidget* parent = nullptr);
58 | ~NewStrategyPopup();
59 |
60 | QString get_strategy_id() const;
61 | QString get_allocation() const;
62 | QString get_strategy_type() const;
63 |
64 | private:
65 | void on_submit();
66 | Ui::NewStrategyPopup* ui;
67 |
68 | };
69 |
70 | ///
71 | /// Pop up window presented when a new exchange is requested.
72 | ///
73 | class NewExchangePopup : public QDialog
74 | {
75 | Q_OBJECT
76 |
77 | public:
78 | explicit NewExchangePopup(
79 | QWidget* parent = nullptr,
80 | std::optional exchange = std::nullopt
81 | );
82 | ~NewExchangePopup();
83 |
84 | QString get_vol_lookback() const;
85 | QString get_source() const;
86 | QString get_exchange_id() const;
87 | QString get_freq() const;
88 | QString get_dt_format() const;
89 | QString get_market_asset_id() const;
90 | QString get_beta_lookback() const;
91 |
92 | Ui::NewExchangePopup* ui;
93 |
94 | private slots:
95 | void selectFolder();
96 |
97 | private:
98 | void on_submit();
99 |
100 | };
101 |
102 |
103 | ///
104 | /// Pop up window presented when exchanges are requested.
105 | ///
106 | class ExchangesPopup : public QDialog
107 | {
108 | Q_OBJECT
109 |
110 | public:
111 | explicit ExchangesPopup(
112 | QWidget* parent = nullptr,
113 | std::optional hydra = std::nullopt
114 | );
115 | ~ExchangesPopup();
116 |
117 | bool get_cov_enabled() const;
118 | QString get_cov_lookback() const;
119 | QString get_cov_step() const;
120 |
121 | Ui::ExchangesPopup* ui;
122 |
123 | size_t cov_lookback = 0;
124 | size_t cov_step_size = 1;
125 |
126 | private:
127 | void on_submit();
128 | std::optional hydra;
129 | };
130 |
131 |
132 | ///
133 | /// Popup window when Nexus settings ar
134 | ///
135 | class NexusSettings : public QDialog
136 | {
137 | Q_OBJECT
138 |
139 | signals:
140 | void settings_changed();
141 |
142 | public:
143 | explicit NexusSettings(
144 | NexusEnv const * nexs_env,
145 | QWidget* parent = nullptr
146 | );
147 | ~NexusSettings();
148 |
149 | QString get_agis_include_path() const;
150 | QString get_agis_lib_path() const;
151 | QString get_agis_pyd_path() const;
152 | QString get_vs_version() const;
153 |
154 | private slots:
155 | void select_folder(std::string dest);
156 |
157 | private:
158 | void on_submit();
159 | Ui::NexusSettings* ui;
160 | NexusEnv const * nexs_env;
161 | };
--------------------------------------------------------------------------------
/include/NexusPortfolio.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | #include "DockWidget.h"
10 |
11 | #include "NexusEnv.h"
12 | #include "NexusPlot.h"
13 | #include "Hydra.h"
14 |
15 | namespace Ui {
16 | class NexusPortfolio;
17 | }
18 |
19 | class NexusPortfolio;
20 | class NexusPortfolioPlot;
21 |
22 |
23 | class NexusPortfolioPlot : public NexusPlot
24 | {
25 | Q_OBJECT
26 | public:
27 | explicit NexusPortfolioPlot(QWidget* parent_);
28 | ~NexusPortfolioPlot() = default;
29 |
30 | void load(HydraPtr hydra_, std::string portfolio_id_) {
31 | this->hydra = hydra_;
32 | this->portfolio_id = portfolio_id_;
33 | };
34 |
35 | void load_portfolio(NexusPortfolio* portfolio) {
36 | this->nexus_portfolio = portfolio;
37 | }
38 |
39 | ///
40 | /// List of columns currently plotted
41 | ///
42 | std::vector plotted_graphs;
43 |
44 | protected slots:
45 | void removeAllGraphs() override;
46 | void removeSelectedGraph() override;
47 |
48 | private slots:
49 | void contextMenuRequest(QPoint pos) override;
50 | void add_plot(QString const& name);
51 |
52 | private:
53 | HydraPtr hydra = nullptr;
54 | NexusPortfolio* nexus_portfolio = nullptr;
55 | std::string portfolio_id;
56 |
57 | std::vector get_data(
58 | const std::variant& entity,
59 | const std::string& name
60 | );
61 | };
62 |
63 |
64 | class NexusPortfolio : public QMainWindow
65 | {
66 | Q_OBJECT
67 | public:
68 | NexusPortfolio(
69 | NexusEnv const* nexus_env,
70 | ads::CDockWidget* DockWidget,
71 | std::string portfolio_id,
72 | QWidget* parent = nullptr
73 | );
74 |
75 | Ui::NexusPortfolio* ui;
76 | ads::CDockWidget* DockWidget;
77 |
78 | QTabWidget* table_container;
79 | QTableView* stats_table_view;
80 | QTreeView* portfolio_treeview;
81 |
82 | NexusPortfolioPlot* nexus_plot;
83 |
84 | std::vector get_plotted_graphs() const { return this->nexus_plot->plotted_graphs; }
85 | std::string get_portfolio_id() { return this->portfolio_id; }
86 | std::vector get_selected_strategies() const;
87 |
88 | public slots:
89 | void on_new_hydra_run();
90 | void on_portfolio_download();
91 |
92 | private:
93 | std::unordered_map strategies_checkboxes;
94 |
95 | void set_up_strategies_menu();
96 | void set_up_portfolio_table();
97 | void set_up_toolbar();
98 | NexusEnv const* nexus_env;
99 | std::string portfolio_id;
100 | };
101 |
--------------------------------------------------------------------------------
/include/NexusTree.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "NexusPch.h"
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #include "Hydra.h"
14 |
15 | class NexusEnv;
16 |
17 | class ToggleButtonDelegate : public QStyledItemDelegate {
18 | public:
19 | ToggleButtonDelegate(QObject* parent = nullptr) : QStyledItemDelegate(parent) {}
20 |
21 | void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override {
22 | QStyleOptionViewItem adjustedOption = option;
23 | // Draw the checkbox and the text conditionally
24 | if (index.column() == 0 && index.parent().isValid() && index.parent().parent().isValid()) {
25 | adjustedOption.showDecorationSelected = false; // Prevent text highlighting
26 | QStyleOptionButton buttonOption;
27 | buttonOption.rect = option.rect;
28 | buttonOption.state = index.data(Qt::CheckStateRole).toInt() == Qt::Checked ? QStyle::State_On : QStyle::State_Off;
29 |
30 | // Calculate the rect for the checkbox and the text
31 | QRect checkBoxRect = QApplication::style()->subElementRect(QStyle::SE_CheckBoxIndicator, &buttonOption, nullptr);
32 | QRect textRect = adjustedOption.rect.adjusted(checkBoxRect.width() + 2, 0, 0, 0); // Adjust for spacing
33 |
34 | // Draw the checkbox and text
35 | QApplication::style()->drawControl(QStyle::CE_CheckBox, &buttonOption, painter);
36 | painter->drawText(textRect, Qt::AlignVCenter, index.data().toString());
37 | }
38 | else {
39 | QStyledItemDelegate::paint(painter, adjustedOption, index);
40 | }
41 | }
42 |
43 | bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index) override {
44 | if (event->type() == QEvent::MouseButtonRelease) {
45 | QMouseEvent* mouseEvent = static_cast(event);
46 | if (mouseEvent->button() == Qt::LeftButton && index.column() == 0) {
47 | Qt::CheckState currentState = static_cast(index.data(Qt::CheckStateRole).toInt());
48 | model->setData(index, currentState == Qt::Unchecked ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
49 | return true;
50 | }
51 | }
52 | return QStyledItemDelegate::editorEvent(event, model, option, index);
53 | }
54 | };
55 |
56 |
57 | class NexusTree : public QTreeView
58 | {
59 | Q_OBJECT
60 |
61 | public:
62 | explicit NexusTree(QWidget* parent = nullptr);
63 | void reset_tree();
64 | virtual void restore_tree(rapidjson::Document const& j) = 0;
65 | virtual rapidjson::Value to_json(rapidjson::Document::AllocatorType& allocator) const;
66 | QStandardItemModel* get_model() { return this->model; }
67 |
68 | protected:
69 | virtual void contextMenuEvent(QContextMenuEvent* event) override;
70 | virtual void create_new_item(const QModelIndex& parentIndex) = 0;
71 | void remove_item(const QModelIndex& parentIndex);
72 |
73 | QStandardItemModel* model;
74 | QStandardItem* root;
75 |
76 | public slots:
77 | void handle_new_item_action();
78 | virtual void new_item_accepted(const QModelIndex& parentIndex, const QString& name);
79 | void remove_item_accepeted(const QModelIndex& index);
80 |
81 | signals:
82 | void remove_item_requested(const QString& name, const QModelIndex& parentIndex);
83 | };
84 |
85 |
86 | class PortfolioTree : public NexusTree
87 | {
88 | Q_OBJECT
89 |
90 | public:
91 | explicit PortfolioTree(QWidget* parent, HydraPtr hydra);
92 | void restore_tree(rapidjson::Document const& j) override;
93 | void relink_tree(std::vector const& portfolios);
94 | void restore_strategies(QStandardItem* addedItem, QString portfolio_id);
95 |
96 | protected:
97 | void mouseDoubleClickEvent(QMouseEvent* event) override;
98 |
99 | private:
100 | ///
101 | /// Create a new Portfolio from params using the popup window
102 | ///
103 | ///
104 | virtual void create_new_item(const QModelIndex& parentIndex) override;
105 |
106 | ///
107 | /// Create a new strategy underneath a portfolio
108 | ///
109 | ///
110 | void create_new_strategy(const QModelIndex& parentIndex);
111 |
112 |
113 | ///
114 | /// Set the benchmark strategy for a portfolio
115 | ///
116 | ///
117 | void set_benchmark_strategy(const QModelIndex& parentIndex);
118 |
119 | ///
120 | /// Delete a new strategy underneath a portfolio
121 | ///
122 | ///
123 | void delete_strategy(const QModelIndex& parentIndex);
124 |
125 | ///
126 | /// Override context menu event to prevent nested portfolios
127 | ///
128 | ///
129 | void contextMenuEvent(QContextMenuEvent* event) override;
130 |
131 | ///
132 | /// Clear all elements from the tree except for the root
133 | ///
134 | void clear();
135 |
136 | ///
137 | /// Parent hydra instance
138 | ///
139 | HydraPtr hydra;
140 |
141 | ///
142 | /// strategy toggle button delegate
143 | ///
144 | ToggleButtonDelegate toggleButtonDelegate;
145 |
146 | signals:
147 | void strategy_double_clicked(const QString& asset_id);
148 | void strategy_toggled(const QString& strategy_id, bool checked);
149 | void portfolio_double_clicked(const QString& portfolio_id);
150 |
151 | void new_item_requested(const QModelIndex& parentIndex,
152 | const QString& portfolio_id,
153 | const QString& starting_cash
154 | );
155 | void new_strategy_requested(const QModelIndex& parentIndex,
156 | const QString& portfolio_id,
157 | const QString& strategy_id,
158 | const QString& starting_cash,
159 | AgisStrategyType strategy_type = AgisStrategyType::FLOW
160 | );
161 | void strategy_remove_requested(const QModelIndex& parentIndex,
162 | const QString& strategy_id);
163 |
164 |
165 | public slots:
166 | void new_item_accepted(const QModelIndex& parentIndex, const QString& name) override;
167 | void strategy_remove_accepted(const QModelIndex& parentIndex, const QString& strategy_id);
168 | };
169 |
170 | //============================================================================
171 | class ExchangeTree : public NexusTree
172 | {
173 | Q_OBJECT
174 |
175 | public:
176 | explicit ExchangeTree(QWidget* parent, NexusEnv* nexus_env);
177 | void restore_tree(rapidjson::Document const& j) override;
178 | void restore_ids(QStandardItem* newItem, QString exchange_id);
179 |
180 | protected:
181 | void mouseDoubleClickEvent(QMouseEvent* event) override;
182 |
183 | private:
184 | ///
185 | /// Create a new exchange from params using the popup window
186 | ///
187 | ///
188 | virtual void create_new_item(const QModelIndex& parentIndex) override;
189 |
190 | ///
191 | /// Override context menu event method to prevent nested exchange
192 | ///
193 | ///
194 | void contextMenuEvent(QContextMenuEvent* event) override;
195 |
196 | ///
197 | /// Clear all elements from the tree except for the root
198 | ///
199 | void clear();
200 |
201 | ///
202 | /// On double click of exchange allow for editing of params
203 | ///
204 | ///
205 | AgisResult edit_exchange_instance(QString const& exchange_id);
206 |
207 | ///
208 | /// On double click of exchanges allow for editing of params
209 | ///
210 | AgisResult edit_exchanges_instance();
211 |
212 | ///
213 | /// Parent hydra instance
214 | ///
215 | HydraPtr hydra;
216 |
217 | ///
218 | /// Parent nexus env pointer
219 | ///
220 | NexusEnv* nexus_env;
221 |
222 | signals:
223 | void asset_double_click(const QString& asset_id);
224 | void new_item_requested(const QModelIndex& parentIndex,
225 | NewExchangePopup* popup
226 | );
227 |
228 | public slots:
229 | void new_item_accepted(const QModelIndex& parentIndex, const QString& name) override;
230 | };
--------------------------------------------------------------------------------
/include/NexusWidgetFactory.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "DockAreaWidget.h"
4 | #include "DockWidget.h"
5 |
6 | class MainWindow;
7 |
8 | class NexusWidgetFactory
9 | {
10 | public:
11 | NexusWidgetFactory();
12 | ~NexusWidgetFactory();
13 |
14 | static ads::CDockWidget* create_portfolios_widget(MainWindow* w);
15 | static ads::CDockWidget* create_exchanges_widget(MainWindow* w);
16 | static ads::CDockWidget* create_file_system_tree_widget(MainWindow* w);
17 |
18 | };
--------------------------------------------------------------------------------
/include/QScintillaEditor.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | /****************************************************************************
3 | ** Copyright (C) 2020 Riverbank Computing Limited
4 | ** Copyright (C) 2016 The Qt Company Ltd.
5 | ** Contact: https://www.qt.io/licensing/
6 | **
7 | ** This file is part of the examples of the Qt Toolkit.
8 | **
9 | ** $QT_BEGIN_LICENSE:BSD$
10 | ** Commercial License Usage
11 | ** Licensees holding valid commercial Qt licenses may use this file in
12 | ** accordance with the commercial license agreement provided with the
13 | ** Software or, alternatively, in accordance with the terms contained in
14 | ** a written agreement between you and The Qt Company. For licensing terms
15 | ** and conditions see https://www.qt.io/terms-conditions. For further
16 | ** information use the contact form at https://www.qt.io/contact-us.
17 | **
18 | ** BSD License Usage
19 | ** Alternatively, you may use this file under the terms of the BSD license
20 | ** as follows:
21 | **
22 | ** "Redistribution and use in source and binary forms, with or without
23 | ** modification, are permitted provided that the following conditions are
24 | ** met:
25 | ** * Redistributions of source code must retain the above copyright
26 | ** notice, this list of conditions and the following disclaimer.
27 | ** * Redistributions in binary form must reproduce the above copyright
28 | ** notice, this list of conditions and the following disclaimer in
29 | ** the documentation and/or other materials provided with the
30 | ** distribution.
31 | ** * Neither the name of The Qt Company Ltd nor the names of its
32 | ** contributors may be used to endorse or promote products derived
33 | ** from this software without specific prior written permission.
34 | **
35 | **
36 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
37 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
38 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
39 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
40 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
43 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
46 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
47 | **
48 | ** $QT_END_LICENSE$
49 | ****************************************************************************/
50 |
51 | #pragma once
52 |
53 | #include
54 | #include
55 | #include "DockWidget.h"
56 |
57 |
58 |
59 | class QAction;
60 | class QMenu;
61 | class QsciScintilla;
62 | class AgisLuaStrategy;
63 | class NexusEnv;
64 |
65 |
66 | class QScintillaEditor : public QMainWindow
67 | {
68 | Q_OBJECT
69 |
70 | public:
71 | QScintillaEditor(ads::CDockWidget* DockWidget);
72 | void loadFile(const QString& fileName);
73 |
74 | QString get_file_name() const { return curFile; }
75 | int get_id() const { return this->DockWidget->get_id(); }
76 | bool maybeSave();
77 |
78 | void load_lua_strategy(AgisLuaStrategy* strategy_) { this->strategy = strategy_; }
79 | static void set_nexus_env(NexusEnv* nexus_env_) { QScintillaEditor::nexus_env = nexus_env_; }
80 | protected:
81 | void closeEvent(QCloseEvent* event);
82 |
83 | private slots:
84 | void newFile();
85 | void open();
86 | bool save();
87 | bool saveAs();
88 | void about();
89 | void documentWasModified();
90 |
91 | private:
92 | void createActions();
93 | void createMenus();
94 | void createToolBars();
95 | void createStatusBar();
96 | void readSettings();
97 | void writeSettings();
98 |
99 | void set_current_strategy(const QString& fileName);
100 |
101 |
102 | bool saveFile(const QString& fileName);
103 | void setCurrentFile(const QString& fileName);
104 | QString strippedName(const QString& fullFileName);
105 |
106 | ads::CDockWidget* DockWidget;
107 | QsciScintilla* textEdit;
108 | QString curFile;
109 |
110 | QMenu* fileMenu;
111 | QMenu* editMenu;
112 | QMenu* helpMenu;
113 | QToolBar* fileToolBar;
114 | QToolBar* editToolBar;
115 | QAction* newAct;
116 | QAction* openAct;
117 | QAction* saveAct;
118 | QAction* saveAsAct;
119 | QAction* exitAct;
120 | QAction* cutAct;
121 | QAction* copyAct;
122 | QAction* pasteAct;
123 | QAction* aboutAct;
124 | QAction* aboutQtAct;
125 |
126 | static NexusEnv* nexus_env;
127 | std::optional strategy = std::nullopt;
128 | };
--------------------------------------------------------------------------------
/include/QTerminal.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #ifndef QTERMINAL_H
4 | #define QTERMINAL_H
5 |
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 |
18 | //#include "resource-manager.h"
19 |
20 | class QTerminal : public QWidget
21 | {
22 | Q_OBJECT
23 |
24 | public:
25 |
26 | static QTerminal* create(QWidget* xparent = nullptr);
27 |
28 | static QList default_colors(void);
29 |
30 | static QStringList color_names(void);
31 |
32 | virtual ~QTerminal(void) = default;
33 |
34 | virtual void setTerminalFont(const QFont& font) = 0;
35 |
36 | virtual void setSize(int h, int v) = 0;
37 |
38 | virtual void sendText(const QString& text) = 0;
39 |
40 | virtual QString selectedText() = 0;
41 |
42 | virtual void has_extra_interrupt(bool extra) = 0;
43 |
44 | virtual QList get_hotspot_actions(const QPoint&)
45 | {
46 | return QList();
47 | }
48 |
49 | enum CursorType
50 | {
51 | UnderlineCursor,
52 | BlockCursor,
53 | IBeamCursor
54 | };
55 |
56 | virtual void setCursorType(CursorType type, bool blinking)
57 | {
58 | // Provide empty default impl in order to avoid conflicts with the
59 | // win impl.
60 |
61 | Q_UNUSED(type);
62 | Q_UNUSED(blinking);
63 | }
64 |
65 | virtual void setBackgroundColor(const QColor& color) = 0;
66 |
67 | virtual void setForegroundColor(const QColor& color) = 0;
68 |
69 | virtual void setSelectionColor(const QColor& color) = 0;
70 |
71 | virtual void setCursorColor(bool useForegroundColor,
72 | const QColor& color) = 0;
73 |
74 | virtual void setScrollBufferSize(int value = 1000) = 0;
75 |
76 | signals:
77 |
78 | void report_status_message(const QString&);
79 |
80 | void interrupt_signal(void);
81 |
82 | void edit_mfile_request(const QString&, int);
83 |
84 | void execute_command_in_terminal_signal(const QString&);
85 |
86 | public slots:
87 |
88 | virtual void copyClipboard(void) = 0;
89 |
90 | virtual void pasteClipboard(void) = 0;
91 |
92 | virtual void selectAll(void) = 0;
93 |
94 | virtual void handleCustomContextMenuRequested(const QPoint& at);
95 |
96 | void notice_settings(const QSettings* settings);
97 |
98 | virtual void init_terminal_size(void) { }
99 |
100 | void terminal_interrupt(void) { emit interrupt_signal(); }
101 |
102 | void set_global_shortcuts(bool focus_out);
103 |
104 | void run_selection(void);
105 |
106 | void edit_file(void);
107 |
108 | virtual void handle_visibility_changed(bool) { };
109 |
110 | protected:
111 |
112 | QTerminal(QWidget* xparent = nullptr) : QWidget(xparent)
113 | {
114 | // context menu
115 | setContextMenuPolicy(Qt::CustomContextMenu);
116 |
117 | _contextMenu = new QMenu(this);
118 |
119 | //_copy_action = _contextMenu->addAction
120 | //(octave::resource_manager::icon("edit-copy"),
121 | // tr("Copy"), this, SLOT(copyClipboard()));
122 |
123 | //_paste_action = _contextMenu->addAction
124 | //(octave::resource_manager::icon("edit-paste"),
125 | // tr("Paste"), this, SLOT(pasteClipboard()));
126 |
127 | _contextMenu->addSeparator();
128 |
129 | _selectall_action = _contextMenu->addAction(
130 | tr("Select All"), this, SLOT(selectAll()));
131 |
132 | _run_selection_action = _contextMenu->addAction(
133 | tr("Run Selection"), this, SLOT(run_selection()));
134 |
135 | _edit_action = _contextMenu->addAction(
136 | tr(""), this, SLOT(edit_file()));
137 |
138 | _contextMenu->addSeparator();
139 |
140 | _contextMenu->addAction(tr("Clear Window"), parent(),
141 | SLOT(handle_clear_command_window_request()));
142 |
143 | connect(this, SIGNAL(customContextMenuRequested(QPoint)),
144 | this, SLOT(handleCustomContextMenuRequested(QPoint)));
145 |
146 | connect(this, SIGNAL(report_status_message(const QString&)),
147 | xparent, SLOT(report_status_message(const QString&)));
148 |
149 | connect(this, SIGNAL(edit_mfile_request(const QString&, int)),
150 | xparent, SLOT(edit_mfile(const QString&, int)));
151 |
152 | connect(this, SIGNAL(execute_command_in_terminal_signal(const QString&)),
153 | xparent, SLOT(execute_command_in_terminal(const QString&)));
154 |
155 | connect(xparent, SIGNAL(settings_changed(const QSettings*)),
156 | this, SLOT(notice_settings(const QSettings*)));
157 |
158 | connect(xparent, SIGNAL(init_terminal_size_signal()),
159 | this, SLOT(init_terminal_size()));
160 |
161 | connect(xparent, SIGNAL(copyClipboard_signal()),
162 | this, SLOT(copyClipboard()));
163 |
164 | connect(xparent, SIGNAL(pasteClipboard_signal()),
165 | this, SLOT(pasteClipboard()));
166 |
167 | connect(xparent, SIGNAL(selectAll_signal()),
168 | this, SLOT(selectAll()));
169 |
170 | // extra interrupt action
171 | _interrupt_action = new QAction(this);
172 | addAction(_interrupt_action);
173 |
174 | _interrupt_action->setShortcut(
175 | QKeySequence(Qt::ControlModifier + Qt::Key_C));
176 |
177 | connect(_interrupt_action, SIGNAL(triggered()),
178 | this, SLOT(terminal_interrupt()));
179 |
180 | // dummy (nop) action catching Ctrl-D in terminal, no connection
181 | _nop_action = new QAction(this);
182 | addAction(_nop_action);
183 |
184 | _nop_action->setShortcut(
185 | QKeySequence(Qt::ControlModifier + Qt::Key_D));
186 | }
187 |
188 | private:
189 |
190 | QMenu* _contextMenu;
191 | QAction* _copy_action;
192 | QAction* _paste_action;
193 | QAction* _selectall_action;
194 | QAction* _edit_action;
195 | QAction* _run_selection_action;
196 |
197 | QAction* _interrupt_action;
198 | QAction* _nop_action;
199 | };
200 |
201 | #endif // QTERMINAL_H
--------------------------------------------------------------------------------
/include/QTerminalImpl.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef __QConsole_h__
3 | #define __QConsole_h__ 1
4 |
5 | #include
6 | #include
7 |
8 | //////////////////////////////////////////////////////////////////////////////
9 |
10 | class QConsoleColors : public QMap
11 | {
12 | public:
13 | QConsoleColors(void);
14 | };
15 |
16 |
17 | #include
18 | #include "QTerminal.h"
19 |
20 | class QFocusEvent;
21 | class QKeyEvent;
22 | class QPainter;
23 | class QPaintEvent;
24 | class QResizeEvent;
25 | class QWheelEvent;
26 | class QPoint;
27 | class QDragEnterEvent;
28 | class QDropEvent;
29 |
30 | class QConsolePrivate;
31 | class QConsoleThread;
32 | class QConsoleView;
33 |
34 | //////////////////////////////////////////////////////////////////////////////
35 |
36 | class QWinTerminalImpl : public QTerminal
37 | {
38 | Q_OBJECT
39 | friend class QConsolePrivate;
40 | friend class QConsoleThread;
41 | friend class QConsoleView;
42 |
43 | public:
44 | QWinTerminalImpl(QWidget* parent = 0);
45 | QWinTerminalImpl(const QString& cmd, QWidget* parent = 0);
46 | ~QWinTerminalImpl(void);
47 |
48 | void setTerminalFont(const QFont& font);
49 | void setSize(int columns, int lines);
50 | void sendText(const QString& s);
51 | void setCursorType(CursorType type, bool blinking);
52 |
53 | void setBackgroundColor(const QColor& color);
54 | void setForegroundColor(const QColor& color);
55 | void setSelectionColor(const QColor& color);
56 | void setCursorColor(bool useForegoundColor, const QColor& color);
57 | void setScrollBufferSize(int value);
58 |
59 | QString selectedText();
60 |
61 | void has_extra_interrupt(bool);
62 |
63 | public slots:
64 | void copyClipboard(void);
65 | void pasteClipboard(void);
66 | void selectAll(void);
67 | void blinkCursorEvent(void);
68 | void init_terminal_size(void);
69 |
70 | signals:
71 | void terminated(void);
72 | void titleChanged(const QString&);
73 | void set_global_shortcuts_signal(bool);
74 | void set_screen_size_signal(int, int);
75 |
76 | protected:
77 | void viewPaintEvent(QConsoleView*, QPaintEvent*);
78 | void setBlinkingCursor(bool blink);
79 | void setBlinkingCursorState(bool blink);
80 | void viewResizeEvent(QConsoleView*, QResizeEvent*);
81 | void wheelEvent(QWheelEvent*);
82 | void focusInEvent(QFocusEvent*);
83 | void focusOutEvent(QFocusEvent*);
84 | void keyPressEvent(QKeyEvent*);
85 | virtual void start(void);
86 | void mouseMoveEvent(QMouseEvent* event);
87 | void mousePressEvent(QMouseEvent* event);
88 | void mouseReleaseEvent(QMouseEvent* event);
89 | void mouseDoubleClickEvent(QMouseEvent* event);
90 | void mouseTripleClickEvent(QMouseEvent* event);
91 |
92 | bool eventFilter(QObject* obj, QEvent* ev);
93 |
94 | void dragEnterEvent(QDragEnterEvent* event);
95 | void dropEvent(QDropEvent* event);
96 |
97 | private slots:
98 | void horizontalScrollValueChanged(int value);
99 | void verticalScrollValueChanged(int value);
100 | void monitorConsole(void);
101 | void updateSelection(void);
102 | void tripleClickTimeout(void);
103 |
104 | private:
105 | QConsolePrivate* d;
106 | bool allowTripleClick;
107 | bool _extra_interrupt;
108 | };
109 |
110 | //////////////////////////////////////////////////////////////////////////////
111 |
112 | #endif // __QConsole_h__
--------------------------------------------------------------------------------
/src/NexusBroker.cpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "NexusPch.h"
3 | #include "NexusBroker.h"
4 | #include "ui_NexusBroker.h"
5 |
6 | NexusBroker::NexusBroker(
7 | NexusEnv const* nexus_env_,
8 | ads::CDockWidget* DockWidget_,
9 | QWidget* parent_) :
10 | QMainWindow(parent_),
11 | nexus_env(nexus_env_),
12 | ui(new Ui::NexusBroker),
13 | DockWidget(DockWidget_)
14 | {
15 | }
--------------------------------------------------------------------------------
/src/NexusDockManager.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include "DockAreaWidget.h"
3 | #include "NexusDockManager.h"
4 | #include "MainWindow.h"
5 | #include "DockWidget.h"
6 | #include "NexusPortfolio.h"
7 |
8 | NexusDockManager::NexusDockManager(MainWindow* main_window_, QWidget* parent) :
9 | main_window(main_window_),
10 | ads::CDockManager(parent)
11 | {
12 | }
13 |
14 | Document NexusDockManager::save_widgets()
15 | {
16 | Document widgets;
17 | widgets.SetObject(); // Create a JSON object to store the data.
18 |
19 | auto& allocator = widgets.GetAllocator();
20 | for (auto const& dock_widget : this->get_widgets())
21 | {
22 | rapidjson::Value widget(rapidjson::kObjectType);
23 | widget.AddMember("widget_id", dock_widget->get_id(), allocator);
24 |
25 | // Add widget_type as a member
26 | rapidjson::Value widgetTypeValue;
27 | widgetTypeValue.SetUint64(static_cast(dock_widget->get_widget_type()));
28 | widget.AddMember("widget_type", widgetTypeValue, allocator);
29 |
30 | if (dock_widget->get_widget_type() == WidgetType::Asset)
31 | {
32 | auto child = dock_widget->widget();
33 | NexusAsset* asset_child = static_cast(child);
34 | widget.AddMember("asset_id", rapidjson::Value(asset_child->get_asset_id().c_str(), allocator), allocator);
35 |
36 | rapidjson::Value plottedGraphs(rapidjson::kArrayType);
37 | const std::vector graphs = asset_child->get_plotted_graphs();
38 | for (const std::string& graph : graphs)
39 | {
40 | rapidjson::Value graphValue(graph.c_str(), allocator);
41 | plottedGraphs.PushBack(graphValue, allocator);
42 | }
43 | widget.AddMember("plotted_graphs", plottedGraphs, allocator);
44 | }
45 | else if (dock_widget->get_widget_type() == WidgetType::NodeEditor)
46 | {
47 | auto child = dock_widget->widget();
48 | NexusNodeEditor* asset_child = static_cast(child);
49 | asset_child->__save();
50 | widget.AddMember("strategy_id", rapidjson::Value(asset_child->get_strategy_id().c_str(), allocator), allocator);
51 |
52 | }
53 | else if (dock_widget->get_widget_type() == WidgetType::Portfolio)
54 | {
55 | auto child = dock_widget->widget();
56 | NexusPortfolio* p = static_cast(child);
57 | widget.AddMember("portfolio_id", rapidjson::Value(p->get_portfolio_id().c_str(), allocator), allocator);
58 |
59 | auto graphs = p->get_plotted_graphs();
60 | if (graphs.size() > 0) {
61 | rapidjson::Value plottedGraphs(rapidjson::kArrayType);
62 | for (const std::string& graph : graphs)
63 | {
64 | rapidjson::Value graphValue(graph.c_str(), allocator);
65 | plottedGraphs.PushBack(graphValue, allocator);
66 | }
67 | widget.AddMember("plotted_graphs", plottedGraphs, allocator);
68 | }
69 | }
70 |
71 | // Use dock_widget's objectName() as the key
72 | rapidjson::Value key(dock_widget->objectName().toStdString().c_str(), allocator);
73 |
74 | // Add the widget object with the custom key to the main JSON object
75 | widgets.AddMember(key.Move(), widget, allocator);
76 | }
77 | return widgets;
78 | }
79 |
80 | void NexusDockManager::restore_widgets(Document const& j)
81 | {
82 | auto const& widgets = j["widgets"];
83 |
84 | // Store the exchange items in a vector for parallel processing
85 | int max_widget_id = -1;
86 | size_t widget_id = 0;
87 | for (rapidjson::Value::ConstMemberIterator itr = widgets.MemberBegin(); itr != widgets.MemberEnd(); ++itr) {
88 | //auto widget_id_str = itr->name.GetString();
89 | //auto widget_id = static_cast(std::stoi(widget_id_str));
90 | const rapidjson::Value& widget_json = itr->value; // Get the value
91 |
92 | size_t widget_type_uint = widget_json["widget_type"].GetUint64();
93 | WidgetType widget_type = static_cast(widget_type_uint);
94 |
95 | ads::CDockWidget* widget = nullptr;
96 | switch (widget_type) {
97 | case WidgetType::Editor:{
98 | widget = this->main_window->create_editor_widget();
99 | break;
100 | }
101 | case WidgetType::Asset: {
102 | auto asset_id = QString::fromStdString(widget_json["asset_id"].GetString());
103 | widget = this->main_window->create_asset_widget(asset_id);
104 |
105 | std::vector plots;
106 | if (widget_json.HasMember("plotted_graphs") && widget_json["plotted_graphs"].IsArray()) {
107 | const rapidjson::Value& plottedGraphsArray = widget_json["plotted_graphs"];
108 |
109 | for (rapidjson::SizeType i = 0; i < plottedGraphsArray.Size(); i++) {
110 | if (plottedGraphsArray[i].IsString()) {
111 | plots.push_back(plottedGraphsArray[i].GetString());
112 | }
113 | }
114 | }
115 |
116 | auto child = widget->widget();
117 | NexusAsset* asset_child = static_cast(child);
118 | asset_child->set_plotted_graphs(plots);
119 | break;
120 | }
121 | case WidgetType::NodeEditor:{
122 | auto strategy_id = QString::fromStdString(widget_json["strategy_id"].GetString());
123 | widget = this->main_window->create_node_editor_widget(strategy_id);
124 | break;
125 | }
126 | case WidgetType::Portfolio: {
127 | auto portfolio_id = QString::fromStdString(widget_json["portfolio_id"].GetString());
128 | widget = this->main_window->create_portfolio_widget(portfolio_id);
129 | break;
130 | }
131 | case WidgetType::Exchanges: {
132 | break;
133 | }
134 | case WidgetType::FileTree: {
135 | break;
136 | }
137 | }
138 | if (widget_id > max_widget_id) max_widget_id = widget_id;
139 |
140 | if (!widget) { continue; }
141 | widget->set_id(widget_id);
142 | widget->set_widget_type(widget_type);
143 | this->addDockWidget(ads::TopDockWidgetArea, widget);
144 | widget_id++;
145 | }
146 | ads::CDockWidget::counter = max_widget_id + 1;
147 | }
--------------------------------------------------------------------------------
/src/NexusNodeWidget.cpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "NexusNodeModel.h"
4 | #include "NexusNodeWidget.h"
5 | #include "ExchangeMap.h"
6 |
7 |
8 | //============================================================================
9 | ExchangeNode::ExchangeNode(
10 | HydraPtr hydra_,
11 | QWidget* parent_)
12 | : QWidget(parent_)
13 | , hydra(hydra_)
14 | , layout(nullptr)
15 | {
16 | setSizePolicy(QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Minimum);
17 |
18 | this->layout = new QHBoxLayout(this);
19 |
20 | this->exchange_id = new QComboBox();
21 | auto& exchanges = this->hydra->get_exchanges();
22 | auto exchange_ids = exchanges.get_exchange_ids();
23 | for (const auto& item : exchange_ids) {
24 | // Convert each std::string to QString before adding to the QComboBox
25 | exchange_id->addItem(QString::fromStdString(item));
26 | }
27 |
28 | QLabel* label = new QLabel("Exchange ID: ");
29 | layout->addWidget(label);
30 | layout->addWidget(exchange_id);
31 | this->setFixedSize(layout->sizeHint());
32 | }
33 |
34 |
35 | //============================================================================
36 | TradeExitNode::TradeExitNode(
37 | QWidget* parent_)
38 | : QWidget(parent_)
39 | , layout(nullptr)
40 | {
41 | setSizePolicy(QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Minimum);
42 |
43 | this->layout = new QVBoxLayout(this);
44 |
45 | QHBoxLayout* row_layout = new QHBoxLayout(this);
46 | this->exit_type = new QComboBox();
47 | for (const auto& item : agis_trade_exit_strings) {
48 | // Convert each std::string to QString before adding to the QComboBox
49 | this->exit_type->addItem(QString::fromStdString(item));
50 | }
51 | QLabel* label = new QLabel("Exit Type: ");
52 | row_layout->addWidget(label);
53 | row_layout->addWidget(this->exit_type);
54 | this->layout->addLayout(row_layout);
55 |
56 | row_layout = new QHBoxLayout(this);
57 | this->extra_param = new QLineEdit(this);
58 | label = new QLabel("Extra Param: ");
59 | row_layout->addWidget(label);
60 | row_layout->addWidget(this->extra_param);
61 | this->layout->addLayout(row_layout);
62 |
63 | this->setFixedSize(layout->sizeHint());
64 | }
65 |
66 |
67 | //============================================================================
68 | AssetLambdaNode::AssetLambdaNode(
69 | QWidget* parent_)
70 | : QWidget(parent_)
71 | , layout(nullptr)
72 | {
73 | setSizePolicy(QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Minimum);
74 |
75 | this->layout = new QVBoxLayout(this);
76 |
77 | // column type
78 | QHBoxLayout* name_layout = new QHBoxLayout(this);
79 | QLabel* name_label = new QLabel("Column: ");
80 | this->column = new QLineEdit(this);
81 | name_layout->addWidget(name_label);
82 | name_layout->addWidget(this->column);
83 | layout->addLayout(name_layout);
84 |
85 | // row value
86 | QHBoxLayout* row_layout = new QHBoxLayout(this);
87 | QLabel* row_label = new QLabel("Row: ");
88 | this->row = new QSpinBox(this);
89 | this->row->setMinimum(-1e6); // Set the minimum value to the minimum possible integer value (most negative value)
90 | this->row->setMaximum(0); // Set the maximum value to 0
91 | row_layout->addWidget(row_label);
92 | row_layout->addWidget(this->row);
93 | layout->addLayout(row_layout);
94 |
95 | // operation type
96 | QHBoxLayout* rowLayout = new QHBoxLayout(this);
97 | this->opperation = new QComboBox();
98 | for (const auto& item : agis_function_strings) {
99 | opperation->addItem(QString::fromStdString(item));
100 | }
101 | QLabel* label = new QLabel("Operation: ");
102 | rowLayout->addWidget(label);
103 | rowLayout->addWidget(this->opperation);
104 | layout->addLayout(rowLayout);
105 |
106 | // optional filter
107 | QHBoxLayout* filter_layout = new QHBoxLayout(this);
108 | QLabel* filter_label = new QLabel("Filter Range: ");
109 | this->filter = new QLineEdit(this);
110 | filter_layout->addWidget(filter_label);
111 | filter_layout->addWidget(this->filter);
112 | layout->addLayout(filter_layout);
113 |
114 |
115 | this->setFixedSize(layout->sizeHint());
116 | }
117 |
118 |
119 | //============================================================================
120 | ExchangeViewNode::ExchangeViewNode(
121 | QWidget* parent_)
122 | : QWidget(parent_)
123 | , layout(nullptr)
124 | {
125 | setSizePolicy(QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Minimum);
126 |
127 | this->layout = new QVBoxLayout(this);
128 |
129 | // operation type
130 | QHBoxLayout* row_layout = new QHBoxLayout(this);
131 | this->query_type = new QComboBox();
132 | for (const auto& item : agis_query_strings) {
133 | query_type->addItem(QString::fromStdString(item));
134 | }
135 | QLabel* label = new QLabel("Query Type: ");
136 | row_layout->addWidget(label);
137 | row_layout->addWidget(this->query_type);
138 | layout->addLayout(row_layout);
139 |
140 | // row value
141 | row_layout = new QHBoxLayout(this);
142 | QLabel* row_label = new QLabel("Count: ");
143 | this->N = new QSpinBox(this);
144 | this->N->setMinimum(1); // Set the minimum value to the minimum possible integer value (most negative value)
145 | this->N->setMaximum(1e5);
146 | row_layout->addWidget(row_label);
147 | row_layout->addWidget(this->N);
148 | layout->addLayout(row_layout);
149 |
150 | this->setFixedSize(layout->sizeHint());
151 | }
152 |
153 |
154 | //============================================================================
155 | void StrategyAllocationNode::update_ev_opp_param_state() {
156 | auto val = this->ev_opp_type->currentText().toStdString();
157 | bool isEnabled = (val == "CONDITIONAL_SPLIT" || val == "CONSTANT");
158 | this->ev_opp_param->setEnabled(isEnabled);
159 | }
160 |
161 |
162 | //============================================================================
163 | StrategyAllocationNode::StrategyAllocationNode(
164 | QWidget* parent_)
165 | : QWidget(parent_)
166 | , layout(nullptr)
167 | {
168 | setSizePolicy(QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Minimum);
169 |
170 | this->layout = new QVBoxLayout(this);
171 |
172 | // Allocation type
173 | QHBoxLayout* row_layout = new QHBoxLayout(this);
174 | this->alloc_type = new QComboBox();
175 | for (const auto& item : agis_strat_alloc_strings) {
176 | this->alloc_type->addItem(QString::fromStdString(item));
177 | }
178 | QLabel* label = new QLabel("Alloc Type: ");
179 | row_layout->addWidget(label);
180 | row_layout->addWidget(this->alloc_type);
181 | layout->addLayout(row_layout);
182 |
183 | // function to generate weights from the view
184 | row_layout = new QHBoxLayout(this);
185 | this->ev_opp_type = new QComboBox();
186 | for (const auto& item : exchange_view_opps) {
187 | this->ev_opp_type->addItem(QString::fromStdString(item));
188 | }
189 | connect(this->ev_opp_type, QOverload::of(&QComboBox::currentIndexChanged),
190 | this, &StrategyAllocationNode::update_ev_opp_param_state);
191 | label = new QLabel("Ev Opp Type: ");
192 | row_layout->addWidget(label);
193 | row_layout->addWidget(this->ev_opp_type);
194 | layout->addLayout(row_layout);
195 |
196 | // EV Opp Param
197 | row_layout = new QHBoxLayout(this);
198 | QLabel* row_label = new QLabel("EV Opp Param: ");
199 | this->ev_opp_param = new QLineEdit(this);
200 | QDoubleValidator* validator = new QDoubleValidator();
201 | this->ev_opp_param->setValidator(validator);
202 | this->ev_opp_param->setEnabled(false);
203 | row_layout->addWidget(row_label);
204 | row_layout->addWidget(this->ev_opp_param);
205 |
206 | layout->addLayout(row_layout);
207 |
208 | // row value
209 | row_layout = new QHBoxLayout(this);
210 | row_label = new QLabel("Epsilon: ");
211 | this->epsilon = new QLineEdit(this);
212 | validator = new QDoubleValidator(-1.0, 1.0, 3, epsilon); // 2 decimal places
213 | this->epsilon->setValidator(validator);
214 | this->epsilon->setText(".01");
215 | row_layout->addWidget(row_label);
216 | row_layout->addWidget(this->epsilon);
217 | layout->addLayout(row_layout);
218 |
219 | // target leverage
220 | row_layout = new QHBoxLayout(this);
221 | row_label = new QLabel("Target Lev: ");
222 | this->target_leverage = new QLineEdit(this);
223 | validator = new QDoubleValidator(-10.0, 10.0, 2, target_leverage); // 2 decimal places
224 | this->target_leverage->setValidator(validator);
225 | this->target_leverage->setText("1.00");
226 | row_layout->addWidget(row_label);
227 | row_layout->addWidget(this->target_leverage);
228 | layout->addLayout(row_layout);
229 |
230 | row_layout = new QHBoxLayout(this);
231 | this->clear_missing = new QCheckBox("Clear Missing: ");
232 | this->clear_missing->setChecked(true);
233 | layout->addWidget(this->clear_missing);
234 | layout->addLayout(row_layout);
235 |
236 |
237 | this->setFixedSize(layout->sizeHint());
238 | }
239 |
--------------------------------------------------------------------------------
/src/NexusWidgetFactory.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include "NexusWidgetFactory.h"
3 | #include "MainWindow.h"
4 |
5 |
6 | //============================================================================
7 | NexusWidgetFactory::NexusWidgetFactory()
8 | {
9 | }
10 |
11 |
12 | //============================================================================
13 | NexusWidgetFactory::~NexusWidgetFactory()
14 | {
15 | }
16 |
17 |
18 | //============================================================================
19 | ads::CDockWidget* NexusWidgetFactory::create_portfolios_widget(MainWindow* window)
20 | {
21 | PortfolioTree* w = new PortfolioTree(window, window->nexus_env.get_hydra());
22 | window->nexus_env.new_tree(w);
23 | window->portfolio_tree = w;
24 |
25 | // Signal that requests new strategy
26 | QObject::connect(
27 | w,
28 | SIGNAL(new_strategy_requested(QModelIndex, QString, QString, QString, AgisStrategyType)),
29 | window,
30 | SLOT(window->on_new_strategy_requested(QModelIndex, QString, QString, QString, AgisStrategyType))
31 | );
32 | // Signal that requests to remove a strategy
33 | QObject::connect(
34 | w,
35 | SIGNAL(strategy_remove_requested(QModelIndex, QString)),
36 | window,
37 | SLOT(window->on_strategy_remove_requested(QModelIndex, QString))
38 | );
39 | // Signal to request removal of portfolio
40 | QObject::connect(
41 | w,
42 | SIGNAL(remove_item_requested(QString, QModelIndex)),
43 | window,
44 | SLOT(window->on_remove_portfolio_request(QString, QModelIndex))
45 | );
46 | // Signal that requests new portfolio
47 | QObject::connect(
48 | w,
49 | SIGNAL(new_item_requested(QModelIndex, QString, QString)),
50 | window,
51 | SLOT(window->on_new_portfolio_request(QModelIndex, QString, QString))
52 | );
53 | // Signal that accepets new strategy
54 | QObject::connect(
55 | window,
56 | SIGNAL(window->new_strategy_accepeted(QModelIndex, QString)),
57 | w,
58 | SLOT(new_item_accepted(QModelIndex, QString))
59 | );
60 | // Signal to accept new portfolio
61 | QObject::connect(
62 | window,
63 | SIGNAL(window->new_portfolio_accepeted(QModelIndex, QString)),
64 | w,
65 | SLOT(new_item_accepted(QModelIndex, QString))
66 | );
67 | // Signal to accept removal of portfolio
68 | QObject::connect(
69 | window,
70 | SIGNAL(window->remove_portfolio_accepted(QModelIndex)),
71 | w,
72 | SLOT(remove_item_accepeted(QModelIndex))
73 | );
74 | // Signal that accepts to remove a strategy
75 | QObject::connect(
76 | window,
77 | SIGNAL(window->remove_strategy_accepted(QModelIndex)),
78 | w,
79 | SLOT(remove_item_accepeted(QModelIndex))
80 | );
81 | // Signal to create new node editor window
82 | QObject::connect(
83 | w,
84 | SIGNAL(strategy_double_clicked(QString)),
85 | window,
86 | SLOT(window->on_new_node_editor_request(QString))
87 | );
88 | // Signal to create new portfolio window
89 | QObject::connect(
90 | w,
91 | SIGNAL(portfolio_double_clicked(QString)),
92 | window,
93 | SLOT(window->on_new_portfolio_window_request(QString))
94 | );
95 | // Signal to toggle strategy
96 | QObject::connect(
97 | w,
98 | SIGNAL(strategy_toggled(QString, bool)),
99 | window,
100 | SLOT(window->on_strategy_toggle(QString, bool))
101 | );
102 |
103 | ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Portfolios")
104 | .arg(0));
105 | w->setFocusPolicy(Qt::NoFocus);
106 | DockWidget->setWidget(w);
107 | DockWidget->setIcon(svgIcon("./images/piechart.png"));
108 |
109 | DockWidget->set_widget_type(WidgetType::Portfolios);
110 | return DockWidget;
111 | }
112 |
113 |
114 | //============================================================================
115 | ads::CDockWidget* NexusWidgetFactory::create_exchanges_widget(MainWindow* window)
116 | {
117 | ExchangeTree* w = new ExchangeTree(window, &window->nexus_env);
118 | window->nexus_env.new_tree(w);
119 | window->exchange_tree = w;
120 |
121 | // Signal that requests new exchanges
122 | QObject::connect(
123 | w,
124 | SIGNAL(new_item_requested(QModelIndex, NewExchangePopup*)),
125 | window,
126 | SLOT(on_new_exchange_request(QModelIndex, NewExchangePopup*))
127 | );
128 |
129 | // Signal to accept new exchanges
130 | QObject::connect(
131 | window,
132 | SIGNAL(new_exchange_accepted(QModelIndex, QString)),
133 | w,
134 | SLOT(new_item_accepted(QModelIndex, QString))
135 | );
136 |
137 | // Signal to request removal of exchange
138 | QObject::connect(
139 | w,
140 | SIGNAL(remove_item_requested(QString, QModelIndex)),
141 | window,
142 | SLOT(on_remove_exchange_request(QString, QModelIndex))
143 | );
144 |
145 | // Signal to accept removal of exchange
146 | QObject::connect(
147 | window,
148 | SIGNAL(remove_exchange_accepted(QModelIndex)),
149 | w,
150 | SLOT(remove_item_accepted(QModelIndex))
151 | );
152 |
153 | // Signal to create a new asset window
154 | QObject::connect(
155 | w,
156 | SIGNAL(asset_double_click(QString)),
157 | window,
158 | SLOT(on_new_asset_window_request(QString))
159 | );
160 |
161 | ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Exchanges")
162 | .arg(0));
163 | DockWidget->setWidget(w);
164 | DockWidget->setIcon(svgIcon("./images/exchange.png"));
165 | DockWidget->set_widget_type(WidgetType::Exchanges);
166 |
167 | w->setFocusPolicy(Qt::NoFocus);
168 | return DockWidget;
169 | }
170 |
171 |
172 | //============================================================================
173 | ads::CDockWidget* NexusWidgetFactory::create_file_system_tree_widget(MainWindow* window)
174 | {
175 | QTreeView* w = new QTreeView();
176 | w->setFrameShape(QFrame::NoFrame);
177 | QFileSystemModel* m = new QFileSystemModel(w);
178 | m->setRootPath(QDir::currentPath());
179 | w->setModel(m);
180 | w->setRootIndex(m->index(QDir::currentPath()));
181 |
182 | ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Files")
183 | .arg(0));
184 | DockWidget->setWidget(w);
185 | DockWidget->set_widget_type(WidgetType::FileTree);
186 | DockWidget->setIcon(svgIcon(".images/folder_open.svg"));
187 | // We disable focus to test focus highlighting if the dock widget content
188 | // does not support focus
189 | w->setFocusPolicy(Qt::NoFocus);
190 |
191 | QObject::connect(
192 | w,
193 | &QAbstractItemView::doubleClicked,
194 | window,
195 | &MainWindow::onFileDoubleClicked
196 | );
197 | return DockWidget;
198 | }
--------------------------------------------------------------------------------
/src/QTerminal.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include
3 |
4 | #include "QTerminal.h"
5 |
6 |
7 | #if defined (Q_OS_WIN32)
8 | # include "QTerminalImpl.h"
9 | #else
10 | # include "unix/QUnixTerminalImpl.h"
11 | #endif
12 |
13 | QTerminal*
14 | QTerminal::create(QWidget* xparent)
15 | {
16 | #if defined (Q_OS_WIN32)
17 | return new QWinTerminalImpl(xparent);
18 | #else
19 | return new QUnixTerminalImpl(xparent);
20 | #endif
21 | }
22 |
23 | QList
24 | QTerminal::default_colors(void)
25 | {
26 | static QList colors;
27 |
28 | if (colors.isEmpty())
29 | {
30 | colors << QColor(0, 0, 0)
31 | << QColor(255, 255, 255)
32 | << QColor(192, 192, 192)
33 | << QColor(128, 128, 128);
34 | }
35 |
36 | return colors;
37 | }
38 |
39 | QStringList
40 | QTerminal::color_names(void)
41 | {
42 | static QStringList names;
43 |
44 | if (names.isEmpty())
45 | {
46 | names << QObject::tr("foreground")
47 | << QObject::tr("background")
48 | << QObject::tr("selection")
49 | << QObject::tr("cursor");
50 | }
51 |
52 | return names;
53 | }
54 |
55 | // slot for disabling the interrupt action when terminal loses focus
56 | void
57 | QTerminal::set_global_shortcuts(bool focus_out)
58 | {
59 | if (focus_out)
60 | {
61 | _interrupt_action->setShortcut(QKeySequence());
62 | _nop_action->setShortcut(QKeySequence());
63 | }
64 | else
65 | {
66 | _interrupt_action->setShortcut(
67 | QKeySequence(Qt::ControlModifier | Qt::Key_C));
68 | _nop_action->setShortcut(
69 | QKeySequence(Qt::ControlModifier | Qt::Key_D));
70 | }
71 | }
72 |
73 | // slot for the terminal's context menu
74 | void
75 | QTerminal::handleCustomContextMenuRequested(const QPoint& at)
76 | {
77 | QClipboard* cb = QApplication::clipboard();
78 | QString selected_text = selectedText();
79 | bool has_selected_text = !selected_text.isEmpty();
80 |
81 | _edit_action->setVisible(false);
82 |
83 | #if defined (Q_OS_WIN32)
84 | // include this when in windows because there is no filter for
85 | // detecting links and error messages yet
86 | if (has_selected_text)
87 | {
88 | QRegularExpression file("(?:[ \\t]+)(\\S+) at line (\\d+) column (?:\\d+)");
89 | /*
90 | int pos = file.indexIn(selected_text);
91 |
92 | if (pos > -1)
93 | {
94 | QString file_name = file.cap(1);
95 | QString line = file.cap(2);
96 |
97 | _edit_action->setVisible(true);
98 | _edit_action->setText(tr("Edit %1 at line %2")
99 | .arg(file_name).arg(line));
100 |
101 | QStringList data;
102 | data << file_name << line;
103 | _edit_action->setData(data);
104 | }
105 | */
106 | }
107 | #endif
108 |
109 | _paste_action->setEnabled(cb->text().length() > 0);
110 | _copy_action->setEnabled(has_selected_text);
111 | _run_selection_action->setEnabled(has_selected_text);
112 |
113 | // Get the actions of any hotspots the filters may have found
114 | QList actions = get_hotspot_actions(at);
115 | if (actions.length())
116 | _contextMenu->addSeparator();
117 | for (int i = 0; i < actions.length(); i++)
118 | _contextMenu->addAction(actions.at(i));
119 |
120 | // Finally, show the context menu
121 | _contextMenu->exec(mapToGlobal(at));
122 |
123 | // Cleaning up, remove actions of the hotspot
124 | for (int i = 0; i < actions.length(); i++)
125 | _contextMenu->removeAction(actions.at(i));
126 | }
127 |
128 | // slot for running the selected code
129 | void
130 | QTerminal::run_selection()
131 | {
132 | QStringList commands = selectedText().split(QRegularExpression("[\r\n]"),
133 | Qt::SkipEmptyParts);
134 | for (int i = 0; i < commands.size(); i++)
135 | emit execute_command_in_terminal_signal(commands.at(i));
136 |
137 | }
138 |
139 | // slot for edit files in error messages
140 | void
141 | QTerminal::edit_file()
142 | {
143 | QString file = _edit_action->data().toStringList().at(0);
144 | int line = _edit_action->data().toStringList().at(1).toInt();
145 |
146 | emit edit_mfile_request(file, line);
147 | }
148 |
149 | void
150 | QTerminal::notice_settings(const QSettings* settings)
151 | {
152 | // QSettings pointer is checked before emitting.
153 |
154 | // Set terminal font:
155 | QFont term_font = QFont();
156 | term_font.setStyleHint(QFont::TypeWriter);
157 | //QString default_font = settings->value(global_mono_font.key, global_mono_font.def).toString();
158 | //term_font.setFamily
159 | //(settings->value(cs_font.key, default_font).toString());
160 | term_font.setPointSize(settings->value("terminal/fontSize", 10).toInt());
161 | setTerminalFont(term_font);
162 |
163 | QFontMetrics metrics(term_font);
164 | setMinimumSize(metrics.maxWidth() * 16, metrics.height() * 3);
165 |
166 | QString cursorType
167 | = settings->value("terminal/cursorType", "ibeam").toString();
168 |
169 | bool cursorBlinking;
170 | if (settings->contains("cursor_blinking"))
171 | cursorBlinking = settings->value("cursor_blinking", true).toBool();
172 | else
173 | cursorBlinking = settings->value("terminal/cursorBlinking", true).toBool();
174 |
175 | if (cursorType == "ibeam")
176 | setCursorType(QTerminal::IBeamCursor, cursorBlinking);
177 | else if (cursorType == "block")
178 | setCursorType(QTerminal::BlockCursor, cursorBlinking);
179 | else if (cursorType == "underline")
180 | setCursorType(QTerminal::UnderlineCursor, cursorBlinking);
181 |
182 | bool cursorUseForegroundColor
183 | = settings->value("terminal/cursorUseForegroundColor", true).toBool();
184 |
185 | QList colors = default_colors();
186 |
187 | setForegroundColor
188 | (settings->value("terminal/color_f",
189 | QVariant(colors.at(0))).value());
190 |
191 | setBackgroundColor
192 | (settings->value("terminal/color_b",
193 | QVariant(colors.at(1))).value());
194 |
195 | setSelectionColor
196 | (settings->value("terminal/color_s",
197 | QVariant(colors.at(2))).value());
198 |
199 | setCursorColor
200 | (cursorUseForegroundColor,
201 | settings->value("terminal/color_c",
202 | QVariant(colors.at(3))).value());
203 | setScrollBufferSize(settings->value("terminal/history_buffer", 1000).toInt());
204 |
205 | // check whether Copy shortcut is Ctrl-C
206 | QKeySequence sc;
207 | sc = QKeySequence(settings->value("shortcuts/main_edit:copy").toString());
208 |
209 | // if sc is empty, shortcuts are not yet in the settings (take the default)
210 | if (sc.isEmpty()) // QKeySequence::Copy as second argument in
211 | sc = QKeySequence::Copy; // settings->value () does not work!
212 |
213 | // dis- or enable extra interrupt action
214 | bool extra_ir_action = (sc != QKeySequence(Qt::ControlModifier | Qt::Key_C));
215 | _interrupt_action->setEnabled(extra_ir_action);
216 | has_extra_interrupt(extra_ir_action);
217 |
218 | // check whether shortcut Ctrl-D is in use by the main-window
219 | bool ctrld = settings->value("shortcuts/main_ctrld", false).toBool();
220 | _nop_action->setEnabled(!ctrld);
221 | }
--------------------------------------------------------------------------------
/src/main.cpp:
--------------------------------------------------------------------------------
1 | #include "NexusPch.h"
2 | #include
3 |
4 | #include
5 | #include
6 |
7 | #include
8 | #include
9 |
10 | #include "MainWindow.h"
11 |
12 | using QtNodes::ConnectionStyle;
13 |
14 |
15 | //============================================================================
16 | static void setStyle()
17 | {
18 | ConnectionStyle::setConnectionStyle(
19 | R"(
20 | {
21 | "ConnectionStyle": {
22 | "UseDataDefinedColors": true
23 | }
24 | }
25 | )");
26 | }
27 |
28 | int main(int argc, char *argv[])
29 | {
30 | qDebug() << "INIT MAIN";
31 |
32 | WCHAR path[MAX_PATH] = { 0 };
33 | DWORD size = GetModuleFileName(NULL, path, MAX_PATH);
34 |
35 | if (size == 0) {
36 | std::cerr << "Failed to get the executable path." << std::endl;
37 | return 1;
38 | }
39 |
40 | // Convert WCHAR to std::string
41 | int utf8Size = WideCharToMultiByte(CP_UTF8, 0, path, -1, NULL, 0, NULL, NULL);
42 | if (utf8Size == 0) {
43 | std::cerr << "Failed to convert WCHAR to UTF-8." << std::endl;
44 | return 1;
45 | }
46 |
47 | std::string exePath(utf8Size, '\0');
48 | if (WideCharToMultiByte(CP_UTF8, 0, path, -1, &exePath[0], utf8Size, NULL, NULL) == 0) {
49 | std::cerr << "Failed to convert WCHAR to UTF-8." << std::endl;
50 | return 1;
51 | }
52 | // Create fs::path from std::wstring
53 | std::filesystem::path exe_directory(exePath);
54 |
55 | // Extract the directory path (excluding the executable name)
56 | exe_directory.remove_filename();
57 |
58 | setStyle();
59 |
60 | QCoreApplication::setApplicationName("Nexus");
61 | QCoreApplication::setOrganizationName("Agis Systems");
62 | QApplication::setStyle("Fusion");
63 |
64 | QApplication a(argc, argv);
65 | a.setQuitOnLastWindowClosed(true);
66 |
67 | QFile styleSheetFile("./styles/NexusTree.qss");
68 | styleSheetFile.open(QFile::ReadOnly);
69 | QString styleSheet = QLatin1String(styleSheetFile.readAll());
70 | a.setStyleSheet(styleSheet);
71 |
72 | MainWindow w;
73 | w.resize(1280, 720);
74 | w.show();
75 |
76 | qDebug() << "INIT MAIN COMPLETE\n EXECUTING QApplication";
77 | return a.exec();
78 | }
79 |
--------------------------------------------------------------------------------
/style/NexusTree.qss:
--------------------------------------------------------------------------------
1 | QTreeView {
2 | show-decoration-selected: 1;
3 | }
4 |
5 | QTreeView::item {
6 | border: 1px solid #d9d9d9;
7 | border-top-color: transparent;
8 | border-bottom-color: transparent;
9 | }
10 |
11 | QTreeView::item:hover {
12 | background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #e7effd, stop: 1 #cbdaf1);
13 | border: 1px solid #bfcde4;
14 | }
15 |
16 | QTreeView::item:selected {
17 | border: 1px solid #567dbc;
18 | }
19 |
20 | QTreeView::item:selected:active{
21 | background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #6ea1f1, stop: 1 #567dbc);
22 | }
23 |
24 | QTreeView::item:selected:!active {
25 | background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #6b9be8, stop: 1 #577fbf);
26 | }
27 |
28 | QTreeView::branch:has-siblings:!adjoins-item {
29 | border-image: url(./images/vline.png) 0;
30 | }
31 |
32 | QTreeView::branch:has-siblings:adjoins-item {
33 | border-image: url(./images/branch-more.png) 0;
34 | }
35 |
36 | QTreeView::branch:!has-children:!has-siblings:adjoins-item {
37 | border-image: url(./images/branch-end.png) 0;
38 | }
39 |
40 | QTreeView::branch:has-children:!has-siblings:closed,
41 | QTreeView::branch:closed:has-children:has-siblings {
42 | border-image: none;
43 | image: url(./images/branch-closed.png);
44 | }
45 |
46 | QTreeView::branch:open:has-children:!has-siblings,
47 | QTreeView::branch:open:has-children:has-siblings {
48 | border-image: none;
49 | image: url(./images/branch-open.png);
50 | }
--------------------------------------------------------------------------------
/ui/ExchangesPopup.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | ExchangesPopup
4 |
5 |
6 |
7 | 0
8 | 0
9 | 480
10 | 283
11 |
12 |
13 |
14 | Exchanges
15 |
16 |
17 | -
18 |
19 |
-
20 |
21 |
22 | Covariance Matrix Step
23 |
24 |
25 |
26 | -
27 |
28 |
29 | -
30 |
31 |
32 | Covariance Matrix Lookback
33 |
34 |
35 |
36 | -
37 |
38 |
39 | 1
40 |
41 |
42 |
43 | -
44 |
45 |
46 | Covariance Enabled
47 |
48 |
49 |
50 |
51 |
52 | -
53 |
54 |
55 | 6
56 |
57 |
-
58 |
59 |
60 | Save
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/ui/NewExchangePopup.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | NewExchangePopup
4 |
5 |
6 |
7 | 0
8 | 0
9 | 462
10 | 283
11 |
12 |
13 |
14 | New Exchange
15 |
16 |
17 | -
18 |
19 |
-
20 |
21 |
22 | -
23 |
24 |
25 | -
26 |
27 |
28 | false
29 |
30 |
-
31 |
32 | Day1
33 |
34 |
35 | -
36 |
37 | Hour4
38 |
39 |
40 | -
41 |
42 | Hour1
43 |
44 |
45 | -
46 |
47 | Min30
48 |
49 |
50 | -
51 |
52 | Min15
53 |
54 |
55 | -
56 |
57 | Min5
58 |
59 |
60 | -
61 |
62 | Min1
63 |
64 |
65 | -
66 |
67 | Second1
68 |
69 |
70 | -
71 |
72 | Tick
73 |
74 |
75 |
76 |
77 | -
78 |
79 |
80 |
81 |
82 |
83 |
84 | -
85 |
86 |
87 | Frequency:
88 |
89 |
90 |
91 | -
92 |
93 |
94 | Dt Format:
95 |
96 |
97 |
98 | -
99 |
100 |
101 | Beta Lookback
102 |
103 |
104 |
105 | -
106 |
107 |
108 | 0
109 |
110 |
111 |
112 | -
113 |
114 |
-
115 |
116 | %Y-%m-%d
117 |
118 |
119 | -
120 |
121 | %Y-%m-%d %H:%M:%S
122 |
123 |
124 | -
125 |
126 | %Y-%m-%d %H:%M:%S.%f
127 |
128 |
129 | -
130 |
131 | %d-%b-%Y
132 |
133 |
134 | -
135 |
136 | %Y-%m-%dT%H:%M:%S%z
137 |
138 |
139 |
140 |
141 | -
142 |
143 |
144 | Source:
145 |
146 |
147 |
148 | -
149 |
150 |
151 | Exchange ID:
152 |
153 |
154 |
155 | -
156 |
157 |
158 | Select Folder
159 |
160 |
161 |
162 | -
163 |
164 |
165 | Market Asset
166 |
167 |
168 |
169 | -
170 |
171 |
172 | 0
173 |
174 |
175 |
176 | -
177 |
178 |
179 | Vol Lookback
180 |
181 |
182 |
183 |
184 |
185 | -
186 |
187 |
188 | 6
189 |
190 |
-
191 |
192 |
193 | Submit
194 |
195 |
196 |
197 | -
198 |
199 |
200 | Cancel
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
--------------------------------------------------------------------------------
/ui/NewPortfolioPopup.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | NewPortfolioPopup
4 |
5 |
6 |
7 | 0
8 | 0
9 | 480
10 | 283
11 |
12 |
13 |
14 | New Portfolio
15 |
16 |
17 | -
18 |
19 |
-
20 |
21 |
22 | -
23 |
24 |
25 | Starting Cash
26 |
27 |
28 |
29 | -
30 |
31 |
32 | Portfolio ID
33 |
34 |
35 |
36 | -
37 |
38 |
39 |
40 |
41 | -
42 |
43 |
44 | 6
45 |
46 |
-
47 |
48 |
49 | Submit
50 |
51 |
52 |
53 | -
54 |
55 |
56 | Cancel
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/ui/NewStrategyPopup.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | NewStrategyPopup
4 |
5 |
6 |
7 | 0
8 | 0
9 | 480
10 | 283
11 |
12 |
13 |
14 | New Portfolio
15 |
16 |
17 | -
18 |
19 |
-
20 |
21 |
22 | Allocation
23 |
24 |
25 |
26 | -
27 |
28 |
29 | -
30 |
31 |
32 | Strategy ID
33 |
34 |
35 |
36 | -
37 |
38 |
39 | -
40 |
41 |
42 | Source Type
43 |
44 |
45 |
46 | -
47 |
48 |
49 | false
50 |
51 |
-
52 |
53 | FLOW
54 |
55 |
56 | -
57 |
58 | CPP
59 |
60 |
61 | -
62 |
63 | LUAJIT
64 |
65 |
66 |
67 |
68 |
69 |
70 | -
71 |
72 |
73 | 6
74 |
75 |
-
76 |
77 |
78 | Submit
79 |
80 |
81 |
82 | -
83 |
84 |
85 | Cancel
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/ui/NexusAsset.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | NexusAsset
4 |
5 |
6 |
7 | 0
8 | 0
9 | 714
10 | 600
11 |
12 |
13 |
14 | MainWindow
15 |
16 |
17 |
18 |
19 |
20 | 0
21 | 0
22 |
23 |
24 |
25 |
26 |
36 |
37 |
38 |
39 |
40 | NexusAssetPlot
41 | QWidget
42 |
43 | 1
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/ui/NexusBroker.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.3
2 |
3 | Rectangle {
4 | width: 200
5 | height: 100
6 | color: "red"
7 |
8 | Text {
9 | anchors.centerIn: parent
10 | text: "Hello, World!"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/ui/NexusBroker.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NexusBroker
6 |
7 |
8 |
9 | 0
10 | 0
11 | 800
12 | 600
13 |
14 |
15 |
16 | MainWindow
17 |
18 |
19 |
20 |
21 | 0
22 | 21
23 | 800
24 | 560
25 |
26 |
27 |
28 |
38 |
39 |
40 |
41 | 0
42 | 581
43 | 800
44 | 19
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/ui/NexusNodeEditor.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NexusNodeEditor
6 |
7 |
8 |
9 | 0
10 | 0
11 | 800
12 | 600
13 |
14 |
15 |
16 | MainWindow
17 |
18 |
19 |
20 |
21 | 0
22 | 21
23 | 800
24 | 560
25 |
26 |
27 |
28 |
38 |
39 |
40 |
41 | 0
42 | 581
43 | 800
44 | 19
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/ui/NexusPortfolio.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | NexusPortfolio
4 |
5 |
6 |
7 | 0
8 | 0
9 | 632
10 | 600
11 |
12 |
13 |
14 | MainWindow
15 |
16 |
17 |
18 |
19 |
20 |
21 | 0
22 | 0
23 | 100
24 | 30
25 |
26 |
27 |
28 |
29 | 0
30 | 0
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | toolBar
40 |
41 |
42 | TopToolBarArea
43 |
44 |
45 | false
46 |
47 |
48 |
49 | Export Portfolio
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | NexusPortfolioPlot
58 | QWidget
59 |
60 | 1
61 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/ui/NexusSettings.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | NexusSettings
4 |
5 |
6 |
7 | 0
8 | 0
9 | 431
10 | 218
11 |
12 |
13 |
14 | NexusSettings
15 |
16 |
17 |
18 |
19 | 0
20 | 0
21 | 411
22 | 221
23 |
24 |
25 |
26 |
27 |
28 | 40
29 | 20
30 | 331
31 | 181
32 |
33 |
34 |
35 | -
36 |
37 |
38 | select
39 |
40 |
41 |
42 | -
43 |
44 |
45 | -
46 |
47 |
48 | Agis Include Path
49 |
50 |
51 |
52 | -
53 |
54 |
55 | Agis DLL Path
56 |
57 |
58 |
59 | -
60 |
61 |
62 | -
63 |
64 |
65 | Agis PYD Path
66 |
67 |
68 |
69 | -
70 |
71 |
72 | select
73 |
74 |
75 |
76 | -
77 |
78 |
79 | -
80 |
81 |
82 | Save
83 |
84 |
85 |
86 | -
87 |
88 |
89 | select
90 |
91 |
92 |
93 | -
94 |
95 |
96 | Visual Studio
97 |
98 |
99 |
100 | -
101 |
102 |
103 | Visual Studio 17 2022
104 |
105 |
106 |
107 |
108 |
109 |
110 |
120 |
121 |
122 |
123 |
124 |
--------------------------------------------------------------------------------