# WTFIX
The Pythonic Financial Information eXchange (FIX) client for humans.
[![Build status](https://travis-ci.org/jcass77/WTFIX.svg?branch=develop)](https://travis-ci.org/jcass77/WTFIX)
[![Coverage Status](https://coveralls.io/repos/github/jcass77/WTFIX/badge.svg?branch=develop)](https://coveralls.io/github/jcass77/WTFIX?branch=develop)
[![PyPI version shields.io](https://img.shields.io/pypi/v/wtfix.svg)](https://pypi.python.org/pypi/wtfix/)
[![PyPI pyversions](https://img.shields.io/pypi/pyversions/wtfix.svg)](https://pypi.python.org/pypi/wtfix/)
[![PyPI license](https://img.shields.io/pypi/l/wtfix.svg)](https://pypi.python.org/pypi/wtfix/)
[![Code style:black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://pypi.org/project/black/)
## Project Highlights and Goals
- Built from the ground up for Python 3.
- Batteries included - comes with everything that you need to connect to a FIX server and start sending and receiving
messages in minutes. Provides default implementations for:
- Authentication
- Maintaining a heartbeat
- Sequence number management and resend requests
- Message storage and retrieval
- Fast, easy to understand message processing pipeline based on a modern ``async and await`` implementation.
- Easily extendable architecture - modular 'apps' can be added to the pipeline stack to add custom message processing
routines or new application features.
```python
PIPELINE_APPS = [
"my_app.apps.SecretAlgoTradingRecipe", # <-- Your application logic
"wtfix.apps.api.RESTfulServiceApp", # REST API for sending messages
"wtfix.apps.brokers.RedisPubSubApp", # Redis Pub/Sub broker for sending / receiving messages
"wtfix.apps.admin.HeartbeatApp", # Heartbeat monitoring and maintenance
"wtfix.apps.admin.AuthenticationApp", # Login / logout handling
"wtfix.apps.admin.SeqNumManagerApp", # Message gap detection and filling
"wtfix.apps.store.MessageStoreApp", # Store messages (caching or persistence)
"wtfix.apps.utils.InboundLoggingApp", # Log inbound messages
"wtfix.apps.parsers.RawMessageParserApp", # Message parsing: Logon (A): {BeginString (8): FIX.4.4 | BodyLength (9): 99 | MsgType (35): A | MsgSeqNum (34): 1 | SenderCompID (49): SENDER | SendingTime (52): 20190305-08:45:45.979 | TargetCompID (56): TARGET | EncryptMethod (98): 0 | HeartBtInt (108): 30 | Username (553): USERNAME | Password (554): PASSWORD | ResetSeqNumFlag (141): Y | CheckSum (10): 94}
"wtfix.apps.utils.OutboundLoggingApp", # Log outbound messages
"wtfix.apps.wire.WireCommsApp", # Raw message encoding / decoding: b'8=FIX.4.4\x019=99\x0135=A\x0134=1\x0149=SENDER\x0152=20190305-08:42:32.793\x0156=TARGET\x0198=0\x01108=30\x01553=USERNAME\x01554=PASSWORD\x01141=Y\x0110=081\x01'
"wtfix.apps.sessions.ClientSessionApp", # HTTP session management
]
```
- Messages can be cached in memory or saved to a Redis message store for later retrieval. Alternatively you can add
your own message storage solution using the provided interfaces.
- Send messages directly from the pipeline, via 3rd party applications using a REST API, or by publishing them to
a Redis Pub/Sub channel for immediate delivery.
- Provides a convenient ``@on`` decorator for fine-grained control over which apps will respond to which types of messages:
```python
from wtfix.apps.base import MessageTypeHandlerApp, on
from wtfix.conf import settings
logger = settings.logger
class SecretAlgoTradingRecipe(MessageTypeHandlerApp):
@on(settings.protocol.MsgType.Logon) # Only invoked when 'Logon (type A)' messages are received.
def on_logon(self, message):
self.send_security_definition_request()
return message
def on_receive(self, message): # Invoked for every type of message.
logger.info(f"Received message {message}!")
```
- Provides custom `Field` and `FieldMap` types for working with FIX tags and field values. These types are 'pythonic',
implementing many of the standard protocols, and behave as expected when you integrate them in existing Python
code.
- A simple message tag syntax, with various convenience methods, for quick access to commonly
used message attributes.
```python
>>> from wtfix.message import admin
# Instantiate a new 'Logon' message
>>> logon_msg = admin.LogonMessage("my_username", "my_password", heartbeat_int=30)
# Short, concise string representation
>>> str(logon_msg)
'A: {(35, A) | (98, 0) | (108, 30) | (553, my_username) | (554, my_password)}'
# Pretty print tag names by using the 't' formatting option
>>> f"{logon_msg:t}"
'Logon (A): {MsgType (35): A | EncryptMethod (98): 0 | HeartBtInt (108): 30 | Username (553): my_username | Password (554): my_password}'
# Example of getting the message type
>>> logon_msg.type
'A'
# Example of getting the message type name
>>> logon_msg.name
'Logon'
# Look up the sequence number
>>> logon_msg.seq_num
1
# Various ways for accessing the different fields that make up the message. Fields are just
# (tag, value) namedtuples.
>>> logon_msg[108] # Using old school tag number
Field(108, '30')
>>> logon_msg[settings.protocol.Tag.HeartBtInt] # Using the tag name as per the FIX specification
Field(108, '30')
>>> logon_msg.HeartBtInt # Using tag name shortcut
Field(108, '30')
```
- A pragmatic [unicode sandwich](https://nedbatchelder.com/text/unipain.html) based approach to encoding / decoding
messages mean that you never need to deal with byte sequences directly.
```python
from wtfix.message.field import Field
from wtfix.message.message import generic_message_factory
# Create a new Message from a byte sequence received over the wire
>>> fields = Field.fields_frombytes(b"35=A\x0198=0\x01108=30\x01553=my_username\x01554=my_password\x01")
>>> logon_msg = generic_message_factory(*fields)
>>> str(logon_msg)
'A: {(35, A) | (98, 0) | (108, 30) | (553, my_username) | (554, my_password)}'
# Fields are tuples of (tag, value) pairs
>>> username = logon_msg.Username
>>> username.tag
553
>>> username.value
"my_username"
# Fields behave just like Python's built-in types, and most operations can be performed directly
# on a field's 'value' attribute.
>>> username += "_123"
>>> username
Field(553, 'my_username_123')
```
- Access to the underlying byte sequence when you need it:
```python
>>> bytes(logon_msg)
b'35=A\x0198=0\x01108=30\x01553=my_username\x01554=my_password\x01'
```
- It is easy to add Fields to a Message: simply assign the tag value:
```python
>>> logon_msg.PossDupFlag = "Y"
>>> f"{logon_msg:t}"
'Logon (A): {MsgType (35): A | EncryptMethod (98): 0 | HeartBtInt (108): 30 | Username (553): my_username | Password (554): my_password | PossDupFlag (43): Y}'
# Most FIX field values can be cast to their corresponding Python built-in type
>>> bool(logon_msg.PossDupFlag) is True
True
```
- A very forgiving approach to repeating groups of message tags:
```python
from wtfix.protocol.common import Tag, MsgType
from wtfix.message.message import generic_message_factory
# If you provide a group template, then messages are stored in an 'OrderedDict' for fast lookups
>>> msg = generic_message_factory((Tag.MsgType, MsgType.ExecutionReport), (Tag.NoMiscFees, 2), (Tag.MiscFeeAmt, 10.00), (Tag.MiscFeeType, 2), (Tag.MiscFeeAmt, 20.00), (Tag.MiscFeeType, "A"), group_templates={Tag.NoMiscFees: [Tag.MiscFeeAmt, Tag.MiscFeeType,]})
>>> msg.data
OrderedDict([(35, Field(35, '8')), (136, Group(Field(136, '2'), Field(137, '10.0'), Field(139, '2'), Field(137, '20.0'), Field(139, 'A')))])
# Get 'NoMiscFees' group
>>> g
没有合适的资源?快使用搜索试试~ 我知道了~
PyPI 官网下载 | wtfix-0.13.0.tar.gz
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 142 浏览量
2022-01-17
12:18:41
上传
评论
收藏 86KB GZ 举报
温馨提示
共81个文件
py:73个
txt:4个
pkg-info:2个
资源来自pypi官网。 资源全名:wtfix-0.13.0.tar.gz
资源推荐
资源详情
资源评论
收起资源包目录
wtfix-0.13.0.tar.gz (81个子文件)
wtfix-0.13.0
PKG-INFO 13KB
wtfix.egg-info
PKG-INFO 13KB
requires.txt 91B
SOURCES.txt 2KB
top_level.txt 13B
dependency_links.txt 1B
config
wsgi.py 2KB
__init__.py 736B
settings
local.py 163B
test.py 910B
staging.py 28B
__init__.py 736B
production.py 28B
base.py 2KB
wtfix
core
klass.py 1KB
utils.py 9KB
encoders.py 2KB
tests
test_utils.py 7KB
conftest.py 1KB
__init__.py 0B
test_decoders.py 2KB
test_encoders.py 2KB
__init__.py 736B
decoders.py 2KB
exceptions.py 3KB
conf
global_settings.py 2KB
__init__.py 6KB
protocol
fix
_44
message_types.py 4KB
tags.py 44KB
spec.py 983B
__init__.py 736B
spec.py 1021B
__init__.py 736B
message_types.py 2KB
tags.py 2KB
tests
__init__.py 0B
test_spec.py 2KB
spec.py 4KB
__init__.py 736B
conftest.py 4KB
tests
conftest.py 3KB
__init__.py 0B
test_pipeline.py 10KB
pipeline.py 8KB
__init__.py 736B
message
message.py 7KB
tests
test_message.py 6KB
conftest.py 529B
__init__.py 0B
test_field.py 20KB
test_collections.py 37KB
__init__.py 736B
admin.py 3KB
field.py 17KB
collections.py 33KB
apps
brokers.py 2KB
wire.py 11KB
utils.py 2KB
parsers.py 2KB
tests
test_wire.py 6KB
test_parsers.py 6KB
conftest.py 4KB
__init__.py 0B
test_base.py 2KB
test_store.py 8KB
test_admin.py 17KB
test_sessions.py 3KB
api
utils.py 2KB
tests
conftest.py 624B
__init__.py 0B
test_rest.py 1KB
__init__.py 736B
rest.py 5KB
__init__.py 736B
store.py 10KB
sessions.py 8KB
admin.py 28KB
base.py 7KB
setup.cfg 140B
setup.py 1KB
README.md 10KB
共 81 条
- 1
资源评论
挣扎的蓝藻
- 粉丝: 13w+
- 资源: 15万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功