fm-sdk 0.0.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.
- fm_sdk-0.0.0/.gitignore +25 -0
- fm_sdk-0.0.0/PKG-INFO +156 -0
- fm_sdk-0.0.0/README.md +133 -0
- fm_sdk-0.0.0/fm/__init__.py +71 -0
- fm_sdk-0.0.0/fm/client.py +994 -0
- fm_sdk-0.0.0/fm/events.py +332 -0
- fm_sdk-0.0.0/fm/exceptions.py +41 -0
- fm_sdk-0.0.0/fm/order_utils.py +157 -0
- fm_sdk-0.0.0/fm/orderbook.py +195 -0
- fm_sdk-0.0.0/fm/trades.py +119 -0
- fm_sdk-0.0.0/fm/types.py +196 -0
- fm_sdk-0.0.0/pyproject.toml +41 -0
- fm_sdk-0.0.0/ticker.py +123 -0
fm_sdk-0.0.0/.gitignore
ADDED
fm_sdk-0.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fm-sdk
|
|
3
|
+
Version: 0.0.0
|
|
4
|
+
Summary: Python SDK for the Flexemarkets API
|
|
5
|
+
Project-URL: Homepage, https://github.com/flexemarkets/fm-sdk
|
|
6
|
+
Project-URL: Documentation, https://github.com/flexemarkets/fm-sdk#readme
|
|
7
|
+
Project-URL: Repository, https://github.com/flexemarkets/fm-sdk.git
|
|
8
|
+
Project-URL: Issues, https://github.com/flexemarkets/fm-sdk/issues
|
|
9
|
+
Author-email: Flexemarkets <support@flexemarkets.com>
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Requires-Python: >=3.11
|
|
20
|
+
Requires-Dist: httpx>=0.27
|
|
21
|
+
Requires-Dist: websockets>=13
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# fm-sdk-python
|
|
25
|
+
|
|
26
|
+
Python SDK for the [Flexemarkets](https://fm-data.herokuapp.com) API.
|
|
27
|
+
|
|
28
|
+
## Requirements
|
|
29
|
+
|
|
30
|
+
- Python 3.11+
|
|
31
|
+
|
|
32
|
+
## Install
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
python3.11 -m pip install .
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Or install dependencies directly:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
python3.11 -m pip install httpx websockets
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Configuration
|
|
45
|
+
|
|
46
|
+
The SDK loads credentials and endpoint from these sources (highest priority first):
|
|
47
|
+
|
|
48
|
+
1. Arguments passed to `Flexemarkets.connect()`
|
|
49
|
+
2. Files `~/.fm/credential` and `~/.fm/endpoint` (Java `.properties` format)
|
|
50
|
+
3. Environment variable `FM_API_URL` (defaults to `https://fm-data.herokuapp.com`)
|
|
51
|
+
|
|
52
|
+
### Credential file
|
|
53
|
+
|
|
54
|
+
Create `~/.fm/credential`:
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
account=myaccount
|
|
58
|
+
email=user@example.com
|
|
59
|
+
password=secret
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Or use a bearer token:
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
token=eyJhbGciOiJIUzI1NiJ9...
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Endpoint file
|
|
69
|
+
|
|
70
|
+
Create `~/.fm/endpoint`:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
endpoint=https://fm-data.herokuapp.com/api/marketplaces/123
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## SDK usage
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
from fm import Flexemarkets, OrderBooks, MarketplaceTrades
|
|
80
|
+
|
|
81
|
+
# Connect
|
|
82
|
+
fm = Flexemarkets.connect(
|
|
83
|
+
credential="~/.fm/credential",
|
|
84
|
+
endpoint="https://fm-data.herokuapp.com/api/marketplaces/123",
|
|
85
|
+
client_description="my-bot",
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
# REST API
|
|
89
|
+
marketplace_id = fm.endpoint_marketplace_id
|
|
90
|
+
markets = fm.markets(marketplace_id)
|
|
91
|
+
session = fm.session(marketplace_id)
|
|
92
|
+
holdings = fm.holdings(marketplace_id)
|
|
93
|
+
|
|
94
|
+
# Submit orders
|
|
95
|
+
order = fm.submit_limit(marketplace_id, market_id, "BUY", units=1, price=950)
|
|
96
|
+
fm.submit_cancel(marketplace_id, market_id, order.id)
|
|
97
|
+
|
|
98
|
+
# WebSocket events
|
|
99
|
+
import queue
|
|
100
|
+
|
|
101
|
+
q = queue.Queue(maxsize=1000)
|
|
102
|
+
fm.listen(marketplace_id, q)
|
|
103
|
+
|
|
104
|
+
books = OrderBooks(markets)
|
|
105
|
+
trades = MarketplaceTrades(markets)
|
|
106
|
+
|
|
107
|
+
while True:
|
|
108
|
+
event = q.get()
|
|
109
|
+
match event:
|
|
110
|
+
case list() as orders:
|
|
111
|
+
books.update(orders)
|
|
112
|
+
trades.update(orders)
|
|
113
|
+
case Session() as s:
|
|
114
|
+
print(s.state)
|
|
115
|
+
case Holding() as h:
|
|
116
|
+
print(h.cash)
|
|
117
|
+
|
|
118
|
+
fm.close()
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
The client also works as a context manager:
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
with Flexemarkets.connect(credential, endpoint, "my-bot") as fm:
|
|
125
|
+
...
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Applications
|
|
129
|
+
|
|
130
|
+
### ticker
|
|
131
|
+
|
|
132
|
+
Live terminal display of order book best bid/ask, spread, and recent trade prices.
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
python3.11 ticker.py -C ~/.fm/credential -E https://fm-data.herokuapp.com/api/marketplaces/123
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Options:
|
|
139
|
+
|
|
140
|
+
| Flag | Description |
|
|
141
|
+
|------|-------------|
|
|
142
|
+
| `-C`, `--credential` | Credential file path or bearer token |
|
|
143
|
+
| `-E`, `--endpoint` | Marketplace endpoint file path or URL |
|
|
144
|
+
|
|
145
|
+
Output:
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
fm-ticker OPEN
|
|
149
|
+
|
|
150
|
+
Symbol Bid Ask Spread Last trades
|
|
151
|
+
------ ------ ------ ------ -----------
|
|
152
|
+
AAPL $ 9.50 $10.50 $ 1.00 $9.50 $10.00
|
|
153
|
+
IBM $ 4.00 $ 5.00 $ 1.00 $4.50
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
The display refreshes on each order book update. Press `Ctrl-C` to stop.
|
fm_sdk-0.0.0/README.md
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# fm-sdk-python
|
|
2
|
+
|
|
3
|
+
Python SDK for the [Flexemarkets](https://fm-data.herokuapp.com) API.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- Python 3.11+
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
python3.11 -m pip install .
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Or install dependencies directly:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
python3.11 -m pip install httpx websockets
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Configuration
|
|
22
|
+
|
|
23
|
+
The SDK loads credentials and endpoint from these sources (highest priority first):
|
|
24
|
+
|
|
25
|
+
1. Arguments passed to `Flexemarkets.connect()`
|
|
26
|
+
2. Files `~/.fm/credential` and `~/.fm/endpoint` (Java `.properties` format)
|
|
27
|
+
3. Environment variable `FM_API_URL` (defaults to `https://fm-data.herokuapp.com`)
|
|
28
|
+
|
|
29
|
+
### Credential file
|
|
30
|
+
|
|
31
|
+
Create `~/.fm/credential`:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
account=myaccount
|
|
35
|
+
email=user@example.com
|
|
36
|
+
password=secret
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Or use a bearer token:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
token=eyJhbGciOiJIUzI1NiJ9...
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Endpoint file
|
|
46
|
+
|
|
47
|
+
Create `~/.fm/endpoint`:
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
endpoint=https://fm-data.herokuapp.com/api/marketplaces/123
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## SDK usage
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
from fm import Flexemarkets, OrderBooks, MarketplaceTrades
|
|
57
|
+
|
|
58
|
+
# Connect
|
|
59
|
+
fm = Flexemarkets.connect(
|
|
60
|
+
credential="~/.fm/credential",
|
|
61
|
+
endpoint="https://fm-data.herokuapp.com/api/marketplaces/123",
|
|
62
|
+
client_description="my-bot",
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
# REST API
|
|
66
|
+
marketplace_id = fm.endpoint_marketplace_id
|
|
67
|
+
markets = fm.markets(marketplace_id)
|
|
68
|
+
session = fm.session(marketplace_id)
|
|
69
|
+
holdings = fm.holdings(marketplace_id)
|
|
70
|
+
|
|
71
|
+
# Submit orders
|
|
72
|
+
order = fm.submit_limit(marketplace_id, market_id, "BUY", units=1, price=950)
|
|
73
|
+
fm.submit_cancel(marketplace_id, market_id, order.id)
|
|
74
|
+
|
|
75
|
+
# WebSocket events
|
|
76
|
+
import queue
|
|
77
|
+
|
|
78
|
+
q = queue.Queue(maxsize=1000)
|
|
79
|
+
fm.listen(marketplace_id, q)
|
|
80
|
+
|
|
81
|
+
books = OrderBooks(markets)
|
|
82
|
+
trades = MarketplaceTrades(markets)
|
|
83
|
+
|
|
84
|
+
while True:
|
|
85
|
+
event = q.get()
|
|
86
|
+
match event:
|
|
87
|
+
case list() as orders:
|
|
88
|
+
books.update(orders)
|
|
89
|
+
trades.update(orders)
|
|
90
|
+
case Session() as s:
|
|
91
|
+
print(s.state)
|
|
92
|
+
case Holding() as h:
|
|
93
|
+
print(h.cash)
|
|
94
|
+
|
|
95
|
+
fm.close()
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The client also works as a context manager:
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
with Flexemarkets.connect(credential, endpoint, "my-bot") as fm:
|
|
102
|
+
...
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Applications
|
|
106
|
+
|
|
107
|
+
### ticker
|
|
108
|
+
|
|
109
|
+
Live terminal display of order book best bid/ask, spread, and recent trade prices.
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
python3.11 ticker.py -C ~/.fm/credential -E https://fm-data.herokuapp.com/api/marketplaces/123
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Options:
|
|
116
|
+
|
|
117
|
+
| Flag | Description |
|
|
118
|
+
|------|-------------|
|
|
119
|
+
| `-C`, `--credential` | Credential file path or bearer token |
|
|
120
|
+
| `-E`, `--endpoint` | Marketplace endpoint file path or URL |
|
|
121
|
+
|
|
122
|
+
Output:
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
fm-ticker OPEN
|
|
126
|
+
|
|
127
|
+
Symbol Bid Ask Spread Last trades
|
|
128
|
+
------ ------ ------ ------ -----------
|
|
129
|
+
AAPL $ 9.50 $10.50 $ 1.00 $9.50 $10.00
|
|
130
|
+
IBM $ 4.00 $ 5.00 $ 1.00 $4.50
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The display refreshes on each order book update. Press `Ctrl-C` to stop.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""Flexemarkets Python SDK."""
|
|
2
|
+
|
|
3
|
+
from .client import Flexemarkets
|
|
4
|
+
from .events import EventListener, WsException, WsTransportError
|
|
5
|
+
from .exceptions import (
|
|
6
|
+
AccountNameConflictError,
|
|
7
|
+
AuthenticationError,
|
|
8
|
+
AuthorizationError,
|
|
9
|
+
ConfigurationError,
|
|
10
|
+
ConflictError,
|
|
11
|
+
ConnectionFailedError,
|
|
12
|
+
FlexemarketsError,
|
|
13
|
+
InvalidArgumentError,
|
|
14
|
+
PersonHasMarketplaceDataError,
|
|
15
|
+
)
|
|
16
|
+
from .orderbook import OrderBook, OrderBooks
|
|
17
|
+
from .trades import MarketplaceTrades, Trades
|
|
18
|
+
from .types import (
|
|
19
|
+
Account,
|
|
20
|
+
Allotment,
|
|
21
|
+
ApiRoot,
|
|
22
|
+
Assets,
|
|
23
|
+
ClientConnection,
|
|
24
|
+
Holding,
|
|
25
|
+
Market,
|
|
26
|
+
Marketplace,
|
|
27
|
+
Order,
|
|
28
|
+
Person,
|
|
29
|
+
Security,
|
|
30
|
+
Session,
|
|
31
|
+
Token,
|
|
32
|
+
Version,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
__all__ = [
|
|
36
|
+
"Flexemarkets",
|
|
37
|
+
# types
|
|
38
|
+
"Account",
|
|
39
|
+
"Allotment",
|
|
40
|
+
"ApiRoot",
|
|
41
|
+
"Assets",
|
|
42
|
+
"ClientConnection",
|
|
43
|
+
"Holding",
|
|
44
|
+
"Market",
|
|
45
|
+
"Marketplace",
|
|
46
|
+
"Order",
|
|
47
|
+
"Person",
|
|
48
|
+
"Security",
|
|
49
|
+
"Session",
|
|
50
|
+
"Token",
|
|
51
|
+
"Version",
|
|
52
|
+
# orderbook & trades
|
|
53
|
+
"OrderBook",
|
|
54
|
+
"OrderBooks",
|
|
55
|
+
"Trades",
|
|
56
|
+
"MarketplaceTrades",
|
|
57
|
+
# events
|
|
58
|
+
"EventListener",
|
|
59
|
+
"WsTransportError",
|
|
60
|
+
"WsException",
|
|
61
|
+
# exceptions
|
|
62
|
+
"FlexemarketsError",
|
|
63
|
+
"AuthenticationError",
|
|
64
|
+
"AuthorizationError",
|
|
65
|
+
"InvalidArgumentError",
|
|
66
|
+
"AccountNameConflictError",
|
|
67
|
+
"PersonHasMarketplaceDataError",
|
|
68
|
+
"ConflictError",
|
|
69
|
+
"ConnectionFailedError",
|
|
70
|
+
"ConfigurationError",
|
|
71
|
+
]
|