mftik 0.0.3__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.
- mftik-0.0.3/.gitignore +41 -0
- mftik-0.0.3/PKG-INFO +92 -0
- mftik-0.0.3/README.md +71 -0
- mftik-0.0.3/pyproject.toml +52 -0
- mftik-0.0.3/src/mftik/__init__.py +10 -0
- mftik-0.0.3/src/mftik/broker/__init__.py +22 -0
- mftik-0.0.3/src/mftik/broker/client.py +554 -0
- mftik-0.0.3/src/mftik/broker/config.py +37 -0
- mftik-0.0.3/src/mftik/broker/errors.py +21 -0
- mftik-0.0.3/src/mftik/broker/request.py +46 -0
- mftik-0.0.3/src/mftik/broker/stream.py +87 -0
- mftik-0.0.3/src/mftik/cli/__init__.py +16 -0
- mftik-0.0.3/src/mftik/cli/app.py +340 -0
- mftik-0.0.3/src/mftik/cli/check.py +92 -0
- mftik-0.0.3/src/mftik/cli/client.py +277 -0
- mftik-0.0.3/src/mftik/cli/config.py +190 -0
- mftik-0.0.3/src/mftik/cli/connect.py +192 -0
- mftik-0.0.3/src/mftik/cli/exits.py +16 -0
- mftik-0.0.3/src/mftik/cli/init.py +208 -0
- mftik-0.0.3/src/mftik/cli/node.py +108 -0
- mftik-0.0.3/src/mftik/cli/output.py +41 -0
- mftik-0.0.3/src/mftik/cli/profiles.py +47 -0
- mftik-0.0.3/src/mftik/cli/push.py +51 -0
- mftik-0.0.3/src/mftik/cli/run.py +101 -0
- mftik-0.0.3/src/mftik/cli/sessions.py +75 -0
- mftik-0.0.3/src/mftik/cli/templates/Caddyfile +24 -0
- mftik-0.0.3/src/mftik/cli/templates/docker-compose.yml +206 -0
- mftik-0.0.3/src/mftik/cli/templates/env +53 -0
- mftik-0.0.3/src/mftik/cli/tree.py +71 -0
- mftik-0.0.3/src/mftik/exchange/__init__.py +284 -0
- mftik-0.0.3/src/mftik/exchange/base.py +68 -0
- mftik-0.0.3/src/mftik/exchange/binance/__init__.py +1 -0
- mftik-0.0.3/src/mftik/exchange/binance/feed.py +181 -0
- mftik-0.0.3/src/mftik/exchange/binance/future/__init__.py +150 -0
- mftik-0.0.3/src/mftik/exchange/binance/future/client.py +422 -0
- mftik-0.0.3/src/mftik/exchange/binance/future/feed.py +294 -0
- mftik-0.0.3/src/mftik/exchange/binance/future/methods.py +133 -0
- mftik-0.0.3/src/mftik/exchange/binance/future/models.py +1040 -0
- mftik-0.0.3/src/mftik/exchange/binance/future/private.py +519 -0
- mftik-0.0.3/src/mftik/exchange/binance/future/protocol.py +124 -0
- mftik-0.0.3/src/mftik/exchange/binance/future/public.py +419 -0
- mftik-0.0.3/src/mftik/exchange/binance/future/rest.py +289 -0
- mftik-0.0.3/src/mftik/exchange/binance/future/streams.py +221 -0
- mftik-0.0.3/src/mftik/exchange/binance/future/user.py +249 -0
- mftik-0.0.3/src/mftik/exchange/binance/models.py +126 -0
- mftik-0.0.3/src/mftik/exchange/binance/protocol.py +455 -0
- mftik-0.0.3/src/mftik/exchange/binance/rest.py +172 -0
- mftik-0.0.3/src/mftik/exchange/binance/socket.py +407 -0
- mftik-0.0.3/src/mftik/exchange/binance/spot/__init__.py +137 -0
- mftik-0.0.3/src/mftik/exchange/binance/spot/client.py +531 -0
- mftik-0.0.3/src/mftik/exchange/binance/spot/feed.py +157 -0
- mftik-0.0.3/src/mftik/exchange/binance/spot/methods.py +139 -0
- mftik-0.0.3/src/mftik/exchange/binance/spot/models.py +820 -0
- mftik-0.0.3/src/mftik/exchange/binance/spot/private.py +383 -0
- mftik-0.0.3/src/mftik/exchange/binance/spot/protocol.py +68 -0
- mftik-0.0.3/src/mftik/exchange/binance/spot/public.py +360 -0
- mftik-0.0.3/src/mftik/exchange/binance/spot/rest.py +148 -0
- mftik-0.0.3/src/mftik/exchange/binance/spot/socket.py +12 -0
- mftik-0.0.3/src/mftik/exchange/binance/spot/streams.py +111 -0
- mftik-0.0.3/src/mftik/exchange/bybit/__init__.py +152 -0
- mftik-0.0.3/src/mftik/exchange/bybit/account.py +269 -0
- mftik-0.0.3/src/mftik/exchange/bybit/channels.py +248 -0
- mftik-0.0.3/src/mftik/exchange/bybit/feed.py +471 -0
- mftik-0.0.3/src/mftik/exchange/bybit/models.py +790 -0
- mftik-0.0.3/src/mftik/exchange/bybit/private.py +621 -0
- mftik-0.0.3/src/mftik/exchange/bybit/protocol.py +609 -0
- mftik-0.0.3/src/mftik/exchange/bybit/public.py +392 -0
- mftik-0.0.3/src/mftik/exchange/bybit/rest.py +611 -0
- mftik-0.0.3/src/mftik/exchange/bybit/socket.py +459 -0
- mftik-0.0.3/src/mftik/exchange/bybit/trade.py +295 -0
- mftik-0.0.3/src/mftik/exchange/errors.py +21 -0
- mftik-0.0.3/src/mftik/exchange/gate/__init__.py +1 -0
- mftik-0.0.3/src/mftik/exchange/gate/spot/__init__.py +83 -0
- mftik-0.0.3/src/mftik/exchange/gate/spot/channels.py +103 -0
- mftik-0.0.3/src/mftik/exchange/gate/spot/client.py +744 -0
- mftik-0.0.3/src/mftik/exchange/gate/spot/models.py +455 -0
- mftik-0.0.3/src/mftik/exchange/gate/spot/private.py +365 -0
- mftik-0.0.3/src/mftik/exchange/gate/spot/protocol.py +288 -0
- mftik-0.0.3/src/mftik/exchange/gate/spot/public.py +317 -0
- mftik-0.0.3/src/mftik/exchange/gate/spot/rest.py +473 -0
- mftik-0.0.3/src/mftik/exchange/intervals.py +87 -0
- mftik-0.0.3/src/mftik/exchange/models.py +590 -0
- mftik-0.0.3/src/mftik/exchange/oms.py +118 -0
- mftik-0.0.3/src/mftik/exchange/paper/__init__.py +12 -0
- mftik-0.0.3/src/mftik/exchange/paper/engine.py +1015 -0
- mftik-0.0.3/src/mftik/exchange/paper/private.py +135 -0
- mftik-0.0.3/src/mftik/exchange/paper/public.py +83 -0
- mftik-0.0.3/src/mftik/exchange/paper/remote.py +229 -0
- mftik-0.0.3/src/mftik/exchange/paper/remote_public.py +124 -0
- mftik-0.0.3/src/mftik/exchange/stream.py +63 -0
- mftik-0.0.3/src/mftik/exchange/symbols.py +97 -0
- mftik-0.0.3/src/mftik/exchange/tickers.py +213 -0
- mftik-0.0.3/src/mftik/exchange/venues.py +283 -0
- mftik-0.0.3/src/mftik/liveness.py +94 -0
- mftik-0.0.3/src/mftik/protocol/__init__.py +482 -0
- mftik-0.0.3/src/mftik/protocol/envelope.py +69 -0
- mftik-0.0.3/src/mftik/protocol/messages.py +1223 -0
- mftik-0.0.3/src/mftik/protocol/query_codes.py +166 -0
- mftik-0.0.3/src/mftik/protocol/reject_codes.py +193 -0
- mftik-0.0.3/src/mftik/protocol/session_log.py +112 -0
- mftik-0.0.3/src/mftik/protocol/strategy_catalog.py +257 -0
- mftik-0.0.3/src/mftik/protocol/strategy_yml.py +190 -0
- mftik-0.0.3/src/mftik/protocol/topics.py +229 -0
- mftik-0.0.3/src/mftik/py.typed +1 -0
- mftik-0.0.3/src/mftik/registry/__init__.py +48 -0
- mftik-0.0.3/src/mftik/registry/digest.py +27 -0
- mftik-0.0.3/src/mftik/registry/errors.py +18 -0
- mftik-0.0.3/src/mftik/registry/files.py +82 -0
- mftik-0.0.3/src/mftik/registry/gate.py +309 -0
- mftik-0.0.3/src/mftik/registry/inspect.py +74 -0
- mftik-0.0.3/src/mftik/registry/load.py +143 -0
- mftik-0.0.3/src/mftik/registry/protocol.py +55 -0
- mftik-0.0.3/src/mftik/registry/qualify.py +26 -0
- mftik-0.0.3/src/mftik/registry/store.py +396 -0
- mftik-0.0.3/src/mftik/registry/sync.py +236 -0
- mftik-0.0.3/src/mftik/runtime.py +37 -0
- mftik-0.0.3/src/mftik/strategy/__init__.py +27 -0
- mftik-0.0.3/src/mftik/strategy/base.py +513 -0
- mftik-0.0.3/src/mftik/strategy/client_order_id.py +120 -0
- mftik-0.0.3/src/mftik/strategy/eventlog.py +491 -0
- mftik-0.0.3/src/mftik/strategy/ledger.py +261 -0
- mftik-0.0.3/src/mftik/strategy/mds.py +283 -0
- mftik-0.0.3/src/mftik/strategy/oms.py +381 -0
- mftik-0.0.3/src/mftik/strategy/session.py +47 -0
- mftik-0.0.3/src/mftik/strategy/symbols.py +144 -0
- mftik-0.0.3/src/mftik/strategy/tape.py +255 -0
- mftik-0.0.3/src/mftik/strategy/timer.py +226 -0
- mftik-0.0.3/src/mftik/symbols/__init__.py +5 -0
- mftik-0.0.3/src/mftik/symbols/client.py +185 -0
- mftik-0.0.3/tests/binance_future_stub.py +231 -0
- mftik-0.0.3/tests/binance_stub.py +263 -0
- mftik-0.0.3/tests/bybit_stub.py +222 -0
- mftik-0.0.3/tests/conftest.py +126 -0
- mftik-0.0.3/tests/gate_stub.py +149 -0
- mftik-0.0.3/tests/test_binance_future_client.py +368 -0
- mftik-0.0.3/tests/test_binance_future_feed.py +169 -0
- mftik-0.0.3/tests/test_binance_future_models.py +474 -0
- mftik-0.0.3/tests/test_binance_future_private.py +589 -0
- mftik-0.0.3/tests/test_binance_future_public.py +317 -0
- mftik-0.0.3/tests/test_binance_future_rest.py +206 -0
- mftik-0.0.3/tests/test_binance_future_streams.py +130 -0
- mftik-0.0.3/tests/test_binance_spot_client.py +585 -0
- mftik-0.0.3/tests/test_binance_spot_models.py +706 -0
- mftik-0.0.3/tests/test_binance_spot_private.py +515 -0
- mftik-0.0.3/tests/test_binance_spot_protocol.py +301 -0
- mftik-0.0.3/tests/test_binance_spot_public.py +395 -0
- mftik-0.0.3/tests/test_binance_spot_rest.py +262 -0
- mftik-0.0.3/tests/test_broker.py +272 -0
- mftik-0.0.3/tests/test_bybit_models.py +508 -0
- mftik-0.0.3/tests/test_bybit_private.py +693 -0
- mftik-0.0.3/tests/test_bybit_private_stream.py +308 -0
- mftik-0.0.3/tests/test_bybit_protocol.py +271 -0
- mftik-0.0.3/tests/test_bybit_public.py +441 -0
- mftik-0.0.3/tests/test_bybit_rest.py +359 -0
- mftik-0.0.3/tests/test_bybit_trade.py +170 -0
- mftik-0.0.3/tests/test_cli_app.py +123 -0
- mftik-0.0.3/tests/test_cli_check.py +197 -0
- mftik-0.0.3/tests/test_cli_client.py +260 -0
- mftik-0.0.3/tests/test_cli_config.py +213 -0
- mftik-0.0.3/tests/test_cli_connect.py +385 -0
- mftik-0.0.3/tests/test_cli_init.py +246 -0
- mftik-0.0.3/tests/test_cli_node.py +222 -0
- mftik-0.0.3/tests/test_cli_push.py +137 -0
- mftik-0.0.3/tests/test_cli_run.py +321 -0
- mftik-0.0.3/tests/test_cli_sessions.py +126 -0
- mftik-0.0.3/tests/test_envelope.py +73 -0
- mftik-0.0.3/tests/test_gate_spot_client.py +481 -0
- mftik-0.0.3/tests/test_gate_spot_models.py +437 -0
- mftik-0.0.3/tests/test_gate_spot_private.py +781 -0
- mftik-0.0.3/tests/test_gate_spot_public.py +578 -0
- mftik-0.0.3/tests/test_instrument_identity.py +202 -0
- mftik-0.0.3/tests/test_intervals.py +106 -0
- mftik-0.0.3/tests/test_order_status.py +131 -0
- mftik-0.0.3/tests/test_paper_exchange.py +523 -0
- mftik-0.0.3/tests/test_paper_remote_public.py +92 -0
- mftik-0.0.3/tests/test_query_codes.py +287 -0
- mftik-0.0.3/tests/test_registry_digest.py +20 -0
- mftik-0.0.3/tests/test_registry_files.py +34 -0
- mftik-0.0.3/tests/test_registry_gate.py +206 -0
- mftik-0.0.3/tests/test_registry_load.py +63 -0
- mftik-0.0.3/tests/test_registry_load_reload.py +102 -0
- mftik-0.0.3/tests/test_registry_protocol.py +41 -0
- mftik-0.0.3/tests/test_registry_qualify.py +24 -0
- mftik-0.0.3/tests/test_registry_remotes.py +230 -0
- mftik-0.0.3/tests/test_registry_remove.py +89 -0
- mftik-0.0.3/tests/test_registry_store.py +266 -0
- mftik-0.0.3/tests/test_registry_sync.py +182 -0
- mftik-0.0.3/tests/test_socket_close_timeout.py +68 -0
- mftik-0.0.3/tests/test_strategy_yml.py +206 -0
- mftik-0.0.3/tests/test_symbol_rounding.py +108 -0
- mftik-0.0.3/tests/test_symbols.py +58 -0
- mftik-0.0.3/tests/test_tape_broker.py +140 -0
- mftik-0.0.3/tests/test_tickers.py +149 -0
- mftik-0.0.3/tests/test_venues.py +163 -0
mftik-0.0.3/.gitignore
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
.venv/
|
|
8
|
+
venv/
|
|
9
|
+
.env
|
|
10
|
+
*.egg-info/
|
|
11
|
+
dist/
|
|
12
|
+
build/
|
|
13
|
+
.pytest_cache/
|
|
14
|
+
.mypy_cache/
|
|
15
|
+
.ruff_cache/
|
|
16
|
+
.coverage
|
|
17
|
+
htmlcov/
|
|
18
|
+
|
|
19
|
+
# Node / SvelteKit
|
|
20
|
+
node_modules/
|
|
21
|
+
frontend/.svelte-kit/
|
|
22
|
+
frontend/build/
|
|
23
|
+
frontend/.vite/
|
|
24
|
+
frontend/package-lock.json
|
|
25
|
+
|
|
26
|
+
# IDE / OS
|
|
27
|
+
.idea/
|
|
28
|
+
.vscode/
|
|
29
|
+
*.swp
|
|
30
|
+
.DS_Store
|
|
31
|
+
*.log
|
|
32
|
+
|
|
33
|
+
# Docker
|
|
34
|
+
*.pid
|
|
35
|
+
|
|
36
|
+
# Live API tokens (Hostinger, GitHub, Discord). Never commit.
|
|
37
|
+
credentials/
|
|
38
|
+
|
|
39
|
+
# Local node data (strategy registry). Default when MFTIK_DATA is unset.
|
|
40
|
+
.mftik/
|
|
41
|
+
mft/
|
mftik-0.0.3/PKG-INFO
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: mftik
|
|
3
|
+
Version: 0.0.3
|
|
4
|
+
Summary: MFTIK — strategy SDK and client for a self-hosted trading node
|
|
5
|
+
Project-URL: Homepage, https://github.com/lynxlinkage/mftik
|
|
6
|
+
Project-URL: Source, https://github.com/lynxlinkage/mftik
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Financial and Insurance Industry
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
12
|
+
Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
13
|
+
Requires-Python: >=3.12
|
|
14
|
+
Requires-Dist: cryptography>=42.0
|
|
15
|
+
Requires-Dist: httpx>=0.27
|
|
16
|
+
Requires-Dist: pydantic>=2.0
|
|
17
|
+
Requires-Dist: pyyaml>=6.0
|
|
18
|
+
Requires-Dist: redis>=5.0
|
|
19
|
+
Requires-Dist: websockets>=14.0
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# mftik
|
|
23
|
+
|
|
24
|
+
The strategy SDK and command-line client for a [MFTIK](https://github.com/lynxlinkage/mftik)
|
|
25
|
+
node — a self-hosted, mid-frequency algorithmic trading platform.
|
|
26
|
+
|
|
27
|
+
You run the node yourself with Docker Compose — `mftik node-init` writes the
|
|
28
|
+
stack for you. This package is both that and what you install on the machine
|
|
29
|
+
you write strategies on.
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install mftik
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Writing a strategy
|
|
36
|
+
|
|
37
|
+
A strategy is a subclass of `Strategy` and a directory of `.py` files. It reads
|
|
38
|
+
market data through the hooks it overrides and trades through the accessors the
|
|
39
|
+
base class binds.
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
from mftik.strategy import Strategy
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class MyStrategy(Strategy):
|
|
46
|
+
name = "my_strategy"
|
|
47
|
+
|
|
48
|
+
async def on_best_quote(self, quote) -> None:
|
|
49
|
+
await self.log(f"{quote.universal_ticker} {quote.bid}/{quote.ask}")
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
`self.oms` places and cancels orders, `self.ledger` reads balances, `self.mds`
|
|
53
|
+
queries history the feeds do not carry, `self.tape` warms up on prints from
|
|
54
|
+
before the session started, `self.symbols` gives you the tick and step sizes to
|
|
55
|
+
round to, and `self.timer` schedules work. See `Strategy`'s docstring for the
|
|
56
|
+
full set of hooks.
|
|
57
|
+
|
|
58
|
+
A strategy may import the standard library, `mftik`, and other files in its own
|
|
59
|
+
directory — nothing else. The node runs the source you send it rather than an
|
|
60
|
+
environment you built, so a third-party import would be a module that is not
|
|
61
|
+
there. `mftik check` tells you before you push.
|
|
62
|
+
|
|
63
|
+
## The client
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
mftik node-init ./mynode # a whole node: compose, edge, .env
|
|
67
|
+
mftik connect https://node.example.com # sign in once; stores an API key
|
|
68
|
+
mftik whoami # who you are to that node
|
|
69
|
+
mftik profiles # every node this machine knows
|
|
70
|
+
mftik disconnect <name> # forget one
|
|
71
|
+
mftik init ./hello # scaffold, filled in from that node
|
|
72
|
+
mftik check ./hello # import gate and on_initialized, offline
|
|
73
|
+
mftik run ./hello # push, deploy, tail; ^C stops it
|
|
74
|
+
mftik push ./hello # copy the tree into the node's private registry
|
|
75
|
+
mftik run ./hello # push, deploy, tail the session log
|
|
76
|
+
mftik ps # what is running
|
|
77
|
+
mftik logs -f <session> # what it is saying
|
|
78
|
+
mftik stop <session> # stop it
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`connect` signs in with your password, mints an API key through that session,
|
|
82
|
+
stores the key and drops the session — so the password is never written down.
|
|
83
|
+
Profiles live in `~/.config/mftik/config.toml` at mode `0600`. For CI, pass an
|
|
84
|
+
existing key with `--token` and no prompt is reached.
|
|
85
|
+
|
|
86
|
+
`init` is being built — see
|
|
87
|
+
[docs/CLI.md](https://github.com/lynxlinkage/mftik/blob/main/docs/CLI.md) for the
|
|
88
|
+
shape it is landing in.
|
|
89
|
+
|
|
90
|
+
## License
|
|
91
|
+
|
|
92
|
+
MIT
|
mftik-0.0.3/README.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# mftik
|
|
2
|
+
|
|
3
|
+
The strategy SDK and command-line client for a [MFTIK](https://github.com/lynxlinkage/mftik)
|
|
4
|
+
node — a self-hosted, mid-frequency algorithmic trading platform.
|
|
5
|
+
|
|
6
|
+
You run the node yourself with Docker Compose — `mftik node-init` writes the
|
|
7
|
+
stack for you. This package is both that and what you install on the machine
|
|
8
|
+
you write strategies on.
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
pip install mftik
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Writing a strategy
|
|
15
|
+
|
|
16
|
+
A strategy is a subclass of `Strategy` and a directory of `.py` files. It reads
|
|
17
|
+
market data through the hooks it overrides and trades through the accessors the
|
|
18
|
+
base class binds.
|
|
19
|
+
|
|
20
|
+
```python
|
|
21
|
+
from mftik.strategy import Strategy
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class MyStrategy(Strategy):
|
|
25
|
+
name = "my_strategy"
|
|
26
|
+
|
|
27
|
+
async def on_best_quote(self, quote) -> None:
|
|
28
|
+
await self.log(f"{quote.universal_ticker} {quote.bid}/{quote.ask}")
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`self.oms` places and cancels orders, `self.ledger` reads balances, `self.mds`
|
|
32
|
+
queries history the feeds do not carry, `self.tape` warms up on prints from
|
|
33
|
+
before the session started, `self.symbols` gives you the tick and step sizes to
|
|
34
|
+
round to, and `self.timer` schedules work. See `Strategy`'s docstring for the
|
|
35
|
+
full set of hooks.
|
|
36
|
+
|
|
37
|
+
A strategy may import the standard library, `mftik`, and other files in its own
|
|
38
|
+
directory — nothing else. The node runs the source you send it rather than an
|
|
39
|
+
environment you built, so a third-party import would be a module that is not
|
|
40
|
+
there. `mftik check` tells you before you push.
|
|
41
|
+
|
|
42
|
+
## The client
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
mftik node-init ./mynode # a whole node: compose, edge, .env
|
|
46
|
+
mftik connect https://node.example.com # sign in once; stores an API key
|
|
47
|
+
mftik whoami # who you are to that node
|
|
48
|
+
mftik profiles # every node this machine knows
|
|
49
|
+
mftik disconnect <name> # forget one
|
|
50
|
+
mftik init ./hello # scaffold, filled in from that node
|
|
51
|
+
mftik check ./hello # import gate and on_initialized, offline
|
|
52
|
+
mftik run ./hello # push, deploy, tail; ^C stops it
|
|
53
|
+
mftik push ./hello # copy the tree into the node's private registry
|
|
54
|
+
mftik run ./hello # push, deploy, tail the session log
|
|
55
|
+
mftik ps # what is running
|
|
56
|
+
mftik logs -f <session> # what it is saying
|
|
57
|
+
mftik stop <session> # stop it
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`connect` signs in with your password, mints an API key through that session,
|
|
61
|
+
stores the key and drops the session — so the password is never written down.
|
|
62
|
+
Profiles live in `~/.config/mftik/config.toml` at mode `0600`. For CI, pass an
|
|
63
|
+
existing key with `--token` and no prompt is reached.
|
|
64
|
+
|
|
65
|
+
`init` is being built — see
|
|
66
|
+
[docs/CLI.md](https://github.com/lynxlinkage/mftik/blob/main/docs/CLI.md) for the
|
|
67
|
+
shape it is landing in.
|
|
68
|
+
|
|
69
|
+
## License
|
|
70
|
+
|
|
71
|
+
MIT
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
# The distribution a strategy author installs, and the one every service in
|
|
3
|
+
# this workspace already shares. It was `mftik-common`, which named its role
|
|
4
|
+
# in the monorepo rather than what it is off one: `pip install mftik` gets
|
|
5
|
+
# you `import mftik` and the `mftik` command, and nothing about "common"
|
|
6
|
+
# survives being read from outside this repository.
|
|
7
|
+
name = "mftik"
|
|
8
|
+
version = "0.0.3"
|
|
9
|
+
description = "MFTIK — strategy SDK and client for a self-hosted trading node"
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
requires-python = ">=3.12"
|
|
13
|
+
dependencies = [
|
|
14
|
+
"pydantic>=2.0",
|
|
15
|
+
"redis>=5.0",
|
|
16
|
+
"pyyaml>=6.0",
|
|
17
|
+
"httpx>=0.27",
|
|
18
|
+
"websockets>=14.0",
|
|
19
|
+
# Ed25519, for Binance's WebSocket API session logon. Gate signs with
|
|
20
|
+
# HMAC out of hashlib; Binance accepts nothing but Ed25519 there.
|
|
21
|
+
"cryptography>=42.0",
|
|
22
|
+
]
|
|
23
|
+
classifiers = [
|
|
24
|
+
"Development Status :: 3 - Alpha",
|
|
25
|
+
"Intended Audience :: Financial and Insurance Industry",
|
|
26
|
+
"Programming Language :: Python :: 3.12",
|
|
27
|
+
"Programming Language :: Python :: 3.13",
|
|
28
|
+
"Topic :: Office/Business :: Financial :: Investment",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
Homepage = "https://github.com/lynxlinkage/mftik"
|
|
33
|
+
Source = "https://github.com/lynxlinkage/mftik"
|
|
34
|
+
|
|
35
|
+
# The CLI is argparse and httpx, both of which are here already. A dependency
|
|
36
|
+
# added for it would land in every service image too — they all install this
|
|
37
|
+
# package — so the client stays built out of what the library already needs.
|
|
38
|
+
[project.scripts]
|
|
39
|
+
mftik = "mftik.cli:main"
|
|
40
|
+
|
|
41
|
+
[build-system]
|
|
42
|
+
requires = ["hatchling"]
|
|
43
|
+
build-backend = "hatchling.build"
|
|
44
|
+
|
|
45
|
+
[tool.hatch.build.targets.wheel]
|
|
46
|
+
packages = ["src/mftik"]
|
|
47
|
+
# The compose stack `mftik node init` writes. Data, not code, so it has
|
|
48
|
+
# to be named or the wheel ships a command that cannot do anything.
|
|
49
|
+
artifacts = ["src/mftik/cli/templates/*"]
|
|
50
|
+
|
|
51
|
+
[tool.hatch.build.targets.wheel.sources]
|
|
52
|
+
"src/mftik" = "mftik"
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""Shared MFTIK library — protocol, broker, runtime, exchange, strategy.
|
|
2
|
+
|
|
3
|
+
:mod:`mftik.strategy` is what a strategy is written against, and it is here
|
|
4
|
+
rather than in the STS app so it installs beside a strategy on a developer's
|
|
5
|
+
machine. Nothing in it needs a database or a running node.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from mftik.runtime import configure_logging, run_heartbeat_service
|
|
9
|
+
|
|
10
|
+
__all__ = ["configure_logging", "run_heartbeat_service"]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""Async Redis broker — pub/sub, request-reply, and bidirectional streams."""
|
|
2
|
+
|
|
3
|
+
from mftik.broker.client import Broker, BrokerClient
|
|
4
|
+
from mftik.broker.config import BrokerConfig
|
|
5
|
+
from mftik.broker.errors import (
|
|
6
|
+
BrokerError,
|
|
7
|
+
BrokerNotConnectedError,
|
|
8
|
+
RequestTimeoutError,
|
|
9
|
+
)
|
|
10
|
+
from mftik.broker.request import IncomingRequest
|
|
11
|
+
from mftik.broker.stream import BidirectionalStream
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"BidirectionalStream",
|
|
15
|
+
"Broker",
|
|
16
|
+
"BrokerClient",
|
|
17
|
+
"BrokerConfig",
|
|
18
|
+
"BrokerError",
|
|
19
|
+
"BrokerNotConnectedError",
|
|
20
|
+
"IncomingRequest",
|
|
21
|
+
"RequestTimeoutError",
|
|
22
|
+
]
|