marketMaker script places/cancels orders

This commit is contained in:
Sayantan Karmakar 2022-05-01 12:39:50 +05:30
parent 4949d1aa83
commit 2a2f46131d
3 changed files with 121 additions and 15 deletions

View File

@ -11,7 +11,7 @@ import { DexMarket, MarketAccounts } from "./market";
import { DexInstructions } from "@project-serum/serum";
import { getVaultOwnerAndNonce } from "./utils";
import { Coin } from "./coin";
import { fork } from "child_process";
import { ChildProcess, fork } from "child_process";
import { FileKeypair } from "./fileKeypair";
export type MarketArgs = {
@ -21,6 +21,11 @@ export type MarketArgs = {
feeRate: number;
quoteDustThreshold: BN;
};
type MarketMakerOpts = {
unref: boolean;
durationInSecs: number;
};
export class Dex {
public address: PublicKey;
@ -185,7 +190,11 @@ export class Dex {
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
public async runMarketMaker(market: DexMarket, owner: FileKeypair) {
public runMarketMaker(
market: DexMarket,
owner: FileKeypair,
opts: MarketMakerOpts,
): ChildProcess {
const child = fork("./src/scripts/marketMaker", null, {
detached: true,
stdio: ["pipe", 0, 0, "ipc"],
@ -196,7 +205,7 @@ export class Dex {
});
// https://nodejs.org/api/child_process.html#optionsdetached
child.unref();
if (opts.unref) child.unref();
child.send({
action: "start",
@ -205,9 +214,10 @@ export class Dex {
programID: this.address.toString(),
rpcEndpoint: this.connection.rpcEndpoint,
ownerFilePath: owner.filePath,
duration: opts.durationInSecs * 1000,
},
});
console.log(`Market Maker started at process ${child.pid}`);
return child;
}
}

View File

@ -2,3 +2,4 @@ export * from "./dex";
export * from "./coin";
export * from "./market";
export * from "./fileKeypair";
export * from "./types";

View File

@ -1,4 +1,10 @@
import { Connection, PublicKey } from "@solana/web3.js";
import {
Connection,
Keypair,
PublicKey,
Signer,
Transaction,
} from "@solana/web3.js";
import { Market as SerumMarket } from "@project-serum/serum";
import { FileKeypair } from "../fileKeypair";
import { DexMarket } from "../market";
@ -15,6 +21,86 @@ process.on("message", async (message: MessageType) => {
}
});
const cancelOrders = async (
owner: Keypair,
serumMarket: SerumMarket,
connection: Connection,
) => {
const orders = await serumMarket.loadOrdersForOwner(
connection,
owner.publicKey,
);
const tx = new Transaction();
const signersArray: Signer[][] = [];
for (const order of orders) {
const { transaction, signers } = await DexMarket.getCancelOrderTransaction(
connection,
owner,
serumMarket,
order,
);
tx.add(transaction);
signersArray.push(signers);
}
const signersUnion: Signer[] = [...new Set(signersArray.flat())];
const txSig = await connection.sendTransaction(tx, signersUnion);
await connection.confirmTransaction(txSig, "confirmed");
console.log(`----- Cancelled ${orders.length} orders ------`);
};
const placeOrders = async (
owner: Keypair,
serumMarket: SerumMarket,
connection: Connection,
opts: {
isBuy: boolean;
midPrice: number;
count: number;
},
) => {
const { isBuy, midPrice, count } = opts;
const tx = new Transaction();
const signersArray: Signer[][] = [];
for (let i = 0; i < count; i++) {
const orderPrice =
midPrice +
(isBuy ? -1 * (midPrice * 0.01 * (i + 1)) : midPrice * 0.01) * (i + 1);
const { transaction, signers } = await DexMarket.getPlaceOrderTransaction(
connection,
owner,
serumMarket,
isBuy ? "buy" : "sell",
10,
orderPrice,
);
tx.add(transaction);
signersArray.push(signers);
console.log(`Order ${i} price: ${orderPrice}`);
}
const signersUnion: Signer[] = [...new Set(signersArray.flat())];
const txSig = await connection.sendTransaction(tx, signersUnion);
await connection.confirmTransaction(txSig, "confirmed");
console.log(
`----- Placed ${count} ${
isBuy ? "buy" : "sell"
} orders at midPrice: ${midPrice} ------c`,
);
};
const marketMaker = async (args) => {
const connection = new Connection(args.rpcEndpoint, "confirmed");
@ -27,16 +113,25 @@ const marketMaker = async (args) => {
const owner = FileKeypair.load(args.ownerFilePath);
const txSig = await DexMarket.placeOrder(
connection,
owner.keypair,
serumMarket,
"buy",
1,
10,
);
placeOrders(owner.keypair, serumMarket, connection, {
isBuy: true,
midPrice: 10,
count: 3,
});
console.log(`Order Placed: ${txSig}`);
setInterval(async () => {
await cancelOrders(owner.keypair, serumMarket, connection);
await placeOrders(owner.keypair, serumMarket, connection, {
isBuy: true,
midPrice: 10,
count: 3,
});
}, 10000);
process.kill(0);
if (Number.parseInt(args.duration) > 0) {
setTimeout(() => {
console.log(`Exiting Market Maker @ ${process.pid}`);
process.exit(0);
}, Number.parseInt(args.duration));
}
};