---
title: "Getting Started"
description: "OpenPit ships public SDKs for:"
---

<!-- markdownlint-disable MD033 -->
# Getting Started

OpenPit ships public SDKs for:

- Go [module `go.openpit.dev/openpit`](https://go.openpit.dev/openpit)
- Python [package `openpit`](https://pypi.org/project/openpit/)
- JavaScript / TypeScript [package `@openpit/engine`](https://www.npmjs.com/package/@openpit/engine)
- C++ [`OpenPit::openpit` CMake target](https://github.com/openpitkit/pit)
- Rust [crate `openpit`](https://crates.io/crates/openpit)
- C [API header and docs](https://docs.openpit.dev/c-api/)

All SDKs follow the same operational flow:

1. Build an engine once during application startup.
2. Run the `start stage` for each order.
3. `Execute request` if the start stage passes.
4. `Finalize reservation` explicitly.
5. `Apply execution report` after realized outcomes are known.

Prose uses the conceptual step names; exact API names stay inside the code
blocks.

## Integration route

Record your SDK version and target platform before coding. This wiki and the
`main` links below describe current development and may be newer than an
installed package. For a released SDK, select its tag in the
[source repository](https://github.com/openpitkit/pit/tags) before copying
README examples or runnable scenarios. Check the API surface shipped with that
version and its [release notes](https://github.com/openpitkit/pit/releases);
do not infer one binding's method names from another.

1. **Install and run a first example.** Read
   [Runtime Delivery](Runtime-Delivery.md) for native prerequisites and runtime
   selection, then use the selected binding's installation and quick start:

   <!-- markdownlint-disable MD013 -->
   | SDK | Install | First example |
   | --- | --- | --- |
   | Go | [Guide](https://github.com/openpitkit/pit/blob/main/bindings/go/README.md#install) | [Quick start](https://github.com/openpitkit/pit/blob/main/bindings/go/README.md#quick-start) |
   | Python | [Guide](https://github.com/openpitkit/pit/blob/main/bindings/python/README.md#install) | [Quick start](https://github.com/openpitkit/pit/blob/main/bindings/python/README.md#quick-start) |
   | JavaScript / TypeScript | [Guide](https://github.com/openpitkit/pit/blob/main/bindings/js/README.md#install) | [Quick start](https://github.com/openpitkit/pit/blob/main/bindings/js/README.md#quick-start) |
   | C++ | [Guide](https://github.com/openpitkit/pit/blob/main/bindings/cpp/README.md#getting-started) | [Quick start](https://github.com/openpitkit/pit/blob/main/bindings/cpp/README.md#quick-start) |
   | Rust | [Guide](https://github.com/openpitkit/pit/blob/main/crates/openpit/README.md#install) | [Quick start](https://github.com/openpitkit/pit/blob/main/crates/openpit/README.md#quick-start) |
   | C | [Guide](https://github.com/openpitkit/pit/blob/main/bindings/c/README.md#install) | [Quick start](https://github.com/openpitkit/pit/blob/main/bindings/c/README.md#quick-start) |
   <!-- markdownlint-enable MD013 -->

2. **Handle both verdicts and failures.** Use [Domain Types](Domain-Types.md)
   for values and precision, [Errors](Errors.md) for each binding's error model,
   and [Reject Codes](Reject-Codes.md) for business decisions. Demonstrate one
   accepted order and one policy rejection before adding more controls.
3. **Connect the lifecycle.** Follow [Pre-trade Pipeline](Pre-trade-Pipeline.md)
   for reservation finalization and execution feedback. Read
   [Pre-Trade Lock](Pre-Trade-Lock.md) before persisting orders that need later
   reconciliation, and [Threading Contract](Threading-Contract.md) before sharing
   an engine or its state across execution contexts.
4. **Add the controls your application needs.** Start with [Policies](Policies.md).
   Use [Account Groups](Account-Groups.md) for membership and group-aware controls,
   [Market Data](Market-Data.md) for account-specific and group quotes, and
   [Policy API](Policy-API.md) for custom checks and their state contracts.
5. **Validate the integration.** Use the same release's
   [runnable examples](https://github.com/openpitkit/pit/tree/main/examples)
   as a starting point. Exercise acceptance, rejection, reservation rollback,
   and execution feedback in your application's tests. SDK contributor checks
   are separate and documented in [Building From Source](Building-From-Source.md).

### Prompt for a coding assistant

Replace the bracketed fields before using this prompt:

```text
Integrate OpenPit into [application] using [language], [SDK version], and
[target platform]. Start at:
https://wiki.openpit.dev/Getting-Started/#integration-route

Use public documentation and examples matching the installed SDK version.
Use the selected binding's API names; do not translate another binding's API.
First demonstrate an accepted order and a documented policy rejection. Then
connect application-owned venue submission, explicit reservation finalization,
and execution feedback according to the lifecycle and threading contracts.
Preserve locks and persistent state where the selected policies require them.
Add account scopes, market data, or custom policies only as required.
Do not invent missing APIs or silently substitute behavior. Identify a missing
contract or prerequisite before continuing with work that depends on it.
Report the SDK version, documentation used, changes, and validation results.
```

## Install

### Go

```bash
go get go.openpit.dev/openpit
```

### Python

```bash
pip install openpit
```

### JavaScript / TypeScript

```bash
npm install @openpit/engine
```

Node.js 18 and later load the packaged Node WebAssembly build. Browser and edge
bundles use the base64-inlined WebAssembly build, so they do not need `fetch`,
`fs`, or a separately hosted `.wasm` file. Both runtimes initialize
synchronously on import for the common path. See
[Runtime Delivery](Runtime-Delivery.md) for the full resolution matrix.

No build step is needed in a browser or in Deno: import the package straight
from a CDN.

```html
<script type="module">
  import { Engine } from "https://esm.sh/@openpit/engine";
  // or: https://cdn.jsdelivr.net/npm/@openpit/engine/+esm
</script>
```

Deno also accepts the npm specifier directly.

<!-- markdownlint-disable-next-line MD013 -->
<!-- Test mirror: https://github.com/openpitkit/pit/blob/main/bindings/js/tests/examples.readme.test.ts -->
```ts
import { Engine as DenoEngine } from "npm:@openpit/engine";
```

### C++

The C++ binding is a CMake config package. Pull it in with `FetchContent` and
link the `OpenPit::openpit` alias; the prebuilt runtime is resolved
automatically.

```cmake
include(FetchContent)
FetchContent_Declare(
  openpit
  GIT_REPOSITORY https://github.com/openpitkit/pit.git
  SOURCE_SUBDIR  bindings/cpp
)
FetchContent_MakeAvailable(openpit)

target_link_libraries(my_app PRIVATE OpenPit::openpit)
```

Include `<openpit/openpit.hpp>` for the complete SDK surface, or
`<openpit/fwd.hpp>` in precompiled headers when forward declarations are
enough. See [Runtime Delivery](Runtime-Delivery.md) for how the package finds the
runtime library and for the Windows DLL-copy helper.

#### C++ Through vcpkg

[vcpkg](https://vcpkg.io/) is the packaged alternative. Declare the dependency
in the project manifest, `vcpkg.json`:

<!-- markdownlint-disable-next-line MD013 -->
<!-- Test mirror: https://github.com/openpitkit/pit/blob/main/e2e/scripts/cpp-vcpkg.sh -->
```json
{
  "name": "your-project",
  "version-string": "0",
  "builtin-baseline": "<microsoft-vcpkg-commit>",
  "dependencies": ["openpit"]
}
```

`builtin-baseline` is a commit of the `microsoft/vcpkg` checkout the project
builds against; `vcpkg x-update-baseline --add-initial-baseline` fills it in. It
fixes the package versions of the whole build and is required for both
installation paths below.

Consume the port like any other CMake package, then configure the project with
the vcpkg toolchain file. The normal runtime resolver takes over from there.

<!-- markdownlint-disable-next-line MD013 -->
<!-- Test mirror: https://github.com/openpitkit/pit/blob/main/e2e/clients/cpp/CMakeLists.txt -->
```cmake
find_package(OpenPit CONFIG REQUIRED)
target_link_libraries(your_target PRIVATE OpenPit::openpit)
```

##### Managed OpenPit registry

The [managed registry](https://github.com/openpitkit/vcpkg-registry) receives
every release first and is the way to install OpenPit through vcpkg today. It
takes one extra file next to the manifest, `vcpkg-configuration.json`:

<!-- markdownlint-disable-next-line MD013 -->
<!-- Test mirror: https://github.com/openpitkit/pit/blob/main/e2e/scripts/cpp-vcpkg.sh -->
```json
{
  "registries": [
    {
      "kind": "git",
      "repository": "https://github.com/openpitkit/vcpkg-registry.git",
      "baseline": "<openpit-registry-commit>",
      "packages": ["openpit"]
    }
  ]
}
```

This `baseline` is a commit of the managed registry, not of `microsoft/vcpkg`;
every release note publishes the commit to use.

##### Public microsoft/vcpkg registry

Not available yet: the OpenPit port is in upstream review. Once it is accepted,
the manifest above is the whole setup, because vcpkg already ships with this
registry; new releases reach it with a delay, and the managed registry keeps
getting them first.

### Rust

```bash
cargo add openpit
```

### C

Install the generated header and matching native runtime from the same release,
then link the runtime into your application. Follow the
[C installation guide](https://github.com/openpitkit/pit/blob/main/bindings/c/README.md#install)
and its quick start; use the [C API reference](https://docs.openpit.dev/c-api/)
for exact signatures and ownership rules.

## Example: Build an Engine

The examples below are host-integration sketches. Venue submission is supplied
by your application: `send_order_to_venue` and `sendOrderToVenue` are not OpenPit
APIs. Use the binding READMEs in the [integration route](#integration-route) for
a self-contained first example. When wiring a real venue, follow the
[reservation lifecycle](Pre-trade-Pipeline.md#reservation) and
[lock persistence rules](Pre-Trade-Lock.md#the-order-lifecycle).

<details>
<summary>Go</summary>

<!-- markdownlint-disable-next-line MD013 -->
<!-- Test mirror: https://github.com/openpitkit/pit/blob/main/bindings/go/examples_wiki_test.go -->
```go
package main

import (
 "fmt"
 "log"
 "time"

 "go.openpit.dev/openpit"
 "go.openpit.dev/openpit/model"
 "go.openpit.dev/openpit/param"
 "go.openpit.dev/openpit/pkg/optional"
 "go.openpit.dev/openpit/pretrade/policies"
)

func main() {
 usd, err := param.NewAsset("USD")
 if err != nil {
  log.Fatal(err)
 }
 aapl, err := param.NewAsset("AAPL")
 if err != nil {
  log.Fatal(err)
 }

 lowerBound, err := param.NewPnlFromString("-1000")
 if err != nil {
  log.Fatal(err)
 }
 brokerMaxQty, err := param.NewQuantityFromString("500")
 if err != nil {
  log.Fatal(err)
 }
 brokerMaxNotional, err := param.NewVolumeFromString("100000")
 if err != nil {
  log.Fatal(err)
 }
 assetMaxQty, err := param.NewQuantityFromString("200")
 if err != nil {
  log.Fatal(err)
 }
 assetMaxNotional, err := param.NewVolumeFromString("50000")
 if err != nil {
  log.Fatal(err)
 }

 // 1. Build the engine (one time at the platform initialization).
 engine, err := openpit.NewEngineBuilder().
  FullSync().
  Builtin(policies.BuildOrderValidation()).
  Builtin(
   policies.BuildPnlBoundsKillSwitch().
    BrokerBarriers(
     policies.PnlBoundsBrokerBarrier{
      SettlementAsset: usd,
      LowerBound:      optional.Some(lowerBound),
     },
    ),
  ).
  Builtin(
   policies.BuildRateLimit().
    BrokerBarrier(
     policies.RateLimitBrokerBarrier{
      Limit: policies.RateLimit{
       MaxOrders: 100,
       Window:    time.Second,
      },
     },
    ),
  ).
  Builtin(
   // Quantity is keyed by the underlying asset, notional by the
   // settlement asset; broker caps apply on top.
   policies.BuildOrderSizeLimit().
    AssetBarriers(
     policies.OrderSizeAssetBarrier{
      Asset: aapl,
      Limit: policies.OrderSizeLimit{
       MaxQuantity: optional.Some(assetMaxQty),
       MaxNotional: optional.None[param.Volume](),
      },
     },
     policies.OrderSizeAssetBarrier{
      Asset: usd,
      Limit: policies.OrderSizeLimit{
       MaxQuantity: optional.None[param.Quantity](),
       MaxNotional: optional.Some(assetMaxNotional),
      },
     },
    ).
    BrokerBarrier(
     policies.OrderSizeBrokerBarrier{
      Limit: policies.OrderSizeLimit{
       MaxQuantity: optional.Some(brokerMaxQty),
       MaxNotional: optional.Some(brokerMaxNotional),
      },
     },
    ),
  ).
  Build()
 if err != nil {
  log.Fatal(err)
 }
 defer engine.Stop()

 // 2. Check an order.
 order := model.NewOrder()
 op := order.EnsureOperationView()
 op.SetInstrument(param.NewInstrument(aapl, usd))
 op.SetAccountID(param.NewAccountIDFromUint64(99224416))
 op.SetSide(param.SideBuy)
 price, _ := param.NewPriceFromString("185")
 qty, _ := param.NewQuantityFromString("100")
 op.SetTradeAmount(param.NewQuantityTradeAmount(qty))
 op.SetPrice(price)

 request, rejects, err := engine.StartPreTrade(order)
 if err != nil {
  log.Fatal(err)
 }
 if rejects != nil {
  for _, r := range rejects {
   fmt.Printf(
    "rejected by %s [%d]: %s (%s)\n",
    r.Policy, r.Code, r.Reason, r.Details,
   )
  }
  return
 }
 defer request.Close()

 // 3. Quick, lightweight checks were performed during start stage. The
 // system state has not yet changed (except controls that must observe every
 // request). Before the heavy-duty checks, other work on the request can be
 // performed simply by holding the request object.

 // 4. Real pre-trade and risk control.
 reservation, rejects, err := request.Execute()
 if err != nil {
  log.Fatal(err)
 }
 if rejects != nil {
  for _, r := range rejects {
   fmt.Printf(
    "rejected by %s [%d]: %s (%s)\n",
    r.Policy, r.Code, r.Reason, r.Details,
   )
  }
  return
 }
 defer reservation.Close()

 // Optional shortcut for the same two-stage flow:
 // reservation, rejects, err := engine.ExecutePreTrade(order)

 // 5. If the request is successfully sent to the venue, it must be committed.
 // The rollback must be called otherwise to revert all performed reservations.
 reservation.Commit()

 // 6. The order goes to the venue and returns with an execution report.
 report := model.NewExecutionReport()
 reportOp := model.NewExecutionReportOperation()
 reportOp.SetInstrument(param.NewInstrument(aapl, usd))
 reportOp.SetAccountID(param.NewAccountIDFromUint64(99224416))
 reportOp.SetSide(param.SideBuy)
 report.SetOperation(reportOp)

 pnl, _ := param.NewPnlFromString("-50")
 fee, _ := param.NewFeeFromString("3.4")
 impact := model.NewExecutionReportFinancialImpact()
 impact.SetPnl(pnl)
 impact.SetFee(fee)
 report.SetFinancialImpact(impact)

 result, err := engine.ApplyExecutionReport(report)
 if err != nil {
  log.Fatal(err)
 }

 for _, outcome := range result.AccountPnls {
  fmt.Printf("account P&L outcome for %v\n", outcome.AccountID)
 }
 for _, outcome := range result.AccountAdjustments {
  fmt.Printf("account adjustment from group %d\n", outcome.PolicyGroupID)
 }

 // 7. After each execution report is applied, the system may report that it
 // has been determined in advance that all subsequent requests will be
 // rejected if the account status does not change.
 if len(result.AccountBlocks) > 0 {
  fmt.Println("halt new orders until the blocked state is cleared")
 }
}
```

</details>

<details>
<summary>Python</summary>

<!-- markdownlint-disable-next-line MD013 -->
<!-- Test mirror: https://github.com/openpitkit/pit/blob/main/bindings/python/tests/integration/test_examples_readme.py -->
```python
import datetime
import openpit
import openpit.pretrade.policies

# 1. Build the engine (one time at the platform initialization).
broker_max_qty = openpit.param.Quantity("500")
broker_max_notional = openpit.param.Volume("100000")
asset_max_qty = openpit.param.Quantity("200")
asset_max_notional = openpit.param.Volume("50000")
engine = (
    openpit.Engine.builder()
    .no_sync()
    .builtin(openpit.pretrade.policies.build_order_validation())
    .builtin(
        openpit.pretrade.policies.build_pnl_bounds_killswitch()
        .broker_barriers(
            openpit.pretrade.policies.PnlBoundsBrokerBarrier(
                settlement_asset="USD",
                lower_bound=openpit.param.Pnl("-1000"),
            ),
        )
    )
    .builtin(
        openpit.pretrade.policies.build_rate_limit()
        .broker_barrier(
            openpit.pretrade.policies.RateLimitBrokerBarrier(
                limit=openpit.pretrade.policies.RateLimit(
                    max_orders=100,
                    window=datetime.timedelta(seconds=1),
                ),
            ),
        )
    )
    .builtin(
        # Quantity is keyed by the underlying asset, notional by the
        # settlement asset; broker caps apply on top.
        openpit.pretrade.policies.build_order_size_limit()
        .broker_barrier(
            openpit.pretrade.policies.OrderSizeBrokerBarrier(
                limit=openpit.pretrade.policies.OrderSizeLimit(
                    max_quantity=broker_max_qty,
                    max_notional=broker_max_notional,
                ),
            )
        )
        .asset_barriers(
            openpit.pretrade.policies.OrderSizeAssetBarrier(
                limit=openpit.pretrade.policies.OrderSizeLimit(
                    max_quantity=asset_max_qty,
                    max_notional=None,
                ),
                asset="AAPL",
            ),
            openpit.pretrade.policies.OrderSizeAssetBarrier(
                limit=openpit.pretrade.policies.OrderSizeLimit(
                    max_quantity=None,
                    max_notional=asset_max_notional,
                ),
                asset="USD",
            ),
        )
    )
    .build()
)

# 2. Check an order.
order = openpit.Order(
    operation=openpit.OrderOperation(
        instrument=openpit.Instrument("AAPL", "USD"),
        account_id=openpit.param.AccountId.from_int(99224416),
        side=openpit.param.Side.BUY,
        trade_amount=openpit.param.TradeAmount.quantity(100.0),
        price=openpit.param.Price(185.0),
    ),
)

start_result = engine.start_pre_trade(order=order)

if not start_result:
    messages = ", ".join(
        f"{r.policy} [{r.code}]: {r.reason}: {r.details}"
        for r in start_result.rejects
    )
    raise RuntimeError(messages)

request = start_result.request

# 3. Quick, lightweight checks, such as fat-finger scope or enabled kill
# switch, were performed during pre-trade request creation. The system state
# has not yet changed, except in cases where each request, even rejected ones,
# must be considered. Before the heavy-duty checks, other work on the request
# can be performed simply by holding the request object.

# 4. Real pre-trade and risk control.
execute_result = request.execute()

# Optional shortcut for the same two-stage flow:
# execute_result = engine.execute_pre_trade(order=order)

if not execute_result:
    messages = ", ".join(
        f"{reject.policy} [{reject.code}]: {reject.reason}: {reject.details}"
        for reject in execute_result.rejects
    )
    raise RuntimeError(messages)

reservation = execute_result.reservation

# 5. If the request is successfully sent to the venue, it must be committed.
# The rollback must be called otherwise to revert all performed reservations.
try:
    send_order_to_venue(order)
except Exception:
    reservation.rollback()
    raise

reservation.commit()

# 6. The order goes to the venue and returns with an execution report.
report = openpit.ExecutionReport(
    operation=openpit.ExecutionReportOperation(
        instrument=openpit.Instrument("AAPL", "USD"),
        account_id=openpit.param.AccountId.from_int(99224416),
        side=openpit.param.Side.BUY,
    ),
    financial_impact=openpit.FinancialImpact(
        pnl=openpit.param.Pnl("-50"),
        fee=openpit.param.Fee("3.4"),
    ),
)

result = engine.apply_execution_report(report=report)
for outcome in result.account_pnls:
    print(f"account P&L outcome for {outcome.account_id}")
for outcome in result.account_adjustments:
    print(f"account adjustment from group {outcome.policy_group_id}")

# 7. After each execution report is applied, the system may report that it has
# been determined in advance that all subsequent requests will be rejected if
# the account status does not change.
assert not result.account_blocks
```

</details>

<details>
<summary>JavaScript</summary>

<!-- markdownlint-disable-next-line MD013 -->
<!-- Test mirror: https://github.com/openpitkit/pit/blob/main/bindings/js/tests/examples_wiki.test.ts -->
```ts
import { Engine } from "@openpit/engine";
import { TradeAmount } from "@openpit/engine/param";
import {
  type ExecutionReportInit,
  type OrderInit,
} from "@openpit/engine/model";
import {
  buildOrderSizeLimit,
  buildOrderValidation,
  buildPnlBoundsKillswitch,
  buildRateLimit,
  OrderSizeAssetBarrier,
  OrderSizeBrokerBarrier,
  OrderSizeLimit,
  PnlBoundsBrokerBarrier,
  RateLimit,
  RateLimitBrokerBarrier,
} from "@openpit/engine/pretrade/policies";

// 1. Build the engine (one time at the platform initialization). The WASM
// engine is single-threaded and has no user-selectable sync mode. The first
// builtin() advances the staged builder to the ready builder; the rest register
// in place.
const ready = Engine.builder().builtin(buildOrderValidation());

ready.builtin(
  buildPnlBoundsKillswitch().brokerBarriers([
    new PnlBoundsBrokerBarrier("USD", "-1000", undefined),
  ]),
);

ready.builtin(
  buildRateLimit().brokerBarrier(
    new RateLimitBrokerBarrier(new RateLimit(100, 1000)),
  ),
);

// Quantity is keyed by the underlying asset, notional by the
// settlement asset; broker caps apply on top.
ready.builtin(
  buildOrderSizeLimit()
    .brokerBarrier(
      new OrderSizeBrokerBarrier(new OrderSizeLimit("500", "100000")),
    )
    .assetBarriers([
      new OrderSizeAssetBarrier(new OrderSizeLimit("200", undefined), "AAPL"),
      new OrderSizeAssetBarrier(
        new OrderSizeLimit(undefined, "50000"),
        "USD",
      ),
    ]),
);

const engine = ready.build();

// 2. Check an order. Scalars accept plain values (the account id as a number,
// the price as a decimal string); the order is an object literal.
const order: OrderInit = {
  operation: {
    underlyingAsset: "AAPL",
    settlementAsset: "USD",
    accountId: 99224416,
    side: "BUY",
    tradeAmount: TradeAmount.quantity("100"),
    price: "185",
  },
};

const start = engine.startPreTrade(order);
if (!start.ok) {
  const reasons = start.rejects
    .map((r) => `${r.policy} [${r.code}]: ${r.reason} (${r.details})`)
    .join(", ");
  throw new Error(reasons);
}

// 3. Quick, lightweight checks were performed during the start stage. The
// system state has not yet changed. Before the heavy-duty checks, other work on
// the request can be performed by holding the request object.

// 4. Real pre-trade and risk control.
const request = start.request;
if (request === undefined) {
  throw new Error("accepted start result is missing its request");
}
const execute = request.execute();
if (!execute.ok) {
  const reasons = execute.rejects
    .map((r) => `${r.policy} [${r.code}]: ${r.reason} (${r.details})`)
    .join(", ");
  throw new Error(reasons);
}

// Optional shortcut for the same two-stage flow:
// const execute = engine.executePreTrade(order);

// 5. If the request is successfully sent to the venue, commit; roll back
// otherwise to revert all performed reservations.
const reservation = execute.reservation;
if (reservation === undefined) {
  throw new Error("accepted execute result is missing its reservation");
}
try {
  // sendOrderToVenue(order);
  reservation.commit();
} catch (err) {
  reservation.rollback();
  throw err;
}

// 6. The order goes to the venue and returns with an execution report.
const report: ExecutionReportInit = {
  operation: {
    underlyingAsset: "AAPL",
    settlementAsset: "USD",
    accountId: 99224416,
    side: "BUY",
  },
  financialImpact: { pnl: "-50", fee: "3.4" },
};

const result = engine.applyExecutionReport(report);
for (const outcome of result.accountPnls) {
  console.log(`account P&L outcome for ${outcome.accountId.toString()}`);
}
for (const outcome of result.accountAdjustments) {
  console.log(`account adjustment from group ${outcome.policyGroupId}`);
}

// 7. A non-empty accountBlocks means a kill switch has fired for the account.
if (result.accountBlocks.length > 0) {
  console.log("halt new orders until the blocked state is cleared");
}
```

</details>

<details>
<summary>C++</summary>

<!-- markdownlint-disable-next-line MD013 -->
<!-- Test mirror: https://github.com/openpitkit/pit/blob/main/bindings/cpp/test/wiki/getting_started_test.cpp -->
```cpp
#include <openpit/openpit.hpp>
#include <openpit/pretrade/policies.hpp>

#include <iostream>

namespace policies = openpit::pretrade::policies;
using openpit::param::Fee;
using openpit::param::Pnl;
using openpit::param::Price;
using openpit::param::Quantity;
using openpit::param::Volume;

int main() {
  const Quantity brokerMaxQty = Quantity::FromString("500");
  const Volume brokerMaxNotional = Volume::FromString("100000");
  const Quantity assetMaxQty = Quantity::FromString("200");
  const Volume assetMaxNotional = Volume::FromString("50000");

  // 1. Build the engine (one time at the platform initialization).
  openpit::EngineBuilder builder(openpit::SyncPolicy::None);

  builder.Add(policies::OrderValidationPolicy{});

  policies::PnlBoundsBrokerBarrier pnlBarrier{openpit::param::Asset("USD")};
  pnlBarrier.lowerBound = Pnl::FromString("-1000");
  builder.Add(policies::PnlBoundsKillSwitchPolicy{}.BrokerBarrier(pnlBarrier));

  builder.Add(
      policies::RateLimitPolicy{}.BrokerBarrier(policies::RateLimitBrokerBarrier(
          policies::RateLimit(/*maxOrders=*/100,
                              /*windowNanoseconds=*/1'000'000'000))));

  // Quantity is keyed by the underlying asset, notional by the
  // settlement asset; broker caps apply on top.
  builder.Add(
      policies::OrderSizeLimitPolicy{}
          .BrokerBarrier(policies::OrderSizeBrokerBarrier(
              policies::OrderSizeLimit::Both(brokerMaxQty, brokerMaxNotional)))
          .AssetBarrier(policies::OrderSizeAssetBarrier(
              policies::OrderSizeLimit::Quantity(assetMaxQty),
              openpit::param::Asset("AAPL")))
          .AssetBarrier(policies::OrderSizeAssetBarrier(
              policies::OrderSizeLimit::Notional(assetMaxNotional),
              openpit::param::Asset("USD"))));

  const openpit::Engine engine = builder.Build();

  // 2. Check an order.
  openpit::model::Order order = openpit::model::Order::Limit(
      openpit::model::Instrument(::openpit::param::Asset("AAPL"),
                                 ::openpit::param::Asset("USD")),
      openpit::param::AccountId::FromUint64(99224416),
      openpit::model::Side::Buy,
      openpit::model::TradeAmount::OfQuantity(Quantity::FromString("100")),
      Price::FromString("185"));

  openpit::pretrade::StartResult start = engine.StartPreTrade(order);
  if (!start.Passed()) {
    for (const openpit::pretrade::Reject& r : start.rejects) {
      std::cout << "rejected by " << r.policy << " [" << static_cast<int>(r.code)
                << "]: " << r.reason << " (" << r.details << ")\n";
    }
    return 0;
  }
  openpit::pretrade::Request request = std::move(*start.request);

  // 3. Quick, lightweight checks were performed during the start stage. The
  // system state has not yet changed (except controls that must observe every
  // request). Before the heavy-duty checks, other work on the request can be
  // performed simply by holding the request object.

  // 4. Real pre-trade and risk control.
  openpit::pretrade::ExecuteResult executed = request.Execute();

  // Optional shortcut for the same two-stage flow:
  // openpit::pretrade::ExecuteResult executed = engine.ExecutePreTrade(order);

  if (!executed.Passed()) {
    for (const openpit::pretrade::Reject& r : executed.rejects) {
      std::cout << "rejected by " << r.policy << " [" << static_cast<int>(r.code)
                << "]: " << r.reason << " (" << r.details << ")\n";
    }
    return 0;
  }
  openpit::pretrade::Reservation reservation = std::move(*executed.reservation);

  // 5. Commit after a successful venue handoff. Call Rollback() on a known
  // failure; if an exception exits this scope first, Reservation destruction
  // rolls the pending state back automatically.
  reservation.Commit();

  // 6. The order goes to the venue and returns with an execution report.
  openpit::model::ExecutionReport report;
  openpit::model::ExecutionReportOperation reportOp;
  reportOp.instrument = openpit::model::Instrument(
      ::openpit::param::Asset("AAPL"), ::openpit::param::Asset("USD"));
  reportOp.accountId = openpit::param::AccountId::FromUint64(99224416);
  reportOp.side = openpit::model::Side::Buy;
  report.operation = std::move(reportOp);

  openpit::model::FinancialImpact impact;
  impact.pnl = Pnl::FromString("-50");
  impact.fee = Fee::FromString("3.4");
  report.financialImpact = std::move(impact);

  const openpit::PostTradeResult result = engine.ApplyExecutionReport(report);

  for (const auto& outcome : result.accountPnls) {
    std::cout << "account P&L outcome for " << outcome.accountId.ToString()
              << '\n';
  }
  for (const auto& outcome : result.accountAdjustments) {
    std::cout << "account adjustment from group "
              << outcome.policyGroupId.Value() << '\n';
  }

  // 7. After each execution report is applied, the system may report that it
  // has been determined in advance that all subsequent requests will be
  // rejected if the account status does not change.
  if (!result.accountBlocks.empty()) {
    std::cout << "halt new orders until the blocked state is cleared\n";
  }
  return 0;
}
```

</details>

<details>
<summary>Rust</summary>

<!-- markdownlint-disable-next-line MD013 -->
<!-- Test mirror: https://github.com/openpitkit/pit/blob/main/crates/openpit/tests/examples_wiki.rs -->
```rust
use std::time::Duration;

use openpit::{
    FinancialImpact, ExecutionReportOperation, OrderOperation,
    WithFinancialImpact, WithExecutionReportOperation,
};
use openpit::param::{
    AccountId, Asset, Fee, Pnl, Price, Quantity, Side, TradeAmount, Volume,
};
use openpit::pretrade::policies::{
    OrderSizeAssetBarrier, OrderSizeBrokerBarrier, OrderSizeLimit, OrderSizeLimitPolicy,
    OrderSizeLimitSettings, OrderValidationPolicy,
    PnlBoundsBrokerBarrier, PnlBoundsKillSwitchPolicy, PnlBoundsKillSwitchSettings,
    RateLimit, RateLimitBrokerBarrier, RateLimitPolicy, RateLimitSettings,
};
use openpit::storage::NoLocking;
use openpit::{Engine, Instrument};

# fn main() -> Result<(), Box<dyn std::error::Error>> {
let aapl = Asset::new("AAPL")?;
let usd = Asset::new("USD")?;

// 1. Build the engine builder.
type Report = WithExecutionReportOperation<WithFinancialImpact<()>>;
let builder = Engine::builder::<OrderOperation, Report, ()>().no_sync();

// 2. Configure policies.
let pnl_policy = PnlBoundsKillSwitchPolicy::new(
    PnlBoundsKillSwitchSettings::new(
        [PnlBoundsBrokerBarrier {
            settlement_asset: usd.clone(),
            lower_bound: Some(Pnl::from_str("-1000")?),
            upper_bound: None,
        }],
        [],
    )?,
    builder.storage_builder(),
);

let rate_limit_policy = RateLimitPolicy::new(
    RateLimitSettings::new(
        Some(RateLimitBrokerBarrier {
            limit: RateLimit {
                max_orders: 100,
                window: Duration::from_secs(1),
            },
        }),
        [],
        [],
        [],
    )?,
    builder.storage_builder(),
);

// 3. Build the engine (one time at the platform initialization).
let engine = builder
    .pre_trade(OrderValidationPolicy::new())
    .pre_trade(pnl_policy)
    .pre_trade(rate_limit_policy)
    // Quantity is keyed by the underlying asset, notional by the
    // settlement asset; broker caps apply on top.
    .pre_trade(OrderSizeLimitPolicy::<NoLocking>::new(
        OrderSizeLimitSettings::new(
            Some(OrderSizeBrokerBarrier {
                limit: OrderSizeLimit {
                    max_quantity: Some(Quantity::from_str("500")?),
                    max_notional: Some(Volume::from_str("100000")?),
                },
            }),
            [
                OrderSizeAssetBarrier {
                    limit: OrderSizeLimit {
                        max_quantity: Some(Quantity::from_str("200")?),
                        max_notional: None,
                    },
                    asset: aapl.clone(),
                },
                OrderSizeAssetBarrier {
                    limit: OrderSizeLimit {
                        max_quantity: None,
                        max_notional: Some(Volume::from_str("50000")?),
                    },
                    asset: usd.clone(),
                },
            ],
            [],
        )?,
    ))
    .build()?;

// 4. Check an order.
let order = OrderOperation {
    instrument: Instrument::new(
        aapl.clone(),
        usd.clone(),
    ),
    account_id: AccountId::from_u64(99224416),
    side: Side::Buy,
    trade_amount: TradeAmount::Quantity(
        Quantity::from_f64(100.0)?,
    ),
    price: Some(Price::from_str("185")?),
};

let request = engine.start_pre_trade(order).map_err(|rejects| {
    let message = rejects
        .iter()
        .map(|r| format!(
            "rejected by {} [{}]: {} ({})",
            r.policy, r.code, r.reason, r.details,
        ))
        .collect::<Vec<_>>()
        .join(", ");
    std::io::Error::other(message)
})?;

// 5. Quick, lightweight checks, such as fat-finger scope or enabled killswitch,
// were performed during pre-trade request creation. The system state has not
// yet changed, except in cases where each request, even rejected ones, must be
// considered (for example, to prevent frequent transfers). Before the
// heavy-duty checks, other work on the request can be performed simply by
// holding the request object.

// 6. Real pre-trade and risk control.
let mut reservation = request.execute().map_err(|rejects| {
    let message = rejects
        .iter()
        .map(|r| format!(
            "rejected by {} [{}]: {} ({})",
            r.policy, r.code, r.reason, r.details,
        ))
        .collect::<Vec<_>>()
        .join(", ");
    std::io::Error::other(message)
})?;

// Optional shortcut for the same two-stage flow:
// let reservation = engine.execute_pre_trade(order)?;

// 7. If the request is successfully sent to the venue, it must be committed.
// The rollback must be called otherwise to revert all performed reservations.
reservation.commit();

// 8. The order goes to the venue and returns with an execution report.
let report = WithExecutionReportOperation {
    inner: WithFinancialImpact {
        inner: (),
        financial_impact: FinancialImpact {
            pnl: Pnl::from_str("-50")?,
            fee: Fee::from_str("3.4")?,
        },
    },
    operation: ExecutionReportOperation {
        instrument: Instrument::new(
            aapl,
            usd,
        ),
        account_id: AccountId::from_u64(99224416),
        side: Side::Buy,
    },
};

let result = engine.apply_execution_report(&report);
for outcome in &result.account_pnls {
    eprintln!("account P&L outcome for {}", outcome.account_id);
}
for outcome in &result.account_adjustments {
    eprintln!(
        "account adjustment from group {}",
        outcome.policy_group_id.value()
    );
}

// 9. After each execution report is applied, the system may report that it has
// been determined in advance that all subsequent requests will be rejected if
// the account status does not change.
assert!(result.account_blocks.is_empty());
# Ok(())
# }
```

</details>

## Example: Shortcut for Start + Main Stages

<details>
<summary>Go</summary>

<!-- markdownlint-disable-next-line MD013 -->
<!-- Test mirror: https://github.com/openpitkit/pit/blob/main/bindings/go/examples_wiki_test.go -->
```go
reservation, rejects, err := engine.ExecutePreTrade(order)
if err != nil {
 log.Fatal(err)
}
if rejects != nil {
 for _, r := range rejects {
  log.Printf(
   "rejected by %s [%d]: %s (%s)",
   r.Policy,
   r.Code,
   r.Reason,
   r.Details,
  )
 }
 return
}
defer reservation.Close()
reservation.Commit()
```

</details>

<details>
<summary>Python</summary>

<!-- markdownlint-disable-next-line MD013 -->
<!-- Test mirror: https://github.com/openpitkit/pit/blob/main/bindings/python/tests/integration/test_examples_wiki.py -->
```python
# The shortcut runs start stage and main stage as one convenience call.
execute_result = engine.execute_pre_trade(order=order)
if execute_result:
    # Finalization is still explicit even when the two stages are composed.
    execute_result.reservation.commit()
else:
    for reject in execute_result.rejects:
        print(
            f"rejected by {reject.policy} "
            f"[{reject.code}]: {reject.reason}: {reject.details}"
        )
```

</details>

<details>
<summary>JavaScript</summary>

<!-- markdownlint-disable-next-line MD013 -->
<!-- Test mirror: https://github.com/openpitkit/pit/blob/main/bindings/js/tests/examples_wiki.test.ts -->
```ts
import { Engine } from "@openpit/engine";
import { TradeAmount } from "@openpit/engine/param";
import { type OrderInit } from "@openpit/engine/model";
import { buildOrderValidation } from "@openpit/engine/pretrade/policies";

const engine = Engine.builder().builtin(buildOrderValidation()).build();
const order: OrderInit = {
  operation: {
    underlyingAsset: "AAPL",
    settlementAsset: "USD",
    accountId: 99224416,
    side: "BUY",
    tradeAmount: TradeAmount.quantity("100"),
    price: "185",
  },
};

// The shortcut runs start stage and main stage as one convenience call.
const execute = engine.executePreTrade(order);
if (execute.ok) {
  // Finalization is still explicit even when the two stages are composed.
  const reservation = execute.reservation;
  if (reservation === undefined) {
    throw new Error("accepted execute result is missing its reservation");
  }
  reservation.commit();
} else {
  for (const reject of execute.rejects) {
    console.log(
      `rejected by ${reject.policy} [${reject.code}]: ${reject.reason}: ${reject.details}`,
    );
  }
}
```

</details>

<details>
<summary>C++</summary>

<!-- markdownlint-disable-next-line MD013 -->
<!-- Test mirror: https://github.com/openpitkit/pit/blob/main/bindings/cpp/test/wiki/getting_started_test.cpp -->
```cpp
// The shortcut runs start stage and main stage as one convenience call.
openpit::pretrade::ExecuteResult executed = engine.ExecutePreTrade(order);
if (executed.Passed()) {
  // Finalization is still explicit even when the two stages are composed.
  executed.reservation->Commit();
} else {
  for (const openpit::pretrade::Reject& reject : executed.rejects) {
    std::cerr << "rejected by " << reject.policy << " ["
              << static_cast<int>(reject.code) << "]: " << reject.reason << " ("
              << reject.details << ")\n";
  }
}
```

</details>

<details>
<summary>Rust</summary>

<!-- markdownlint-disable-next-line MD013 -->
<!-- Test mirror: https://github.com/openpitkit/pit/blob/main/crates/openpit/tests/examples_wiki.rs -->
```rust
// The shortcut runs start stage and main stage as one convenience call.
match engine.execute_pre_trade(order) {
    Ok(mut reservation) => {
        // Finalization is still explicit even when the two stages are composed.
        reservation.commit()
    }
    Err(rejects) => {
        for reject in rejects.iter() {
            eprintln!(
                "rejected by {} [{}]: {} ({})",
                reject.policy,
                reject.code,
                reject.reason,
                reject.details
            );
        }
    }
}
```

</details>

## Example: Run an Order Through the Engine

<details>
<summary>Go</summary>

<!-- markdownlint-disable-next-line MD013 -->
<!-- Test mirror: https://github.com/openpitkit/pit/blob/main/bindings/go/examples_wiki_test.go -->
```go
request, rejects, err := engine.StartPreTrade(order)
if err != nil {
 log.Fatal(err)
}
if rejects != nil {
 for _, r := range rejects {
  log.Printf(
   "rejected by %s [%d]: %s (%s)",
   r.Policy,
   r.Code,
   r.Reason,
   r.Details,
  )
 }
 return
}
defer request.Close()

reservation, rejects, err := request.Execute()
if err != nil {
 log.Fatal(err)
}
if rejects != nil {
 for _, r := range rejects {
  log.Printf(
   "rejected by %s [%d]: %s (%s)",
   r.Policy,
   r.Code,
   r.Reason,
   r.Details,
  )
 }
 return
}
defer reservation.Close()
reservation.Commit()
```

</details>

<details>
<summary>Python</summary>

<!-- markdownlint-disable-next-line MD013 -->
<!-- Test mirror: https://github.com/openpitkit/pit/blob/main/bindings/python/tests/integration/test_examples_wiki.py -->
```python
start_result = engine.start_pre_trade(order=order)
if not start_result:
    messages = ", ".join(
        f"{r.policy} [{r.code}]: {r.reason}: {r.details}"
        for r in start_result.rejects
    )
    raise RuntimeError(messages)

execute_result = start_result.request.execute()
if not execute_result:
    messages = ", ".join(
        f"{reject.policy} [{reject.code}]: {reject.reason}: {reject.details}"
        for reject in execute_result.rejects
    )
    raise RuntimeError(messages)

execute_result.reservation.commit()
```

</details>

<details>
<summary>JavaScript</summary>

<!-- markdownlint-disable-next-line MD013 -->
<!-- Test mirror: https://github.com/openpitkit/pit/blob/main/bindings/js/tests/examples_wiki.test.ts -->
```ts
import { Engine } from "@openpit/engine";
import { TradeAmount } from "@openpit/engine/param";
import { type OrderInit } from "@openpit/engine/model";
import { buildOrderValidation } from "@openpit/engine/pretrade/policies";

const engine = Engine.builder().builtin(buildOrderValidation()).build();
const order: OrderInit = {
  operation: {
    underlyingAsset: "AAPL",
    settlementAsset: "USD",
    accountId: 99224416,
    side: "BUY",
    tradeAmount: TradeAmount.quantity("100"),
    price: "185",
  },
};

const start = engine.startPreTrade(order);
if (!start.ok) {
  const reasons = start.rejects
    .map((r) => `${r.policy} [${r.code}]: ${r.reason}: ${r.details}`)
    .join(", ");
  throw new Error(reasons);
}

const request = start.request;
if (request === undefined) {
  throw new Error("accepted start result is missing its request");
}
const execute = request.execute();
if (!execute.ok) {
  const reasons = execute.rejects
    .map((r) => `${r.policy} [${r.code}]: ${r.reason}: ${r.details}`)
    .join(", ");
  throw new Error(reasons);
}

const reservation = execute.reservation;
if (reservation === undefined) {
  throw new Error("accepted execute result is missing its reservation");
}
reservation.commit();
```

</details>

<details>
<summary>C++</summary>

<!-- markdownlint-disable-next-line MD013 -->
<!-- Test mirror: https://github.com/openpitkit/pit/blob/main/bindings/cpp/test/wiki/getting_started_test.cpp -->
```cpp
openpit::pretrade::StartResult start = engine.StartPreTrade(order);
if (!start.Passed()) {
  for (const openpit::pretrade::Reject& reject : start.rejects) {
    std::cerr << "rejected by " << reject.policy << " ["
              << static_cast<int>(reject.code) << "]: " << reject.reason << " ("
              << reject.details << ")\n";
  }
  return;
}

openpit::pretrade::ExecuteResult executed = start.request->Execute();
if (!executed.Passed()) {
  for (const openpit::pretrade::Reject& reject : executed.rejects) {
    std::cerr << "rejected by " << reject.policy << " ["
              << static_cast<int>(reject.code) << "]: " << reject.reason << " ("
              << reject.details << ")\n";
  }
  return;
}

executed.reservation->Commit();
```

</details>

<details>
<summary>Rust</summary>

<!-- markdownlint-disable-next-line MD013 -->
<!-- Test mirror: https://github.com/openpitkit/pit/blob/main/crates/openpit/tests/examples_wiki.rs -->
```rust
let request = match engine.start_pre_trade(order) {
    Ok(request) => request,
    Err(rejects) => {
        for reject in rejects.iter() {
            eprintln!(
                "rejected by {} [{}]: {} ({})",
                reject.policy,
                reject.code,
                reject.reason,
                reject.details
            );
        }
        return;
    }
};

let mut reservation = match request.execute() {
    Ok(reservation) => reservation,
    Err(rejects) => {
        for reject in rejects.iter() {
            eprintln!(
                "rejected by {} [{}]: {} ({})",
                reject.policy,
                reject.code,
                reject.reason,
                reject.details
            );
        }
        return;
    }
};

reservation.commit();
```

</details>

## Example: Apply Post-Trade Feedback

<details>
<summary>Go</summary>

<!-- markdownlint-disable-next-line MD013 -->
<!-- Test mirror: https://github.com/openpitkit/pit/blob/main/bindings/go/examples_wiki_test.go -->
```go
// Execution reports feed realized outcomes back into cumulative policy state.
result, err := engine.ApplyExecutionReport(report)
if err != nil {
 log.Fatal(err)
}
for _, outcome := range result.AccountPnls {
 log.Printf("account P&L outcome for %v", outcome.AccountID)
}
for _, outcome := range result.AccountAdjustments {
 log.Printf("account adjustment from group %d", outcome.PolicyGroupID)
}
if len(result.AccountBlocks) > 0 {
 log.Print("halt new orders until the blocked state is cleared")
}
```

</details>

<details>
<summary>Python</summary>

<!-- markdownlint-disable-next-line MD013 -->
<!-- Test mirror: https://github.com/openpitkit/pit/blob/main/bindings/python/tests/integration/test_examples_wiki.py -->
```python
result = engine.apply_execution_report(report=report)
for outcome in result.account_pnls:
    print(f"account P&L outcome for {outcome.account_id}")
for outcome in result.account_adjustments:
    print(f"account adjustment from group {outcome.policy_group_id}")
if result.account_blocks:
    print("halt new orders until the blocked state is cleared")
```

</details>

<details>
<summary>JavaScript</summary>

<!-- markdownlint-disable-next-line MD013 -->
<!-- Test mirror: https://github.com/openpitkit/pit/blob/main/bindings/js/tests/examples_wiki.test.ts -->
```ts
import { Engine } from "@openpit/engine";
import { type ExecutionReportInit } from "@openpit/engine/model";
import { buildOrderValidation } from "@openpit/engine/pretrade/policies";

const engine = Engine.builder().builtin(buildOrderValidation()).build();
const report: ExecutionReportInit = {
  operation: {
    underlyingAsset: "AAPL",
    settlementAsset: "USD",
    accountId: 99224416,
    side: "BUY",
  },
  financialImpact: { pnl: "-50", fee: "3.4" },
};

// Execution reports feed realized outcomes back into cumulative policy state.
const result = engine.applyExecutionReport(report);
for (const outcome of result.accountPnls) {
  console.log(`account P&L outcome for ${outcome.accountId.toString()}`);
}
for (const outcome of result.accountAdjustments) {
  console.log(`account adjustment from group ${outcome.policyGroupId}`);
}
if (result.accountBlocks.length > 0) {
  console.log("halt new orders until the blocked state is cleared");
}
```

</details>

<details>
<summary>C++</summary>

<!-- markdownlint-disable-next-line MD013 -->
<!-- Test mirror: https://github.com/openpitkit/pit/blob/main/bindings/cpp/test/wiki/getting_started_test.cpp -->
```cpp
// Execution reports feed realized outcomes back into cumulative policy state.
const openpit::PostTradeResult result = engine.ApplyExecutionReport(report);
for (const auto& outcome : result.accountPnls) {
  std::cerr << "account P&L outcome for " << outcome.accountId.ToString()
            << '\n';
}
for (const auto& outcome : result.accountAdjustments) {
  std::cerr << "account adjustment from group "
            << outcome.policyGroupId.Value() << '\n';
}
if (!result.accountBlocks.empty()) {
  std::cerr << "halt new orders until the blocked state is cleared\n";
}
```

</details>

<details>
<summary>Rust</summary>

<!-- markdownlint-disable-next-line MD013 -->
<!-- Test mirror: https://github.com/openpitkit/pit/blob/main/crates/openpit/tests/examples_wiki.rs -->
```rust
let result = engine.apply_execution_report(&report);
for outcome in &result.account_pnls {
    eprintln!("account P&L outcome for {}", outcome.account_id);
}
for outcome in &result.account_adjustments {
    eprintln!(
        "account adjustment from group {}",
        outcome.policy_group_id.value()
    );
}
if !result.account_blocks.is_empty() {
    eprintln!("halt new orders until the blocked state is cleared");
}
```

</details>

## Operational Notes

- OpenPit is in-memory. Persistence belongs to the host system.
- OpenPit does not route orders or talk to venues.
- Most policies consume caller-supplied realized outcomes. Spot Funds is the
  exception: it derives independent position and account P&L from reconciled
  fills, cost basis, fees, account currency, and available FX quotes.
- A shared engine instance behaves according to the chosen sync mode (full,
  local, or account). See [Threading Contract](Threading-Contract.md) for the
  per-mode contract.
- Treat custom-policy state according to the same sync mode. Under full
  sync, shared state must be thread-safe; under local or account sync, do
  not access it concurrently with engine calls. Prefer feeding state
  corrections through `apply account adjustments`.

## Related Pages

- [Pre-trade Pipeline](Pre-trade-Pipeline.md): Request, reject, and reservation
  semantics
- [Policies](Policies.md): Built-in controls and custom policy hooks
- [Dynamic Policy Reconfiguration](Dynamic-Policy-Reconfiguration.md): Retune
  built-in policies at runtime
- [Reject Codes](Reject-Codes.md): Standard business reject codes
- [Architecture](Architecture.md): Public integration model
