Repository: ccxt/ccxt
File: ts/src/bybit.ts (TypeScript)

Code before:
        const isTakeProfit = takeProfit !== undefined;
        const isMarket = lowerCaseType === 'market';
        const isLimit = lowerCaseType === 'limit';
        const isBuy = side === 'buy';
        let defaultMethod = undefined;
        if ((isTrailingAmountOrder || isStopLossTriggerOrder || isTakeProfitTriggerOrder) && !market['spot']) {
            defaultMethod = 'privatePostV5PositionTradingStop';
        } else {
            defaultMethod = 'privatePostV5OrderCreate';
        }
        let method = undefined;
        [ method, params ] = this.handleOptionAndParams (params, 'createOrder', 'method', defaultMethod);
        const isAlternativeEndpoint = method === 'privatePostV5PositionTradingStop';
        const amountString = this.getAmount (symbol, amount);
        const priceString = (price !== undefined) ? this.getPrice (symbol, this.numberToString (price)) : undefined;
        if (isTrailingAmountOrder || isAlternativeEndpoint) {
            if (isStopLoss || isTakeProfit || isTriggerOrder || market['spot']) {
                throw new InvalidOrder (this.id + ' the API endpoint used only supports contract trailingAmount, stopLossPrice and takeProfitPrice orders');
            }
            if (isStopLossTriggerOrder || isTakeProfitTriggerOrder) {
                const tpslMode = this.safeString (params, 'tpslMode') || 'partial';
                const isFullTpsl = tpslMode === 'full';
                const isPartialTpsl = tpslMode === 'partial';
                if (isLimit && isFullTpsl) {
                    throw new InvalidOrder (this.id + ' full tpsl orders only support market orders');
                }
                request['tpslMode'] = this.capitalize (tpslMode);
                if (isStopLossTriggerOrder) {
                    request['stopLoss'] = this.getPrice (symbol, stopLossTriggerPrice);
                    if (isPartialTpsl) {
                        request['slSize'] = amountString;
                    }
                    if (isLimit) {
                        request['slOrderType'] = 'Limit';
                        request['slLimitPrice'] = priceString;
                    }
                } else if (isTakeProfitTriggerOrder) {
                    request['takeProfit'] = this.getPrice (symbol, takeProfitTriggerPrice);
                    if (isPartialTpsl) {
                        request['tpSize'] = amountString;
                    }
                    if (isLimit) {
                        request['tpOrderType'] = 'Limit';
                        request['tpLimitPrice'] = priceString;
                    }
                }
            }
        } else {
            request['side'] = this.capitalize (side);
            request['orderType'] = this.capitalize (lowerCaseType);
            const timeInForce = this.safeStringLower (params, 'timeInForce'); // this is same as exchange specific param

Review comment (suggestion):
This already throws from exchange:
```ts
await exchange.createOrder("ETH/USDT:USDT",
    "limit",
    "sell",
    10,
    3200,
    {
      clientOrderId: "1234567890",
      tpslMode: "full",
      stopLossPrice: 3100
    }
);
```

maps to:
```json
{"symbol":"ETHUSDT","stopLoss":"3100","tpslMode":"full","slOrderType":"Limit","slLimitPrice":"3200","category":"linear"}
```

returns:
```json
{"retCode":10001,"retMsg":"slOrderType only support Market when tpSlMode is Full","result":{},"retExtInfo":{},"time":1762349958482}
```

Code after:
        const isTakeProfit = takeProfit !== undefined;
        const isMarket = lowerCaseType === 'market';
        const isLimit = lowerCaseType === 'limit';
        const isBuy = side === 'buy';
        let defaultMethod = undefined;
        if ((isTrailingAmountOrder || isStopLossTriggerOrder || isTakeProfitTriggerOrder) && !market['spot']) {
            defaultMethod = 'privatePostV5PositionTradingStop';
        } else {
            defaultMethod = 'privatePostV5OrderCreate';
        }
        let method = undefined;
        [ method, params ] = this.handleOptionAndParams (params, 'createOrder', 'method', defaultMethod);
        const isAlternativeEndpoint = method === 'privatePostV5PositionTradingStop';
        const amountString = this.getAmount (symbol, amount);
        const priceString = (price !== undefined) ? this.getPrice (symbol, this.numberToString (price)) : undefined;
        if (isTrailingAmountOrder || isAlternativeEndpoint) {
            if (isStopLoss || isTakeProfit || isTriggerOrder || market['spot']) {
                throw new InvalidOrder (this.id + ' the API endpoint used only supports contract trailingAmount, stopLossPrice and takeProfitPrice orders');
            }
            if (isStopLossTriggerOrder || isTakeProfitTriggerOrder) {
                const tpslMode = this.safeString (params, 'tpslMode', 'Partial');
                const isFullTpsl = tpslMode === 'Full';
                const isPartialTpsl = tpslMode === 'Partial';
                if (isLimit && isFullTpsl) {
                    throw new InvalidOrder (this.id + ' tpsl orders with "full" tpslMode only support "market" type');
                }
                request['tpslMode'] = tpslMode;
                if (isStopLossTriggerOrder) {
                    request['stopLoss'] = this.getPrice (symbol, stopLossTriggerPrice);
                    if (isPartialTpsl) {
                        request['slSize'] = amountString;
                    }
                    if (isLimit) {
                        request['slOrderType'] = 'Limit';
                        request['slLimitPrice'] = priceString;
                    }
                } else if (isTakeProfitTriggerOrder) {
                    request['takeProfit'] = this.getPrice (symbol, takeProfitTriggerPrice);
                    if (isPartialTpsl) {
                        request['tpSize'] = amountString;
                    }
                    if (isLimit) {
                        request['tpOrderType'] = 'Limit';
                        request['tpLimitPrice'] = priceString;
                    }
                }
            }
        } else {
            request['side'] = this.capitalize (side);
            request['orderType'] = this.capitalize (lowerCaseType);
            const timeInForce = this.safeStringLower (params, 'timeInForce'); // this is same as exchange specific param