PositionSizer#
- class qf_lib.backtesting.position_sizer.position_sizer.PositionSizer(broker: Broker, data_provider: DataProvider, order_factory: OrderFactory, signals_register: SignalsRegister)[source]#
Bases:
objectConverts
Signalobjects into sized orders.Concrete implementations map each signal to a target portfolio weight or value, then call
OrderFactory. Whenuse_stop_losses=True,size_signals()also attaches stop orders fromfraction_at_riskandlast_available_price.See
SimplePositionSizer,FixedPortfolioPercentagePositionSizer,InitialRiskPositionSizer, andInitialRiskWithVolumePositionSizer.- size_signals(signals: List[Signal], use_stop_losses: bool = True, time_in_force: TimeInForce = TimeInForce.OPG, frequency: Frequency = None) List[Order][source]#
Based on the signals provided, creates a list of Orders where proper sizing has been applied
- Parameters:
signals (List[Signal]) – list of signals, based on which the orders will be created
use_stop_losses (bool) – if true, for each MarketOrder generated for a signal, additionally a StopOrder will be created
time_in_force (TimeInForce) – time in force, which will be used to create the Orders based on the provided Signals
frequency (Frequency) – frequency of trading, further used to create Orders
details (StopOrders)
-------------------
quantity (For each Market Order a Stop Order is generated if and only if the quantity in Market Order + position)
close (for this ticker != 0. This means that StopOrders are not generated if the MarketOrder should completely)
ticker. (the position for the)
- Returns:
Market orders sized by the concrete position sizer, optionally followed by stop orders.
- Return type:
List[Order]
Examples
Portfolio value is 100,000, price is 100, so a full LONG targets 1,000 shares:
>>> sizer = SimplePositionSizer(broker, data_provider, order_factory, BacktestSignalsRegister()) >>> long_signal = Signal(ticker, Exposure.LONG, 0.02, 100.0, now) >>> orders = sizer.size_signals([long_signal], use_stop_losses=False) >>> len(orders) 1 >>> orders[0].quantity 1000.0
With
use_stop_losses=True(default), a stop is added atlast_available_price * (1 - fraction_at_risk)for a LONG signal:>>> orders = sizer.size_signals([long_signal], use_stop_losses=True) >>> len(orders) 2 >>> orders[1].execution_style.stop_price 98.0
An
Exposure.OUTsignal with no open position is ignored (no orders):>>> flat_signal = Signal(ticker, Exposure.OUT, 0.02, 100.0, now) >>> sizer.size_signals([flat_signal], use_stop_losses=False) []