Positions operations
Examples assume an initialized synchronous or asynchronous client named ig.
ig.operations.positions.list()
List all open positions for the active account.
Official IG reference: https://labs.ig.com/reference/positions.html
Signatures
- Sync:
() -> 'PositionsResponse'
- Async:
() -> 'PositionsResponse'
Parameters
| Name |
Type |
Required/default |
Constraints |
Description |
| None |
- |
- |
- |
This method accepts no parameters. |
Sync example
result = ig.operations.positions.list()
Async example
result = await ig.operations.positions.list()
Response shape: PositionsResponse
| Field |
Type |
Required/default |
positions[] |
tuple[PositionSummary, ...] |
default: () |
positions[].position |
Position |
required |
positions[].position.contract_size |
Decimal | None |
default: None |
positions[].position.controlled_risk |
bool | None |
default: None |
positions[].position.created_date |
str | None |
default: None |
positions[].position.created_date_utc |
str | None |
default: None |
positions[].position.currency |
str | None |
default: None |
positions[].position.deal_id |
str |
required |
positions[].position.deal_reference |
str | None |
default: None |
positions[].position.direction |
Literal['BUY', 'SELL'] | None |
default: None |
positions[].position.size |
Decimal | None |
default: None |
positions[].position.level |
Decimal | None |
default: None |
positions[].position.limit_level |
Decimal | None |
default: None |
positions[].position.limited_risk_premium |
Decimal | None |
default: None |
positions[].position.stop_level |
Decimal | None |
default: None |
positions[].position.trailing_step |
Decimal | None |
default: None |
positions[].position.trailing_stop_distance |
Decimal | None |
default: None |
positions[].market |
DealingMarket |
required |
positions[].market.bid |
Decimal | None |
default: None |
positions[].market.delay_time |
int | None |
default: None |
positions[].market.epic |
str |
required |
positions[].market.expiry |
str | None |
default: None |
positions[].market.high |
Decimal | None |
default: None |
positions[].market.instrument_name |
str | None |
default: None |
positions[].market.instrument_type |
str | None |
default: None |
positions[].market.low |
Decimal | None |
default: None |
positions[].market.market_status |
str | None |
default: None |
positions[].market.net_change |
Decimal | None |
default: None |
positions[].market.offer |
Decimal | None |
default: None |
positions[].market.percentage_change |
Decimal | None |
default: None |
positions[].market.scaling_factor |
Decimal | None |
default: None |
positions[].market.streaming_prices_available |
bool | None |
default: None |
positions[].market.update_time |
str | None |
default: None |
positions[].market.update_time_utc |
str | None |
default: None |
positions[].market.lot_size |
Decimal | None |
default: None |
Response example
{
"positions": [
{
"position": {
"contract_size": "1.0",
"controlled_risk": true,
"created_date": "example",
"created_date_utc": "example",
"currency": "GBP",
"deal_id": "DIAAAABBBCCC",
"deal_reference": "ABC123",
"direction": "BUY",
"size": "1.0",
"level": "1.0",
"limit_level": "1.0",
"limited_risk_premium": "1.0",
"stop_level": "1.0",
"trailing_step": "1.0",
"trailing_stop_distance": "1.0"
},
"market": {
"bid": "1.0",
"delay_time": 1,
"epic": "CS.D.EURUSD.CFD.IP",
"expiry": "-",
"high": "1.0",
"instrument_name": "EUR/USD",
"instrument_type": "example",
"low": "1.0",
"market_status": "TRADEABLE",
"net_change": "1.0",
"offer": "1.0",
"percentage_change": "1.0",
"scaling_factor": "1.0",
"streaming_prices_available": true,
"update_time": "12:34:56",
"update_time_utc": "example",
"lot_size": "1.0"
}
}
]
}
Limitations
- Returned resources and fields depend on the active account, environment, entitlements, and current IG catalogue.
- IG can change account-specific allowances and availability independently of this library.
Exceptions
| Exception |
Trigger |
Recovery |
AuthenticationError |
IG rejected the credentials, required session values were absent, or refresh failed. |
Re-authenticate with valid credentials before retrying. |
AuthorizationError |
The active account cannot access the requested resource or action. |
Switch to an entitled account or request the required IG permission. |
RateLimitError |
IG rejected the request because an allowance was exhausted. |
Wait for retry_after_seconds when present, then retry with bounded backoff. |
ProviderRejectionError |
IG rejected an otherwise well-formed request. |
Inspect error_code and correct the provider-specific input or account state. |
ResourceNotFoundError |
The requested provider resource does not exist or is inaccessible. |
Verify the identifier and active account before retrying. |
TransportError |
A network or timeout failure prevented a completed read request. |
Retry the idempotent read with bounded backoff. |
ValidationError |
Request construction failed or an IG response did not match the declared model. |
Correct invalid request fields; report provider response drift with redacted diagnostics. |
ig.operations.positions.get()
Retrieve one open position by deal identifier.
Official IG reference: https://labs.ig.com/reference/positions-deal-id.html
Signatures
- Sync:
(deal_id: 'str') -> 'PositionResponse'
- Async:
(deal_id: 'str') -> 'PositionResponse'
Parameters
| Name |
Type |
Required/default |
Constraints |
Description |
deal_id |
str |
required |
- |
IG identifier of an existing position or working order. |
Sync example
result = ig.operations.positions.get(deal_id="DIAAAABBBCCC")
Async example
result = await ig.operations.positions.get(deal_id="DIAAAABBBCCC")
Response shape: PositionResponse
| Field |
Type |
Required/default |
position |
Position |
required |
position.contract_size |
Decimal | None |
default: None |
position.controlled_risk |
bool | None |
default: None |
position.created_date |
str | None |
default: None |
position.created_date_utc |
str | None |
default: None |
position.currency |
str | None |
default: None |
position.deal_id |
str |
required |
position.deal_reference |
str | None |
default: None |
position.direction |
Literal['BUY', 'SELL'] | None |
default: None |
position.size |
Decimal | None |
default: None |
position.level |
Decimal | None |
default: None |
position.limit_level |
Decimal | None |
default: None |
position.limited_risk_premium |
Decimal | None |
default: None |
position.stop_level |
Decimal | None |
default: None |
position.trailing_step |
Decimal | None |
default: None |
position.trailing_stop_distance |
Decimal | None |
default: None |
market |
DealingMarket |
required |
market.bid |
Decimal | None |
default: None |
market.delay_time |
int | None |
default: None |
market.epic |
str |
required |
market.expiry |
str | None |
default: None |
market.high |
Decimal | None |
default: None |
market.instrument_name |
str | None |
default: None |
market.instrument_type |
str | None |
default: None |
market.low |
Decimal | None |
default: None |
market.market_status |
str | None |
default: None |
market.net_change |
Decimal | None |
default: None |
market.offer |
Decimal | None |
default: None |
market.percentage_change |
Decimal | None |
default: None |
market.scaling_factor |
Decimal | None |
default: None |
market.streaming_prices_available |
bool | None |
default: None |
market.update_time |
str | None |
default: None |
market.update_time_utc |
str | None |
default: None |
market.lot_size |
Decimal | None |
default: None |
Response example
{
"position": {
"contract_size": "1.0",
"controlled_risk": true,
"created_date": "example",
"created_date_utc": "example",
"currency": "GBP",
"deal_id": "DIAAAABBBCCC",
"deal_reference": "ABC123",
"direction": "BUY",
"size": "1.0",
"level": "1.0",
"limit_level": "1.0",
"limited_risk_premium": "1.0",
"stop_level": "1.0",
"trailing_step": "1.0",
"trailing_stop_distance": "1.0"
},
"market": {
"bid": "1.0",
"delay_time": 1,
"epic": "CS.D.EURUSD.CFD.IP",
"expiry": "-",
"high": "1.0",
"instrument_name": "EUR/USD",
"instrument_type": "example",
"low": "1.0",
"market_status": "TRADEABLE",
"net_change": "1.0",
"offer": "1.0",
"percentage_change": "1.0",
"scaling_factor": "1.0",
"streaming_prices_available": true,
"update_time": "12:34:56",
"update_time_utc": "example",
"lot_size": "1.0"
}
}
Limitations
- Returned resources and fields depend on the active account, environment, entitlements, and current IG catalogue.
- IG can change account-specific allowances and availability independently of this library.
- The position must belong to the active account.
Exceptions
| Exception |
Trigger |
Recovery |
AuthenticationError |
IG rejected the credentials, required session values were absent, or refresh failed. |
Re-authenticate with valid credentials before retrying. |
AuthorizationError |
The active account cannot access the requested resource or action. |
Switch to an entitled account or request the required IG permission. |
RateLimitError |
IG rejected the request because an allowance was exhausted. |
Wait for retry_after_seconds when present, then retry with bounded backoff. |
ProviderRejectionError |
IG rejected an otherwise well-formed request. |
Inspect error_code and correct the provider-specific input or account state. |
ResourceNotFoundError |
The requested provider resource does not exist or is inaccessible. |
Verify the identifier and active account before retrying. |
TransportError |
A network or timeout failure prevented a completed read request. |
Retry the idempotent read with bounded backoff. |
ValidationError |
Request construction failed or an IG response did not match the declared model. |
Correct invalid request fields; report provider response drift with redacted diagnostics. |
ig.operations.positions.create()
Create an OTC position and return its deal reference.
Official IG reference: https://labs.ig.com/reference/positions-otc.html
Signatures
- Sync:
(request: 'CreatePositionRequest') -> 'DealReferenceResponse'
- Async:
(request: 'CreatePositionRequest') -> 'DealReferenceResponse'
Parameters
| Name |
Type |
Required/default |
Constraints |
Description |
request |
CreatePositionRequest |
required |
- |
Validated typed request body. |
request.epic |
str |
required |
minimum length 1 |
IG market epic. |
request.direction |
Literal['BUY', 'SELL'] |
required |
- |
Deal direction; BUY or SELL. |
request.size |
Decimal |
required |
> 0 |
Positive deal size. |
request.order_type |
Literal['LIMIT', 'MARKET', 'QUOTE'] |
required |
- |
Provider order type for the requested deal. |
request.currency_code |
str |
required |
minimum length 3; maximum length 3 |
Three-letter deal currency code. |
request.expiry |
str |
default: '-' |
- |
Market expiry, or - for a non-expiring market. |
request.force_open |
bool |
default: True |
- |
Whether the deal must create a separate position. |
request.guaranteed_stop |
bool |
default: False |
- |
Whether the stop is guaranteed by IG. |
request.level |
Decimal | None |
default: None |
- |
Requested order or quote price level. |
request.quote_id |
str | None |
default: None |
- |
IG quote identifier required for a QUOTE order. |
request.time_in_force |
Literal['EXECUTE_AND_ELIMINATE', 'FILL_OR_KILL'] | None |
default: None |
- |
Provider rule controlling how long or how aggressively an order executes. |
request.limit_distance |
Decimal | None |
default: None |
- |
Limit distance in market points; mutually exclusive with limit_level. |
request.limit_level |
Decimal | None |
default: None |
- |
Absolute limit level; mutually exclusive with limit_distance. |
request.stop_distance |
Decimal | None |
default: None |
- |
Stop distance in market points; mutually exclusive with stop_level. |
request.stop_level |
Decimal | None |
default: None |
- |
Absolute stop level; mutually exclusive with stop_distance. |
request.trailing_stop |
bool | None |
default: None |
- |
Whether trailing-stop behavior is enabled. |
request.trailing_stop_increment |
Decimal | None |
default: None |
- |
Minimum movement before a trailing stop advances. |
request.deal_reference |
str | None |
default: None |
- |
Client or provider reference used to correlate a deal. |
Sync example
from ig_trading_lib.operations.dealing import CreatePositionRequest
result = ig.operations.positions.create(request=CreatePositionRequest(epic="CS.D.EURUSD.CFD.IP", direction="BUY", size="1", order_type="MARKET", currency_code="GBP"))
Async example
from ig_trading_lib.operations.dealing import CreatePositionRequest
result = await ig.operations.positions.create(request=CreatePositionRequest(epic="CS.D.EURUSD.CFD.IP", direction="BUY", size="1", order_type="MARKET", currency_code="GBP"))
Response shape: DealReferenceResponse
| Field |
Type |
Required/default |
deal_reference |
str |
required |
Response example
{
"deal_reference": "ABC123"
}
Limitations
- Live calls require an explicit
TradingPermit; demo calls do not.
- Mutations are sent once and are never automatically retried after an uncertain outcome.
- Order-level, stop, limit, force-open, quote, and trailing-stop combinations are validated before sending.
Exceptions
| Exception |
Trigger |
Recovery |
AuthenticationError |
IG rejected the credentials, required session values were absent, or refresh failed. |
Re-authenticate with valid credentials before retrying. |
AuthorizationError |
The active account cannot access the requested resource or action. |
Switch to an entitled account or request the required IG permission. |
RateLimitError |
IG rejected the request because an allowance was exhausted. |
Wait for retry_after_seconds when present, then retry with bounded backoff. |
ProviderRejectionError |
IG rejected an otherwise well-formed request. |
Inspect error_code and correct the provider-specific input or account state. |
ResourceNotFoundError |
The requested provider resource does not exist or is inaccessible. |
Verify the identifier and active account before retrying. |
AmbiguousExecutionError |
A mutation may have reached IG before a network or timeout failure. |
Reconcile account state or query by deal reference; never replay blindly. |
LiveTradingPermissionError |
A live-environment mutation was called without an acknowledged TradingPermit. |
Construct the client with an explicit TradingPermit after confirming live intent. |
ValidationError |
Request construction failed or an IG response did not match the declared model. |
Correct invalid request fields; report provider response drift with redacted diagnostics. |
ig.operations.positions.amend()
Amend stops or limits on an open position.
Official IG reference: https://labs.ig.com/reference/positions-otc-deal-id.html
Signatures
- Sync:
(deal_id: 'str', request: 'AmendPositionRequest') -> 'DealReferenceResponse'
- Async:
(deal_id: 'str', request: 'AmendPositionRequest') -> 'DealReferenceResponse'
Parameters
| Name |
Type |
Required/default |
Constraints |
Description |
deal_id |
str |
required |
- |
IG identifier of an existing position or working order. |
request |
AmendPositionRequest |
required |
- |
Validated typed request body. |
request.limit_level |
Decimal | None |
default: None |
- |
Absolute limit level; mutually exclusive with limit_distance. |
request.stop_level |
Decimal | None |
default: None |
- |
Absolute stop level; mutually exclusive with stop_distance. |
request.guaranteed_stop |
bool | None |
default: None |
- |
Whether the stop is guaranteed by IG. |
request.trailing_stop |
bool | None |
default: None |
- |
Whether trailing-stop behavior is enabled. |
request.trailing_stop_distance |
Decimal | None |
default: None |
- |
Distance maintained by an amended trailing stop. |
request.trailing_stop_increment |
Decimal | None |
default: None |
- |
Minimum movement before a trailing stop advances. |
Sync example
from ig_trading_lib.operations.dealing import AmendPositionRequest
result = ig.operations.positions.amend(deal_id="DIAAAABBBCCC", request=AmendPositionRequest(limit_level="1.0900"))
Async example
from ig_trading_lib.operations.dealing import AmendPositionRequest
result = await ig.operations.positions.amend(deal_id="DIAAAABBBCCC", request=AmendPositionRequest(limit_level="1.0900"))
Response shape: DealReferenceResponse
| Field |
Type |
Required/default |
deal_reference |
str |
required |
Response example
{
"deal_reference": "ABC123"
}
Limitations
- Live calls require an explicit
TradingPermit; demo calls do not.
- Mutations are sent once and are never automatically retried after an uncertain outcome.
- Guaranteed and trailing-stop amendments require provider-valid field combinations.
Exceptions
| Exception |
Trigger |
Recovery |
AuthenticationError |
IG rejected the credentials, required session values were absent, or refresh failed. |
Re-authenticate with valid credentials before retrying. |
AuthorizationError |
The active account cannot access the requested resource or action. |
Switch to an entitled account or request the required IG permission. |
RateLimitError |
IG rejected the request because an allowance was exhausted. |
Wait for retry_after_seconds when present, then retry with bounded backoff. |
ProviderRejectionError |
IG rejected an otherwise well-formed request. |
Inspect error_code and correct the provider-specific input or account state. |
ResourceNotFoundError |
The requested provider resource does not exist or is inaccessible. |
Verify the identifier and active account before retrying. |
AmbiguousExecutionError |
A mutation may have reached IG before a network or timeout failure. |
Reconcile account state or query by deal reference; never replay blindly. |
LiveTradingPermissionError |
A live-environment mutation was called without an acknowledged TradingPermit. |
Construct the client with an explicit TradingPermit after confirming live intent. |
ValidationError |
Request construction failed or an IG response did not match the declared model. |
Correct invalid request fields; report provider response drift with redacted diagnostics. |
ig.operations.positions.close()
Close all or part of an OTC position.
Official IG reference: https://labs.ig.com/reference/positions-otc.html
Signatures
- Sync:
(request: 'ClosePositionRequest') -> 'DealReferenceResponse'
- Async:
(request: 'ClosePositionRequest') -> 'DealReferenceResponse'
Parameters
| Name |
Type |
Required/default |
Constraints |
Description |
request |
ClosePositionRequest |
required |
- |
Validated typed request body. |
request.direction |
Literal['BUY', 'SELL'] |
required |
- |
Deal direction; BUY or SELL. |
request.size |
Decimal |
required |
> 0 |
Positive deal size. |
request.order_type |
Literal['LIMIT', 'MARKET', 'QUOTE'] |
default: 'MARKET' |
- |
Provider order type for the requested deal. |
request.deal_id |
str | None |
default: None |
- |
IG identifier of an existing position or working order. |
request.epic |
str | None |
default: None |
- |
IG market epic. |
request.expiry |
str | None |
default: None |
- |
Market expiry, or - for a non-expiring market. |
request.level |
Decimal | None |
default: None |
- |
Requested order or quote price level. |
request.quote_id |
str | None |
default: None |
- |
IG quote identifier required for a QUOTE order. |
request.time_in_force |
Literal['EXECUTE_AND_ELIMINATE', 'FILL_OR_KILL'] | None |
default: None |
- |
Provider rule controlling how long or how aggressively an order executes. |
Sync example
from ig_trading_lib.operations.dealing import ClosePositionRequest
result = ig.operations.positions.close(request=ClosePositionRequest(direction="SELL", size="1", deal_id="DIAAAABBBCCC"))
Async example
from ig_trading_lib.operations.dealing import ClosePositionRequest
result = await ig.operations.positions.close(request=ClosePositionRequest(direction="SELL", size="1", deal_id="DIAAAABBBCCC"))
Response shape: DealReferenceResponse
| Field |
Type |
Required/default |
deal_reference |
str |
required |
Response example
{
"deal_reference": "ABC123"
}
Limitations
- Live calls require an explicit
TradingPermit; demo calls do not.
- Mutations are sent once and are never automatically retried after an uncertain outcome.
- Identify the position by exactly one of
deal_id or epic; epic also requires expiry.
Exceptions
| Exception |
Trigger |
Recovery |
AuthenticationError |
IG rejected the credentials, required session values were absent, or refresh failed. |
Re-authenticate with valid credentials before retrying. |
AuthorizationError |
The active account cannot access the requested resource or action. |
Switch to an entitled account or request the required IG permission. |
RateLimitError |
IG rejected the request because an allowance was exhausted. |
Wait for retry_after_seconds when present, then retry with bounded backoff. |
ProviderRejectionError |
IG rejected an otherwise well-formed request. |
Inspect error_code and correct the provider-specific input or account state. |
ResourceNotFoundError |
The requested provider resource does not exist or is inaccessible. |
Verify the identifier and active account before retrying. |
AmbiguousExecutionError |
A mutation may have reached IG before a network or timeout failure. |
Reconcile account state or query by deal reference; never replay blindly. |
LiveTradingPermissionError |
A live-environment mutation was called without an acknowledged TradingPermit. |
Construct the client with an explicit TradingPermit after confirming live intent. |
ValidationError |
Request construction failed or an IG response did not match the declared model. |
Correct invalid request fields; report provider response drift with redacted diagnostics. |