ConnecMent / dydx-bot

An extensible dydx trader bot
2 stars 0 forks source link

Research on dydx orders #22

Closed mkermani144 closed 3 weeks ago

mkermani144 commented 1 month ago

Description

Search about dydx order types, their differences, parameters, etc. In essence, any doc related to placeOrder should be checked.

Mr-MRF-Dev commented 1 month ago

Before placing Orders, we need to initialize the client and wallet

Initializing

see the link to initialize real client

// test client
const NETWORK = Network.testnet();

const client = await CompositeClient.connect(NETWORK);

create a local wallet

import {
  BECH32_PREFIX,
  LocalWallet,
} from '@dydxprotocol/v4-client-js';

const mnemonic = 'YOUR MNEMONIC HERE';
const wallet = await LocalWallet.fromMnemonic(mnemonic, BECH32_PREFIX);

Placing an Order

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
);

Canceling an Order

/*
order is an Order object from the Indexer
*/
const tx = await client.cancelOrder(
  subaccount,
  order.clientId,
  order.orderFlags,
  order.clobPairId,
  order.goodTilBlock,
  order.goodTilBlockTime
);

get order api

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
}

Replacing an Order

link

Mr-MRF-Dev commented 1 month ago

@mkermani144

mkermani144 commented 1 month ago

Thanks. Two more notes:

  1. Please also read about order type, time in force, execution, post only, reduce only, and trigger price.
  2. Try to create a wallet on testnet, and create an actual order to make sure everything works as expected. To do so, you need testnet tokens. You can get some testnet tokens using a faucet. Refer to the docs for more information. If you feel you need to know more about crypto wallets, etc. better, please feel free to ask for additional learning issues.
Mr-MRF-Dev commented 1 month ago

we have 3 Order Types: Market, Limit, and Stop Orders

link1

link2

link3

link4

Mr-MRF-Dev commented 1 month ago

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;
  }
Mr-MRF-Dev commented 1 month ago

execution:

link

Mr-MRF-Dev commented 1 month ago

Reduce-Only ensures that your order:

link

Mr-MRF-Dev commented 1 month ago

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

link

Mr-MRF-Dev commented 1 month ago

Trigger price is the price at which your buy or sell order becomes active for execution at the exchange servers

link

Mr-MRF-Dev commented 1 month ago

I tried the faucet and realized that the testnet doesn't have the placeOrder function.

@mkermani144

Mr-MRF-Dev commented 1 month ago

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();
mkermani144 commented 1 month ago

@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.