def login(self, secret: str, cancel_on_disconnect: Optional[str] = None) -> None: send_time_str = datetime.now().strftime('%Y%m%d-%H:%M:%S') sign_target = b'\x01'.join([ fix_val(val) for val in [ send_time_str, simplefix.MSGTYPE_LOGON, self._next_seq_num, self._client_id, self._target_id, ] ]) signed = hmac.new(secret.encode(), sign_target, 'sha256').hexdigest() self.send({ simplefix.TAG_MSGTYPE: simplefix.MSGTYPE_LOGON, simplefix.TAG_SENDING_TIME: send_time_str, simplefix.TAG_ENCRYPTMETHOD: 0, simplefix.TAG_HEARTBTINT: 30, simplefix.TAG_RAWDATA: signed, **({ 8013: cancel_on_disconnect } if cancel_on_disconnect else {}), **({ simplefix.TAG_ACCOUNT: self._subaccount_name } if self._subaccount_name else {}), })
def _validate_message(self, msg: FixMessage) -> bool: try: # Hack to make msg.get return decoded strings. decoded = ImmutableMultiDict([(k, v.decode()) for k, v in msg.pairs]) msg.get = lambda key: decoded.get(fix_val(key)) except ValueError: self.reject_message( msg, reason='Invalid encoding', error_code=simplefix. SESSIONREJECTREASON_INCOORECT_DATA_FORMAT_FOR_VALUE, ) return False if self._target_id is None and msg.get(simplefix.TAG_SENDER_COMPID): self._target_id = msg.get(simplefix.TAG_SENDER_COMPID) if msg.get(simplefix.TAG_MSGSEQNUM): if msg.get(simplefix.TAG_MSGSEQNUM) == str( self._next_recv_seq_num): self._next_recv_seq_num += 1 else: self.reject_message( msg, reason='Incorrect sequence number', tag_id=simplefix.TAG_MSGSEQNUM, error_code=simplefix. SESSIONREJECTREASON_VALUE_INCORRECT_FOR_THIS_TAG) return False for tag, description in [ (simplefix.TAG_MSGTYPE, 'message type'), (simplefix.TAG_BEGINSTRING, 'begin string'), (simplefix.TAG_SENDER_COMPID, 'sender ID'), (simplefix.TAG_TARGET_COMPID, 'target ID'), (simplefix.TAG_SENDING_TIME, 'sending time'), (simplefix.TAG_MSGSEQNUM, 'sequence number'), ]: if not msg.get(tag): self.reject_message(msg, reason=f'Missing {description}', tag_id=tag, error_code=simplefix. SESSIONREJECTREASON_REQUIRED_TAG_MISSING) return False if msg.get(simplefix.TAG_BEGINSTRING) != 'FIX.4.2': self.reject_message( msg, reason='Invalid FIX version', tag_id=simplefix.TAG_BEGINSTRING, error_code=simplefix. SESSIONREJECTREASON_VALUE_INCORRECT_FOR_THIS_TAG) return False elif msg.get(simplefix.TAG_SENDER_COMPID) != self._target_id: self.reject_message( msg, reason='Incorrect sender', tag_id=simplefix.TAG_SENDER_COMPID, error_code=simplefix. SESSIONREJECTREASON_VALUE_INCORRECT_FOR_THIS_TAG) return False elif msg.get(simplefix.TAG_TARGET_COMPID) != self._sender_id: self.reject_message( msg, reason='Incorrect target', tag_id=simplefix.TAG_TARGET_COMPID, error_code=simplefix. SESSIONREJECTREASON_VALUE_INCORRECT_FOR_THIS_TAG) return False self._last_recv_time = time.time() return True
def test_val_str(self): """Test string value returns bytes.""" self.assertEqual(b"123", fix_val("123")) self.assertEqual(bytes, type(fix_val("123"))) return
def test_val_bytes(self): """Test bytes value returns bytes.""" self.assertEqual(b"123", fix_val(b"123")) self.assertEqual(bytes, type(fix_val(b"123"))) return