From fe0638ffc17d1d78ac1388a056f5ef6c0ba24079 Mon Sep 17 00:00:00 2001 From: Hieu Le Date: Mon, 7 Aug 2023 15:59:55 +0700 Subject: [PATCH] submit use market depth and cancel use spread --- packages/market-maker/.env.example | 3 +- packages/market-maker/src/cli.ts | 18 ++++--- packages/market-maker/src/common.ts | 84 +++++++++++++++++++---------- packages/market-maker/src/index.ts | 18 ++++--- 4 files changed, 80 insertions(+), 43 deletions(-) diff --git a/packages/market-maker/.env.example b/packages/market-maker/.env.example index 9e9ae1df..f79478b3 100644 --- a/packages/market-maker/.env.example +++ b/packages/market-maker/.env.example @@ -1,7 +1,8 @@ CANCEL_PERCENTAGE = 1 # 100% cancel ORDER_INTERVAL_RANGE = 50, 100 SPREAD_RANGE = 0.003, 0.006 -VOLUME_RANGE = 100000, 150000 +MARKET_DEPTH = 100000000 # 1000 +SPREAD_CANCEL_PERCENTAGE = 0.1 # 10% BUY_PERCENTAGE = 0.55 ORAI_THRESHOLD = 10000000 USDT_THRESHOLD = 10000000 diff --git a/packages/market-maker/src/cli.ts b/packages/market-maker/src/cli.ts index df0e5842..417e5351 100644 --- a/packages/market-maker/src/cli.ts +++ b/packages/market-maker/src/cli.ts @@ -16,27 +16,28 @@ import { } from "./index"; const cancelPercentage = Number(process.env.CANCEL_PERCENTAGE || 1); // 100% cancel -const [volumeMin, volumeMax] = process.env.VOLUME_RANGE - ? process.env.VOLUME_RANGE.split(",").map(Number) - : [100000, 150000]; + +const marketDepth = Number(process.env.MARKET_DEPTH); const buyPercentage = Number(process.env.BUY_PERCENTAGE || 0.55); const [spreadMin, spreadMax] = process.env.SPREAD_RANGE ? process.env.SPREAD_RANGE.split(",").map(Number) : [0.003, 0.006]; +const spread_cancel_percentage = Number(process.env.SPREAD_CANCEL_PERCENTAGE); +const maxRepeat = 5; +const totalOrders = 10; + const orderConfig: MakeOrderConfig = { cancelPercentage, - volumeMin, - volumeMax, buyPercentage, spreadMax, - spreadMin + spreadMin, + marketDepth, + totalOrders }; const [orderIntervalMin, orderIntervalMax] = process.env.ORDER_INTERVAL_RANGE ? process.env.ORDER_INTERVAL_RANGE.split(",").map(Number) : [50, 100]; -const maxRepeat = 5; -const totalOrders = 10; (async () => { let buyer: UserWallet, seller: UserWallet, usdtToken: OraiswapTokenClient, orderBook: OraiswapLimitOrderClient; @@ -82,6 +83,7 @@ const totalOrders = 10; orderBook.contractAddress, oraiPrice, totalOrders, + spread_cancel_percentage, orderConfig ); diff --git a/packages/market-maker/src/common.ts b/packages/market-maker/src/common.ts index 5d8a27d6..bce6a438 100644 --- a/packages/market-maker/src/common.ts +++ b/packages/market-maker/src/common.ts @@ -1,7 +1,7 @@ import { ExecuteInstruction, SigningCosmWasmClient } from "@cosmjs/cosmwasm-stargate"; import { stringToPath } from "@cosmjs/crypto"; import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing"; -import { GasPrice } from "@cosmjs/stargate"; +import { GasPrice, logs } from "@cosmjs/stargate"; import { deployContract } from "@oraichain/oraidex-contracts-build"; import { Addr, @@ -125,13 +125,13 @@ export const deployToken = async ( client, senderAddress, ( - await deployContract(client, senderAddress, "oraiswap_token", { + await deployContract(client, senderAddress, { decimals, symbol, name, mint: { minter: senderAddress }, initial_balances: [{ address: senderAddress, amount: "1000000000" }, ...initial_balances] - }) + }, "oraiswap_token", "oraiswap_token") ).contractAddress ); }; @@ -144,11 +144,11 @@ export const deployOrderbook = async ( client, senderAddress, ( - await deployContract(client, senderAddress, "oraiswap_limit_order", { + await deployContract(client, senderAddress, { admin: senderAddress, version: "0.0.1", name: "Orderbook" - }) + }, "oraiswap_limit_order", "oraiswap_limit_order") ).contractAddress ); }; @@ -157,34 +157,64 @@ export const cancelOrder = async ( orderbookAddress: Addr, sender: UserWallet, assetInfos: AssetInfo[], - limit: number + direction: string, + spread_percentage: number, + oraiPrice: number, + limit: number, ) => { - const queryAll = await sender.client.queryContractSmart(orderbookAddress, { - orders: { + const upperPriceLimit = oraiPrice * (1 + spread_percentage); + const lowerPriceLimit = oraiPrice * (1 - spread_percentage); + console.log({upperPriceLimit}); + console.log({lowerPriceLimit}); + let queryTicks = await sender.client.queryContractSmart(orderbookAddress, { + ticks: { asset_infos: assetInfos, - order_by: 1, + order_by: direction === "buy" ? 2 : 1, + direction, limit, - filter: { - bidder: sender.address - } } } as OraiswapLimitOrderTypes.QueryMsg); - - const multipleCancelMsg: ExecuteInstruction[] = []; - for (const order of queryAll.orders) { - const cancelMsg: ExecuteInstruction = { - contractAddress: orderbookAddress, - msg: { - cancel_order: { - asset_infos: assetInfos, - order_id: order.order_id + + for (const ticks of Object.values(queryTicks)) { + for (const tick of ticks as any[]) { + let tick_price = Number(tick.price); + if (tick_price >= upperPriceLimit || tick_price <= lowerPriceLimit) { + console.log("cancel all orders with price", tick_price); + console.log({sender_addr: sender.address}); + const queryorderswithPrice = await sender.client.queryContractSmart(orderbookAddress, { + orders: { + asset_infos: assetInfos, + order_by: 1, + limit, + filter: { + price: tick_price.toString() + } + } + } as OraiswapLimitOrderTypes.QueryMsg); + console.log({queryorderswithPrice: queryorderswithPrice}); + + const multipleCancelMsg: ExecuteInstruction[] = []; + for (const order of queryorderswithPrice.orders) { + const cancelMsg: ExecuteInstruction = { + contractAddress: orderbookAddress, + msg: { + cancel_order: { + asset_infos: assetInfos, + order_id: order.order_id + } + } + }; + console.log({bidder_addr: order.bidder_addr}); + // console.log({sender_addr: sender.address}); + if (order.bidder_addr === sender.address) { + multipleCancelMsg.push(cancelMsg); + } + } + if (multipleCancelMsg.length > 0) { + const cancelResult = await sender.client.executeMultiple(sender.address, multipleCancelMsg, "auto"); + console.log("cancel orders - txHash:", cancelResult.transactionHash); } } - }; - multipleCancelMsg.push(cancelMsg); - } - if (multipleCancelMsg.length > 0) { - const cancelResult = await sender.client.executeMultiple(sender.address, multipleCancelMsg, "auto"); - console.log("cancel orders - txHash:", cancelResult.transactionHash); + } } }; diff --git a/packages/market-maker/src/index.ts b/packages/market-maker/src/index.ts index 5804773e..01e66c14 100644 --- a/packages/market-maker/src/index.ts +++ b/packages/market-maker/src/index.ts @@ -1,5 +1,5 @@ import { toBinary } from '@cosmjs/cosmwasm-stargate'; -import { Addr, OraiswapLimitOrderTypes, OraiswapTokenTypes, OrderDirection } from '@oraichain/oraidex-contracts-sdk'; +import { Addr, AssetInfo, OraiswapLimitOrderTypes, OraiswapTokenTypes, OrderDirection } from '@oraichain/oraidex-contracts-sdk'; import { matchingOrders } from '@oraichain/orderbook-matching-relayer'; import { UserWallet, atomic, cancelOrder, getRandomPercentage, getRandomRange, getSpreadPrice } from './common'; import { ExecuteInstruction } from '@cosmjs/cosmwasm-stargate'; @@ -10,8 +10,8 @@ export type MakeOrderConfig = { spreadMax: number; buyPercentage: number; cancelPercentage: number; - volumeMin: number; - volumeMax: number; + marketDepth: number; + totalOrders: number; }; const oraiThreshold = process.env.ORAI_THRESHOLD; @@ -21,15 +21,19 @@ const getRandomSpread = (min: number, max: number) => { return getRandomRange(min * atomic, max * atomic) / atomic; }; -const generateOrderMsg = (oraiPrice: number, usdtContractAddress: Addr, { spreadMin, spreadMax, buyPercentage, volumeMin, volumeMax, makeProfit }: MakeOrderConfig): OraiswapLimitOrderTypes.ExecuteMsg => { +const generateOrderMsg = (oraiPrice: number, usdtContractAddress: Addr, { spreadMin, spreadMax, buyPercentage, totalOrders, marketDepth, makeProfit }: MakeOrderConfig): OraiswapLimitOrderTypes.ExecuteMsg => { const spread = getRandomSpread(spreadMin, spreadMax); // buy percentage is 55% const direction: OrderDirection = getRandomPercentage() < buyPercentage * 100 ? 'buy' : 'sell'; // if make profit then buy lower, sell higher than market const oraiPriceEntry = getSpreadPrice(oraiPrice, spread * (direction === 'buy' ? 1 : -1) * (makeProfit ? -1 : 1)); + const volumeMax = marketDepth / totalOrders; + const volumeMin = (marketDepth / totalOrders)*0.7; const oraiVolume = getRandomRange(volumeMin, volumeMax); // between 0.1 and 0.15 orai + console.log({oraiVolume}) const usdtVolume = (oraiPriceEntry * oraiVolume).toFixed(0); + console.log({usdtVolume}) return { submit_order: { @@ -52,7 +56,7 @@ const generateOrderMsg = (oraiPrice: number, usdtContractAddress: Addr, { spread }; }; -export async function makeOrders(buyer: UserWallet, seller: UserWallet, usdtTokenAddress: Addr, orderBookAddress: Addr, oraiPrice: number, totalOrders: number, config: MakeOrderConfig, limit = 30, denom = 'orai') { +export async function makeOrders(buyer: UserWallet, seller: UserWallet, usdtTokenAddress: Addr, orderBookAddress: Addr, oraiPrice: number, totalOrders: number, spread_percentage: number, config: MakeOrderConfig, limit = 10, denom = 'orai') { const assetInfos = [{ native_token: { denom } }, { token: { contract_addr: usdtTokenAddress } }]; const multipleBuyMsg: ExecuteInstruction[] = []; const multipleSellMsg: ExecuteInstruction[] = []; @@ -143,7 +147,7 @@ export async function makeOrders(buyer: UserWallet, seller: UserWallet, usdtToke // console.log(orderBookAddress, await client.getBalance(orderBookAddress, 'orai')); try { - await cancelOrder(orderBookAddress, sellerWallet, assetInfos, cancelLimit); + await cancelOrder(orderBookAddress, sellerWallet, assetInfos, "sell", spread_percentage, oraiPrice, cancelLimit); } catch (error) { console.error(error); } @@ -151,7 +155,7 @@ export async function makeOrders(buyer: UserWallet, seller: UserWallet, usdtToke // console.log(orderBookAddress, await client.getBalance(orderBookAddress, 'orai')); try { - await cancelOrder(orderBookAddress, buyerWallet, assetInfos, cancelLimit); + await cancelOrder(orderBookAddress, buyerWallet, assetInfos, "buy", spread_percentage, oraiPrice, cancelLimit); } catch (error) { console.error(error); }