# Decorated strategies and runtime



Use `@backtest` plus `runtime.run` when a strategy file should carry its default execution settings. For a script or notebook that constructs the run itself, [Backtest](https://docs.openbacktesting.com/reference/core/index.md) is the shorter path.

[backtest](https://docs.openbacktesting.com/reference/runtime/#openbacktesting-backtest-declaration) · [discover](https://docs.openbacktesting.com/reference/runtime/#openbacktesting-runtime-discover) · [describe](https://docs.openbacktesting.com/reference/runtime/#openbacktesting-runtime-describe) · [run](https://docs.openbacktesting.com/reference/runtime/#openbacktesting-runtime-run) · [RunLogs](https://docs.openbacktesting.com/reference/runtime/#openbacktesting-runlogs) · [CommissionType](https://docs.openbacktesting.com/reference/runtime/#openbacktesting-commissiontype) · [QuantityType](https://docs.openbacktesting.com/reference/runtime/#openbacktesting-quantitytype) · [SlippageType](https://docs.openbacktesting.com/reference/runtime/#openbacktesting-slippagetype) · [ExecutionTiming](https://docs.openbacktesting.com/reference/runtime/#openbacktesting-executiontiming) · [EndPolicy](https://docs.openbacktesting.com/reference/runtime/#openbacktesting-endpolicy) · [optimize](https://docs.openbacktesting.com/reference/runtime/#openbacktesting-runtime-optimize) · [resume_optimization](https://docs.openbacktesting.com/reference/runtime/#openbacktesting-runtime-resume-optimization)

## Define and run a decorated strategy

```python
from openbacktesting import (
    Strategy, backtest, runtime, DataContext, Timeframe, EndPolicy,
)
from openbacktesting.broker import InstrumentSpec
from openbacktesting.test import GOOG

@backtest(cash=10_000, commission_value=0.2,
          end_policy=EndPolicy.CLOSE_AT_LAST_CLOSE)
class HoldOne(Strategy):
    def init(self):
        pass

    def next(self):
        if self.bar_index == 0:
            self.buy(qty=1)

data = GOOG.copy()
data.index = data.index.tz_localize("UTC")
description = runtime.describe(globals())
result = runtime.run(
    globals(), data=data, context=DataContext(Timeframe.days(1), "UTC"),
    instrument=InstrumentSpec(symbol="GOOG"),
)
print(result["Return [%]"])
```

Here `commission_value=0.2` means **0.2%**, whereas the direct `Backtest` argument is `commission=0.002`. A declaration stores settings without running the strategy. `runtime.run` adopts them; plain `Backtest` does not.

## Decorator settings

| Setting | Values and units |
| --- | --- |
| `cash`, `spread`, `margin`, `risk_free_rate` | Initial balance, fractional execution spread, margin fraction, and annualized statistics rate. See [Backtest](https://docs.openbacktesting.com/reference/core/index.md#constructor-parameters). |
| `commission_type`, `commission_value` | `CommissionType.PERCENT` uses percentage points; `CASH_PER_ORDER` uses fee per fill; `CASH_PER_CONTRACT` uses fee per asset unit. |
| `default_qty_type`, `default_qty_value` | `QuantityType.FIXED` uses asset units; `PERCENT_OF_EQUITY` uses `(0, 100]`, e.g. `20` for 20%. `None` requires explicit order sizing. |
| `slippage_type`, `slippage_value` | `SlippageType.BPS` uses basis points; `FIXED` uses price distance. |
| `execution_timing` | `ExecutionTiming.NEXT_OPEN` or `SAME_CLOSE`. |
| `end_policy` | `EndPolicy.MARK_TO_MARKET` or `CLOSE_AT_LAST_CLOSE`. |
| `allow_short`, `max_gross_exposure`, `hedging`, `exclusive_orders` | Trading controls described on [Backtest](https://docs.openbacktesting.com/reference/core/index.md). |

Use the enums imported from `openbacktesting` in decorators. Strategy parameters belong in [inputs](https://docs.openbacktesting.com/reference/inputs/index.md), not decorator settings. Instrument rules and timeframe come from the data supplied for each run.

## Runtime arguments and discovery

`namespace` is the loaded module mapping (`globals()` in the example, or `vars(module)`). It must contain exactly one concrete strategy directly decorated in that module. `runtime.discover(namespace)` returns the class; `runtime.describe(namespace)` returns its input schema and settings without running it.

| `runtime.run` argument | What to pass |
| --- | --- |
| `request` | Optional title-based input request from `inputs.request_for`; omit to use defaults. |
| `data`, `context`, `instrument` | Required chart data, timezone/timeframe, and asset rules. Data must have an aware DatetimeIndex. |
| `settings` | Sparse dictionary overriding declaration settings, e.g. `{"cash": 20000}`. Changing a quantity/cost type requires its value too. |
| `options` | Optional `indicator_cache_bytes`, `plotting`, and `plotting_limits` controls. |
| `logs` | Optional `RunLogs()` to retain logs when execution raises. |

The result is the same statistics Series as `Backtest.run`, with effective settings in `result.attrs["backtest_snapshot"]`. `runtime` runs an already loaded module; loading arbitrary Python executes code and should be limited to scripts you trust.

For a separate strategy file, load it as an importable Python module, then pass `vars(module)`. The [file runner example](https://docs.openbacktesting.com/repository/examples/advanced/run_author.py/index.md) demonstrates this from a source checkout.

<a id="openbacktesting-backtest-declaration"></a>



## backtest

```python
backtest(
    *,
    cash=10000,
    spread=0.0,
    commission_type=CommissionType.PERCENT,
    commission_value=0.0,
    risk_free_rate=0.0,
    default_qty_type=QuantityType.FIXED,
    default_qty_value=None,
    margin=1.0,
    execution_timing=ExecutionTiming.NEXT_OPEN,
    slippage_type=SlippageType.BPS,
    slippage_value=0.0,
    allow_short=True,
    max_gross_exposure=None,
    hedging=False,
    exclusive_orders=False,
    end_policy=EndPolicy.MARK_TO_MARKET,
)
```

Attach default backtest settings to a concrete strategy class; the host supplies actual market data and execution.

<a id="openbacktesting-runtime-discover"></a>



## discover

```python
runtime.discover(namespace)
```

Discover the single concrete strategy directly decorated in this module; deduplicate aliases and exclude imported and inherited entry points.

<a id="openbacktesting-runtime-describe"></a>



## describe

```python
runtime.describe(namespace)
```

Export inputs and complete default backtest settings without market data or executing the strategy lifecycle.

<a id="openbacktesting-runtime-run"></a>



## run

```python
runtime.run(
    namespace,
    request=None,
    *,
    data,
    context,
    instrument,
    settings=None,
    options=None,
    logs=None,
)
```

Run a new session for this chart and return existing results plus backtest_snapshot.

<a id="openbacktesting-runlogs"></a>



## RunLogs

```python
RunLogs()
```

Host-owned single-run log session, injected through runtime.run(..., logs=session).

<a id="openbacktesting-runlogs-get-logs"></a>



### RunLogs.get_logs

```python
RunLogs.get_logs()
```

Return an independent copy of all logs from this run; an empty list before the first run.

Create `logs = RunLogs()`, pass it to `runtime.run(..., logs=logs)`, and read `logs.get_logs()` after success or in an exception handler. Reusing it for another run clears the previous records.

## Setting enums

<a id="openbacktesting-commissiontype"></a>



## CommissionType

Author-facing commission type; PERCENT uses percentage points, and other members use account amounts.

| Member | Value |
| --- | --- |
| `CommissionType.PERCENT` | `percent` |
| `CommissionType.CASH_PER_ORDER` | `cash_per_order` |
| `CommissionType.CASH_PER_CONTRACT` | `cash_per_contract` |

<a id="openbacktesting-commissiontype-percent"></a>


<a id="openbacktesting-commissiontype-cash-per-order"></a>


<a id="openbacktesting-commissiontype-cash-per-contract"></a>



<a id="openbacktesting-quantitytype"></a>



## QuantityType

Default order size: Fixed asset quantity or a percentage of equity at request time.

| Member | Value |
| --- | --- |
| `QuantityType.FIXED` | `fixed` |
| `QuantityType.PERCENT_OF_EQUITY` | `percent_of_equity` |

<a id="openbacktesting-quantitytype-fixed"></a>


<a id="openbacktesting-quantitytype-percent-of-equity"></a>



<a id="openbacktesting-slippagetype"></a>



## SlippageType

Slippage distance: Fixed price units or basis points of price.

| Member | Value |
| --- | --- |
| `SlippageType.FIXED` | `fixed` |
| `SlippageType.BPS` | `bps` |

<a id="openbacktesting-slippagetype-fixed"></a>


<a id="openbacktesting-slippagetype-bps"></a>



<a id="openbacktesting-executiontiming"></a>



## ExecutionTiming

Execution timing: Process no earlier than the next bar, or process new unconditional market orders at this bar's close.

| Member | Value |
| --- | --- |
| `ExecutionTiming.NEXT_OPEN` | `next_open` |
| `ExecutionTiming.SAME_CLOSE` | `same_close` |

<a id="openbacktesting-executiontiming-next-open"></a>


<a id="openbacktesting-executiontiming-same-close"></a>



<a id="openbacktesting-endpolicy"></a>



## EndPolicy

End policy: Retain marked positions or liquidate actual positions at the final close.

| Member | Value |
| --- | --- |
| `EndPolicy.MARK_TO_MARKET` | `mark_to_market` |
| `EndPolicy.CLOSE_AT_LAST_CLOSE` | `close_at_last_close` |

<a id="openbacktesting-endpolicy-mark-to-market"></a>


<a id="openbacktesting-endpolicy-close-at-last-close"></a>



## Parameter experiments

`runtime.optimize` saves every candidate's Portfolio; `runtime.resume_optimization` continues an existing experiment with matching inputs, source identity, and market data. See [saved experiments](https://docs.openbacktesting.com/reference/optimizer/index.md) for a complete example and argument meanings.

<a id="openbacktesting-runtime-optimize"></a>



## optimize

```python
runtime.optimize(
    namespace,
    search,
    *,
    path,
    identity,
    data,
    context,
    instrument,
    request=None,
    settings=None,
    constraint=None,
    constraint_id=None,
    cancel=None,
    on_progress=None,
)
```

Exhaustively search selected inputs sequentially, committing each complete Portfolio to a new local result database.

<a id="openbacktesting-runtime-resume-optimization"></a>



## resume_optimization

```python
runtime.resume_optimization(
    namespace,
    *,
    path,
    experiment_id,
    identity,
    data,
    context,
    instrument,
    request=None,
    settings=None,
    constraint=None,
    constraint_id=None,
    cancel=None,
    on_progress=None,
)
```

Resume unfinished trials after checking current declarations, inputs, and execution identity; failed trials are not automatically retried.

[Data and instruments](https://docs.openbacktesting.com/reference/data/index.md) · [Strategy parameters](https://docs.openbacktesting.com/reference/inputs/index.md) · [User manual](https://docs.openbacktesting.com/index.md)
