Skip to navigation

Profit & Loss

View as MarkdownOpen in Claude

Introduction

Requests can be made to receive real time updates about the daily P&L and unrealized P&L for an account, or for individual positions. Financial Advisors can also request P&L figures for ‘All’ subaccounts, or for a portfolio model. This is further extended to include realized P&L information at the account or individual position level.

The P&L API functions demonstrated below return the data which is displayed in the TWS Portfolio Window in current versions of TWS. As such, the P&L values are calculated based on the reset schedule specified in TWS Global Configuration (by default an instrument-specific reset schedule) and this setting affects values sent to the associated API functions as well. Also in TWS, P&L data from virtual forex positions will be included in the account P&L if and only if the Virtual Fx section of the Account Window is expanded.

See Account Updates for alternative PnL data.


Request P&L for Accounts

EClient.reqPnL(reqId, account, modelCode)

Creates subscription for real time daily PnL and unrealized PnL updates. Updates are sent to EWrapper.pnl.

  • Introducing broker accounts with less than 50 subaccounts can receive aggregate PnL for all subaccounts by specifying ‘All’ as the account code.
  • With requests for advisor accounts with many subaccounts and/or positions can take several seconds for aggregated P&L to be computed and returned.
  • For account P&L data the TWS setting “Prepare portfolio PnL data when downloading positions” must be checked.
reqId
int

Request ID to track the data.

account
string

Account for which to receive PnL updates.

modelCode
string

Specify to request PnL updates for a specific model.


self.reqPnL(reqId, "U1234567", "")

Receive P&L for Accounts

EWrapper.pnl(reqId, dailyPnL, unrealizedPnL, realizedPnL)

reqId
int

Request identifier for tracking data.

dailyPnL
double

DailyPnL updates for the account in real time.

unrealizedPnL
double

Total Unrealized PnL updates for the account in real time.

realizedPnL
double

Total Realized PnL updates for the account in real time.


def pnl(self, reqId: int, dailyPnL: float, unrealizedPnL: float, realizedPnL: float):
print("Daily PnL. ReqId:", reqId, "DailyPnL:", dailyPnL, "UnrealizedPnL:", unrealizedPnL, "RealizedPnL:", realizedPnL)

Cancel P&L for Accounts

EClient.cancelPnL(reqId)

Cancels subscription for real time updated daily PnL.

reqId
int

Request identifier for tracking data.


self.cancelPnL(reqId)

Request P&L for Individual Positions

EClient.reqPnLSingle(reqId, account, modelCode, conId)

Requests real time updates for daily PnL of individual positions. Updates are returned to EWrapper.pnlSingle approximately once per second.

  • If a P&L subscription request is made for an invalid conId or contract not in the account, there will not be a response.
  • As elsewhere in the API, a max double value will indicate an ‘unset’ value. This corresponds to an empty cell in TWS.
  • Introducing broker accounts without a large number of subaccounts (<50) can receive aggregate data by specifying the account as “All”.
  • Cannot be used with IBroker accounts configured for on-demand lookup with account = 'All'.
reqId
int

Request identifier to track the data.

account
string

Account in which position exists.

modelCode
string

Model in which position exists.

conId
int

Contract ID (conId) of contract to receive daily PnL updates for. Note: does not return message if invalid conId is entered.


self.reqPnLSingle(requestId, "U1234567", "", 265598)

Receive P&L for Individual Positions

EWrapper.pnlSingle(reqId, pos, dailyPnL, unrealizedPnL, realizedPnL, value)

Receives real time updates for single position daily PnL values.

reqId
int

Request identifier used for tracking.

pos
decimal

Current size of the position.

dailyPnL
double

DailyPnL for the position.

unrealizedPnL
double

Total unrealized PnL for the position (since inception) updating in real time.

realizedPnL
double

Total realized PnL for the position (since inception) updating in real time.

value
double

Current market value of the position.


def pnlSingle(self, reqId: int, pos: Decimal, dailyPnL: float, unrealizedPnL: float, realizedPnL: float, value: float):
print("Daily PnL Single. ReqId:", reqId, "Position:", pos, "DailyPnL:", dailyPnL, "UnrealizedPnL:", unrealizedPnL, "RealizedPnL:", realizedPnL, "Value:", value)

Cancel P&L for Individual Positions

EClient.cancelPnLSingle(reqId)

Cancels real time subscription for a position’s daily PnL information.

reqId
int

Request identifier to cancel the P&L subscription for.


self.cancelPnLSingle(requestId)