# jetblack-fixengine
A pure python asyncio FIX engine.
## Status
This is work in progress.
## Installation
The package can be install from the pie store.
```bash
pip install jetblack-fixengine
```
## Overview
This project provides a pure Python, asyncio implementation of
a FIX engine, supporting both initiators and acceptors.
The engine uses the [jetblack-fixparser](https://github.com/rob-blackbourn/jetblack-fixparser)
package to present the FIX messages a plain Python objects. For example, a `LOGON` message
can be sent as follows:
```python
await send_message({
'MsgType': 'LOGON',
'MsgSeqNum': 42,
'SenderCompID': 'ME',
'TargetCompID': 'BANK OF SOMEWHERE',
'SendingTime': datetime.now(timezone.utc),
'EncryptMethod': "NONE",
'HeartBtInt': 30
})
```
### FIX Protocols
The FIX protocol is a combination of *well known* messages (like `LOGON`)
and *custom* messages (like an order to buy or sell). The protocol
has evolved through a number of different versions providing new features.
Because of this the protocols are provided by config files. Historically
`XML` was used. While this is supported, `yaml` is preferred and some
example protocols are provided in the
[etc](https://github.com/rob-blackbourn/jetblack-fixengine/tree/master/etc)
folder.
Currently supported versions are 4.0, 4.1, 4.2, 4.3, 4.4.
### Initiators
An initiator is a class which inherits from `FIXApplication`, and implements a
few methods, and has access to `send_message` from the `fix_engine`. Here is an example.
```python
import asyncio
import logging
from pathlib import Path
from typing import Mapping, Any
from jetblack_fixparser import load_yaml_protocol
from jetblack_fixengine import (
FileStore,
start_initiator,
InitiatorConfig,
FIXApplication,
FIXEngine
)
LOGGER = logging.getLogger(__name__)
class MyInitiator(FIXApplication):
"""An instance of the initiator"""
async def on_logon(
self,
_message: Mapping[str, Any],
fix_engine: FIXEngine
) -> None:
LOGGER.info('on_logon')
async def on_logout(
self,
_message: Mapping[str, Any],
fix_engine: FIXEngine
) -> None:
LOGGER.info('on_logout')
async def on_application_message(
self,
_message: Mapping[str, Any],
fix_engine: FIXEngine
) -> None:
LOGGER.info('on_application_message')
app = MyInitiator()
config = InitiatorConfig(
'127.0.0.1',
9801,
load_yaml_protocol(Path('etc') / 'FIX44.yaml'),
'INITIATOR1',
'ACCEPTOR',
FileStore(Path('store'))
)
logging.basicConfig(level=logging.DEBUG)
asyncio.run(
start_initiator(app, config)
)
```
### Acceptor
The acceptor works in the same way as the initiator. Here is an example:
```python
import asyncio
import logging
from pathlib import Path
from typing import Mapping, Any
from jetblack_fixparser import load_yaml_protocol
from jetblack_fixengine import (
FileStore,
start_acceptor,
AcceptorConfig,
FIXApplication,
FIXEngine
)
LOGGER = logging.getLogger(__name__)
class MyAcceptor(FIXApplication):
"""An instance of the acceptor"""
async def on_logon(
self,
_message: Mapping[str, Any],
_fix_engine: FIXEngine
) -> None:
LOGGER.info('on_logon')
async def on_logout(
self,
_message: Mapping[str, Any],
_fix_engine: FIXEngine
) -> None:
LOGGER.info('on_logout')
async def on_application_message(
self,
_message: Mapping[str, Any],
_fix_engine: FIXEngine
) -> None:
LOGGER.info('on_application_message')
logging.basicConfig(level=logging.DEBUG)
app = MyAcceptor()
config = AcceptorConfig(
'0.0.0.0',
9801,
load_yaml_protocol(Path('etc') / 'FIX44.yaml'),
'ACCEPTOR',
'INITIATOR1',
FileStore(Path("store"))
)
asyncio.run(
start_acceptor(
app,
config
)
)
```
Note that throwing the exception `LogonError` from `on_logon` will reject
the logon request.
### Stores
The engines need to store their state. Two stores are currently provided:
a file store (`FileStore`) and sqlite (`SqlStore`).
## Implementation
The engines are implemented as state machines. This means they can be
tested without the need for IO.
Raw data
{
"_id": null,
"home_page": "https://github.com/rob-blackbourn/jetblack-fixengine",
"name": "jetblack-fixengine",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.8,<4.0",
"maintainer_email": "",
"keywords": "fix,fix-engine",
"author": "Rob Blackbourn",
"author_email": "rob.blackbourn@googlemail.com",
"download_url": "https://files.pythonhosted.org/packages/06/45/5613673f3851bd74e91dd979ec08c275b86645b1b32e1518ab44ed2a2786/jetblack-fixengine-1.0.0a5.tar.gz",
"platform": null,
"description": "# jetblack-fixengine\n\nA pure python asyncio FIX engine.\n\n## Status\n\nThis is work in progress.\n\n## Installation\n\nThe package can be install from the pie store.\n\n```bash\npip install jetblack-fixengine\n```\n\n## Overview\n\nThis project provides a pure Python, asyncio implementation of\na FIX engine, supporting both initiators and acceptors.\n\nThe engine uses the [jetblack-fixparser](https://github.com/rob-blackbourn/jetblack-fixparser)\npackage to present the FIX messages a plain Python objects. For example, a `LOGON` message\ncan be sent as follows:\n\n```python\nawait send_message({\n 'MsgType': 'LOGON',\n 'MsgSeqNum': 42,\n 'SenderCompID': 'ME',\n 'TargetCompID': 'BANK OF SOMEWHERE',\n 'SendingTime': datetime.now(timezone.utc),\n 'EncryptMethod': \"NONE\",\n 'HeartBtInt': 30\n})\n```\n\n### FIX Protocols\n\nThe FIX protocol is a combination of *well known* messages (like `LOGON`)\nand *custom* messages (like an order to buy or sell). The protocol\nhas evolved through a number of different versions providing new features.\n\nBecause of this the protocols are provided by config files. Historically\n`XML` was used. While this is supported, `yaml` is preferred and some\nexample protocols are provided in the\n[etc](https://github.com/rob-blackbourn/jetblack-fixengine/tree/master/etc)\nfolder.\n\nCurrently supported versions are 4.0, 4.1, 4.2, 4.3, 4.4.\n\n### Initiators\n\nAn initiator is a class which inherits from `FIXApplication`, and implements a\nfew methods, and has access to `send_message` from the `fix_engine`. Here is an example.\n\n```python\nimport asyncio\nimport logging\nfrom pathlib import Path\nfrom typing import Mapping, Any\n\nfrom jetblack_fixparser import load_yaml_protocol\nfrom jetblack_fixengine import (\n FileStore,\n start_initiator,\n InitiatorConfig,\n FIXApplication,\n FIXEngine\n)\n\nLOGGER = logging.getLogger(__name__)\n\n\nclass MyInitiator(FIXApplication):\n \"\"\"An instance of the initiator\"\"\"\n\n async def on_logon(\n self,\n _message: Mapping[str, Any],\n fix_engine: FIXEngine\n ) -> None:\n LOGGER.info('on_logon')\n\n async def on_logout(\n self,\n _message: Mapping[str, Any],\n fix_engine: FIXEngine\n ) -> None:\n LOGGER.info('on_logout')\n\n async def on_application_message(\n self,\n _message: Mapping[str, Any],\n fix_engine: FIXEngine\n ) -> None:\n LOGGER.info('on_application_message')\n\n\napp = MyInitiator()\nconfig = InitiatorConfig(\n '127.0.0.1',\n 9801,\n load_yaml_protocol(Path('etc') / 'FIX44.yaml'),\n 'INITIATOR1',\n 'ACCEPTOR',\n FileStore(Path('store'))\n)\n\nlogging.basicConfig(level=logging.DEBUG)\n\nasyncio.run(\n start_initiator(app, config)\n)\n```\n\n### Acceptor\n\nThe acceptor works in the same way as the initiator. Here is an example:\n\n```python\nimport asyncio\nimport logging\nfrom pathlib import Path\nfrom typing import Mapping, Any\n\nfrom jetblack_fixparser import load_yaml_protocol\nfrom jetblack_fixengine import (\n FileStore,\n start_acceptor,\n AcceptorConfig,\n FIXApplication,\n FIXEngine\n)\n\n\nLOGGER = logging.getLogger(__name__)\n\n\nclass MyAcceptor(FIXApplication):\n \"\"\"An instance of the acceptor\"\"\"\n\n async def on_logon(\n self,\n _message: Mapping[str, Any],\n _fix_engine: FIXEngine\n ) -> None:\n LOGGER.info('on_logon')\n\n async def on_logout(\n self,\n _message: Mapping[str, Any],\n _fix_engine: FIXEngine\n ) -> None:\n LOGGER.info('on_logout')\n\n async def on_application_message(\n self,\n _message: Mapping[str, Any],\n _fix_engine: FIXEngine\n ) -> None:\n LOGGER.info('on_application_message')\n\n\nlogging.basicConfig(level=logging.DEBUG)\n\napp = MyAcceptor()\nconfig = AcceptorConfig(\n '0.0.0.0',\n 9801,\n load_yaml_protocol(Path('etc') / 'FIX44.yaml'),\n 'ACCEPTOR',\n 'INITIATOR1',\n FileStore(Path(\"store\"))\n)\n\nasyncio.run(\n start_acceptor(\n app,\n config\n )\n)\n```\n\nNote that throwing the exception `LogonError` from `on_logon` will reject\nthe logon request.\n\n### Stores\n\nThe engines need to store their state. Two stores are currently provided:\na file store (`FileStore`) and sqlite (`SqlStore`).\n\n## Implementation\n\nThe engines are implemented as state machines. This means they can be\ntested without the need for IO.\n",
"bugtrack_url": null,
"license": "Apache-2.0",
"summary": "A pure Python implementation of the FIX protocol",
"version": "1.0.0a5",
"split_keywords": [
"fix",
"fix-engine"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "65084b7fccb7858e9c287a087b751038dc1d866bf521e2e03eb7c990189735eb",
"md5": "3b46798e3a8183cfaa60a6b87e6a437f",
"sha256": "5b5728bafcf9ec92a90ee29a9acd9f6783aa69b20a64a51de2c48b68233918f9"
},
"downloads": -1,
"filename": "jetblack_fixengine-1.0.0a5-py3-none-any.whl",
"has_sig": false,
"md5_digest": "3b46798e3a8183cfaa60a6b87e6a437f",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8,<4.0",
"size": 40229,
"upload_time": "2023-04-06T09:54:58",
"upload_time_iso_8601": "2023-04-06T09:54:58.337906Z",
"url": "https://files.pythonhosted.org/packages/65/08/4b7fccb7858e9c287a087b751038dc1d866bf521e2e03eb7c990189735eb/jetblack_fixengine-1.0.0a5-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "06455613673f3851bd74e91dd979ec08c275b86645b1b32e1518ab44ed2a2786",
"md5": "60cc171a92767e735ec7bdc4c3e29f18",
"sha256": "1cfcc80be8e9866921f6d8b42f67227afac317eb95148801e91a322db810ba1a"
},
"downloads": -1,
"filename": "jetblack-fixengine-1.0.0a5.tar.gz",
"has_sig": false,
"md5_digest": "60cc171a92767e735ec7bdc4c3e29f18",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8,<4.0",
"size": 29051,
"upload_time": "2023-04-06T09:54:55",
"upload_time_iso_8601": "2023-04-06T09:54:55.208593Z",
"url": "https://files.pythonhosted.org/packages/06/45/5613673f3851bd74e91dd979ec08c275b86645b1b32e1518ab44ed2a2786/jetblack-fixengine-1.0.0a5.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-04-06 09:54:55",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "rob-blackbourn",
"github_project": "jetblack-fixengine",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "jetblack-fixengine"
}