arvo-client 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- arvo_client-0.1.0/.gitignore +12 -0
- arvo_client-0.1.0/PKG-INFO +115 -0
- arvo_client-0.1.0/README.md +96 -0
- arvo_client-0.1.0/pyproject.toml +37 -0
- arvo_client-0.1.0/src/arvo/__init__.py +468 -0
- arvo_client-0.1.0/src/arvo/common/__init__.py +0 -0
- arvo_client-0.1.0/src/arvo/common/v1/__init__.py +0 -0
- arvo_client-0.1.0/src/arvo/common/v1/models_pb2.py +38 -0
- arvo_client-0.1.0/src/arvo/common/v1/models_pb2_grpc.py +24 -0
- arvo_client-0.1.0/src/arvo/market/__init__.py +0 -0
- arvo_client-0.1.0/src/arvo/market/v1/__init__.py +0 -0
- arvo_client-0.1.0/src/arvo/market/v1/models_pb2.py +46 -0
- arvo_client-0.1.0/src/arvo/market/v1/models_pb2_grpc.py +24 -0
- arvo_client-0.1.0/src/arvo/market/v1/views_pb2.py +56 -0
- arvo_client-0.1.0/src/arvo/market/v1/views_pb2_grpc.py +24 -0
- arvo_client-0.1.0/src/arvo/platform/__init__.py +0 -0
- arvo_client-0.1.0/src/arvo/platform/v1/__init__.py +0 -0
- arvo_client-0.1.0/src/arvo/platform/v1/models_pb2.py +50 -0
- arvo_client-0.1.0/src/arvo/platform/v1/models_pb2_grpc.py +24 -0
- arvo_client-0.1.0/src/arvo/platform/v1/views_pb2.py +90 -0
- arvo_client-0.1.0/src/arvo/platform/v1/views_pb2_grpc.py +24 -0
- arvo_client-0.1.0/src/arvo/portfolio/__init__.py +0 -0
- arvo_client-0.1.0/src/arvo/portfolio/v1/__init__.py +0 -0
- arvo_client-0.1.0/src/arvo/portfolio/v1/models_pb2.py +36 -0
- arvo_client-0.1.0/src/arvo/portfolio/v1/models_pb2_grpc.py +24 -0
- arvo_client-0.1.0/src/arvo/portfolio/v1/views_pb2.py +48 -0
- arvo_client-0.1.0/src/arvo/portfolio/v1/views_pb2_grpc.py +24 -0
- arvo_client-0.1.0/src/arvo/py.typed +0 -0
- arvo_client-0.1.0/src/arvo/research/__init__.py +0 -0
- arvo_client-0.1.0/src/arvo/research/v1/__init__.py +0 -0
- arvo_client-0.1.0/src/arvo/research/v1/models_pb2.py +100 -0
- arvo_client-0.1.0/src/arvo/research/v1/models_pb2_grpc.py +24 -0
- arvo_client-0.1.0/src/arvo/research/v1/views_pb2.py +110 -0
- arvo_client-0.1.0/src/arvo/research/v1/views_pb2_grpc.py +24 -0
- arvo_client-0.1.0/src/arvo/services/__init__.py +0 -0
- arvo_client-0.1.0/src/arvo/services/v1/__init__.py +0 -0
- arvo_client-0.1.0/src/arvo/services/v1/accounts_pb2.py +39 -0
- arvo_client-0.1.0/src/arvo/services/v1/accounts_pb2_grpc.py +246 -0
- arvo_client-0.1.0/src/arvo/services/v1/market_pb2.py +39 -0
- arvo_client-0.1.0/src/arvo/services/v1/market_pb2_grpc.py +375 -0
- arvo_client-0.1.0/src/arvo/services/v1/platform_pb2.py +39 -0
- arvo_client-0.1.0/src/arvo/services/v1/platform_pb2_grpc.py +377 -0
- arvo_client-0.1.0/src/arvo/services/v1/portfolio_pb2.py +39 -0
- arvo_client-0.1.0/src/arvo/services/v1/portfolio_pb2_grpc.py +202 -0
- arvo_client-0.1.0/src/arvo/services/v1/research_pb2.py +43 -0
- arvo_client-0.1.0/src/arvo/services/v1/research_pb2_grpc.py +1372 -0
- arvo_client-0.1.0/src/arvo/services/v1/scripts_pb2.py +39 -0
- arvo_client-0.1.0/src/arvo/services/v1/scripts_pb2_grpc.py +357 -0
- arvo_client-0.1.0/src/arvo/services/v1/sessions_pb2.py +38 -0
- arvo_client-0.1.0/src/arvo/services/v1/sessions_pb2_grpc.py +369 -0
- arvo_client-0.1.0/src/arvo/session/__init__.py +0 -0
- arvo_client-0.1.0/src/arvo/session/v1/__init__.py +0 -0
- arvo_client-0.1.0/src/arvo/session/v1/models_pb2.py +44 -0
- arvo_client-0.1.0/src/arvo/session/v1/models_pb2_grpc.py +24 -0
- arvo_client-0.1.0/tests/test_client.py +224 -0
- arvo_client-0.1.0/uv.lock +740 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: arvo-client
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Arvo's engine from Python: a research client that reads findings and runs studies, and the generated stubs for every service.
|
|
5
|
+
Project-URL: Homepage, https://github.com/wjpin84/arvo-engine-api
|
|
6
|
+
Project-URL: Documentation, https://github.com/wjpin84/arvo-engine-api/blob/main/python/README.md
|
|
7
|
+
Project-URL: Changelog, https://github.com/wjpin84/arvo-engine-api/blob/main/CHANGELOG.md
|
|
8
|
+
License-Expression: Apache-2.0
|
|
9
|
+
Keywords: arvo,grpc,research,trading
|
|
10
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
13
|
+
Classifier: Typing :: Typed
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Requires-Dist: grpcio>=1.75.1
|
|
16
|
+
Requires-Dist: pandas>=2
|
|
17
|
+
Requires-Dist: protobuf>=6.31.1
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
|
|
20
|
+
# arvo (Python)
|
|
21
|
+
|
|
22
|
+
Arvo's research from Python: read research memory, run studies and
|
|
23
|
+
walk-forwards, and load the bar library into pandas. It talks to a running
|
|
24
|
+
`arvo-engine` through the research API of the
|
|
25
|
+
[contract](https://github.com/wjpin84/arvo-engine-api), which has no call
|
|
26
|
+
that fetches, touches a credential or trades.
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
pip install arvo-client # the package is `arvo-client`; the module is `arvo`
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
import arvo
|
|
34
|
+
|
|
35
|
+
engine = arvo.connect() # reads engine.json from the Arvo app data directory
|
|
36
|
+
found = engine.run_study("AAPL.RH", "sma_cross", author="script:first-look")
|
|
37
|
+
print(found.verdict) # read these three before any number
|
|
38
|
+
print(found.read_this_first)
|
|
39
|
+
for item in found.advice:
|
|
40
|
+
print(item.severity, item.finding, "->", item.action)
|
|
41
|
+
print(found.detail["out_of_sample"])
|
|
42
|
+
|
|
43
|
+
prices = engine.bars("AAPL.RH") # pandas DataFrame, read-only
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**`author` is required, and it matters.** A run is saved as that author's
|
|
47
|
+
finding and deflated against everything the author has run, so a script
|
|
48
|
+
trying configurations until one passes does not make it pass.
|
|
49
|
+
|
|
50
|
+
## What is in the package
|
|
51
|
+
|
|
52
|
+
Two layers, and you can use either.
|
|
53
|
+
|
|
54
|
+
**`arvo`**, the client: `connect()`, `Engine`, and plain dataclasses for what
|
|
55
|
+
comes back (`Finding`, `Advice`, `Strategy`, ...). This is what a script
|
|
56
|
+
wants. It reads only `engine.json`, so it holds only the research token: it
|
|
57
|
+
cannot reach the control tier that fetches data, holds credentials or trades,
|
|
58
|
+
and that is by construction rather than by policy.
|
|
59
|
+
|
|
60
|
+
**`arvo.<domain>.v1`**, the generated stubs: one module per proto package
|
|
61
|
+
(`arvo.research.v1.models_pb2`, `arvo.research.v1.views_pb2`, and so on) and
|
|
62
|
+
the services under `arvo.services.v1`. Use these for anything the client
|
|
63
|
+
does not wrap, or to reach the control tier from a front end you are writing
|
|
64
|
+
yourself, with the token from `control.json`:
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
import grpc, json, pathlib
|
|
68
|
+
from arvo.services.v1 import platform_pb2_grpc
|
|
69
|
+
from arvo.common.v1 import models_pb2 as common
|
|
70
|
+
|
|
71
|
+
root = arvo.default_root()
|
|
72
|
+
address = json.loads((root / "engine.json").read_text())["address"]
|
|
73
|
+
control = json.loads((root / "control.json").read_text())["token"]
|
|
74
|
+
platform = platform_pb2_grpc.PlatformStub(grpc.insecure_channel(address))
|
|
75
|
+
metadata = (("authorization", f"Bearer {control}"),)
|
|
76
|
+
for job in platform.ListJobs(common.Empty(), metadata=metadata).jobs:
|
|
77
|
+
print(job.id, job.label, job.next_run_at)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Every message and field carries the comment written on it in the protos;
|
|
81
|
+
`help(models_pb2.StudyView)` shows what your editor does.
|
|
82
|
+
|
|
83
|
+
## Setup for development
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
cd python && uv sync
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
The tests start a real `arvo-engine` over a temporary directory, so they
|
|
90
|
+
need one built. Point them at it:
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
ARVO_ENGINE=/path/to/arvo-engine uv run pytest
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Without it they are skipped, not failed.
|
|
97
|
+
|
|
98
|
+
## Regenerating the stubs
|
|
99
|
+
|
|
100
|
+
The modules under `src/arvo/*/v1` are generated from `../protos` and
|
|
101
|
+
committed. After a proto changes:
|
|
102
|
+
|
|
103
|
+
```sh
|
|
104
|
+
cd python && uv run python -m grpc_tools.protoc -I ../protos --python_out=src --grpc_python_out=src $(find ../protos -name '*.proto')
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Versioning
|
|
108
|
+
|
|
109
|
+
This package, `arvo-api` and `arvo-client` on crates.io share one version
|
|
110
|
+
with the protos they are generated from. The rules are in
|
|
111
|
+
[VERSIONING.md](https://github.com/wjpin84/arvo-engine-api/blob/main/VERSIONING.md).
|
|
112
|
+
|
|
113
|
+
## License
|
|
114
|
+
|
|
115
|
+
Apache-2.0.
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# arvo (Python)
|
|
2
|
+
|
|
3
|
+
Arvo's research from Python: read research memory, run studies and
|
|
4
|
+
walk-forwards, and load the bar library into pandas. It talks to a running
|
|
5
|
+
`arvo-engine` through the research API of the
|
|
6
|
+
[contract](https://github.com/wjpin84/arvo-engine-api), which has no call
|
|
7
|
+
that fetches, touches a credential or trades.
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
pip install arvo-client # the package is `arvo-client`; the module is `arvo`
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
import arvo
|
|
15
|
+
|
|
16
|
+
engine = arvo.connect() # reads engine.json from the Arvo app data directory
|
|
17
|
+
found = engine.run_study("AAPL.RH", "sma_cross", author="script:first-look")
|
|
18
|
+
print(found.verdict) # read these three before any number
|
|
19
|
+
print(found.read_this_first)
|
|
20
|
+
for item in found.advice:
|
|
21
|
+
print(item.severity, item.finding, "->", item.action)
|
|
22
|
+
print(found.detail["out_of_sample"])
|
|
23
|
+
|
|
24
|
+
prices = engine.bars("AAPL.RH") # pandas DataFrame, read-only
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**`author` is required, and it matters.** A run is saved as that author's
|
|
28
|
+
finding and deflated against everything the author has run, so a script
|
|
29
|
+
trying configurations until one passes does not make it pass.
|
|
30
|
+
|
|
31
|
+
## What is in the package
|
|
32
|
+
|
|
33
|
+
Two layers, and you can use either.
|
|
34
|
+
|
|
35
|
+
**`arvo`**, the client: `connect()`, `Engine`, and plain dataclasses for what
|
|
36
|
+
comes back (`Finding`, `Advice`, `Strategy`, ...). This is what a script
|
|
37
|
+
wants. It reads only `engine.json`, so it holds only the research token: it
|
|
38
|
+
cannot reach the control tier that fetches data, holds credentials or trades,
|
|
39
|
+
and that is by construction rather than by policy.
|
|
40
|
+
|
|
41
|
+
**`arvo.<domain>.v1`**, the generated stubs: one module per proto package
|
|
42
|
+
(`arvo.research.v1.models_pb2`, `arvo.research.v1.views_pb2`, and so on) and
|
|
43
|
+
the services under `arvo.services.v1`. Use these for anything the client
|
|
44
|
+
does not wrap, or to reach the control tier from a front end you are writing
|
|
45
|
+
yourself, with the token from `control.json`:
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
import grpc, json, pathlib
|
|
49
|
+
from arvo.services.v1 import platform_pb2_grpc
|
|
50
|
+
from arvo.common.v1 import models_pb2 as common
|
|
51
|
+
|
|
52
|
+
root = arvo.default_root()
|
|
53
|
+
address = json.loads((root / "engine.json").read_text())["address"]
|
|
54
|
+
control = json.loads((root / "control.json").read_text())["token"]
|
|
55
|
+
platform = platform_pb2_grpc.PlatformStub(grpc.insecure_channel(address))
|
|
56
|
+
metadata = (("authorization", f"Bearer {control}"),)
|
|
57
|
+
for job in platform.ListJobs(common.Empty(), metadata=metadata).jobs:
|
|
58
|
+
print(job.id, job.label, job.next_run_at)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Every message and field carries the comment written on it in the protos;
|
|
62
|
+
`help(models_pb2.StudyView)` shows what your editor does.
|
|
63
|
+
|
|
64
|
+
## Setup for development
|
|
65
|
+
|
|
66
|
+
```sh
|
|
67
|
+
cd python && uv sync
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The tests start a real `arvo-engine` over a temporary directory, so they
|
|
71
|
+
need one built. Point them at it:
|
|
72
|
+
|
|
73
|
+
```sh
|
|
74
|
+
ARVO_ENGINE=/path/to/arvo-engine uv run pytest
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Without it they are skipped, not failed.
|
|
78
|
+
|
|
79
|
+
## Regenerating the stubs
|
|
80
|
+
|
|
81
|
+
The modules under `src/arvo/*/v1` are generated from `../protos` and
|
|
82
|
+
committed. After a proto changes:
|
|
83
|
+
|
|
84
|
+
```sh
|
|
85
|
+
cd python && uv run python -m grpc_tools.protoc -I ../protos --python_out=src --grpc_python_out=src $(find ../protos -name '*.proto')
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Versioning
|
|
89
|
+
|
|
90
|
+
This package, `arvo-api` and `arvo-client` on crates.io share one version
|
|
91
|
+
with the protos they are generated from. The rules are in
|
|
92
|
+
[VERSIONING.md](https://github.com/wjpin84/arvo-engine-api/blob/main/VERSIONING.md).
|
|
93
|
+
|
|
94
|
+
## License
|
|
95
|
+
|
|
96
|
+
Apache-2.0.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
# `arvo` on PyPI belongs to someone else; the module is still `arvo`.
|
|
3
|
+
name = "arvo-client"
|
|
4
|
+
version = "0.1.0"
|
|
5
|
+
description = "Arvo's engine from Python: a research client that reads findings and runs studies, and the generated stubs for every service."
|
|
6
|
+
readme = "README.md"
|
|
7
|
+
license = "Apache-2.0"
|
|
8
|
+
keywords = ["arvo", "trading", "research", "grpc"]
|
|
9
|
+
classifiers = [
|
|
10
|
+
"Programming Language :: Python :: 3",
|
|
11
|
+
"License :: OSI Approved :: Apache Software License",
|
|
12
|
+
"Topic :: Office/Business :: Financial :: Investment",
|
|
13
|
+
"Typing :: Typed",
|
|
14
|
+
]
|
|
15
|
+
requires-python = ">=3.10"
|
|
16
|
+
dependencies = [
|
|
17
|
+
# The stubs under src/arvo/*/v1 were generated with grpcio-tools 1.75.1,
|
|
18
|
+
# which require at least these runtimes.
|
|
19
|
+
"grpcio>=1.75.1",
|
|
20
|
+
"protobuf>=6.31.1",
|
|
21
|
+
"pandas>=2",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
[project.urls]
|
|
25
|
+
Homepage = "https://github.com/wjpin84/arvo-engine-api"
|
|
26
|
+
Documentation = "https://github.com/wjpin84/arvo-engine-api/blob/main/python/README.md"
|
|
27
|
+
Changelog = "https://github.com/wjpin84/arvo-engine-api/blob/main/CHANGELOG.md"
|
|
28
|
+
|
|
29
|
+
[dependency-groups]
|
|
30
|
+
dev = ["pytest>=8", "grpcio-tools==1.75.1"]
|
|
31
|
+
|
|
32
|
+
[build-system]
|
|
33
|
+
requires = ["hatchling"]
|
|
34
|
+
build-backend = "hatchling.build"
|
|
35
|
+
|
|
36
|
+
[tool.hatch.build.targets.wheel]
|
|
37
|
+
packages = ["src/arvo"]
|