Skip to content

Commit 7a961c1

Browse files
committed
feat: createTakeProfitStopLossOrder tool handles and/or
1 parent c96b41a commit 7a961c1

File tree

3 files changed

+65
-27
lines changed

3 files changed

+65
-27
lines changed

projects/binance/README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,19 @@ Integration between HeyAnon.ai and Binance Spot and Futures trading.
2222

2323
- Market buy 1 BTC with USDT on @binance
2424
- Buy 1 BTC at 40000 USDT on @binance
25+
- Sell half of my BTC at 40000 USDT on @binance
2526

26-
1. **Trigger orders**
27+
1. **Conditional orders**
2728

2829
- Market buy 1 BTC on @binance when the price goes below 50000 USDT
2930
- Buy 1 BTC at 45000 USDT on @binance when the price goes below 50000 USDT
3031
- Sell 100 USDT for BTC for 10% profit on @binance
3132

33+
1. **Take profit & stop loss (OCO)**
34+
35+
- Sell 0.01 BTC with a 10% take profit and a 15% stop loss on @binance
36+
- Sell all of my BTC with a 10% take profit and a 15% stop loss on @binance
37+
3238
1. **Cancel orders**
3339

3440
- Cancel all my orders on @binance
Lines changed: 53 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { FunctionReturn, toResult } from '@heyanon/sdk';
22
import { FunctionOptionsWithExchange } from '../overrides';
3-
import { createBinanceOcoOrder } from '../helpers/orders';
3+
import { createBinanceOcoOrder, createTriggerOrder } from '../helpers/orders';
4+
import { formatOrderSingleLine } from '../helpers/format';
45

56
interface Props {
67
market: string;
@@ -13,15 +14,15 @@ interface Props {
1314
}
1415

1516
/**
16-
* Create two orders: a take profit order and a stop loss order, bundled together in
17-
* an OCO (one-cancels-the-other) order.
17+
* Create take profit and/or stop loss orders. If both are provided, they will be
18+
* created as an OCO (one-cancels-the-other) order.
1819
*
1920
* @param {Object} props - The function input parameters
2021
* @param {string} props.market - Symbol of the market to trade, for example "BTC/USDT" or "AAVE/ETH"
2122
* @param {'buy' | 'sell'} props.side - Side of the order; either "buy" or "sell"
2223
* @param {number} props.amount - Amount of base currency to buy or sell
23-
* @param {number} props.takeProfitTriggerPrice - Price at which the take profit order will be activated
24-
* @param {number} props.stopLossTriggerPrice - Price at which the stop loss order will be activated
24+
* @param {number|null} props.takeProfitTriggerPrice - Price at which the take profit order will be activated
25+
* @param {number|null} props.stopLossTriggerPrice - Price at which the stop loss order will be activated
2526
* @param {number|null} props.takeProfitLimitPrice - Price for limit orders (optional)
2627
* @param {number|null} props.stopLossLimitPrice - Price for limit orders (optional)
2728
* @param {FunctionOptions} options
@@ -31,21 +32,52 @@ export async function createTakeProfitStopLossOrder(
3132
{ market, side, amount, takeProfitTriggerPrice, takeProfitLimitPrice, stopLossTriggerPrice, stopLossLimitPrice }: Props,
3233
{ exchange }: FunctionOptionsWithExchange,
3334
): Promise<FunctionReturn> {
34-
try {
35-
await createBinanceOcoOrder(
36-
exchange,
37-
market,
38-
side,
39-
amount,
40-
takeProfitTriggerPrice,
41-
stopLossTriggerPrice,
42-
takeProfitLimitPrice ?? undefined,
43-
stopLossLimitPrice ?? undefined,
44-
);
45-
return toResult(`Successfully created order`);
46-
// return toResult(`Successfully created ${formatOrderSingleLine(order, undefined, false)}`);
47-
} catch (error) {
48-
console.error(error);
49-
return toResult(`Error creating order: ${error}`, true);
35+
// We need a trigger price
36+
if (!takeProfitTriggerPrice && !stopLossTriggerPrice) {
37+
return toResult(`Error: Either take profit or stop loss trigger price must be provided`, true);
38+
}
39+
// Trigger prices cannot be the same
40+
if (takeProfitTriggerPrice && stopLossTriggerPrice && takeProfitTriggerPrice === stopLossTriggerPrice) {
41+
return toResult(`Error: The take profit and stop loss trigger prices cannot be the same`, true);
42+
}
43+
// Case of a take profit order
44+
if (takeProfitTriggerPrice && !stopLossTriggerPrice) {
45+
try {
46+
const order = await createTriggerOrder(exchange, market, side, amount, takeProfitTriggerPrice, takeProfitLimitPrice === null ? undefined : takeProfitLimitPrice);
47+
return toResult(`Successfully created ${formatOrderSingleLine(order, undefined, false)}`);
48+
} catch (error) {
49+
console.error(error);
50+
return toResult(`Error creating take profit order: ${error}`, true);
51+
}
52+
}
53+
// Case of a stop loss order
54+
if (!takeProfitTriggerPrice && stopLossTriggerPrice) {
55+
try {
56+
const order = await createTriggerOrder(exchange, market, side, amount, stopLossTriggerPrice, stopLossLimitPrice === null ? undefined : stopLossLimitPrice);
57+
return toResult(`Successfully created ${formatOrderSingleLine(order, undefined, false)}`);
58+
} catch (error) {
59+
console.error(error);
60+
return toResult(`Error creating stop loss order: ${error}`, true);
61+
}
62+
}
63+
// Case of a take profit AND stop loss order (OCO)
64+
else {
65+
try {
66+
await createBinanceOcoOrder(
67+
exchange,
68+
market,
69+
side,
70+
amount,
71+
takeProfitTriggerPrice,
72+
stopLossTriggerPrice,
73+
takeProfitLimitPrice ?? undefined,
74+
stopLossLimitPrice ?? undefined,
75+
);
76+
return toResult(`Successfully created order`);
77+
// return toResult(`Successfully created ${formatOrderSingleLine(order, undefined, false)}`);
78+
} catch (error) {
79+
console.error(error);
80+
return toResult(`Error creating OCO order: ${error}`, true);
81+
}
5082
}
5183
}

projects/binance/src/tools.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ export const tools: AiTool[] = [
6666
},
6767
{
6868
name: 'createTakeProfitStopLossOrder',
69-
description: 'Create two orders: a take profit order and a stop loss order.',
69+
description: 'Create take profit and/or stop loss orders. If both are provided, they will be created as an OCO (one-cancels-the-other) order.',
7070
required: ['market', 'side', 'amount', 'takeProfitTriggerPrice', 'takeProfitLimitPrice', 'stopLossTriggerPrice', 'stopLossLimitPrice'],
7171
props: [
7272
{
@@ -87,8 +87,8 @@ export const tools: AiTool[] = [
8787
},
8888
{
8989
name: 'takeProfitTriggerPrice',
90-
type: 'number',
91-
description: 'Price at which the take profit order will be activated',
90+
type: ['number', 'null'],
91+
description: 'Price at which the take profit order will be activated. If not specified, the take profit order will not be created.',
9292
},
9393
{
9494
name: 'takeProfitLimitPrice',
@@ -97,8 +97,8 @@ export const tools: AiTool[] = [
9797
},
9898
{
9999
name: 'stopLossTriggerPrice',
100-
type: 'number',
101-
description: 'Price at which the stop loss order will be activated',
100+
type: ['number', 'null'],
101+
description: 'Price at which the stop loss order will be activated. If not specified, the stop loss order will not be created.',
102102
},
103103
{
104104
name: 'stopLossLimitPrice',

0 commit comments

Comments
 (0)