Repository: Ma-r-co/savoia

Issue:
Refine Event Class
- __rept__
- test

Discussion:

Patch:
diff --git a/src/savoia/config/logging.json b/src/savoia/config/logging.json
index f8e0f5d..b902435 100644
--- a/src/savoia/config/logging.json
+++ b/src/savoia/config/logging.json
@@ -3,13 +3,13 @@
     "disable_existing_loggers":false,
     "formatters":{
         "simple":{
-            "format":"%(asctime)s - %(name)-28s - %(levelname)-8s - %(message)s"
+            "format":"%(asctime)s %(name)-28s %(levelname)-8s %(message)s"
         }
     },
     "handlers":{
         "console":{
             "class":"logging.StreamHandler",
-            "level":"DEBUG",
+            "level":"INFO",
             "formatter":"simple",
             "stream":"ext://sys.stdout"
         },
diff --git a/src/savoia/datafeed/datafeed.py b/src/savoia/datafeed/datafeed.py
index 942ca41..ae6c6f2 100644
--- a/src/savoia/datafeed/datafeed.py
+++ b/src/savoia/datafeed/datafeed.py
@@ -1,6 +1,5 @@
 from decimal import Decimal
-from savoia.config.decimal_config \
-    import initializeDecimalContext, DECIMAL_PLACES
+from savoia.config.decimal_config import DECIMAL_PLACES
 
 import os
 import re
@@ -88,7 +87,6 @@ class HistoricCSVDataFeeder(DataFeeder):
         self.cur_date_pairs = self._open_convert_csv_files_for_day(
             self.file_dates[self.cur_date_idx]
         )
-        initializeDecimalContext()
         self.count = 0
 
     def _list_all_csv_files(self) -> List[str]:
@@ -120,22 +118,6 @@ class HistoricCSVDataFeeder(DataFeeder):
         ordered, allowing tick data events to be added to the queue
         in a chronological fashion.
         """
-        # for p in self.pairs:
-        #    pair_path = os.path.join(self.csv_dir, '%s_%s.csv' % (p, date_str))
-        #     self.logger.info("start read: %s", str(pair_path))
-        #     with open(pair_path, 'r') as f:
-
-        #     self.pair_frames[p] = pd.read_csv(
-        #         pair_path,
-        #         header=0,
-        #         index_col=0,
-        #         parse_dates=["Time"],
-        #         dayfirst=True,
-        #         names=("Time", "Ask", "Bid", "AskVolume", "BidVolume")
-        #     )
-        #     self.pair_frames[p]["Pair"] = p
-        #     self.logger.info("end read: %s", str(pair_path))
-        # return pd.concat(self.pair_frames.values()).sort_index().iterrows()
         self.pair_frames = []
         for p in self.pairs:
             pair_path = os.path.join(self.csv_dir, '%s_%s.csv' % (p, date_str))
@@ -145,7 +127,6 @@ class HistoricCSVDataFeeder(DataFeeder):
                 for line in f:
                     self.pair_frames.append(line + f',{p}')
             self.logger.info("end read: %s", str(pair_path))
-        self.logger.info('start sort')
         self.pair_frames.sort()
 
         def _gen() -> Iterator[Tuple[str, str, str, str]]:
diff --git a/src/savoia/engine/engine.py b/src/savoia/engine/engine.py
index 01ee056..6f7c231 100644
--- a/src/savoia/engine/engine.py
+++ b/src/savoia/engine/engine.py
@@ -138,10 +138,11 @@ class Engine(object):
         continue until the maximum number of iterations is
         exceeded.
         """
-        self.logger.info("Running Backtest...")
+        _wait: bool = False
+        self.logger.info("Running engine...")
         while self.iters < self.max_iters and self.toContinue:
             try:
-                event = self.event_q.get(False)
+                event = self.event_q.get(_wait)
             except Empty:
                 try:
                     tick_event = self.feed_q.get(False)
@@ -149,22 +150,27 @@ class Engine(object):
                     pass
                 else:
                     if tick_event is None:
+                        self.logger.info('Acknowledged the end of datafeed.')
                         self.toContinue = False
                     elif tick_event.type != 'TICK':
                         raise Exception
                     else:
+                        self.logger.debug('Process TICK -%s' % tick_event)
                         self.ticker.update_ticker(tick_event)
                         self.portfolio.update_portfolio(tick_event)
                         self.strategy.calculate_signals(tick_event)
             else:
+                _wait = False
                 if event is not None:
                     if event.type == 'SIGNAL':
+                        self.logger.info("Process SIGNAL -%s" % event)
                         self.portfolio.execute_signal(event)
                     elif event.type == 'ORDER':
-                        self.logger.info("Excecution order! :%s" % event)
+                        self.logger.info("Process ORDER -%s" % event)
                         self.exec_q.put(event)
+                        _wait = self.isBacktest
                     elif event.type == 'FILL':
-                        self.logger.info("Fill event! :%s" % event)
+                        self.logger.info("Process FILL -%s" % event)
                         self.portfolio.execute_fill(event)
                     else:
                         raise Exception
@@ -185,9 +191,9 @@ class Engine(object):
         _execution = threading.Thread(target=self.execution.run)
         _engine = threading.Thread(target=self._run_engine)
 
-        _datafeed.start()
         _execution.start()
         _engine.start()
+        _datafeed.start()
 
         _datafeed.join()
         _engine.join()
diff --git a/src/savoia/event/event.py b/src/savoia/event/event.py
index b61a7c4..682e419 100644
--- a/src/savoia/event/event.py
+++ b/src/savoia/event/event.py
@@ -1,6 +1,4 @@
 import pandas as pd
-from typing import Union
-from datetime import datetime
 from decimal import Decimal
 
 from savoia.types.types import EventType, Pair
@@ -11,17 +9,17 @@ class Event(object):
 
 
 class TickEvent(Event):
-    def __init__(self, instrument: Pair, time: Union[pd.Timestamp, datetime],
+    def __init__(self, pair: Pair, time: pd.Timestamp,
             bid: Decimal, ask: Decimal) -> None:
         self.type = EventType('TICK')
-        self.instrument: Pair = instrument
-        self.time: Union[pd.Timestamp, datetime] = time
+        self.pair: Pair = pair
+        self.time: pd.Timestamp = time
         self.bid: Decimal = bid
         self.ask: Decimal = ask
 
     def __str__(self) -> str:
-        return "Type: %s, Instrument: %s, Time: %s, Bid: %s, Ask: %s" % (
-            str(self.type), str(self.instrument),
+        return "Type: %s, Pair: %s, Time: %s, Bid: %s, Ask: %s" % (
+            str(self.type), str(self.pair),
             str(self.time), str(self.bid), str(self.ask)
         )
 
@@ -30,22 +28,23 @@ class TickEvent(Event):
 
 
 class SignalEvent(Event):
-    def __init__(self, ref: str, instrument: Pair, order_type: str,
-            units: Decimal, time: pd.Timestamp,
-            price: Union[Decimal, None] = None):
+    def __init__(self, ref: str, pair: Pair, time: pd.Timestamp,
+            order_type: str, units: Decimal, price: Decimal):
         self.type = EventType('SIGNAL')
         self.ref = ref
-        self.instrument: Pair = instrument
+        self.pair: Pair = pair
         self.order_type = order_type
         self.units = units
         self.time = time  # Time of the last tick that generated the signal
         self.price = price
 
     def __str__(self) -> str:
-        return "Type: %s, Instrument: %s, Order Type: %s, Units: %s, Time: %s" \
+        _form = "Type: %s, Ref: %s, Pair: %s, Time: %s, OrderType: %s, " + \
+            "Units: %s, Price: %s"
+        return _form \
             % (
-                str(self.type), str(self.instrument),
-                str(self.order_type), str(self.units), str(self.time)
+                self.type, self.ref, self.pair, self.time, self.order_type,
+                self.units, self.price
             )
 
     def __repr__(self) -> str:
@@ -53,21 +52,23 @@ class SignalEvent(Event):
 
 
 class OrderEvent(Event):
-    def __init__(self, ref: str, instrument: Pair, units: int, price: Decimal,
-            order_type: str, time: pd.Timestamp):
+    def __init__(self, ref: str, pair: Pair, time: pd.Timestamp,
+            order_type: str, units: Decimal, price: Decimal):
         self.type = EventType('ORDER')
-        self.ref = ref
-        self.instrument: Pair = instrument
-        self.units = units
+        self.ref: str = ref
         self.order_type = order_type
+        self.pair: Pair = pair
+        self.units = units
         self.time = time
         self.price = price
 
     def __str__(self) -> str:
-        return "Type: %s, Instrument: %s, Units: %s, Order Type: %s, Price: %s"\
+        _form = "Type: %s, Ref: %s, Pair: %s, Time: %s, OrderType: %s, " + \
+            "Units: %s, Price: %s"
+        return _form \
             % (
-                str(self.type), str(self.instrument), str(self.units),
-                str(self.order_type), str(self.price)
+                self.type, self.ref, self.pair, self.time, self.order_type,
+                self.units, self.price
             )
 
     def __repr__(self) -> str:
@@ -75,21 +76,22 @@ class OrderEvent(Event):
 
 
 class FillEvent(Event):
-    def __init__(self, ref: str, instrument: Pair, units: int, price: Decimal,
-            status: str, time: pd.Timestamp):
+    def __init__(self, ref: str, pair: Pair, time: pd.Timestamp,
+            units: int, price: Decimal, status: str):
         self.type = EventType('FILL')
         self.ref = ref
-        self.instrument: Pair = instrument
+        self.pair: Pair = pair
         self.units = units
         self.price = price
         self.status = status
         self.time = time
 
     def __str__(self) -> str:
-        return ("Type: %s, Instrument: %s, Units: %s, Price: %s, Time: %s" +
-            ", Status: %s") % (
-                str(self.type), str(self.instrument), str(self.units),
-                str(self.price), str(self.time), str(self.status)
+        _form = "Type: %s, Ref: %s, Pair: %s, Time: %s, " + \
+            "Units: %s, Price: %s, Status: %s"
+        return _form % (
+            self.type, self.ref, self.pair, self.time,
+            self.units, self.price, self.status
         )
 
     def __repr__(self) -> str:
diff --git a/src/savoia/execution/execution.py b/src/savoia/execution/execution.py
index bc112ff..e76d884 100644
--- a/src/savoia/execution/execution.py
+++ b/src/savoia/execution/execution.py
@@ -38,14 +38,16 @@ class SimulatedExecution(ExecutionHandler):
 
     def _execute_order(self, event: OrderEvent) -> None:
         import random
-        ref = event.ref
-        instrument = event.instrument
-        units = event.units
-        price = event.price * Decimal(str(random.uniform(0.99, 1.01)))
-        price = price.quantize(DECIMAL_PLACES)
-        status = 'filled'
-        dt = event.time + pd.offsets.Second(random.randint(3, 10))
-        fillevent = FillEvent(ref, instrument, units, price, status, dt)
+        _price = event.price * Decimal(str(random.uniform(0.99, 1.01)))
+        _time = event.time + pd.offsets.Second(random.randint(3, 10))
+        fillevent = FillEvent(
+            ref=event.ref,
+            pair=event.pair,
+            time=_time,
+            units=event.units,
+            price=_price.quantize(DECIMAL_PLACES),
+            status='filled'
+        )
         self._return_fill_event(fillevent)
 
     def _return_fill_event(self, event: FillEvent) -> None:
@@ -77,13 +79,13 @@ class SimulatedExecution(ExecutionHandler):
 #         return httplib.HTTPSConnection(self.domain)
 
 #     def execute_order(self, event):
-#         instrument = "%s_%s" % (event.instrument[:3], event.instrument[3:])
+#         pair = "%s_%s" % (event.pair[:3], event.pair[3:])
 #         headers = {
 #             "Content-Type": "application/x-www-form-urlencoded",
 #             "Authorization": "Bearer " + self.access_token
 #         }
 #         params = urlencode({
-#             "instrument": instrument,
+#             "pair": pair,
 #             "units": event.units,
 #             "type": event.order_type,
 #             "side": event.side
diff --git a/src/savoia/portfolio/portfolio.py b/src/savoia/portfolio/portfolio.py
index c7b668f..3db5754 100644
--- a/src/savoia/portfolio/portfolio.py
+++ b/src/savoia/portfolio/portfolio.py
@@ -119,7 +119,7 @@ class Portfolio(object):
         # we can execute
         if _execute:
             order = OrderEvent(
-                ref=event.ref, instrument=event.instrument, units=event.units,
+                ref=event.ref, pair=event.pair, units=event.units,
                 price=event.price, order_type=event.order_type, time=event.time)
             self.event_q.put(order)
             self.logger.info(f"OrderEvent Issued: {order}")
@@ -134,7 +134,7 @@ class Portfolio(object):
         _delta_upl: Decimal
 
         _delta_balance, _delta_upl = \
-            self.positions[event.instrument].reflect_filled_order(
+            self.positions[event.pair].reflect_filled_order(
                 event.units, event.price
             )
 
diff --git a/src/savoia/strategy/strategy.py b/src/savoia/strategy/strategy.py
index d4fe2d3..d32ffc9 100644
--- a/src/savoia/strategy/strategy.py
+++ b/src/savoia/strategy/strategy.py
@@ -25,12 +25,12 @@ class DummyStrategy(object):
         self.invested = False
 
     def calculate_signals(self, event: TickEvent) -> None:
-        if event.type == 'TICK' and event.instrument == self.pairs[0]:
+        if event.type == 'TICK' and event.pair == self.pairs[0]:
             if self.ticks % 1500 == 0:
                 if self.invested is False:
                     signal = SignalEvent(
                         ref=str(self.ticks),
-                        instrument=self.pairs[0],
+                        pair=self.pairs[0],
                         order_type="market",
                         units=Decimal(100),
                         time=event.time,
@@ -41,7 +41,7 @@ class DummyStrategy(object):
                 else:
                     signal = SignalEvent(
                         ref=str(self.ticks),
-                        instrument=self.pairs[0],
+                        pair=self.pairs[0],
                         order_type="market",
                         units=Decimal(-100),
                         time=event.time,
@@ -88,7 +88,7 @@ class MovingAverageCrossStrategy(object):
 
     def calculate_signals(self, event: TickEvent) -> None:
         if event.type == 'TICK':
-            pair = event.instrument
+            pair = event.pair
             price = event.bid
             pd = self.pairs_dict[pair]
             if pd["ticks"] == 0:
diff --git a/src/savoia/ticker/ticker.py b/src/savoia/ticker/ticker.py
index 3156b26..df1be2a 100644
--- a/src/savoia/ticker/ticker.py
+++ b/src/savoia/ticker/ticker.py
@@ -62,7 +62,7 @@ class Ticker(object):
             raise Exception(f"Incorrect EventType: {event.type}, " +
                 "expected 'TICK' event.")
         else:
-            _pair = event.instrument
+            _pair = event.pair
             _bid = event.bid
             _ask = event.ask
             _time = event.time


Test patch:
diff --git a/tests/event/event_test.py b/tests/event/event_test.py
index c5c4171..a99e036 100644
--- a/tests/event/event_test.py
+++ b/tests/event/event_test.py
@@ -5,58 +5,91 @@ import pandas as pd
 
 class TestEvent():
     @pytest.mark.skip()
-    @pytest.mark.parametrize("instrument, time, bid, ask", [
+    @pytest.mark.parametrize("pair, time, bid, ask", [
         ("JPYUSD", "2018-01-16T20:31:22.579385Z", '98.02', '100.13'),
     ])
-    def test_TickEvent(self, instrument: str, time: str, bid: str, ask: str) -> None:
+    def test_TickEvent(self, pair: str, time: str, bid: str, ask: str) -> None:
         from savoia.event.event import TickEvent, EventType
         t = pd.Timestamp(time)
         b = Decimal(bid)
         a = Decimal(ask)
 
-        tick = TickEvent(instrument, t, b, a)
+        tick = TickEvent(pair, t, b, a)
 
         assert tick.type == EventType("TICK")
-        assert tick.instrument == instrument
+        assert tick.pair == pair
         assert tick.time == t
         assert tick.bid == b
         assert tick.ask == a
 
-        assert str(tick) == "Type: TICK, Instrument: %s, Time: %s, Bid: %s, Ask: %s" \
-                            % (str(instrument), str(t), str(b), str(a))
+        assert str(tick) == "Type: TICK, Pair: %s, Time: %s, Bid: %s, Ask: %s" \
+                            % (str(pair), str(t), str(b), str(a))
 
-    @pytest.mark.skip()
-    @pytest.mark.parametrize("instrument, order_type, side, time", [
-        ("JPYUSD", "market", "buy", "2018-01-16T20:31:22.579385Z"),
+    @pytest.mark.parametrize("ref, pair, order_type, units, time, price", [
+        ("REF123", "JPYUSD", "market", "200", "2018-01-16 20:31:22", "102.34"),
     ])
-    def test_SignalEvent(self, instrument: str, order_type: str, side: str, time: str) -> None:
+    def test_SignalEvent(self, ref: str, pair: str, order_type: str, units: str,
+            time: str, price: str) -> None:
         from savoia.event.event import SignalEvent, EventType
-        t = pd.Timestamp(time)
-        signal = SignalEvent(instrument, order_type, side, t)
+        signal = SignalEvent(ref, pair, pd.Timestamp(time), order_type,
+            Decimal(units), Decimal(price))
 
         assert signal.type == EventType("SIGNAL")
-        assert signal.instrument == instrument
+        assert signal.pair == pair
         assert signal.order_type == order_type
-        assert signal.side == side
-        assert signal.time == t
+        assert signal.units == Decimal(units)
+        assert signal.time == pd.Timestamp(time)
+        assert signal.price == Decimal(price)
 
-        assert str(signal) == "Type: SIGNAL, Instrument: %s, Order Type: %s, Side: %s, Time: %s" \
-            % (str(instrument), str(order_type), str(side), str(t))
+        _form = "Type: %s, Ref: %s, Pair: %s, Time: %s, OrderType: %s, " + \
+            "Units: %s, Price: %s"
+        assert str(signal) == _form \
+            % ('SIGNAL', ref, pair, pd.Timestamp(time), order_type,
+                Decimal(units), Decimal(price))
 
-    @pytest.mark.skip()
-    @pytest.mark.parametrize("instrument, units, order_type, side", [
-        ("JPYUSD", 100, "market", "buy"),
+    @pytest.mark.parametrize("ref, pair, order_type, units, time, price", [
+        ("REF123", "JPYUSD", "market", "200", "2018-01-16 20:31:22", "102.34"),
     ])
-    def test_OrderEvent(self, instrument: str, units: int, order_type: str, side: str) -> None:
+    def test_OrderEvent(self, ref: str, pair: str, order_type: str, units: int,
+            time: str, price: str) -> None:
         from savoia.event.event import OrderEvent, EventType
 
-        order = OrderEvent(instrument, units, order_type, side)
+        order = OrderEvent(ref, pair, pd.Timestamp(time), order_type,
+            Decimal(units), Decimal(price))
 
         assert order.type == EventType("ORDER")
-        assert order.instrument == instrument
-        assert order.units == units
+        assert order.pair == pair
+        assert order.units == Decimal(units)
         assert order.order_type == order_type
-        assert order.side == side
+        assert order.units == Decimal(units)
+        assert order.price == Decimal(price)
+
+        _form = "Type: %s, Ref: %s, Pair: %s, Time: %s, OrderType: %s, " + \
+            "Units: %s, Price: %s"
+        assert str(order) == _form \
+            % (
+                'ORDER', ref, pair, pd.Timestamp(time), order_type,
+                Decimal(units), Decimal(price))
+
+    @pytest.mark.parametrize("ref, pair, status, units, time, price", [
+        ("REF123", "JPYUSD", "filled", "200", "2018-01-16 20:31:22", "102.34"),
+    ])
+    def test_FillEvent(self, ref: str, pair: str, status: str, units: int,
+            time: str, price: str) -> None:
+        from savoia.event.event import FillEvent, EventType
+
+        fill = FillEvent(ref, pair, pd.Timestamp(time),
+            Decimal(units), Decimal(price), status)
+
+        assert fill.type == EventType("FILL")
+        assert fill.pair == pair
+        assert fill.units == Decimal(units)
+        assert fill.status == status
+        assert fill.units == Decimal(units)
+        assert fill.price == Decimal(price)
 
-        assert str(order) == "Type: ORDER, Instrument: %s, Units: %s, Order Type: %s, Side: %s" \
-            % (str(instrument), str(units), str(order_type), str(side))
+        _form = "Type: %s, Ref: %s, Pair: %s, Time: %s, " + \
+            "Units: %s, Price: %s, Status: %s"
+        assert str(fill) == _form % (
+            'FILL', ref, pair, pd.Timestamp(time),
+            Decimal(units), Decimal(price), status)
diff --git a/tests/execution/execution_test.py b/tests/execution/execution_test.py
index 7abd6fa..ec05bec 100644
--- a/tests/execution/execution_test.py
+++ b/tests/execution/execution_test.py
@@ -29,13 +29,19 @@ def test_return_fill_event(setupSE: Tuple['Queue[Event]', 'Queue[Event]',
         SimulatedExecution]) -> None:
     event_q, exec_q, se = setupSE
     
-    exec_q.put(OrderEvent('ID1234', "USDJPY", Decimal('0.5'), Decimal('107.89'),
-        'market', pd.Timestamp('2020-07-10 20:59:32')))
+    exec_q.put(OrderEvent(
+        ref='ID1234',
+        pair="USDJPY",
+        time=pd.Timestamp('2020-07-10 20:59:32'),
+        order_type='market',
+        units=Decimal('0.5'),
+        price=Decimal('107.89')
+    ))
     exec_q.put(None)
     se.run()
     
     fe: FillEvent = event_q.get(False)
     assert fe.ref == 'ID1234'
-    assert fe.instrument == 'USDJPY'
+    assert fe.pair == 'USDJPY'
     assert fe.units == Decimal('0.5')
     assert fe.status == 'filled'
diff --git a/tests/portfolio/portfolio_test.py b/tests/portfolio/portfolio_test.py
index 12f1982..554b5c0 100644
--- a/tests/portfolio/portfolio_test.py
+++ b/tests/portfolio/portfolio_test.py
@@ -78,11 +78,16 @@ def test_create_equity_file(port: Portfolio) -> None:
 def test_execute_signal(pair: str, order_type: str, units: str, time: str,
         price: str, port: Portfolio, ref: str) -> None:
     _price = None if price is None else Decimal(price)
-    port.execute_signal(SignalEvent(ref, pair, order_type, Decimal(units),
-        pd.Timestamp(time), _price))
+    port.execute_signal(SignalEvent(
+        ref=ref,
+        pair=pair,
+        time=pd.Timestamp(time),
+        order_type=order_type,
+        units=Decimal(units),
+        price=_price))
     _order: OrderEvent = port.event_q.get()
     
-    assert _order.instrument == pair
+    assert _order.pair == pair
     assert _order.units == Decimal(units)
     assert _order.order_type == order_type
     assert _order.time == pd.Timestamp(time)
@@ -105,8 +110,14 @@ def test_execute_signal_lackofticker(port: Portfolio,
     port.ticker.prices[pair][quote] = None
     print(port.ticker.prices[pair])
     with LogCapture() as log:
-        port.execute_signal(event=SignalEvent(ref, pair, order_type,
-            Decimal(units), pd.Timestamp(time)))
+        port.execute_signal(event=SignalEvent(
+            ref=ref,
+            pair=pair,
+            time=pd.Timestamp(time),
+            order_type=order_type,
+            units=Decimal(units),
+            price=Decimal('103.2')
+        ))
         log.check(
             ('savoia.portfolio.portfolio', 'INFO', "Unable to execute order " +
              'as price data was insufficient.')
@@ -168,10 +179,22 @@ def test_execute_fill_exit_entry(
         TickerMock1: Ticker) -> None:
     port = Portfolio(TickerMock1, Queue(), home_currency, ['GBPUSD', 'USDJPY'],
         Decimal(equity), True)
-    port.execute_fill(FillEvent('ref123', pair, Decimal(units),
-        Decimal(exec_price), 'filled', pd.Timestamp('2020-07-08 21:56:00')))
-    port.execute_fill(FillEvent('ref123', pair, Decimal(exit_units),
-        Decimal(exit_price), 'filled', pd.Timestamp('2020-07-08 21:56:00')))
+    port.execute_fill(FillEvent(
+        ref='ref123',
+        pair=pair,
+        time=pd.Timestamp('2020-07-08 21:56:00'),
+        units=Decimal(units),
+        price=Decimal(exec_price),
+        status='filled'
+    ))
+    port.execute_fill(FillEvent(
+        ref='ref123',
+        pair=pair,
+        time=pd.Timestamp('2020-07-08 21:56:00'),
+        units=Decimal(exit_units),
+        price=Decimal(exit_price),
+        status='filled'
+    ))
     
     assert port.balance == Decimal(exp_balance)
     assert port.upl == Decimal(exp_upl)
@@ -220,8 +243,14 @@ def test_update_portfolio(home_currency: str, pair: Pair, exec_price: str,
         exp_equity: str, TickerMock1: Ticker, TickerMock2: Ticker) -> None:
     port = Portfolio(TickerMock1, Queue(), home_currency,
         ["GBPUSD", "EURUSD", "USDJPY"], Decimal(equity), True)
-    port.execute_fill(FillEvent('ref123', pair, Decimal(units),
-        Decimal(exec_price), 'filled', pd.Timestamp('2020-07-08 21:56:00')))
+    port.execute_fill(FillEvent(
+        ref='ref123',
+        pair=pair,
+        time=pd.Timestamp('2020-07-08 21:56:00'),
+        units=Decimal(units),
+        price=Decimal(exec_price),
+        status='filled'
+    ))
     
     for _pair in ['USDJPY', 'GBPUSD']:
         bid = TickerMock2.prices[_pair]['bid']
@@ -258,8 +287,14 @@ def test_update_portfolio_home(home_currency: str, pair: Pair, exec_price: str,
         exp_equity: str, TickerMock1: Ticker, TickerMock2: Ticker) -> None:
     port = Portfolio(TickerMock1, Queue(), home_currency,
         ["GBPUSD", "EURUSD", "USDJPY"], Decimal(equity), True)
-    port.execute_fill(FillEvent('ref123', pair, Decimal(units),
-        Decimal(exec_price), 'filled', pd.Timestamp('2020-07-08 21:56:00')))
+    port.execute_fill(FillEvent(
+        ref='ref123',
+        pair=pair,
+        time=pd.Timestamp('2020-07-08 21:56:00'),
+        units=Decimal(units),
+        price=Decimal(exec_price),
+        status='filled'
+    ))
     
     for _pair in ['USDJPY']:
         bid = TickerMock2.prices[_pair]['bid']