Repository: liampauling/flumine
Pull request #202 (2020-06-03 15:58:27)

release branch created


Patch:
diff --git a/HISTORY.rst b/HISTORY.rst
index 860a60f..7f7b70a 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -3,6 +3,18 @@
 Release History
 ---------------
 
+1.6.3 (2020-06-03)
++++++++++++++++++++
+
+**Improvements**
+
+- #178 Client order stream disable/enable
+- #179 Info properties
+
+**Bug Fixes**
+
+- #191 missing git config
+
 1.6.2 (2020-06-03)
 +++++++++++++++++++
 
diff --git a/flumine/__version__.py b/flumine/__version__.py
index a0c94e1..709bed4 100644
--- a/flumine/__version__.py
+++ b/flumine/__version__.py
@@ -1,6 +1,6 @@
 __title__ = "flumine"
 __description__ = "Betfair trading framework"
 __url__ = "https://github.com/liampauling/flumine"
-__version__ = "1.6.2"
+__version__ = "1.6.3"
 __author__ = "Liam Pauling"
 __license__ = "MIT"
diff --git a/flumine/baseflumine.py b/flumine/baseflumine.py
index fa526df..b59a3f5 100644
--- a/flumine/baseflumine.py
+++ b/flumine/baseflumine.py
@@ -1,5 +1,6 @@
 import queue
 import logging
+import threading
 from typing import Type
 from betfairlightweight import resources
 
@@ -151,7 +152,7 @@ class BaseFlumine:
     ) -> Market:
         market = Market(self, market_id, market_book)
         self.markets.add_market(market_id, market)
-        logger.info("Adding: {0} to markets".format(market.market_id))
+        logger.info("Adding: {0} to markets".format(market.market_id), extra=self.info)
         return market
 
     def _process_raw_data(self, event: events.RawDataEvent) -> None:
@@ -213,11 +214,15 @@ class BaseFlumine:
 
         self.cleared_market_queue.put(market.market_id)
         self.log_control(event)
+        logger.info(
+            "Market removed", extra={"market_id": market.market_id, **self.info}
+        )
 
     def _process_cleared_orders(self, event):
         # todo update blotter?
         logger.info(
-            "Market closed and cleared", extra={"market_id": event.event.market_id},
+            "Market closed and cleared",
+            extra={"market_id": event.event.market_id, **self.info},
         )
 
     def _process_cleared_markets(self, event: events.ClearedMarketsEvent):
@@ -236,8 +241,23 @@ class BaseFlumine:
         for strategy in self.strategies:
             strategy.finish()
 
+    @property
+    def info(self) -> dict:
+        return {
+            "client": self.client.info,
+            "markets": {
+                "market_count": len(self.markets),
+                "open_market_count": len(self.markets.open_market_ids),
+                "live_orders": self.markets.live_orders,
+                "markets": [m.market_id for m in self.markets],
+            },
+            "streams": [s for s in self.streams],
+            "logging_controls": self._logging_controls,
+            "threads": threading.enumerate(),
+        }
+
     def __enter__(self):
-        logger.info("Starting flumine")
+        logger.info("Starting flumine", extra=self.info)
         # add execution to clients
         self.client.add_execution(self)
         # simulated
@@ -276,4 +296,4 @@ class BaseFlumine:
         # logout
         self.client.logout()
         self._running = False
-        logger.info("Exiting flumine")
+        logger.info("Exiting flumine", extra=self.info)
diff --git a/flumine/clients/baseclient.py b/flumine/clients/baseclient.py
index 8a1aec1..e5f2865 100644
--- a/flumine/clients/baseclient.py
+++ b/flumine/clients/baseclient.py
@@ -22,6 +22,7 @@ class BaseClient:
         commission_base: float = DEFAULT_COMMISSION_BASE,
         interactive_login: bool = False,
         id_: str = None,
+        order_stream: bool = True,
     ):
         self.id = id_ or create_short_uuid()
         self.betting_client = betting_client
@@ -29,6 +30,7 @@ class BaseClient:
         self.capital_base = capital_base
         self.commission_base = commission_base
         self.interactive_login = interactive_login
+        self.order_stream = order_stream
 
         self.account_details = None
         self.account_funds = None
@@ -67,3 +69,13 @@ class BaseClient:
     @property
     def min_bsp_liability(self) -> Optional[float]:
         raise NotImplementedError
+
+    @property
+    def info(self) -> dict:
+        return {
+            "id": self.id,
+            "exchange": self.EXCHANGE.value if self.EXCHANGE else None,
+            "betting_client": self.betting_client,
+            "chargeable_transaction_count": self.chargeable_transaction_count,
+            "trading_controls": self.trading_controls,
+        }
diff --git a/flumine/streams/streams.py b/flumine/streams/streams.py
index c453a59..98214d4 100644
--- a/flumine/streams/streams.py
+++ b/flumine/streams/streams.py
@@ -31,10 +31,10 @@ class Streams:
             strategy.streams.append(stream)
 
     def add_client(self, client: BaseClient) -> None:
-        if client.EXCHANGE == ExchangeType.SIMULATED:
-            self.add_simulated_order_stream()
-        elif client.EXCHANGE == ExchangeType.BETFAIR:
-            self.add_order_stream(client)
+        if client.order_stream:
+            # todo if paper_trade: add_simulated_order_stream()
+            if client.EXCHANGE == ExchangeType.BETFAIR:
+                self.add_order_stream(client)
 
     """ market data """
 


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 1c30c22..79d1968 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -65,6 +65,8 @@ jobs:
 
     - name: Publish
       run: |
+        git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
+        git config --local user.name "GitHub Action"
         twine upload dist/*
         mkdocs gh-deploy --force
       env:
diff --git a/tests/test_baseflumine.py b/tests/test_baseflumine.py
index 4558083..f90b498 100644
--- a/tests/test_baseflumine.py
+++ b/tests/test_baseflumine.py
@@ -170,8 +170,9 @@ class BaseFlumineTest(unittest.TestCase):
         mock_event.callback.assert_called_with(self.base_flumine, mock_event)
         mock__process_market_orders.assert_called_with(mock_market)
 
+    @mock.patch("flumine.baseflumine.BaseFlumine.info")
     @mock.patch("flumine.baseflumine.BaseFlumine.log_control")
-    def test__process_close_market(self, mock_log_control):
+    def test__process_close_market(self, mock_log_control, mock_info):
         mock_strategy = mock.Mock()
         mock_strategy.stream_ids = [1, 2, 3]
         self.base_flumine.strategies = [mock_strategy]
@@ -219,6 +220,9 @@ class BaseFlumineTest(unittest.TestCase):
     def test__process_end_flumine(self):
         self.base_flumine._process_end_flumine()
 
+    def test_info(self):
+        self.assertTrue(self.base_flumine.info)
+
     @mock.patch("flumine.baseflumine.events")
     @mock.patch("flumine.baseflumine.BaseFlumine.log_control")
     def test_enter_exit(self, mock_log_control, mock_events):
diff --git a/tests/test_clients.py b/tests/test_clients.py
index aaaa593..c7a1814 100644
--- a/tests/test_clients.py
+++ b/tests/test_clients.py
@@ -27,6 +27,7 @@ class BaseClientTest(unittest.TestCase):
         self.assertEqual(self.base_client.chargeable_transaction_count, 0)
         self.assertIsNone(self.base_client.execution)
         self.assertEqual(self.base_client.trading_controls, [])
+        self.assertTrue(self.base_client.order_stream)
 
     def test_login(self):
         with self.assertRaises(NotImplementedError):
@@ -65,6 +66,9 @@ class BaseClientTest(unittest.TestCase):
         with self.assertRaises(NotImplementedError):
             assert self.base_client.min_bsp_liability
 
+    def test_info(self):
+        self.assertTrue(self.base_client.info)
+
 
 class BetfairClientTest(unittest.TestCase):
     def setUp(self):
diff --git a/tests/test_streams.py b/tests/test_streams.py
index 3da6bd7..6bd467c 100644
--- a/tests/test_streams.py
+++ b/tests/test_streams.py
@@ -58,20 +58,20 @@ class StreamsTest(unittest.TestCase):
         self.streams(mock_strategy)
         self.assertEqual(len(mock_strategy.streams), 0)
 
-    @mock.patch("flumine.streams.streams.Streams.add_simulated_order_stream")
-    def test_add_client_simulated(self, mock_add_simulated_order_stream):
-        mock_client = mock.Mock()
-        mock_client.EXCHANGE = streams.ExchangeType.SIMULATED
-        self.streams.add_client(mock_client)
-        mock_add_simulated_order_stream.assert_called_with()
-
     @mock.patch("flumine.streams.streams.Streams.add_order_stream")
     def test_add_client_betfair(self, mock_add_order_stream):
-        mock_client = mock.Mock()
+        mock_client = mock.Mock(order_stream=True)
         mock_client.EXCHANGE = streams.ExchangeType.BETFAIR
         self.streams.add_client(mock_client)
         mock_add_order_stream.assert_called_with(mock_client)
 
+    @mock.patch("flumine.streams.streams.Streams.add_order_stream")
+    def test_add_client_no_order_stream(self, mock_add_order_stream):
+        mock_client = mock.Mock(order_stream=False)
+        mock_client.EXCHANGE = streams.ExchangeType.BETFAIR
+        self.streams.add_client(mock_client)
+        mock_add_order_stream.assert_not_called()
+
     @mock.patch("flumine.streams.streams.Streams._increment_stream_id")
     def test_add_stream_new(self, mock_increment):
         mock_strategy = mock.Mock()