Skip to main content

arvo_api/generated/
arvo.market.v1.rs

1// This file is @generated by prost-build.
2#[derive(serde::Serialize, serde::Deserialize)]
3#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4pub struct Instrument {
5    /// e.g. "AAPL.RH"
6    #[prost(string, tag = "1")]
7    pub id: ::prost::alloc::string::String,
8    #[prost(string, tag = "2")]
9    pub interval: ::prost::alloc::string::String,
10    /// ISO dates, inclusive.
11    #[prost(string, tag = "3")]
12    pub from: ::prost::alloc::string::String,
13    #[prost(string, tag = "4")]
14    pub to: ::prost::alloc::string::String,
15}
16#[derive(serde::Serialize, serde::Deserialize)]
17#[derive(Clone, PartialEq, ::prost::Message)]
18pub struct Instruments {
19    #[prost(message, repeated, tag = "1")]
20    pub instruments: ::prost::alloc::vec::Vec<Instrument>,
21}
22/// One trade off the live price stream.
23///
24/// Typed rather than a View: there are hundreds a minute, and the four fields
25/// are the whole of it. Display only — a tick never becomes a bar, because the
26/// data library is fetched files with a content hash and that hash is what
27/// makes a stored verdict checkable.
28/// One price, as it arrived.
29///
30/// Separate from `QuoteView` and deliberately thinner: a tick carries only
31/// what moved. Which rows exist, and which of them you hold, is settled once
32/// by the `Watchlist` call — a stream that also decided the row set would make
33/// a socket blip look like a portfolio change.
34///
35/// `regular` is not decoration. Outside 09:30–16:00 the stream keeps sending,
36/// on thin volume and wide spreads, and a pre-market print rendered
37/// identically to a regular-session one is a worse answer than no price at
38/// all. A front end marks it; it does not hide it.
39#[derive(serde::Serialize, serde::Deserialize)]
40#[derive(Clone, PartialEq, ::prost::Message)]
41pub struct QuoteTick {
42    /// The bare ticker, matching `QuoteView.symbol`.
43    #[prost(string, tag = "1")]
44    pub symbol: ::prost::alloc::string::String,
45    #[prost(double, tag = "2")]
46    pub price: f64,
47    /// Move since the previous close, as a fraction.
48    #[prost(double, optional, tag = "3")]
49    pub change: ::core::option::Option<f64>,
50    /// Whether this print happened in the regular session.
51    #[prost(bool, tag = "4")]
52    pub regular: bool,
53}
54/// The control tier (ADR-0018 point 4). Behind the control token, never the
55/// research one: a script or an agent holding `engine.json` cannot reach it.
56#[derive(serde::Serialize, serde::Deserialize)]
57#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
58pub struct InstrumentSearch {
59    #[prost(string, tag = "1")]
60    pub query: ::prost::alloc::string::String,
61    /// The source to ask; the broker when absent.
62    #[prost(string, optional, tag = "2")]
63    pub source: ::core::option::Option<::prost::alloc::string::String>,
64}
65#[derive(serde::Serialize, serde::Deserialize)]
66#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
67pub struct FetchRequest {
68    #[prost(string, tag = "1")]
69    pub instrument: ::prost::alloc::string::String,
70    #[prost(string, tag = "2")]
71    pub interval: ::prost::alloc::string::String,
72    #[prost(uint32, optional, tag = "3")]
73    pub days: ::core::option::Option<u32>,
74    #[prost(string, optional, tag = "4")]
75    pub source: ::core::option::Option<::prost::alloc::string::String>,
76}
77#[derive(serde::Serialize, serde::Deserialize)]
78#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
79pub struct CompareRequest {
80    #[prost(string, tag = "1")]
81    pub instrument: ::prost::alloc::string::String,
82    #[prost(string, tag = "2")]
83    pub interval: ::prost::alloc::string::String,
84    #[prost(string, optional, tag = "3")]
85    pub first: ::core::option::Option<::prost::alloc::string::String>,
86    #[prost(string, optional, tag = "4")]
87    pub second: ::core::option::Option<::prost::alloc::string::String>,
88    #[prost(uint32, optional, tag = "5")]
89    pub days: ::core::option::Option<u32>,
90}
91/// A stored finding, summarised for the history list.
92/// Something wrong with the price series a result was produced from.
93///
94/// Shown beside the verdict rather than in a data screen nobody opens. A
95/// verdict is only as good as the bars under it, and a backtest cannot tell an
96/// unadjusted split from a crash — it will trade both and report a number
97/// either way.
98#[derive(serde::Serialize, serde::Deserialize)]
99#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
100pub struct DataFindingView {
101    /// `fault` for something that cannot legitimately be true of a price
102    /// series, `suspect` for something merely unusual.
103    #[prost(string, tag = "1")]
104    pub severity: ::prost::alloc::string::String,
105    #[prost(string, tag = "2")]
106    pub kind: ::prost::alloc::string::String,
107    #[prost(string, optional, tag = "3")]
108    pub at: ::core::option::Option<::prost::alloc::string::String>,
109    #[prost(string, tag = "4")]
110    pub detail: ::prost::alloc::string::String,
111}
112#[derive(serde::Serialize, serde::Deserialize)]
113#[derive(Clone, PartialEq, ::prost::Message)]
114pub struct DataLibraryView {
115    /// Shown so a user with no data knows where to put some.
116    #[prost(string, tag = "1")]
117    pub directory: ::prost::alloc::string::String,
118    #[prost(message, repeated, tag = "2")]
119    pub instruments: ::prost::alloc::vec::Vec<InstrumentView>,
120}
121/// What a fetch pulled in.
122#[derive(serde::Serialize, serde::Deserialize)]
123#[derive(Clone, PartialEq, ::prost::Message)]
124pub struct FetchView {
125    #[prost(string, tag = "1")]
126    pub instrument: ::prost::alloc::string::String,
127    /// Which source answered. Part of the result rather than assumed, now that
128    /// it is a choice: two vendors' copies of one ticker are two datasets.
129    #[prost(string, tag = "2")]
130    pub source: ::prost::alloc::string::String,
131    #[prost(string, tag = "3")]
132    pub interval: ::prost::alloc::string::String,
133    #[prost(uint32, tag = "4")]
134    pub bars: u32,
135    /// Gap-fill bars the server synthesised, which were dropped. Surfaced
136    /// rather than hidden: a series that is a quarter invented is one to know
137    /// about before drawing a conclusion from it.
138    #[prost(uint32, tag = "5")]
139    pub interpolated: u32,
140    #[prost(string, optional, tag = "6")]
141    pub from: ::core::option::Option<::prost::alloc::string::String>,
142    #[prost(string, optional, tag = "7")]
143    pub to: ::core::option::Option<::prost::alloc::string::String>,
144    #[prost(message, repeated, tag = "8")]
145    pub data_findings: ::prost::alloc::vec::Vec<DataFindingView>,
146    /// What changed against the copy already held, when there was one.
147    ///
148    /// A re-fetch that rewrites history stales every finding on the
149    /// instrument, correctly, via the content hash. This says *why* it
150    /// changed — a re-adjustment after a corporate action leaves the
151    /// underlying facts intact, a revision does not, and the two want
152    /// different responses.
153    #[prost(string, optional, tag = "9")]
154    pub revision: ::core::option::Option<::prost::alloc::string::String>,
155    /// True only when the change was a genuine disagreement about prices,
156    /// rather than a rescaling or extra coverage.
157    #[prost(bool, tag = "10")]
158    pub revised: bool,
159    /// Cash distributions stored alongside the bars.
160    ///
161    /// `None` means the source does not serve dividends at all, which is a
162    /// different fact from `Some(0)` — it looked, and the instrument paid none.
163    /// Collapsing the two would report "no dividends" for an instrument that
164    /// pays them, which is the direction the platform's excess-return bias
165    /// already leans.
166    #[prost(uint32, optional, tag = "11")]
167    pub dividends: ::core::option::Option<u32>,
168}
169#[derive(serde::Serialize, serde::Deserialize)]
170#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
171pub struct InstrumentView {
172    #[prost(string, tag = "1")]
173    pub id: ::prost::alloc::string::String,
174    /// `None` when the file exists but holds no usable bars.
175    #[prost(string, optional, tag = "2")]
176    pub from: ::core::option::Option<::prost::alloc::string::String>,
177    #[prost(string, optional, tag = "3")]
178    pub to: ::core::option::Option<::prost::alloc::string::String>,
179    #[prost(uint32, tag = "4")]
180    pub bars: u32,
181    /// Content hash of the data as it stands right now. The workbench compares
182    /// this against the hash recorded in a held result to tell whether that
183    /// result still describes the data on disk.
184    #[prost(string, optional, tag = "5")]
185    pub fingerprint: ::core::option::Option<::prost::alloc::string::String>,
186}
187/// One instrument the broker knows about.
188#[derive(serde::Serialize, serde::Deserialize)]
189#[derive(Clone, PartialEq, ::prost::Message)]
190pub struct MatchView {
191    /// The Arvo id it would be filed under, ready to fetch.
192    #[prost(string, tag = "1")]
193    pub instrument: ::prost::alloc::string::String,
194    #[prost(string, tag = "2")]
195    pub symbol: ::prost::alloc::string::String,
196    #[prost(string, tag = "3")]
197    pub name: ::prost::alloc::string::String,
198    #[prost(double, optional, tag = "4")]
199    pub price: ::core::option::Option<f64>,
200    /// Move since the previous close, as a fraction.
201    #[prost(double, optional, tag = "5")]
202    pub change: ::core::option::Option<f64>,
203    /// Whether the data library already holds this instrument.
204    #[prost(bool, tag = "6")]
205    pub held: bool,
206}
207/// One row of the watchlist: an instrument, priced now.
208///
209/// `held` is why this is not just a ticker — the same move means something
210/// different depending on whether you own the thing.
211///
212/// # What is deliberately not here
213///
214/// The position's value. A holding is valued from the statement or the last
215/// close on disk, never from the network (see `arvo_runtime::portfolio`), and
216/// putting that figure beside a live price would show two numbers priced two
217/// ways as though they agreed. The live price belongs to the watchlist; the
218/// valuation belongs to the portfolio, and they stay apart.
219#[derive(serde::Serialize, serde::Deserialize)]
220#[derive(Clone, PartialEq, ::prost::Message)]
221pub struct QuoteView {
222    #[prost(string, tag = "1")]
223    pub instrument: ::prost::alloc::string::String,
224    #[prost(string, tag = "2")]
225    pub symbol: ::prost::alloc::string::String,
226    /// `None` when the row exists but nothing has priced it yet — no broker
227    /// session for the snapshot, and no tick arrived for it yet. Optional
228    /// rather than zero because `$0.00` is a price, and a wrong one.
229    #[prost(double, optional, tag = "3")]
230    pub price: ::core::option::Option<f64>,
231    /// Move since the previous close, as a fraction. `None` when there is a
232    /// price but no previous close to measure it against.
233    #[prost(double, optional, tag = "4")]
234    pub change: ::core::option::Option<f64>,
235    #[prost(bool, tag = "5")]
236    pub held: bool,
237}
238/// What two sources say about the same instrument over the same window.
239///
240/// The verdict is \[`Self::summary`\] and the counts are beside it, deliberately:
241/// two vendors disagreeing is the normal case and most of the ways they
242/// disagree are not faults, so a bare count of differing bars is true, useless,
243/// and the kind of thing that gets a check switched off.
244#[derive(serde::Serialize, serde::Deserialize)]
245#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
246pub struct SourceComparisonView {
247    #[prost(string, tag = "1")]
248    pub symbol: ::prost::alloc::string::String,
249    #[prost(string, tag = "2")]
250    pub interval: ::prost::alloc::string::String,
251    #[prost(string, tag = "3")]
252    pub first: ::prost::alloc::string::String,
253    #[prost(string, tag = "4")]
254    pub second: ::prost::alloc::string::String,
255    #[prost(uint32, tag = "5")]
256    pub first_bars: u32,
257    #[prost(uint32, tag = "6")]
258    pub second_bars: u32,
259    /// Bar instants present in both.
260    #[prost(uint32, tag = "7")]
261    pub shared: u32,
262    /// Bars one has and the other does not. Independent of whether the shared
263    /// ones agree: two sources can cover different sessions and match perfectly
264    /// wherever they overlap.
265    #[prost(uint32, tag = "8")]
266    pub only_first: u32,
267    #[prost(uint32, tag = "9")]
268    pub only_second: u32,
269    #[prost(string, tag = "10")]
270    pub summary: ::prost::alloc::string::String,
271    /// True only for a genuine price disagreement — not for a rescaling, which
272    /// is an adjustment difference with neither side wrong, and not for a
273    /// coverage difference.
274    #[prost(bool, tag = "11")]
275    pub diverged: bool,
276    /// Why the two sources cannot be compared at face value, when they cannot.
277    ///
278    /// Neither axis it reports — how much of the tape a feed covers, and what
279    /// the prices are adjusted for — is visible in the bars, so this comes from
280    /// what each source declares rather than from any check. A thin feed and
281    /// the consolidated tape report the same prices; only the volumes differ,
282    /// and `agreement` deliberately does not compare volume.
283    #[prost(string, optional, tag = "12")]
284    pub basis_mismatch: ::core::option::Option<::prost::alloc::string::String>,
285}
286/// One source the app can fetch from.
287#[derive(serde::Serialize, serde::Deserialize)]
288#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
289pub struct SourceView {
290    #[prost(string, tag = "1")]
291    pub id: ::prost::alloc::string::String,
292    #[prost(string, tag = "2")]
293    pub label: ::prost::alloc::string::String,
294    /// The namespace instruments fetched here are filed under. Shown because
295    /// it is half of the instrument id a person will see afterwards.
296    #[prost(string, tag = "3")]
297    pub venue: ::prost::alloc::string::String,
298    /// Whether it can fetch right now. Always true for a source needing no
299    /// credential, which is the honest answer rather than a claim about a
300    /// session that does not exist.
301    #[prost(bool, tag = "4")]
302    pub connected: bool,
303    /// Whether this source has a browser sign-in, so the window does not offer
304    /// a button for something that cannot be done.
305    #[prost(bool, tag = "5")]
306    pub needs_sign_in: bool,
307    /// Whether this source is authorised by a key pair typed in once.
308    ///
309    /// Two flags rather than one enum, because a view is a flattened thing and
310    /// this one crosses to a wasm window that depends on `serde` and nothing
311    /// else. The single source of truth is `arvo_data::source::Credential`,
312    /// read once in `list_sources` through a match the compiler keeps
313    /// exhaustive — so the pair cannot drift from it, even though the pair by
314    /// itself could express nonsense.
315    #[prost(bool, tag = "6")]
316    pub needs_keys: bool,
317}
318/// A list, as a message.
319///
320/// An RPC returns one message, never a bare repeated field, so a call that
321/// answers with a list needs a name for the list. The wrapper is not
322/// ceremony: it is where a total, a cursor or a "when this was read" goes
323/// later, without renumbering what is already here.
324#[derive(serde::Serialize, serde::Deserialize)]
325#[derive(Clone, PartialEq, ::prost::Message)]
326pub struct SourcesView {
327    #[prost(message, repeated, tag = "1")]
328    pub sources: ::prost::alloc::vec::Vec<SourceView>,
329}
330/// What a search matched. A list, as a message; see `SourcesView`.
331#[derive(serde::Serialize, serde::Deserialize)]
332#[derive(Clone, PartialEq, ::prost::Message)]
333pub struct MatchesView {
334    #[prost(message, repeated, tag = "1")]
335    pub matches: ::prost::alloc::vec::Vec<MatchView>,
336}
337/// The watchlist, priced. A list, as a message; see `SourcesView`.
338#[derive(serde::Serialize, serde::Deserialize)]
339#[derive(Clone, PartialEq, ::prost::Message)]
340pub struct WatchlistView {
341    #[prost(message, repeated, tag = "1")]
342    pub rows: ::prost::alloc::vec::Vec<QuoteView>,
343}