Closed mkermani144 closed 3 weeks ago
Before placing Orders, we need to initialize the client and wallet
see the link to initialize real client
// test client
const NETWORK = Network.testnet();
const client = await CompositeClient.connect(NETWORK);
import {
BECH32_PREFIX,
LocalWallet,
} from '@dydxprotocol/v4-client-js';
const mnemonic = 'YOUR MNEMONIC HERE';
const wallet = await LocalWallet.fromMnemonic(mnemonic, BECH32_PREFIX);
first import modules
import {
OrderExecution, OrderSide, OrderTimeInForce, OrderType,
} from '@dydxprotocol/v4-client-js';
second create config variables to pass into function
const subaccount = new SubaccountClient(wallet, 0);
const clientId = 123; // set to a number, can be used by the client to identify the order
const market = "BTC-USD"; // perpertual market id
const type = OrderType.LIMIT; // order type
const side = OrderSide.BUY; // side of the order
const timeInForce = OrderTimeInForce.IOC; // UX TimeInForce
const execution = OrderExecution.DEFAULT;
const price = 30_000; // price of 30,000;
const size = 0.1; // subticks are calculated by the price of the order
const postOnly = false; // If true, order is post only
const reduceOnly = false; // if true, the order will only reduce the position size
const triggerPrice = null; // required for conditional orders
now call function and pass configs
const tx = await client.placeOrder(
subaccount,
market,
type,
side,
price,
size,
clientId,
timeInForce,
0,
execution,
postOnly,
reduceOnly,
triggerPrice
);
or we can be using a validator client like:
import { OrderFlags, Order_Side, Order_TimeInForce, SubaccountClient } from '@dydxprotocol/v4-client-js';
const subaccount = new SubaccountClient(wallet, 0);
const clientId = 123 // set to a number, can be used by the client to identify the order
const clobPairId = 0 // perpertual market id
const side = Order_Side.SIDE_BUY // side of the order
const quantums = Long.fromNumber(1_000_000_000); // quantums are calculated by the size if the order
const subticks = Long.fromNumber(1_000_000_000); // subticks are calculated by the price of the order
const timeInForce = Order_TimeInForce.TIME_IN_FORCE_UNSPECIFIED; // TimeInForce indicates how long an order will remain active before it is executed or expires
const orderFlags = OrderFlags.SHORT_TERM; // either SHORT_TERM, LONG_TERM or CONDITIONAL
const reduceOnly = false; // if true, the order will only reduce the position size
const tx = await client.post.placeOrder(
subaccount,
clientId,
clobPairId,
side,
quantums,
subticks,
timeInForce,
orderFlags,
reduceOnly
);
/*
order is an Order object from the Indexer
*/
const tx = await client.cancelOrder(
subaccount,
order.clientId,
order.orderFlags,
order.clobPairId,
order.goodTilBlock,
order.goodTilBlockTime
);
Example responses:
{
"id": "string",
"subaccountId": "string",
"clientId": "string",
"clobPairId": "string",
"side": "BUY",
"size": "string",
"totalFilled": "string",
"price": "string",
"type": "LIMIT",
"reduceOnly": true,
"orderFlags": "string",
"goodTilBlock": "string",
"goodTilBlockTime": "string",
"createdAtHeight": "string",
"clientMetadata": "string",
"triggerPrice": "string",
"timeInForce": "GTT",
"status": "OPEN",
"postOnly": true,
"ticker": "string",
"updatedAt": "string",
"updatedAtHeight": "string",
"subaccountNumber": 0.1
}
@mkermani144
Thanks. Two more notes:
TimeInForce:
enum TimeInForce {
// TIME_IN_FORCE_UNSPECIFIED represents the default behavior where an
// order will first match with existing orders on the book, and any
// remaining size will be added to the book as a maker order.
TIME_IN_FORCE_UNSPECIFIED = 0;
// TIME_IN_FORCE_IOC enforces that an order only be matched with
// maker orders on the book. If the order has remaining size after
// matching with existing orders on the book, the remaining size
// is not placed on the book.
TIME_IN_FORCE_IOC = 1;
// TIME_IN_FORCE_POST_ONLY enforces that an order only be placed
// on the book as a maker order. Note this means that validators will cancel
// any newly-placed post only orders that would cross with other maker
// orders.
TIME_IN_FORCE_POST_ONLY = 2;
// TIME_IN_FORCE_FILL_OR_KILL enforces that an order will either be filled
// completely and immediately by maker orders on the book or canceled if the
// entire amount can‘t be matched.
TIME_IN_FORCE_FILL_OR_KILL = 3;
}
execution:
Maker orders are orders that do not immediately fill and rest on the order book — these orders add depth and liquidity to the order book. Maker orders will always cost less than taker orders to execute the trade.
Taker orders, on the other hand, immediately cross existing Maker orders. They remove liquidity from the order book.
Reduce-Only ensures that your order:
Will only reduce the size of your current position, not increase
Will not open a position with side opposite to your current position (long to short or short to long)
A "post-only" condition is a feature in limit orders that ensures the order will only be added to the order book if it does not immediately fill against an existing order in the order book. In other words, a post-only limit order will only be placed if it can be added as a maker order and not as a taker order
Trigger price is the price at which your buy or sell order becomes active for execution at the exchange servers
I tried the faucet and realized that the testnet doesn't have the placeOrder
function.
@mkermani144
this my code to run a place a order
import { CompositeClient, Network } from "@dydxprotocol/v4-client-js";
import { BECH32_PREFIX, LocalWallet } from "@dydxprotocol/v4-client-js";
import {
OrderExecution,
OrderSide,
OrderTimeInForce,
OrderType,
SubaccountClient
} from "@dydxprotocol/v4-client-js";
import { FaucetClient, FaucetApiHost } from "@dydxprotocol/v4-client-js";
async function main() {
try {
// Set up the network and mnemonic
const NETWORK = Network.testnet();
const client = await CompositeClient.connect(NETWORK);
const mnemonic = "rough absorb seek tiny zebra jaguar bring pledge soon slam same cool";
const wallet = await LocalWallet.fromMnemonic(mnemonic, BECH32_PREFIX);
// Set up a SubaccountClient
const subaccount = new SubaccountClient(wallet, 0);
const address2 = subaccount.address; // Corrected method to get address
// Use the Faucet to get test tokens
const client2 = new FaucetClient(FaucetApiHost.TESTNET);
const faucetResponse2 = await client2.fill(address2, 0, 2000);
// Logging the Faucet response
console.log(`Faucet Response: ${JSON.stringify(faucetResponse2)}`);
// Placing an order
const clientId = 123; // set to a number, can be used by the client to identify the order
const market = "BTC-USD"; // perpetual market id
const type = OrderType.LIMIT; // order type
const side = OrderSide.BUY; // side of the order
const timeInForce = OrderTimeInForce.IOC; // UX TimeInForce
const execution = OrderExecution.DEFAULT;
const price = 30000; // price of 30,000;
const size = 0.1; // size of the order
const postOnly = false; // If true, order is post only
const reduceOnly = false; // if true, the order will only reduce the position size
const triggerPrice = 10; // required for conditional orders
// Ensure the placeOrder method exists and is used correctly
const tx = await client.placeOrder(
subaccount,
market,
type,
side,
price,
size,
clientId,
timeInForce,
0,
execution,
postOnly,
reduceOnly,
triggerPrice
);
console.log(tx);
} catch (error) {
console.error("An error occurred:", error);
}
}
// Run the main function
main();
@Mr-MRF-Dev Good job! This seems a complete piece of code for placing an order. If you tested your code and placed an order on Testnet successfully, we can close this issue.
Description
Search about dydx order types, their differences, parameters, etc. In essence, any doc related to
placeOrder
should be checked.