Skip to content

Commit e694679

Browse files
committed
Add portfolio crate
1 parent ab354d9 commit e694679

File tree

5 files changed

+307
-0
lines changed

5 files changed

+307
-0
lines changed

nautilus_core/Cargo.lock

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

nautilus_core/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ members = [
1515
"model",
1616
"network",
1717
"persistence",
18+
"portfolio",
1819
"pyo3",
1920
"risk",
2021
"serialization",

nautilus_core/portfolio/Cargo.toml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
[package]
2+
name = "nautilus-portfolio"
3+
version.workspace = true
4+
edition.workspace = true
5+
authors.workspace = true
6+
description.workspace = true
7+
documentation.workspace = true
8+
9+
[lib]
10+
name = "nautilus_portfolio"
11+
crate-type = ["rlib", "cdylib"]
12+
13+
[dependencies]
14+
nautilus-analysis = { path = "../analysis" }
15+
nautilus-common = { path = "../common" }
16+
nautilus-core = { path = "../core" }
17+
nautilus-model = { path = "../model", features = ["stubs"] }
18+
anyhow = { workspace = true }
19+
derive_builder = { workspace = true }
20+
indexmap = { workspace = true }
21+
log = { workspace = true }
22+
pyo3 = { workspace = true, optional = true }
23+
pyo3-async-runtimes = { workspace = true, optional = true }
24+
rust_decimal = { workspace = true }
25+
rust_decimal_macros = { workspace = true }
26+
serde = { workspace = true }
27+
serde_json = { workspace = true }
28+
strum = { workspace = true }
29+
thiserror = { workspace = true }
30+
ustr = { workspace = true }
31+
32+
[dev-dependencies]
33+
criterion = { workspace = true }
34+
rstest = { workspace = true }
35+
36+
[features]
37+
default = ["python"]
38+
extension-module = [
39+
"pyo3/extension-module",
40+
"nautilus-analysis/extension-module",
41+
"nautilus-common/extension-module",
42+
"nautilus-core/extension-module",
43+
"nautilus-model/extension-module",
44+
]
45+
python = [
46+
"pyo3",
47+
"pyo3-async-runtimes",
48+
"nautilus-analysis/python",
49+
"nautilus-common/python",
50+
"nautilus-core/python",
51+
"nautilus-model/python",
52+
]

nautilus_core/portfolio/src/lib.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// -------------------------------------------------------------------------------------------------
2+
// Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
3+
// https://nautechsystems.io
4+
//
5+
// Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6+
// You may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
// -------------------------------------------------------------------------------------------------
15+
16+
//! Provides a generic `Portfolio` for all environments.
17+
18+
pub mod portfolio;
19+
20+
// Re-exports
21+
pub use portfolio::Portfolio;
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
// -------------------------------------------------------------------------------------------------
2+
// Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
3+
// https://nautechsystems.io
4+
//
5+
// Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6+
// You may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
// -------------------------------------------------------------------------------------------------
15+
16+
//! Provides a generic `Portfolio` for all environments.
17+
18+
// Under development
19+
#![allow(dead_code)]
20+
#![allow(unused_variables)]
21+
22+
use std::{
23+
cell::RefCell,
24+
collections::{HashMap, HashSet},
25+
rc::Rc,
26+
};
27+
28+
use nautilus_analysis::analyzer::PortfolioAnalyzer;
29+
use nautilus_common::{cache::Cache, clock::Clock, msgbus::MessageBus};
30+
use nautilus_model::{
31+
accounts::any::AccountAny,
32+
data::quote::QuoteTick,
33+
enums::OrderSide,
34+
events::{account::state::AccountState, order::OrderEventAny, position::PositionEvent},
35+
identifiers::{InstrumentId, Venue},
36+
instruments::any::InstrumentAny,
37+
position::Position,
38+
types::money::Money,
39+
};
40+
use rust_decimal::Decimal;
41+
42+
pub struct Portfolio {
43+
clock: Rc<RefCell<dyn Clock>>,
44+
cache: Rc<RefCell<Cache>>,
45+
msgbus: Rc<RefCell<MessageBus>>,
46+
accounts: HashMap<Venue, AccountAny>,
47+
analyzer: PortfolioAnalyzer,
48+
// venue: Option<Venue>, // Added for completeness but was meant to be a "temporary hack"
49+
unrealized_pnls: HashMap<InstrumentId, Money>,
50+
realized_pnls: HashMap<InstrumentId, Money>,
51+
net_positions: HashMap<InstrumentId, Decimal>,
52+
pending_calcs: HashSet<InstrumentId>,
53+
initialized: bool,
54+
}
55+
56+
impl Portfolio {
57+
// pub fn set_specific_venue(&mut self, venue: Venue) { // Lets try not to use this?
58+
// todo!()
59+
// }
60+
61+
// -- QUERIES ---------------------------------------------------------------------------------
62+
63+
#[must_use]
64+
pub const fn is_initialized(&self) -> bool {
65+
self.initialized
66+
}
67+
68+
#[must_use]
69+
pub const fn analyzer(&self) -> &PortfolioAnalyzer {
70+
&self.analyzer
71+
}
72+
73+
#[must_use]
74+
pub fn account(&self, venue: &Venue) -> Option<&AccountAny> {
75+
self.accounts.get(venue)
76+
}
77+
78+
#[must_use]
79+
pub fn balances_locked(&self, venue: &Venue) -> HashMap<Venue, Money> {
80+
todo!()
81+
}
82+
83+
#[must_use]
84+
pub fn margins_init(&self, venue: &Venue) -> HashMap<Venue, Money> {
85+
todo!()
86+
}
87+
88+
#[must_use]
89+
pub fn margins_maint(&self, venue: &Venue) -> HashMap<Venue, Money> {
90+
todo!()
91+
}
92+
93+
#[must_use]
94+
pub fn unrealized_pnls(&self, venue: &Venue) -> HashMap<Venue, Money> {
95+
todo!()
96+
}
97+
98+
#[must_use]
99+
pub fn realized_pnls(&self, venue: &Venue) -> HashMap<Venue, Money> {
100+
todo!()
101+
}
102+
103+
#[must_use]
104+
pub fn net_exposures(&self, venue: &Venue) -> HashMap<Venue, Money> {
105+
todo!()
106+
}
107+
108+
#[must_use]
109+
pub fn unrealized_pnl(&self, instrument_id: &InstrumentId) -> Option<Money> {
110+
todo!()
111+
}
112+
113+
#[must_use]
114+
pub fn realized_pnl(&self, instrument_id: &InstrumentId) -> Option<Money> {
115+
todo!()
116+
}
117+
118+
#[must_use]
119+
pub fn net_exposure(&self, instrument_id: &InstrumentId) -> Option<Money> {
120+
todo!()
121+
}
122+
123+
#[must_use]
124+
pub fn net_position(&self, instrument_id: &InstrumentId) -> Option<Decimal> {
125+
todo!()
126+
}
127+
128+
#[must_use]
129+
pub fn is_net_long(&self, instrument_id: &InstrumentId) -> bool {
130+
todo!()
131+
}
132+
133+
#[must_use]
134+
pub fn is_net_short(&self, instrument_id: &InstrumentId) -> bool {
135+
todo!()
136+
}
137+
138+
#[must_use]
139+
pub fn is_flat(&self, instrument_id: &InstrumentId) -> bool {
140+
todo!()
141+
}
142+
143+
#[must_use]
144+
pub fn is_completely_flat(&self) -> bool {
145+
todo!()
146+
}
147+
148+
// -- COMMANDS --------------------------------------------------------------------------------
149+
150+
pub fn initialize_orders(&mut self) {
151+
todo!()
152+
}
153+
154+
pub fn initialize_positions(&mut self) {
155+
todo!()
156+
}
157+
158+
pub fn update_quote_tick(&mut self, quote: &QuoteTick) {
159+
todo!()
160+
}
161+
162+
pub fn update_account(&mut self, event: &AccountState) {
163+
todo!()
164+
}
165+
166+
pub fn update_order(&mut self, event: &OrderEventAny) {
167+
todo!()
168+
}
169+
170+
pub fn update_position(&mut self, event: &PositionEvent) {
171+
todo!()
172+
}
173+
174+
// -- INTERNAL --------------------------------------------------------------------------------
175+
176+
// fn net_position(&self, instrument_id: &InstrumentId) -> Decimal { // Same as above?
177+
// todo!()
178+
// }
179+
180+
fn update_net_position(
181+
&self,
182+
instrument_id: &InstrumentId,
183+
positions_open: Vec<&Position>,
184+
) -> Decimal {
185+
todo!()
186+
}
187+
188+
fn calculate_unrealized_pnl(&self, instrument_id: &InstrumentId) -> Money {
189+
todo!()
190+
}
191+
192+
fn calculate_realized_pnl(&self, instrument_id: &InstrumentId) -> Money {
193+
todo!()
194+
}
195+
196+
fn get_last_price(&self, position: &Position) -> Money {
197+
todo!()
198+
}
199+
200+
fn calculate_xrate_to_base(
201+
&self,
202+
account: &AccountAny,
203+
instrument: &InstrumentAny,
204+
side: OrderSide,
205+
) -> f64 {
206+
todo!()
207+
}
208+
}

0 commit comments

Comments
 (0)