future-private: add place order request
This commit is contained in:
parent
d561f69ece
commit
9d70e9ae44
48
README.md
48
README.md
|
|
@ -68,6 +68,47 @@ if ($response->getStatusCode() === 200) {
|
|||
}
|
||||
```
|
||||
|
||||
### Place Order
|
||||
|
||||
```php
|
||||
use Msr\LaravelBitunixApi\Requests\PlaceOrderRequestContract;
|
||||
|
||||
$api = app(PlaceOrderRequestContract::class);
|
||||
|
||||
// Basic market order
|
||||
$response = $api->placeOrder('BTCUSDT', '0.1', 'BUY', 'OPEN', 'MARKET');
|
||||
|
||||
// Limit order with take profit and stop loss
|
||||
$response = $api->placeOrder(
|
||||
'BTCUSDT',
|
||||
'0.1',
|
||||
'BUY',
|
||||
'OPEN',
|
||||
'LIMIT',
|
||||
'50000', // price
|
||||
null, // positionId
|
||||
'GTC', // effect
|
||||
'order-123', // clientId
|
||||
false, // reduceOnly
|
||||
'51000', // tpPrice
|
||||
'MARK_PRICE', // tpStopType
|
||||
'LIMIT', // tpOrderType
|
||||
'51000.1', // tpOrderPrice
|
||||
'49000', // slPrice
|
||||
'MARK_PRICE', // slStopType
|
||||
'LIMIT', // slOrderType
|
||||
'49000.1' // slOrderPrice
|
||||
);
|
||||
|
||||
if ($response->getStatusCode() === 200) {
|
||||
$data = json_decode($response->getBody()->getContents(), true);
|
||||
if ($data['code'] === 0) {
|
||||
echo "Order placed successfully!";
|
||||
echo "Order ID: " . $data['data']['orderId'];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Get Future Kline Data
|
||||
|
||||
```php
|
||||
|
|
@ -89,6 +130,10 @@ if ($response->getStatusCode() === 200) {
|
|||
- `changeLeverage(string $symbol, string $marginCoin, int $leverage)` - Change leverage
|
||||
- `changeMarginMode(string $symbol, string $marginCoin, string $marginMode)` - Change margin mode
|
||||
|
||||
### Trading
|
||||
|
||||
- `placeOrder(...)` - Place a new order with full support for all order types, take profit, stop loss, and position management
|
||||
|
||||
### Market Data
|
||||
|
||||
- `getFutureKline(string $symbol, string $interval, int $limit, ?int $startTime, ?int $endTime, string $type)` - Get kline data
|
||||
|
|
@ -106,6 +151,7 @@ if ($response->getStatusCode() === 200) {
|
|||
|
||||
- **Change Leverage**: 10 req/sec/uid
|
||||
- **Change Margin Mode**: 10 req/sec/uid
|
||||
- **Place Order**: 10 req/sec/uid
|
||||
|
||||
## Error Handling
|
||||
|
||||
|
|
@ -143,6 +189,7 @@ Run specific tests:
|
|||
```bash
|
||||
vendor/bin/pest tests/ChangeLeverageTest.php
|
||||
vendor/bin/pest tests/ChangeMarginModeTest.php
|
||||
vendor/bin/pest tests/PlaceOrderTest.php
|
||||
vendor/bin/pest tests/HeaderTest.php
|
||||
```
|
||||
|
||||
|
|
@ -152,6 +199,7 @@ See the `examples/` directory for complete usage examples:
|
|||
|
||||
- `ChangeLeverageExample.php`
|
||||
- `ChangeMarginModeExample.php`
|
||||
- `PlaceOrderExample.php`
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,167 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Example usage of Place Order functionality
|
||||
*
|
||||
* This example demonstrates how to use the LaravelBitunixApi package
|
||||
* to place orders on Bitunix exchange.
|
||||
*/
|
||||
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
use Msr\LaravelBitunixApi\Requests\PlaceOrderRequestContract;
|
||||
|
||||
// Example configuration (in real usage, these would be in your .env file)
|
||||
config([
|
||||
'bitunix-api.future_base_uri' => 'https://fapi.bitunix.com/',
|
||||
'bitunix-api.api_key' => 'your-api-key-here',
|
||||
'bitunix-api.api_secret' => 'your-api-secret-here',
|
||||
'bitunix-api.language' => 'en-US',
|
||||
]);
|
||||
|
||||
try {
|
||||
// Get the API instance
|
||||
$api = app(PlaceOrderRequestContract::class);
|
||||
|
||||
echo "🚀 Placing Orders Examples\n\n";
|
||||
|
||||
// Example 1: Basic Market Order
|
||||
echo "1. Placing a basic market order...\n";
|
||||
$response = $api->placeOrder(
|
||||
'BTCUSDT',
|
||||
'0.1',
|
||||
'BUY',
|
||||
'OPEN',
|
||||
'MARKET'
|
||||
);
|
||||
|
||||
if ($response->getStatusCode() === 200) {
|
||||
$data = json_decode($response->getBody()->getContents(), true);
|
||||
if ($data['code'] === 0) {
|
||||
echo "✅ Market order placed successfully!\n";
|
||||
echo "Order ID: " . $data['data']['orderId'] . "\n";
|
||||
} else {
|
||||
echo "❌ API Error: " . $data['msg'] . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
echo "\n";
|
||||
|
||||
// Example 2: Limit Order with Take Profit and Stop Loss
|
||||
echo "2. Placing a limit order with TP/SL...\n";
|
||||
$response = $api->placeOrder(
|
||||
'BTCUSDT',
|
||||
'0.1',
|
||||
'BUY',
|
||||
'OPEN',
|
||||
'LIMIT',
|
||||
'50000', // price
|
||||
null, // positionId
|
||||
'GTC', // effect
|
||||
'order-123', // clientId
|
||||
false, // reduceOnly
|
||||
'51000', // tpPrice
|
||||
'MARK_PRICE', // tpStopType
|
||||
'LIMIT', // tpOrderType
|
||||
'51000.1', // tpOrderPrice
|
||||
'49000', // slPrice
|
||||
'MARK_PRICE', // slStopType
|
||||
'LIMIT', // slOrderType
|
||||
'49000.1' // slOrderPrice
|
||||
);
|
||||
|
||||
if ($response->getStatusCode() === 200) {
|
||||
$data = json_decode($response->getBody()->getContents(), true);
|
||||
if ($data['code'] === 0) {
|
||||
echo "✅ Limit order with TP/SL placed successfully!\n";
|
||||
echo "Order ID: " . $data['data']['orderId'] . "\n";
|
||||
echo "Client ID: " . $data['data']['clientId'] . "\n";
|
||||
} else {
|
||||
echo "❌ API Error: " . $data['msg'] . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
echo "\n";
|
||||
|
||||
// Example 3: Close Position Order
|
||||
echo "3. Placing a close position order...\n";
|
||||
$response = $api->placeOrder(
|
||||
'BTCUSDT',
|
||||
'0.1',
|
||||
'SELL',
|
||||
'CLOSE',
|
||||
'MARKET',
|
||||
null,
|
||||
'position-123' // positionId required for CLOSE
|
||||
);
|
||||
|
||||
if ($response->getStatusCode() === 200) {
|
||||
$data = json_decode($response->getBody()->getContents(), true);
|
||||
if ($data['code'] === 0) {
|
||||
echo "✅ Close position order placed successfully!\n";
|
||||
echo "Order ID: " . $data['data']['orderId'] . "\n";
|
||||
} else {
|
||||
echo "❌ API Error: " . $data['msg'] . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
echo "\n";
|
||||
|
||||
// Example 4: Reduce Only Order
|
||||
echo "4. Placing a reduce only order...\n";
|
||||
$response = $api->placeOrder(
|
||||
'BTCUSDT',
|
||||
'0.05',
|
||||
'SELL',
|
||||
'CLOSE',
|
||||
'MARKET',
|
||||
null,
|
||||
'position-123',
|
||||
null,
|
||||
null,
|
||||
true // reduceOnly
|
||||
);
|
||||
|
||||
if ($response->getStatusCode() === 200) {
|
||||
$data = json_decode($response->getBody()->getContents(), true);
|
||||
if ($data['code'] === 0) {
|
||||
echo "✅ Reduce only order placed successfully!\n";
|
||||
echo "Order ID: " . $data['data']['orderId'] . "\n";
|
||||
} else {
|
||||
echo "❌ API Error: " . $data['msg'] . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo '❌ Exception: '.$e->getMessage()."\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Order Types:
|
||||
* - LIMIT: Limit orders (requires price)
|
||||
* - MARKET: Market orders
|
||||
*
|
||||
* Order Sides:
|
||||
* - BUY: Buy order
|
||||
* - SELL: Sell order
|
||||
*
|
||||
* Trade Sides:
|
||||
* - OPEN: Open a new position
|
||||
* - CLOSE: Close an existing position (requires positionId)
|
||||
*
|
||||
* Effect Types:
|
||||
* - IOC: Immediate or cancel
|
||||
* - FOK: Fill or kill
|
||||
* - GTC: Good till canceled (default)
|
||||
* - POST_ONLY: POST only
|
||||
*
|
||||
* Take Profit / Stop Loss Types:
|
||||
* - MARK_PRICE: Mark price
|
||||
* - LAST_PRICE: Last price
|
||||
*
|
||||
* Environment Variables Required:
|
||||
*
|
||||
* BITUNIX_API_KEY=your-api-key
|
||||
* BITUNIX_API_SECRET=your-api-secret
|
||||
* BITUNIX_LANGUAGE=en-US
|
||||
*/
|
||||
|
|
@ -7,9 +7,10 @@ use Msr\LaravelBitunixApi\Requests\ChangeLeverageRequestContract;
|
|||
use Msr\LaravelBitunixApi\Requests\ChangeMarginModeRequestContract;
|
||||
use Msr\LaravelBitunixApi\Requests\FutureKLineRequestContract;
|
||||
use Msr\LaravelBitunixApi\Requests\Header;
|
||||
use Msr\LaravelBitunixApi\Requests\PlaceOrderRequestContract;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class LaravelBitunixApi implements ChangeLeverageRequestContract, ChangeMarginModeRequestContract, FutureKLineRequestContract
|
||||
class LaravelBitunixApi implements ChangeLeverageRequestContract, ChangeMarginModeRequestContract, FutureKLineRequestContract, PlaceOrderRequestContract
|
||||
{
|
||||
private Client $publicFutureClient;
|
||||
|
||||
|
|
@ -76,4 +77,80 @@ class LaravelBitunixApi implements ChangeLeverageRequestContract, ChangeMarginMo
|
|||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function placeOrder(
|
||||
string $symbol,
|
||||
string $qty,
|
||||
string $side,
|
||||
string $tradeSide,
|
||||
string $orderType,
|
||||
?string $price = null,
|
||||
?string $positionId = null,
|
||||
?string $effect = null,
|
||||
?string $clientId = null,
|
||||
?bool $reduceOnly = null,
|
||||
?string $tpPrice = null,
|
||||
?string $tpStopType = null,
|
||||
?string $tpOrderType = null,
|
||||
?string $tpOrderPrice = null,
|
||||
?string $slPrice = null,
|
||||
?string $slStopType = null,
|
||||
?string $slOrderType = null,
|
||||
?string $slOrderPrice = null
|
||||
): ResponseInterface {
|
||||
$body = [
|
||||
'symbol' => $symbol,
|
||||
'qty' => $qty,
|
||||
'side' => $side,
|
||||
'tradeSide' => $tradeSide,
|
||||
'orderType' => $orderType,
|
||||
];
|
||||
|
||||
// Add optional parameters if provided
|
||||
if ($price !== null) {
|
||||
$body['price'] = $price;
|
||||
}
|
||||
if ($positionId !== null) {
|
||||
$body['positionId'] = $positionId;
|
||||
}
|
||||
if ($effect !== null) {
|
||||
$body['effect'] = $effect;
|
||||
}
|
||||
if ($clientId !== null) {
|
||||
$body['clientId'] = $clientId;
|
||||
}
|
||||
if ($reduceOnly !== null) {
|
||||
$body['reduceOnly'] = $reduceOnly;
|
||||
}
|
||||
if ($tpPrice !== null) {
|
||||
$body['tpPrice'] = $tpPrice;
|
||||
}
|
||||
if ($tpStopType !== null) {
|
||||
$body['tpStopType'] = $tpStopType;
|
||||
}
|
||||
if ($tpOrderType !== null) {
|
||||
$body['tpOrderType'] = $tpOrderType;
|
||||
}
|
||||
if ($tpOrderPrice !== null) {
|
||||
$body['tpOrderPrice'] = $tpOrderPrice;
|
||||
}
|
||||
if ($slPrice !== null) {
|
||||
$body['slPrice'] = $slPrice;
|
||||
}
|
||||
if ($slStopType !== null) {
|
||||
$body['slStopType'] = $slStopType;
|
||||
}
|
||||
if ($slOrderType !== null) {
|
||||
$body['slOrderType'] = $slOrderType;
|
||||
}
|
||||
if ($slOrderPrice !== null) {
|
||||
$body['slOrderPrice'] = $slOrderPrice;
|
||||
}
|
||||
|
||||
$response = $this->getPrivateFutureClient([], $body)->post('trade/place_order', [
|
||||
'json' => $body,
|
||||
]);
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use Msr\LaravelBitunixApi\Commands\LaravelBitunixApiCommand;
|
|||
use Msr\LaravelBitunixApi\Requests\ChangeLeverageRequestContract;
|
||||
use Msr\LaravelBitunixApi\Requests\ChangeMarginModeRequestContract;
|
||||
use Msr\LaravelBitunixApi\Requests\FutureKLineRequestContract;
|
||||
use Msr\LaravelBitunixApi\Requests\PlaceOrderRequestContract;
|
||||
use Spatie\LaravelPackageTools\Package;
|
||||
use Spatie\LaravelPackageTools\PackageServiceProvider;
|
||||
|
||||
|
|
@ -33,5 +34,6 @@ class LaravelBitunixApiServiceProvider extends PackageServiceProvider
|
|||
$this->app->bind(FutureKLineRequestContract::class, LaravelBitunixApi::class);
|
||||
$this->app->bind(ChangeLeverageRequestContract::class, LaravelBitunixApi::class);
|
||||
$this->app->bind(ChangeMarginModeRequestContract::class, LaravelBitunixApi::class);
|
||||
$this->app->bind(PlaceOrderRequestContract::class, LaravelBitunixApi::class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
namespace Msr\LaravelBitunixApi\Requests;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
interface PlaceOrderRequestContract
|
||||
{
|
||||
/**
|
||||
* Place a new order
|
||||
*
|
||||
* @param string $symbol Trading pair (e.g., 'BTCUSDT')
|
||||
* @param string $qty Amount (base coin)
|
||||
* @param string $side Order direction ('BUY' or 'SELL')
|
||||
* @param string $tradeSide Direction ('OPEN' or 'CLOSE')
|
||||
* @param string $orderType Order type ('LIMIT' or 'MARKET')
|
||||
* @param string|null $price Price of the order (required for LIMIT orders)
|
||||
* @param string|null $positionId Position ID (required when tradeSide is 'CLOSE')
|
||||
* @param string|null $effect Order expiration date
|
||||
* @param string|null $clientId Customize order ID
|
||||
* @param bool|null $reduceOnly Whether to just reduce the position
|
||||
* @param string|null $tpPrice Take profit trigger price
|
||||
* @param string|null $tpStopType Take profit trigger type
|
||||
* @param string|null $tpOrderType Take profit trigger place order type
|
||||
* @param string|null $tpOrderPrice Take profit trigger place order price
|
||||
* @param string|null $slPrice Stop loss trigger price
|
||||
* @param string|null $slStopType Stop loss trigger type
|
||||
* @param string|null $slOrderType Stop loss trigger place order type
|
||||
* @param string|null $slOrderPrice Stop loss trigger place order price
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function placeOrder(
|
||||
string $symbol,
|
||||
string $qty,
|
||||
string $side,
|
||||
string $tradeSide,
|
||||
string $orderType,
|
||||
?string $price = null,
|
||||
?string $positionId = null,
|
||||
?string $effect = null,
|
||||
?string $clientId = null,
|
||||
?bool $reduceOnly = null,
|
||||
?string $tpPrice = null,
|
||||
?string $tpStopType = null,
|
||||
?string $tpOrderType = null,
|
||||
?string $tpOrderPrice = null,
|
||||
?string $slPrice = null,
|
||||
?string $slStopType = null,
|
||||
?string $slOrderType = null,
|
||||
?string $slOrderPrice = null
|
||||
): ResponseInterface;
|
||||
}
|
||||
|
|
@ -0,0 +1,237 @@
|
|||
<?php
|
||||
|
||||
use Msr\LaravelBitunixApi\Requests\PlaceOrderRequestContract;
|
||||
|
||||
beforeEach(function () {
|
||||
config([
|
||||
'bitunix-api.future_base_uri' => 'https://fapi.bitunix.com/',
|
||||
'bitunix-api.api_key' => 'test-api-key',
|
||||
'bitunix-api.api_secret' => 'test-secret-key',
|
||||
'bitunix-api.language' => 'en-US',
|
||||
]);
|
||||
});
|
||||
|
||||
it('can place a basic market order', function () {
|
||||
$api = app(PlaceOrderRequestContract::class);
|
||||
|
||||
expect(fn() => $api->placeOrder(
|
||||
'BTCUSDT',
|
||||
'0.1',
|
||||
'BUY',
|
||||
'OPEN',
|
||||
'MARKET'
|
||||
))->not->toThrow(Exception::class);
|
||||
});
|
||||
|
||||
it('can place a limit order with price', function () {
|
||||
$api = app(PlaceOrderRequestContract::class);
|
||||
|
||||
expect(fn() => $api->placeOrder(
|
||||
'BTCUSDT',
|
||||
'0.1',
|
||||
'BUY',
|
||||
'OPEN',
|
||||
'LIMIT',
|
||||
'50000'
|
||||
))->not->toThrow(Exception::class);
|
||||
});
|
||||
|
||||
it('can place an order with all optional parameters', function () {
|
||||
$api = app(PlaceOrderRequestContract::class);
|
||||
|
||||
expect(fn() => $api->placeOrder(
|
||||
'BTCUSDT',
|
||||
'0.1',
|
||||
'BUY',
|
||||
'OPEN',
|
||||
'LIMIT',
|
||||
'50000',
|
||||
'12345',
|
||||
'GTC',
|
||||
'custom-client-id',
|
||||
false,
|
||||
'51000',
|
||||
'MARK_PRICE',
|
||||
'LIMIT',
|
||||
'51000.1',
|
||||
'49000',
|
||||
'MARK_PRICE',
|
||||
'LIMIT',
|
||||
'49000.1'
|
||||
))->not->toThrow(Exception::class);
|
||||
});
|
||||
|
||||
it('can place a close position order', function () {
|
||||
$api = app(PlaceOrderRequestContract::class);
|
||||
|
||||
expect(fn() => $api->placeOrder(
|
||||
'BTCUSDT',
|
||||
'0.1',
|
||||
'SELL',
|
||||
'CLOSE',
|
||||
'MARKET',
|
||||
null,
|
||||
'position-123'
|
||||
))->not->toThrow(Exception::class);
|
||||
});
|
||||
|
||||
it('validates required parameters for place order', function () {
|
||||
$api = app(PlaceOrderRequestContract::class);
|
||||
|
||||
expect(fn() => $api->placeOrder('BTCUSDT', '0.1', 'BUY', 'OPEN', 'MARKET'))
|
||||
->not->toThrow(Exception::class)
|
||||
->and(fn() => $api->placeOrder('BTCUSDT', '0.1', 'SELL', 'OPEN', 'MARKET'))
|
||||
->not->toThrow(Exception::class);
|
||||
});
|
||||
|
||||
it('handles different order types correctly', function () {
|
||||
$api = app(PlaceOrderRequestContract::class);
|
||||
|
||||
$orderTypes = ['LIMIT', 'MARKET'];
|
||||
|
||||
foreach ($orderTypes as $orderType) {
|
||||
expect(fn() => $api->placeOrder(
|
||||
'BTCUSDT',
|
||||
'0.1',
|
||||
'BUY',
|
||||
'OPEN',
|
||||
$orderType,
|
||||
$orderType === 'LIMIT' ? '50000' : null
|
||||
))->not->toThrow(Exception::class);
|
||||
}
|
||||
});
|
||||
|
||||
it('handles different trade sides correctly', function () {
|
||||
$api = app(PlaceOrderRequestContract::class);
|
||||
|
||||
$tradeSides = ['OPEN', 'CLOSE'];
|
||||
|
||||
foreach ($tradeSides as $tradeSide) {
|
||||
expect(fn() => $api->placeOrder(
|
||||
'BTCUSDT',
|
||||
'0.1',
|
||||
'BUY',
|
||||
$tradeSide,
|
||||
'MARKET',
|
||||
null,
|
||||
$tradeSide === 'CLOSE' ? 'position-123' : null
|
||||
))->not->toThrow(Exception::class);
|
||||
}
|
||||
});
|
||||
|
||||
it('can handle different trading pairs', function () {
|
||||
$api = app(PlaceOrderRequestContract::class);
|
||||
|
||||
$tradingPairs = ['BTCUSDT', 'ETHUSDT', 'ADAUSDT'];
|
||||
|
||||
foreach ($tradingPairs as $symbol) {
|
||||
expect(fn() => $api->placeOrder($symbol, '0.1', 'BUY', 'OPEN', 'MARKET'))
|
||||
->not->toThrow(Exception::class);
|
||||
}
|
||||
});
|
||||
|
||||
it('validates order side parameter values', function () {
|
||||
$api = app(PlaceOrderRequestContract::class);
|
||||
|
||||
$sides = ['BUY', 'SELL'];
|
||||
|
||||
foreach ($sides as $side) {
|
||||
expect(fn() => $api->placeOrder('BTCUSDT', '0.1', $side, 'OPEN', 'MARKET'))
|
||||
->not->toThrow(Exception::class);
|
||||
}
|
||||
});
|
||||
|
||||
it('validates trade side parameter values', function () {
|
||||
$api = app(PlaceOrderRequestContract::class);
|
||||
|
||||
$tradeSides = ['OPEN', 'CLOSE'];
|
||||
|
||||
foreach ($tradeSides as $tradeSide) {
|
||||
expect(fn() => $api->placeOrder(
|
||||
'BTCUSDT',
|
||||
'0.1',
|
||||
'BUY',
|
||||
$tradeSide,
|
||||
'MARKET',
|
||||
null,
|
||||
$tradeSide === 'CLOSE' ? 'position-123' : null
|
||||
))->not->toThrow(Exception::class);
|
||||
}
|
||||
});
|
||||
|
||||
it('can handle take profit and stop loss parameters', function () {
|
||||
$api = app(PlaceOrderRequestContract::class);
|
||||
|
||||
expect(fn() => $api->placeOrder(
|
||||
'BTCUSDT',
|
||||
'0.1',
|
||||
'BUY',
|
||||
'OPEN',
|
||||
'LIMIT',
|
||||
'50000',
|
||||
null,
|
||||
'GTC',
|
||||
null,
|
||||
false,
|
||||
'51000',
|
||||
'MARK_PRICE',
|
||||
'LIMIT',
|
||||
'51000.1',
|
||||
'49000',
|
||||
'MARK_PRICE',
|
||||
'LIMIT',
|
||||
'49000.1'
|
||||
))->not->toThrow(Exception::class);
|
||||
});
|
||||
|
||||
it('can handle reduce only orders', function () {
|
||||
$api = app(PlaceOrderRequestContract::class);
|
||||
|
||||
expect(fn() => $api->placeOrder(
|
||||
'BTCUSDT',
|
||||
'0.1',
|
||||
'SELL',
|
||||
'CLOSE',
|
||||
'MARKET',
|
||||
null,
|
||||
'position-123',
|
||||
null,
|
||||
null,
|
||||
true
|
||||
))->not->toThrow(Exception::class);
|
||||
});
|
||||
|
||||
it('can handle custom client ID', function () {
|
||||
$api = app(PlaceOrderRequestContract::class);
|
||||
|
||||
expect(fn() => $api->placeOrder(
|
||||
'BTCUSDT',
|
||||
'0.1',
|
||||
'BUY',
|
||||
'OPEN',
|
||||
'MARKET',
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
'custom-order-123'
|
||||
))->not->toThrow(Exception::class);
|
||||
});
|
||||
|
||||
it('can handle different effect types', function () {
|
||||
$api = app(PlaceOrderRequestContract::class);
|
||||
|
||||
$effects = ['IOC', 'FOK', 'GTC', 'POST_ONLY'];
|
||||
|
||||
foreach ($effects as $effect) {
|
||||
expect(fn() => $api->placeOrder(
|
||||
'BTCUSDT',
|
||||
'0.1',
|
||||
'BUY',
|
||||
'OPEN',
|
||||
'LIMIT',
|
||||
'50000',
|
||||
null,
|
||||
$effect
|
||||
))->not->toThrow(Exception::class);
|
||||
}
|
||||
});
|
||||
Loading…
Reference in New Issue