### Initialize Flumine Framework Source: https://github.com/betcode-org/flumine/blob/master/docs/index.md Initialize the Betfair client and the Flumine framework. This is the basic setup required to start using flumine. ```python import betfairlightweight from flumine import Flumine, clients # Initialize your client trading = betfairlightweight.APIClient("username") client = clients.BetfairClient(trading) # Initialize the framework framework = Flumine(client=client) ``` -------------------------------- ### Basic Simulation Setup Source: https://github.com/betcode-org/flumine/blob/master/docs/quickstart.md Set up Flumine for strategy simulation using a SimulatedClient and a historical market data stream. ```python from flumine import FlumineSimulation, clients from flumine.streams.betfairhistoricalstream import BetfairHistoricalStream client = clients.SimulatedClient() framework = FlumineSimulation(client=client) file_path = "/tmp/marketdata/1.170212754" strategy = ExampleStrategy( stream=BetfairHistoricalStream( file_path=file_path, ) ) framework.add_strategy(strategy) framework.run() ``` -------------------------------- ### Basic Flumine Setup and Strategy Source: https://github.com/betcode-org/flumine/blob/master/README.md Sets up the Flumine framework with a basic strategy that checks market books but does not execute orders. This is a starting point for custom strategy development. ```python import betfairlightweight from flumine import Flumine, BaseStrategy, clients from flumine.streams.betfairmarketstream import BetfairMarketStream from betfairlightweight.filters import streaming_market_filter # Define your strategy here class ExampleStrategy(BaseStrategy): def check_market_book(self, market, market_book) -> bool: # process_market_book only executed if this returns True return True def process_market_book(self, market, market_book): # Your strategy logic pass # Initialize your client trading = betfairlightweight.APIClient("username") client = clients.BetfairClient(trading) # Initialize the framework framework = Flumine(client) # Add your strategy to the framework with a stream framework.add_strategy( ExampleStrategy( stream=BetfairMarketStream( framework, market_filter=streaming_market_filter( event_type_ids=["7"], country_codes=["GB"], market_types=["WIN"], ), ) ) ) # Start the trading framework framework.run() ``` -------------------------------- ### Paper Trading Client Setup Source: https://github.com/betcode-org/flumine/blob/master/docs/quickstart.md Initialize a Betfair client for paper trading. This client simulates live trading without real money. ```python from flumine import clients client = clients.BetfairClient(trading, paper_trade=True) ``` -------------------------------- ### Run the Flumine Framework Source: https://github.com/betcode-org/flumine/blob/master/docs/quickstart.md Start the Flumine framework to begin processing market data and executing strategy logic. Ensure the framework is properly initialized before calling run(). ```python framework.run() ``` -------------------------------- ### Example Flumine Strategy Source: https://github.com/betcode-org/flumine/blob/master/docs/index.md A comprehensive example strategy demonstrating how to define a custom strategy, process market data, and place/manage orders. This strategy places a LAY order for selections with a last traded price below 1.5 and manages existing orders. ```python import betfairlightweight from betfairlightweight.filters import streaming_market_filter from betfairlightweight.resources import MarketBook from flumine import Flumine, BaseStrategy, clients from flumine.order.trade import Trade from flumine.order.order import LimitOrder, OrderStatus from flumine.markets.market import Market from flumine.streams.betfairmarketstream import BetfairMarketStream class ExampleStrategy(BaseStrategy): def start(self, flumine) -> None: print("starting strategy 'ExampleStrategy'") def check_market_book(self, market: Market, market_book: MarketBook) -> bool: # process_market_book only executed if this returns True if market_book.status != "CLOSED": return True return False def process_market_book(self, market: Market, market_book: MarketBook) -> None: # process marketBook object for runner in market_book.runners: if runner.status == "ACTIVE" and runner.last_price_traded < 1.5: trade = Trade( market_id=market_book.market_id, selection_id=runner.selection_id, handicap=runner.handicap, strategy=self, ) order = trade.create_order( side="LAY", order_type=LimitOrder(price=1.01, size=2.00) ) market.place_order(order) def process_orders(self, market: Market, orders: list) -> None: for order in orders: if order.status == OrderStatus.EXECUTABLE: if order.size_remaining == 2.00: market.cancel_order(order, 0.02) # reduce size to 1.98 if order.order_type.persistence_type == "LAPSE": market.update_order(order, "PERSIST") if order.size_remaining > 0: market.replace_order(order, 1.02) # move # Initialize your client trading = betfairlightweight.APIClient("username") client = clients.BetfairClient(trading) # Initialize the framework framework = Flumine(client) # Add your strategy to the framework with a stream framework.add_strategy( ExampleStrategy( stream=BetfairMarketStream( framework, market_filter=streaming_market_filter( event_type_ids=["7"], country_codes=["GB"], market_types=["WIN"], ), ) ) ) # Start the trading framework framework.run() ``` -------------------------------- ### Install Flumine Source: https://github.com/betcode-org/flumine/blob/master/docs/index.md Install the flumine package using pip. Requires Python 3.10+. ```bash pip install flumine ``` -------------------------------- ### Setup JSON Logger Source: https://github.com/betcode-org/flumine/blob/master/docs/advanced.md Configure the Python logging module to use JSON formatting for detailed logs. This setup is useful for structured logging and analysis. ```python import time import logging from pythonjsonlogger import jsonlogger logger = logging.getLogger() custom_format = "% (asctime) %(levelname) %(message)" log_handler = logging.StreamHandler() formatter = jsonlogger.JsonFormatter(custom_format) formatter.converter = time.gmtime log_handler.setFormatter(formatter) logger.addHandler(log_handler) logger.setLevel(logging.INFO) ``` -------------------------------- ### Initialize FlumineSimulation Framework with Historical Stream Source: https://github.com/betcode-org/flumine/blob/master/docs/version_migrations.md Shows the v3 setup for FlumineSimulation, adapted to match live trading configurations. It highlights changes like renaming 'market_filter' to 'file_path' and moving 'listener_kwargs'. ```python import betfairlightweight from flumine import FlumineSimulation, clients from flumine.streams.betfairhistoricalstream import BetfairHistoricalStream # Initialize your client client = clients.SimulatedClient() # Initialize the framework framework = FlumineSimulation(client=client) # Add your strategy to the framework with a stream (this can be a list) file_path="tests/resources/PRO-1.170258213" strategy = LowestLayer( stream=BetfairHistoricalStream( file_path=file_path, listener_kwargs={"inplay": True} ), max_order_exposure=1000, max_selection_exposure=105, context={"stake": 2}, ) framework.add_strategy(strategy) # Start the trading framework framework.run() ``` -------------------------------- ### Optimized Simulation Stream Configuration Source: https://github.com/betcode-org/flumine/blob/master/docs/quickstart.md Configure a historical stream for faster simulation by limiting updates using listener arguments like 'inplay' and 'seconds_to_start'. This example focuses on preplay data. ```python stream = BetfairHistoricalStream( file_path=file_path, listener_kwargs={"inplay": False, "seconds_to_start": 600}, ) ``` -------------------------------- ### Single Stream with Multiple Strategies Source: https://github.com/betcode-org/flumine/blob/master/docs/version_migrations.md Illustrates how to attach multiple strategies to a single data stream. This setup is useful when several strategies need to process the same market data. ```python # Create stream(s) (market data) stream = BetfairMarketStream( framework, market_filter=streaming_market_filter( event_type_ids=["7"], country_codes=["GB"], market_types=["WIN"], ), ) # create strategy and subscribe to stream(s) strategy = ExampleStrategy(name="one", stream=stream) framework.add_strategy(strategy) strategy = ExampleStrategy(name="two", stream=stream) framework.add_strategy(strategy) ``` -------------------------------- ### Custom Middleware Implementation Source: https://github.com/betcode-org/flumine/blob/master/docs/markets.md Provides an example of creating a custom middleware class by extending the base `Middleware` class. The `__call__` method is invoked on each `MarketBook` update, while `add_market` and `remove_market` are called when a market is added or removed from the framework. ```python from flumine.markets.middleware import Middleware class CustomMiddleware(Middleware): def __call__(self, market) -> None: pass # called on each MarketBook update def add_market(self, market) -> None: print("market {0} added".format(market.market_id)) def remove_market(self, market) -> None: print("market {0} removed".format(market.market_id)) ``` -------------------------------- ### Define a Basic Flumine Strategy Source: https://github.com/betcode-org/flumine/blob/master/docs/quickstart.md Create a custom strategy by inheriting from BaseStrategy. Implement start, check_market_book, and process_market_book methods to define trading logic. ```python from flumine import BaseStrategy class ExampleStrategy(BaseStrategy): def start(self, flumine): # subscribe to streams print("starting strategy 'ExampleStrategy'") def check_market_book(self, market, market_book): # process_market_book only executed if this returns True if market_book.status != "CLOSED": return True def process_market_book(self, market, market_book): # process marketBook object print(market_book.status) ``` -------------------------------- ### Flumine Strategy with Order Execution Source: https://github.com/betcode-org/flumine/blob/master/README.md Implements a Flumine strategy that includes logic for placing, canceling, and replacing orders based on market conditions. This example demonstrates how to interact with the Betfair API for live trading. ```python import betfairlightweight from flumine import Flumine, BaseStrategy, clients from flumine.order.trade import Trade from flumine.order.order import LimitOrder, OrderStatus from flumine.markets.market import Market from flumine.streams.betfairmarketstream import BetfairMarketStream from betfairlightweight.filters import streaming_market_filter from betfairlightweight.resources import MarketBook class ExampleStrategy(BaseStrategy): def start(self, flumine) -> None: print("starting strategy 'ExampleStrategy'") def check_market_book(self, market: Market, market_book: MarketBook) -> bool: # process_market_book only executed if this returns True if market_book.status != "CLOSED": return True def process_market_book(self, market: Market, market_book: MarketBook) -> None: # process marketBook object for runner in market_book.runners: if runner.status == "ACTIVE" and runner.last_price_traded < 1.5: trade = Trade( market_id=market_book.market_id, selection_id=runner.selection_id, handicap=runner.handicap, strategy=self ) order = trade.create_order( side="LAY", order_type=LimitOrder(price=1.01, size=2.00) ) market.place_order(order) def process_orders(self, market: Market, orders: list) -> None: for order in orders: if order.status == OrderStatus.EXECUTABLE: if order.size_remaining == 2.00: market.cancel_order(order, 0.02) # reduce size to 1.98 if order.order_type.persistence_type == "LAPSE": market.update_order(order, "PERSIST") if order.size_remaining > 0: market.replace_order(order, 1.02) # move # Initialize your client trading = betfairlightweight.APIClient("username") client = clients.BetfairClient(trading) # Initialize the framework framework = Flumine(client) # Add your strategy to the framework with a stream framework.add_strategy( ExampleStrategy( stream=BetfairMarketStream( framework, market_filter=streaming_market_filter( event_type_ids=["7"], country_codes=["GB"], market_types=["WIN"], ), ) ) ) # Start the trading framework framework.run() ``` -------------------------------- ### Configure Listener for Historical Data (Specific Timeframe) Source: https://github.com/betcode-org/flumine/blob/master/docs/performance.md Use listener_kwargs to specify the number of seconds before a scheduled start and to disable inplay data processing for historical streams. ```python stream = BetfairHistoricalStream( file_path="/tmp/marketdata/1.170212754", listener_kwargs={\"seconds_to_start\": 600, \"inplay\": False}, ) ``` -------------------------------- ### Multiprocessing for Flumine Simulation Source: https://github.com/betcode-org/flumine/blob/master/docs/performance.md Utilize multiprocessing to run Flumine simulations across multiple CPU cores, processing markets in chunks to manage memory and improve speed. Ensure 'smart_open' is installed for S3 compatibility. ```python import os import math import smart_open from concurrent import futures from unittest.mock import patch as mock_patch from flumine import FlumineSimulation, clients, utils from flumine.streams.betfairhistoricalstream import BetfairHistoricalStream from strategies.lowestlayer import LowestLayer def run_process(markets): client = clients.SimulatedClient() framework = FlumineSimulation(client=client) streams = [] for market in markets: stream = BetfairHistoricalStream(file_path=market) framework.streams.add_stream(stream) streams.append(stream) strategy = LowestLayer( streams=streams, context={\"stake\": 2}, ) with mock_patch("builtins.open", smart_open.open): framework.add_strategy(strategy) framework.run() if __name__ == "__main__": all_markets = [...] # Replace with your list of market files processes = os.cpu_count() markets_per_process = 8 # optimal _process_jobs = [] with futures.ProcessPoolExecutor(max_workers=processes) as p: chunk = min( markets_per_process, math.ceil(len(all_markets) / processes) ) for m in (utils.chunks(all_markets, chunk)): _process_jobs.append( p.submit( run_process, markets=m, ) ) for job in futures.as_completed(_process_jobs): job.result() # wait for result ``` -------------------------------- ### Initialize Flumine Framework with Strategy and Stream Source: https://github.com/betcode-org/flumine/blob/master/docs/version_migrations.md Demonstrates the v3 initialization of the Flumine framework, allowing users to control data streams and strategy subscriptions. Requires importing necessary modules and initializing a Betfair client. ```python import betfairlightweight from flumine import Flumine, clients from flumine.streams.betfairmarketstream import BetfairMarketStream from betfairlightweight.filters import streaming_market_filter # Initialize your client trading = betfairlightweight.APIClient("username") client = clients.BetfairClient(trading) # Initialize the framework framework = Flumine(client) # Add your strategy to the framework with a stream framework.add_strategy( ExampleStrategy( stream=BetfairMarketStream( framework, market_filter=streaming_market_filter( event_type_ids=["7"], country_codes=["GB"], market_types=["WIN"], ), ) ) ) # Start the trading framework framework.run() ``` -------------------------------- ### Initiate and Add Strategy to Framework Source: https://github.com/betcode-org/flumine/blob/master/docs/quickstart.md Instantiate a strategy with a BetfairMarketStream, configuring market filters for data subscription. Then, add the strategy to the Flumine framework. ```python from flumine.streams.betfairmarketstream import BetfairMarketStream from betfairlightweight.filters import ( streaming_market_filter, streaming_market_data_filter, ) strategy = ExampleStrategy( stream=BetfairMarketStream( framework, market_filter=streaming_market_filter( event_type_ids=["7"], country_codes=["GB"], market_types=["WIN"], ), market_data_filter=streaming_market_data_filter(fields=["EX_ALL_OFFERS"]) ) ) framework.add_strategy(strategy) ``` -------------------------------- ### Add SimulatedClient to Framework Source: https://github.com/betcode-org/flumine/blob/master/docs/clients.md Instantiate and add a SimulatedClient to the FlumineSimulation framework. Requires a username. ```python from flumine import FlumineSimulation, clients framework = FlumineSimulation() client = clients.SimulatedClient(username="123") framework.add_client(client) ``` -------------------------------- ### Configure Race Data Recorder Source: https://github.com/betcode-org/flumine/blob/master/docs/sportsdata.md Set up the MarketRecorder strategy to record race data using BetfairRaceDataStream. This involves specifying context for file handling. ```python from flumine.streams.betfairdatastream import BetfairRaceDataStream strategy= MarketRecorder( stream=BetfairRaceDataStream(framework), context={ "local_dir": "/tmp", "force_update": False, "remove_file": True, "remove_gz_file": False, }, ) ``` -------------------------------- ### Place a Limit Order in Flumine Source: https://github.com/betcode-org/flumine/blob/master/docs/quickstart.md Demonstrates how to create and place a LimitOrder within a strategy's process_market_book method. Orders are validated, stored, and sent for execution. ```python from flumine.order.trade import Trade from flumine.order.order import LimitOrder class ExampleStrategy(BaseStrategy): def process_market_book(self, market, market_book): for runner in market_book.runners: if runner.selection_id == 123: trade = Trade( market_id=market_book.market_id, selection_id=runner.selection_id, handicap=runner.handicap, strategy=self ) order = trade.create_order( side="LAY", order_type=LimitOrder(price=1.01, size=2.00) ) market.place_order(order) ``` -------------------------------- ### Load and Prepare DataFrames Source: https://github.com/betcode-org/flumine/blob/master/examples/controls/analysis.ipynb Imports necessary libraries and loads backtest data from a JSON file into pandas DataFrames for strategies, markets, and orders. Ensure the JSON file exists at the specified path. ```python import json import pandas as pd import seaborn as sns import matplotlib.pyplot as plt sns.set_theme(style="darkgrid") filename = "/tmp/orders.json" with open(filename, "r") as f: data = json.load(f) df_strategies = pd.DataFrame(data["strategies"]) df_markets = pd.DataFrame(data["markets"]) df_orders = pd.DataFrame(data["orders"]) ``` -------------------------------- ### Create and Interact with a BetfairOrder Object Source: https://github.com/betcode-org/flumine/blob/master/docs/trades.md Initialize a BetfairOrder with trade, side, and order type. Check its status and use methods to determine executability and completion. ```python from flumine.order.order import BetfairOrder, LimitOrder order = BetfairOrder( trade=trade, side="LAY", order_type=LimitOrder(price=1.01, size=2.00) ) order.status # OrderStatus.PENDING order.executable() order.execution_complete() ``` -------------------------------- ### Subscribe/Unsubscribe Streams Dynamically Source: https://github.com/betcode-org/flumine/blob/master/docs/version_migrations.md Demonstrates how to subscribe or unsubscribe a strategy from a stream after the strategy has been initialized. This provides flexibility in managing strategy-stream connections during runtime. ```python strategy = ExampleStrategy() strategy.subscribe_to_stream(stream) strategy.unsubscribe_from_stream(stream) ``` -------------------------------- ### Add BetfairClient to Framework Source: https://github.com/betcode-org/flumine/blob/master/docs/clients.md Instantiate and add a BetfairClient to the Flumine framework. Ensure the trading object is available. ```python from flumine import Flumine, clients framework = Flumine() client = clients.BetfairClient(trading) framework.add_client(client) ``` -------------------------------- ### Create and Manage a Trade Object Source: https://github.com/betcode-org/flumine/blob/master/docs/trades.md Instantiate a Trade object with market and selection details. Access its orders and status, and create new orders associated with the trade. ```python from flumine.order.trade import Trade from flumine.order.ordertype import LimitOrder trade = Trade( market_id="1.2345678", selection_id=123456, handicap=1.0, strategy=strategy ) trade.orders # [] trade.status # TradeStatus.LIVE order = trade.create_order( side="LAY", order_type=LimitOrder(price=1.01, size=2.00) ) trade.orders # [] ``` -------------------------------- ### Batch Orders using Flumine Transactions Source: https://github.com/betcode-org/flumine/blob/master/docs/quickstart.md Illustrates how to group multiple orders into a single transaction using a context manager. Orders can be placed, executed, and cancelled within a transaction block. ```python with market.transaction() as t: market.place_order(order) # executed immediately in separate transaction t.place_order(order) # executed on transaction __exit__ with market.transaction() as t: t.place_order(order) t.execute() # above order executed t.cancel_order(order) t.place_order(order) # both executed on transaction __exit__ ``` -------------------------------- ### Place Order Using Specific Client Source: https://github.com/betcode-org/flumine/blob/master/docs/clients.md Place an order using a specific client instance. This overrides the default client selection for the transaction. ```python client = self.clients.get_client(VenueType.SIMULATED, username="123") market.place_order(order, client=client) ``` -------------------------------- ### Analyze and Visualize Backtest Results Source: https://github.com/betcode-org/flumine/blob/master/examples/controls/analysis.ipynb Calculates cumulative profit and ROI, then generates line plots for profit and ROI against average matched price, grouped by race type. Requires 'df' DataFrame to be pre-populated. ```python group_by = "race_type" x_axis = "info__average_price_matched" xlim = None ylim = None palette = "ch:r=-.5,l=.75" df = df.sort_values(x_axis) df['cum_profit'] = df.simulated__profit.groupby(df[group_by]).cumsum() df['cum_roi'] = df.simulated__profit.groupby(df[group_by]).cumsum() / df.info__size_matched.groupby(df[group_by]).cumsum() f, ax = plt.subplots(figsize=(16, 7), nrows=2, gridspec_kw={'height_ratios':[3, 1]}) # Profit sns.lineplot( ax=ax[0], x=x_axis, y="cum_profit", hue=group_by, data=df, palette=palette, legend=False ) ax[0].set(xlabel=None, ylabel="Profit (£)") # ROI sns.lineplot( ax=ax[1], x=x_axis, y="cum_roi", hue=group_by, data=df, palette=palette ) ax[1].set(xlabel="Average Price Matched", ylabel="ROI (%)") plt.show() ``` -------------------------------- ### Adding Custom Middleware to Framework Source: https://github.com/betcode-org/flumine/blob/master/docs/markets.md Shows how to register a custom middleware instance with the Flumine framework. This allows the custom middleware's logic to be applied to market updates and management. ```python framework.add_logging_control(CustomMiddleware()) ``` -------------------------------- ### Multiple Streams with a Single Strategy Source: https://github.com/betcode-org/flumine/blob/master/docs/version_migrations.md Shows how a single strategy can subscribe to multiple data streams concurrently. This allows a strategy to process data from different market types or venues simultaneously. ```python # Create stream(s) (market data) stream_one = BetfairMarketStream( framework, market_filter=streaming_market_filter( event_type_ids=["7"], country_codes=["GB"], market_types=["WIN"], ), ) stream_two = BetfairMarketStream( framework, market_filter=streaming_market_filter( event_type_ids=["1"], country_codes=["GB"], market_types=["MATCH_ODDS"], ), ) # create strategy and subscribe to stream(s) strategy = ExampleStrategy(name="one", streams=[stream_one, stream_two]) framework.add_strategy(strategy) ``` -------------------------------- ### Configure Cricket Data Recorder Source: https://github.com/betcode-org/flumine/blob/master/docs/sportsdata.md Set up the MarketRecorder strategy to record cricket data using BetfairCricketDataStream. This involves specifying context for file handling. ```python from flumine.streams.betfairdatastream import BetfairCricketDataStream strategy= MarketRecorder( stream=BetfairCricketDataStream(framework), context={ "local_dir": "/tmp", "force_update": False, "remove_file": True, "remove_gz_file": False, }, ) ``` -------------------------------- ### Simulation with Event Groups Source: https://github.com/betcode-org/flumine/blob/master/docs/quickstart.md Configure event groups for parallel simulation of specific events. Events with matching group IDs will be processed together. ```python stream = BetfairHistoricalStream( file_path=file_path, event_processing=True, event_groups={"123": "A", "456": "A"}, ) ``` -------------------------------- ### Add Race Subscription to SportsDataStream Source: https://github.com/betcode-org/flumine/blob/master/docs/sportsdata.md Instantiate and add a race subscription to the SportsDataStream. ```python sports_data_stream = SportsDataStream( framework, sports_data_filter="raceSubscription", ) framework.add_stream(sports_data_stream) ``` -------------------------------- ### Access Specific Simulated Client in Strategy Source: https://github.com/betcode-org/flumine/blob/master/docs/clients.md Retrieve a specific Simulated client by VenueType and username. Useful when multiple clients of the same type are configured. ```python client = self.clients.get_client(VenueType.SIMULATED, username="123") ``` -------------------------------- ### Market Transaction Control Source: https://github.com/betcode-org/flumine/blob/master/docs/markets.md Demonstrates how to use the market transaction context manager to control order execution. Orders placed directly within the `with` block are executed immediately, while orders placed on the transaction object `t` are executed upon exiting the block or explicitly with `t.execute()`. ```python with market.transaction() as t: market.place_order(order) # executed immediately in separate transaction t.place_order(order) # executed on transaction __exit__ ``` ```python with market.transaction() as t: t.place_order(order) .. t.execute() # above order executed .. t.cancel_order(order) t.place_order(order) # both executed on transaction __exit__ ``` -------------------------------- ### Profile Python Code with cprofilev Source: https://github.com/betcode-org/flumine/blob/master/docs/performance.md Use the cprofilev tool to profile your Python scripts and identify performance bottlenecks. This is crucial for optimizing complex simulations. ```bash python -m cprofilev examples/simulate.py ``` -------------------------------- ### Place Order Within Transaction Using Specific Client Source: https://github.com/betcode-org/flumine/blob/master/docs/clients.md Place an order within a transaction context, specifying a particular client. Ensures the order is processed by the intended client. ```python client = self.clients.get_client(VenueType.SIMULATED, username="123") with market.transaction(client=client) as t: t.place_order(order) ``` -------------------------------- ### Access Default Betfair Client in Strategy Source: https://github.com/betcode-org/flumine/blob/master/docs/clients.md Retrieve the default Betfair client configured for the strategy. Uses the first added client of the specified VenueType. ```python betfair_client = self.clients.get_default(VenueType.BETFAIR) ``` -------------------------------- ### Add Custom Logging Control Source: https://github.com/betcode-org/flumine/blob/master/docs/controls.md Instantiate and add a `LoggingControl` to the framework to enable custom logging. The base class creates debug logs. ```python from flumine.controls.loggingcontrols import LoggingControl control = LoggingControl() framework.add_logging_control(control) ``` -------------------------------- ### Simulation with Event Processing Enabled Source: https://github.com/betcode-org/flumine/blob/master/docs/quickstart.md Enable event processing for simulating multiple markets or events concurrently. This allows Flumine to handle related markets like win/place in racing. ```python stream = BetfairHistoricalStream( file_path=file_path, event_processing=True, ) ``` -------------------------------- ### Use Real Time in Simulation Source: https://github.com/betcode-org/flumine/blob/master/docs/advanced.md Temporarily bypass Flumine's simulated datetime patching during simulation to access the real system time. This is useful for testing time-sensitive operations. ```python import datetime with framework.simulated_datetime.real_time(): print(datetime.datetime.now(datetime.timezone.utc)) ``` -------------------------------- ### Define a Flumine Data Strategy Source: https://github.com/betcode-org/flumine/blob/master/docs/quickstart.md Create a strategy that processes raw data streams using BetfairDataStream. Implement the process_raw_data method for handling incoming data. ```python from flumine import BaseStrategy from flumine.streams.betfairdatastream import BetfairDataStream class ExampleDataStrategy(BaseStrategy): def process_raw_data(self, publish_time, data): print(publish_time, data) strategy = ExampleDataStrategy( stream=BetfairDataStream( framework, market_filter=streaming_market_filter( event_type_ids=["7"], country_codes=["GB"], market_types=["WIN"], ), ) ) flumine.add_strategy(strategy) ``` -------------------------------- ### Skip Trading Controls with force=True Source: https://github.com/betcode-org/flumine/blob/master/docs/controls.md Pass `force=True` to `place_order`, `cancel_order`, `update_order`, or `replace_order` to bypass trading controls. This is useful for operations like canceling orders when limits are reached. ```python market.place_order(order, force=True) transaction.place_order(order, force=True) ``` -------------------------------- ### Implement a Custom Stream in Python Source: https://github.com/betcode-org/flumine/blob/master/docs/advanced.md Create a custom stream by subclassing BaseStream and defining its run method. This allows for custom data fetching and event processing logic. Ensure to push custom events through the flumine handler queue. ```python from flumine.streams.basestream import BaseStream from flumine.events.events import CustomEvent class CustomStream(BaseStream): def run(self) -> None: # connect to stream / make API requests etc. response = api_call() # callback func def callback(framework, event): for strategy in framework.strategies: strategy.process_my_event(event) # push results through using custom event event = CustomEvent(response, callback) # put in main queue self.flumine.handler_queue.put(event) custom_stream = CustomStream(framework, custom=True) framework.streams.add_stream(custom_stream) ``` -------------------------------- ### Accessing Linked Markets Source: https://github.com/betcode-org/flumine/blob/master/docs/quickstart.md Retrieve a linked market, such as a 'PLACE' market, from a 'Market' object using its event key. ```python place_market = market.event["PLACE"] ```