Overview
Signals Position API
Overview
The Signals Position API allows users to start a trading position with
specified configurations. When a POST request is sent to this API, it
initiates the trade, with order management handled on our side. Users can
specify various parameters such as stop loss, target, and execution
configurations.
This page documents every field and every value each field can take in the request payload, so you can build the exact strategy you want without guessing.
Endpoint
Live URL:
https://api.algotest.in/webhook/custom-position/execution/start/live?broker_id={broker_id}
Paper (Forward Testing) URL:
https://api.algotest.in/webhook/custom-position/execution/start/paper
Method: POST
Request URL Parameters:
broker_id: The broker id on which you want to trade the position. Copy it from the "Broker Setup" page. Required for the live URL, ignored for paper.
Request Body
The request body should be in JSON format and include the following main components:
| Field | Type | Required | Description |
|---|---|---|---|
access_token |
string | Yes | The access token for authentication. Copy it from the profile page. |
alert_name |
string | Yes | The name of the alert triggering the strategy. Shown in your execution history. |
exit_time |
string (YYYY-MM-DDTHH:MM:SS, IST) |
Yes | The scheduled exit time of the strategy. Must not be in the past — a past timestamp is rejected with 400. |
strategy |
object | Yes | The strategy configuration object — see below. |
Market hours
Strategies can only be activated during exchange trading hours
(approximately 08:15 – 15:39 IST for NSE/BSE tickers). Sending a
valid request outside this window returns a 503.
Strategy Object
Within the strategy object, the following fields are defined:
| Field | Type | Required | Description |
|---|---|---|---|
Ticker |
string | Yes | The underlying index, stock, or crypto instrument. See Ticker values below. |
Legs |
array (1–10 items) | Yes | Array of legs, each containing PositionConfig and ExecutionConfig. |
OverallSL |
object | No | Overall Stop Loss configuration across all legs combined. Defaults to no SL if omitted. |
OverallTgt |
object | No | Overall Target configuration across all legs combined. Defaults to no target if omitted. |
Ticker
Ticker accepts one instrument identifier from AlgoTest's supported universe:
- Indices:
NIFTY,BANKNIFTY,FINNIFTY,MIDCPNIFTY,SENSEX,BANKEX - NSE Stocks: any NIFTY-500 stock, prefixed with
NSE_(e.g.NSE_RELIANCE,NSE_TATASTEEL,NSE_SBIN) - Delta Exchange crypto:
DELTA_BTCUSD,DELTA_ETHUSD - Coinswitch crypto:
COINSWITCH_BTCUSDT,COINSWITCH_ETHUSDT,COINSWITCH_SOLUSDT,COINSWITCH_XRPUSDT,COINSWITCH_DOGEUSDT
Primary tickers
NIFTY, SENSEX, and the Delta/Coinswitch crypto tickers above are
treated as primary tickers. This matters for ExpiryKind — see the
ExpiryKind table below. Every other ticker (BANKNIFTY,
FINNIFTY, MIDCPNIFTY, BANKEX, and all individual stocks) is
restricted to monthly expiries only.
OverallSL / OverallTgt
Both use the same { "Type": ..., "Value": ... } shape:
Type |
Meaning | Value |
|---|---|---|
"None" |
No overall SL / Target (default if the field is omitted entirely). | Must be exactly 0. |
OverallTgtSLType.MTM |
Absolute mark-to-market P&L, in ₹ (or the underlying's currency), summed across all legs. | number, >= 1 |
OverallTgtSLType.PremiumPercentage |
% move of the total combined premium across all legs. | number, >= 1 |
{
"OverallSL": {
"Type": "OverallTgtSLType.MTM",
"Value": 3000
}
}
Legs
Each element in the Legs array represents a specific position and how it
should be executed, defined by:
- PositionConfig
- ExecutionConfig
1. PositionConfig
Defines the position details such as instrument type, strike price, expiry,
position type, lot size, and stop loss/target configurations. All fields
below are required inside PositionConfig.
{
"PositionConfig": {
"EntryType" : "EntryType.EntryByExactStrike",
"InstrumentKind": "LegType.CE",
"StrikeParameter": 23850,
"ExpiryKind": "ExpiryType.Weekly",
"PositionType": "PositionType.Sell",
"Lots": 1,
"LegStopLoss": {
"Type": "None",
"Value": 0
},
"LegTarget": {
"Type": "None",
"Value": 0
},
"LegTrailSL": {
"Type": "None",
"Value": {}
}
}
}
InstrumentKind
| Value | Meaning | Constraints |
|---|---|---|
LegType.CE |
Call option | — |
LegType.PE |
Put option | — |
LegType.FUT |
Futures contract | Not available on Delta/Coinswitch (crypto) tickers — rejected with "Futures/Spot is not supported for Delta/Coinswitch Exchange". |
LegType.CASH |
Cash/equity leg — buys or sells the underlying stock directly | Only allowed when Ticker is an individual stock (an NSE_* ticker). Rejected for indices and crypto tickers. |
No perpetual futures via this webhook
AlgoTest's execution engine supports a LegType.FUT_P (perpetual
futures) instrument kind for Delta/Coinswitch, but this specific
custom-position / custom-signal webhook does not accept it —
InstrumentKind is limited to CE, PE, FUT, CASH at the API
layer. In practice, this means crypto strategies sent through this
endpoint should use option legs (CE/PE) only, since FUT and
CASH are both rejected for Delta/Coinswitch tickers and FUT_P isn't
reachable here.
For Futures (LegType.FUT) or Cash (LegType.CASH) legs, there is
no strike to select — set:
"EntryType": "None",
"StrikeParameter": "None"
EntryType
EntryType controls how AlgoTest picks the strike, and it determines the
required shape of StrikeParameter. This is the field with the most
variation, so the table below lists every value together with the exact
StrikeParameter shape it expects.
EntryType |
What it selects | StrikeParameter shape |
Example |
|---|---|---|---|
EntryType.EntryByExactStrike |
An exact, literal strike price you specify. | integer |
23850 |
EntryType.EntryByStrikeType |
A strike relative to spot: at-the-money, or N strikes in/out of the money. | string — one of the StrikeType values |
"StrikeType.OTM5" |
EntryType.EntryBySyntheticFuture |
Same relative strike selection as EntryByStrikeType, but the ATM reference is computed from the synthetic future (put-call parity) instead of raw spot. |
string — one of the StrikeType values |
"StrikeType.ATM" |
EntryType.EntryByAtmMultiplier |
A strike offset expressed as a multiplier of the ATM strike. | number, 0 < x < 2 |
1.02 |
EntryType.EntryByPremium |
The strike whose option premium is closest to a target value. | number, x > 0 |
50 |
EntryType.EntryByPremiumGEQ |
The strike whose premium is closest to the target while staying greater than or equal to it. | number, x > 0 |
50 |
EntryType.EntryByPremiumLEQ |
The strike whose premium is closest to the target while staying less than or equal to it. | number, x > 0 |
50 |
EntryType.EntryByPremiumRange |
A strike whose premium falls within a range. | object: {"LowerRange": number>0, "UpperRange": number>0} |
{"LowerRange": 40, "UpperRange": 60} |
EntryType.EntryByDelta |
The strike whose option delta is closest to a target value. | number, x > 0 |
0.3 |
EntryType.EntryByDeltaRange |
A strike whose option delta falls within a range. | object: {"LowerRange": number>0, "UpperRange": number>0} |
{"LowerRange": 0.2, "UpperRange": 0.4} |
EntryType.EntryByStraddlePrice |
Strike selected from an ATM straddle premium multiplied by a factor, then shifted up or down. | object: {"Multiplier": number, "Adjustment": "AdjustmentType.Plus"\|"AdjustmentType.Minus", "StrikeKind": <StrikeType value>} |
{"Multiplier": 1, "Adjustment": "AdjustmentType.Plus", "StrikeKind": "StrikeType.ATM"} |
EntryType.EntryByPremiumCloseToStraddle |
The strike whose own premium is closest to (straddle premium × multiplier). | object: {"Multiplier": number, "StrikeKind": <StrikeType value>} |
{"Multiplier": 0.5, "StrikeKind": "StrikeType.ATM"} |
"None" |
No strike selection — used only for Futures/Cash legs. | string const "None" |
Pair with InstrumentKind: "LegType.FUT" or "LegType.CASH" |
StrikeType
Used both as the value of StrikeParameter (when EntryType is
EntryByStrikeType / EntryBySyntheticFuture) and as the StrikeKind field
inside the straddle-based entry types above:
| Value | Meaning |
|---|---|
StrikeType.ATM |
At-the-money strike. |
StrikeType.ITM1 … StrikeType.ITM20 |
In-the-money, N strikes deep (1 to 20). |
StrikeType.OTM1 … StrikeType.OTM30 |
Out-of-the-money, N strikes deep (1 to 30). |
AdjustmentType
Used only inside EntryType.EntryByStraddlePrice's StrikeParameter.Adjustment:
| Value | Meaning |
|---|---|
AdjustmentType.Plus |
Shift the computed strike up from the straddle-based reference. |
AdjustmentType.Minus |
Shift the computed strike down from the straddle-based reference. |
ExpiryKind
| Value | Meaning | Constraints |
|---|---|---|
ExpiryType.Weekly |
Nearest weekly expiry. | Primary tickers only. |
ExpiryType.NextWeekly |
The weekly expiry after the nearest one. | Primary tickers only. |
ExpiryType.Monthly |
Nearest monthly expiry. | Available for all tickers. |
ExpiryType.NextMonthly |
The monthly expiry after the nearest one. | Available for all tickers. |
ExpiryType.Today |
Same-day expiry. | Delta/Coinswitch (crypto) tickers only. |
ExpiryType.Tomorrow |
Next-day expiry. | Delta/Coinswitch (crypto) tickers only. |
Non-primary tickers are Monthly-only
For any ticker that isn't a primary ticker — i.e.
BANKNIFTY, FINNIFTY, MIDCPNIFTY, BANKEX, or any individual
stock — only ExpiryType.Monthly and ExpiryType.NextMonthly are
accepted. Sending Weekly/NextWeekly for these is rejected with
"Only Monthly expiries are supported for non-primary tickers".
PositionType
| Value | Meaning |
|---|---|
PositionType.Buy |
Long / buy the leg. |
PositionType.Sell |
Short / sell (write) the leg. |
Lots
integer, minimum 1. Number of lots to trade for this leg (multiplied by
the underlying's exchange-defined lot size internally).
LegStopLoss / LegTarget
Both fields share the same { "Type": ..., "Value": ... } shape:
Type |
Meaning | Value |
|---|---|---|
"None" |
No stop loss / target on this leg. | Must be exactly 0. |
LegTgtSLType.Points |
Absolute price points on the leg's own premium. | number, >= 1 |
LegTgtSLType.Percentage |
% move of the leg's own premium. | number, >= 0 |
LegTgtSLType.UnderlyingPoints |
Absolute points move of the underlying (spot), rather than the option premium. | number, >= 1 |
LegTgtSLType.UnderlyingPercentage |
% move of the underlying (spot). | number, >= 0 |
"LegStopLoss": { "Type": "LegTgtSLType.Percentage", "Value": 50 },
"LegTarget": { "Type": "None", "Value": 0 }
LegTrailSL
Trailing stop loss for this leg. Shape:
Type |
Meaning | Value |
|---|---|---|
"None" |
No trailing stop loss (default). | Must be exactly {}. |
TrailStopLossType.Points |
Trail the SL by absolute points as the instrument moves in your favor. | {"InstrumentMove": number, "StopLossMove": number} |
TrailStopLossType.Percentage |
Trail the SL by percentage. | {"InstrumentMove": number, "StopLossMove": number} |
Value.InstrumentMove / Value.StopLossMove: for every InstrumentMove the
instrument moves in your favor, the stop loss is trailed by StopLossMove
in the same direction.
"LegTrailSL": {
"Type": "TrailStopLossType.Points",
"Value": { "InstrumentMove": 10, "StopLossMove": 5 }
}
2. ExecutionConfig
Defines the execution details such as product type, entry/exit order
configurations, and reference for stop loss/target calculations. Every
field in ExecutionConfig is optional — omitted fields fall back to
their defaults below.
{
"ExecutionConfig": {
"ProductType": "ProductType.NRML",
"ReferenceForTgtSL": "PriceReferenceType.Trigger",
"EntryOrder": {
"Type": "OrderType.Limit",
"Value": {
"Buffer": {
"Type": "BufferType.Points",
"Value": { "TriggerBuffer": 0, "LimitBuffer": 3 }
},
"Modification": { "MarketOrderAfter": 1 }
}
},
"ExitOrder": {
"Type": "OrderType.Limit",
"Value": {
"Buffer": {
"Type": "BufferType.Points",
"Value": { "TriggerBuffer": 0, "LimitBuffer": 3 }
},
"Modification": { "MarketOrderAfter": 1 }
}
},
"EntryDelay": 0
}
}
ProductType
| Value | Meaning |
|---|---|
ProductType.NRML |
Normal / carry-forward margin product. Default if omitted. |
ProductType.MIS |
Intraday margin product — higher leverage, broker auto-square-off before close. |
ProductType.CNC |
Cash & Carry — delivery-based; applies to cash/equity legs. |
ReferenceForTgtSL
| Value | Meaning |
|---|---|
PriceReferenceType.Trigger |
SL/Target are computed from the price at which the entry order was triggered. |
PriceReferenceType.Trade |
SL/Target are computed from the actual filled/traded price. Default if omitted. |
EntryOrder / ExitOrder
Both fields use the same OrderType structure and accept one of three
variants:
{ "Type": "OrderType.Market", "Value": {} }
Value must be an empty object — Market orders cannot carry a Buffer
or Modification.
Warning
Rejected on NSE/BSE tickers (all indices and stocks) with
"Market order has been disabled by the exchange. Update to Limit
to continue." Use Limit or MPP there instead. Market orders
work normally on Delta/Coinswitch (crypto) tickers.
{
"Type": "OrderType.Limit",
"Value": {
"Buffer": {
"Type": "BufferType.Points",
"Value": { "TriggerBuffer": 0, "LimitBuffer": 3 }
},
"Modification": {
"MarketOrderAfter": 1
}
}
}
Value.Buffer:
| Field | Type | Meaning |
|---|---|---|
Type |
BufferType.Points or BufferType.Percentage |
Whether the buffer values below are absolute points or a percentage of price. |
Value.TriggerBuffer |
number | Offset applied to compute the order's trigger price. |
Value.LimitBuffer |
number | Offset applied to compute the order's limit price. |
Value.Modification:
| Field | Type | Required | Meaning |
|---|---|---|---|
MarketOrderAfter |
integer, 0–40 |
Yes | Number of repricing attempts before AlgoTest converts the unfilled limit order to a market order. |
MarketOrderAfter is exchange-dependent
MarketOrderAfter is only honored on Delta/Coinswitch (crypto)
tickers.
{ "Type": "OrderType.MPP", "Value": {} }
Value must be an empty object. MPP ("Market Protection Price") is the
NSE/BSE substitute for a real market order — a protected order type
used where exchanges don't support true market orders.
Warning
Rejected on Delta/Coinswitch tickers with "MPP order is not
supported for this exchange. Update to Limit/Market to continue."
Use Market there instead.
Tip
If EntryOrder / ExitOrder is omitted entirely, AlgoTest falls back
to its internal default order handling. For predictable behavior,
always specify both explicitly.
EntryDelay
integer, 0–50 (seconds). Delay applied before placing the order.
Optional, default 0. Note: this single value is applied to both the
entry and the exit order of the leg — there's no separate delay field per
order.
Additional Configurations
Putting it together, a Limit order buffer/modification block commonly
looks like:
- Buffer using
BufferType.PointsorBufferType.Percentageto offset the trigger/limit price from the reference price. - Modification using
MarketOrderAfterto convert an unfilled limit order to a market order after N repricing attempts (remember: only effective on Delta/Coinswitch).
Validation Rules & Gotchas
A quick-reference checklist of things that will get a request rejected — worth skimming before you go live:
- 1–10 legs per strategy (
Legsarray length). exit_timemust not be in the past, and the request must arrive within exchange trading hours.- Non-primary tickers (
BANKNIFTY,FINNIFTY,MIDCPNIFTY,BANKEX, all stocks) only acceptExpiryType.Monthly/ExpiryType.NextMonthly. ExpiryType.Today/ExpiryType.Tomorroware Delta/Coinswitch-only.InstrumentKind: "LegType.CASH"is only valid whenTickeris an individual stock.InstrumentKind: "LegType.FUT"is rejected on Delta/Coinswitch tickers — and this webhook has no reachable substitute for it there (see the InstrumentKind note above).OrderType.Marketis rejected on NSE/BSE tickers;OrderType.MPPis rejected on Delta/Coinswitch tickers.Modification.MarketOrderAfteronly takes effect on Delta/Coinswitch tickers.- For Futures/Cash legs, set both
EntryTypeandStrikeParameterto the string"None".
Example Request
Below is a minimal example that demonstrates a strategy on NIFTY with two short option legs and an overall MTM stop loss of 3000.
{
"access_token": "your-access-token",
"alert_name": "custom_strategy",
"exit_time": "2025-11-29T15:15:00",
"strategy": {
"Ticker": "NIFTY",
"Legs": [
{
"PositionConfig": {
"EntryType" : "EntryType.EntryByExactStrike",
"InstrumentKind": "LegType.CE",
"StrikeParameter": 23850,
"ExpiryKind": "ExpiryType.Weekly",
"PositionType": "PositionType.Sell",
"Lots": 1,
"LegStopLoss": { "Type": "None", "Value": 0 },
"LegTarget": { "Type": "None", "Value": 0 },
"LegTrailSL": { "Type": "None", "Value": {} }
},
"ExecutionConfig": {
"ProductType": "ProductType.NRML",
"ReferenceForTgtSL": "PriceReferenceType.Trigger",
"EntryOrder": {
"Type": "OrderType.Limit",
"Value": {
"Buffer": {
"Type": "BufferType.Points",
"Value": {
"TriggerBuffer": 0,
"LimitBuffer": 3
}
},
"Modification": {
"MarketOrderAfter": 1
}
}
},
"ExitOrder": {
"Type": "OrderType.Limit",
"Value": {
"Buffer": {
"Type": "BufferType.Points",
"Value": {
"TriggerBuffer": 0,
"LimitBuffer": 3
}
},
"Modification": {
"MarketOrderAfter": 1
}
}
}
}
},
{
"PositionConfig": {
"EntryType" : "EntryType.EntryByExactStrike",
"InstrumentKind": "LegType.PE",
"StrikeParameter": 23350,
"ExpiryKind": "ExpiryType.Weekly",
"PositionType": "PositionType.Sell",
"Lots": 1,
"LegStopLoss": { "Type": "None", "Value": 0 },
"LegTarget": { "Type": "None", "Value": 0 },
"LegTrailSL": { "Type": "None", "Value": {} }
},
"ExecutionConfig": {
"ProductType": "ProductType.NRML",
"ReferenceForTgtSL": "PriceReferenceType.Trigger",
"EntryOrder": {
"Type": "OrderType.Limit",
"Value": {
"Buffer": {
"Type": "BufferType.Points",
"Value": {
"TriggerBuffer": 0,
"LimitBuffer": 3
}
},
"Modification": {
"MarketOrderAfter": 1
}
}
},
"ExitOrder": {
"Type": "OrderType.Limit",
"Value": {
"Buffer": {
"Type": "BufferType.Points",
"Value": {
"TriggerBuffer": 0,
"LimitBuffer": 3
}
},
"Modification": {
"MarketOrderAfter": 1
}
}
}
}
}
],
"OverallSL": {
"Type": "OverallTgtSLType.MTM",
"Value": 3000
}
}
}
Here's a second example showing a relative strike (ATM) entry with an
MPP order — an ATM straddle sell on SENSEX with a 50% per-leg stop
loss:
{
"access_token": "your-access-token",
"alert_name": "atm_straddle_sell",
"exit_time": "2025-11-29T15:15:00",
"strategy": {
"Ticker": "SENSEX",
"Legs": [
{
"PositionConfig": {
"EntryType": "EntryType.EntryByStrikeType",
"InstrumentKind": "LegType.CE",
"StrikeParameter": "StrikeType.ATM",
"ExpiryKind": "ExpiryType.Weekly",
"PositionType": "PositionType.Sell",
"Lots": 2,
"LegStopLoss": { "Type": "LegTgtSLType.Percentage", "Value": 50 },
"LegTarget": { "Type": "None", "Value": 0 },
"LegTrailSL": { "Type": "None", "Value": {} }
},
"ExecutionConfig": {
"ProductType": "ProductType.NRML",
"ReferenceForTgtSL": "PriceReferenceType.Trade",
"EntryOrder": { "Type": "OrderType.MPP", "Value": {} },
"ExitOrder": { "Type": "OrderType.MPP", "Value": {} }
}
},
{
"PositionConfig": {
"EntryType": "EntryType.EntryByStrikeType",
"InstrumentKind": "LegType.PE",
"StrikeParameter": "StrikeType.ATM",
"ExpiryKind": "ExpiryType.Weekly",
"PositionType": "PositionType.Sell",
"Lots": 2,
"LegStopLoss": { "Type": "LegTgtSLType.Percentage", "Value": 50 },
"LegTarget": { "Type": "None", "Value": 0 },
"LegTrailSL": { "Type": "None", "Value": {} }
},
"ExecutionConfig": {
"ProductType": "ProductType.NRML",
"ReferenceForTgtSL": "PriceReferenceType.Trade",
"EntryOrder": { "Type": "OrderType.MPP", "Value": {} },
"ExitOrder": { "Type": "OrderType.MPP", "Value": {} }
}
}
]
}
}
Response Examples
200 - Success
{
"id": "6788c4fb6be04cb2210e9c10"
}
503 - Service Unavailable
{
"msg": "You can only activate strategies during 08:15 IST to 15:39 IST on trading days"
}
API Documentation: Signals API Square-Off
Overview
This API allows users to stop a running position. By sending a POST request to the endpoint with the position ID, you can specify the access token to square off the position.
Endpoint
URL:
https://api.algotest.in/webhook/custom-position/execution/square-off/{position_id}
Method: POST
Request Body
The request body should be in JSON format and include the following main components:
access_token: Your API access token.
Example Request
{
"access_token": "your-access-token"
}