ig_create_position
Create a new trading position on IG Trading by specifying market epic, direction, size, currency, expiry, order type, and time in force. Set stop loss, take profit, and guaranteed stop options for risk management.
Instructions
Create a new trading position
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| currencyCode | Yes | Currency code (e.g., GBP, USD) | |
| direction | Yes | Trade direction | |
| epic | Yes | Market epic code | |
| expiry | Yes | Contract expiry (e.g., DFB for daily funded bet) | |
| forceOpen | No | Force open a new position | |
| guaranteedStop | No | Use guaranteed stop | |
| level | No | Price level (required for LIMIT orders) | |
| limitLevel | No | Take profit level | |
| orderType | Yes | Order type | |
| size | Yes | Position size | |
| stopLevel | No | Stop loss level | |
| timeInForce | Yes | Time in force |
Input Schema (JSON Schema)
{
"properties": {
"currencyCode": {
"description": "Currency code (e.g., GBP, USD)",
"type": "string"
},
"direction": {
"description": "Trade direction",
"enum": [
"BUY",
"SELL"
],
"type": "string"
},
"epic": {
"description": "Market epic code",
"type": "string"
},
"expiry": {
"description": "Contract expiry (e.g., DFB for daily funded bet)",
"type": "string"
},
"forceOpen": {
"default": true,
"description": "Force open a new position",
"type": "boolean"
},
"guaranteedStop": {
"default": false,
"description": "Use guaranteed stop",
"type": "boolean"
},
"level": {
"description": "Price level (required for LIMIT orders)",
"type": "number"
},
"limitLevel": {
"description": "Take profit level",
"type": "number"
},
"orderType": {
"description": "Order type",
"enum": [
"MARKET",
"LIMIT"
],
"type": "string"
},
"size": {
"description": "Position size",
"type": "number"
},
"stopLevel": {
"description": "Stop loss level",
"type": "number"
},
"timeInForce": {
"description": "Time in force",
"enum": [
"FILL_OR_KILL",
"EXECUTE_AND_ELIMINATE"
],
"type": "string"
}
},
"required": [
"epic",
"direction",
"size",
"currencyCode",
"expiry",
"orderType",
"timeInForce"
],
"type": "object"
}
Implementation Reference
- src/services/ig-service.js:160-179 (handler)Core implementation of position creation: validates input, POSTs to IG API /positions/otc endpoint, fetches deal confirmation if available.async createPosition(ticket) { this.validatePositionTicket(ticket); try { const response = await this.apiClient.post('/positions/otc', ticket, 2); if (response.data.dealReference) { const confirmation = await this.getConfirmation(response.data.dealReference); return { position: response.data, confirmation }; } return response.data; } catch (error) { logger.error('Failed to create position:', error.message); throw error; } }
- src/services/mcp-service.js:151-213 (schema)JSON schema defining input parameters, types, enums, defaults, and required fields for the ig_create_position tool.{ name: 'ig_create_position', description: 'Create a new trading position', inputSchema: { type: 'object', properties: { epic: { type: 'string', description: 'Market epic code', }, direction: { type: 'string', enum: ['BUY', 'SELL'], description: 'Trade direction', }, size: { type: 'number', description: 'Position size', }, currencyCode: { type: 'string', description: 'Currency code (e.g., GBP, USD)', }, expiry: { type: 'string', description: 'Contract expiry (e.g., DFB for daily funded bet)', }, orderType: { type: 'string', enum: ['MARKET', 'LIMIT'], description: 'Order type', }, level: { type: 'number', description: 'Price level (required for LIMIT orders)', }, stopLevel: { type: 'number', description: 'Stop loss level', }, limitLevel: { type: 'number', description: 'Take profit level', }, guaranteedStop: { type: 'boolean', description: 'Use guaranteed stop', default: false, }, forceOpen: { type: 'boolean', description: 'Force open a new position', default: true, }, timeInForce: { type: 'string', enum: ['FILL_OR_KILL', 'EXECUTE_AND_ELIMINATE'], description: 'Time in force', }, }, required: ['epic', 'direction', 'size', 'currencyCode', 'expiry', 'orderType', 'timeInForce'], }, },
- src/services/mcp-service.js:601-610 (registration)MCP server tool call handler registration: switch case that invokes the igService.createPosition method and formats the response.case 'ig_create_position': const positionResult = await igService.createPosition(args); return { content: [ { type: 'text', text: JSON.stringify(positionResult, null, 2), }, ], };
- src/services/ig-service.js:496-524 (helper)Input validation helper for position creation ticket, enforcing required fields, valid enums, and order-type specific rules.validatePositionTicket(ticket) { const required = ['currencyCode', 'direction', 'epic', 'expiry', 'size', 'forceOpen', 'orderType', 'guaranteedStop', 'timeInForce']; const missing = required.filter(field => ticket[field] === undefined); if (missing.length > 0) { throw new Error(`Missing required fields: ${missing.join(', ')}`); } const validCurrencies = ['AUD', 'USD', 'EUR', 'GBP', 'CHF', 'NZD', 'JPY', 'CAD']; if (!validCurrencies.includes(ticket.currencyCode)) { throw new Error(`Invalid currency code: ${ticket.currencyCode}`); } if (!['BUY', 'SELL'].includes(ticket.direction)) { throw new Error('Direction must be BUY or SELL'); } if (!['LIMIT', 'MARKET'].includes(ticket.orderType)) { throw new Error('Order type must be LIMIT or MARKET'); } if (ticket.orderType === 'LIMIT' && !ticket.level) { throw new Error('Level is required for LIMIT orders'); } if (ticket.orderType === 'MARKET' && ticket.level) { throw new Error('Level should not be set for MARKET orders'); } }