backpack

backpack 刷成交量脚本,支持手动开启关闭,设置买入卖出点

Verze ze dne 31. 03. 2024. Zobrazit nejnovější verzi.

K instalaci tototo skriptu si budete muset nainstalovat rozšíření jako Tampermonkey, Greasemonkey nebo Violentmonkey.

You will need to install an extension such as Tampermonkey to install this script.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Violentmonkey.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Userscripts.

You will need to install an extension such as Tampermonkey to install this script.

K instalaci tohoto skriptu si budete muset nainstalovat manažer uživatelských skriptů.

(Už mám manažer uživatelských skriptů, nechte mě ho nainstalovat!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Už mám manažer uživatelských stylů, nechte mě ho nainstalovat!)

// ==UserScript==
// @name         backpack
// @namespace    http://tampermonkey.net/
// @version      v0.0.2
// @description  backpack 刷成交量脚本,支持手动开启关闭,设置买入卖出点
// @author       zhowiny
// @match        https://backpack.exchange/trade/*
// @icon         https://backpack.exchange/favicon-32x32.png
// @grant        none
// @license MIT
// ==/UserScript==

// 请使用在浏览器控制台里

const MIN_WAIT_MS = 300;
const MAX_WAIT_MS = 1000;
const MIN_SWITCH_MS = 1500;
const MAX_SWITCH_MS = 5000;

const tradingParams = {
  Buy: 2,
  Sell: 5,
}

let tradeCount = 0;
let running = false;

const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

const findElementsByText = (text, tag) => {
  const elements = document.querySelectorAll(tag);
  return Array.from(elements).filter((div) => div.textContent === text);
};

const getElement = (text, tag) => {
  let element = findElementsByText(text, tag)[0];
  if (!element) {
    element = findElementsByText(getChineseText(text), tag)[0];
    if (!element) return
  }
  return element;
}

const clickElementByText = async (text, tag) => {
  const element = getElement(text, tag);
  if (!element) return;
  element.click();
  await sleep(getRandomWait(MIN_WAIT_MS, MAX_WAIT_MS));
};

const getPriceCnt = () => {
 return document.querySelector('.flex.flex-col.no-scrollbar.h-full.flex-1.snap-mandatory.overflow-y-auto.font-sans');
}
const getPriceElement = (type) => {
  const isBuy = type === 'Buy';
  const priceCnt = getPriceCnt();
  const priceElement = priceCnt.querySelector(`& > div:${isBuy ? 'last' : 'first'}-child > div > div:nth-child(${tradingParams[type]}) button div`);
  return priceElement;
}

const setPrice = async (type) => {
  const price = getPriceElement(type);
  price.classList.add('border');
  price.click();
  await sleep(300);
}

const executeTrade = async (type) => {
  await clickElementByText(type, "p");
  await setPrice(type);
  await clickElementByText("Max", "div");
  await clickElementByText(type, "button");
};

const getRandomWait = (min, max) => Math.floor(Math.random() * max + min);

const performTradeCycle = async () => {
  try {
    tradeCount++;
    await executeTrade("Buy");
    await sleep(getRandomWait(MIN_SWITCH_MS, MAX_SWITCH_MS));
    await executeTrade("Sell");
    await sleep(getRandomWait(MIN_SWITCH_MS, MAX_SWITCH_MS));
  } catch (error) {
    console.error("发生错误:", error);
  }
};

const startTrading = async () => {
  await sleep(3000);
  await performTradeCycle();
  if (running) {
    window.requestAnimationFrame(startTrading);
  }
};

const createStartBtn = () => {
  const startBtn = document.createElement('button');
  startBtn.innerHTML= '启动脚本,开始自动交易';
  startBtn.style.cssText = 'grid-area: a';
  startBtn.classList.add('bg-greenText', 'rounded', 'p-2');
  startBtn.addEventListener('click', () => {
    const input_buy = document.querySelector('.backpack-tool input:nth-of-type(1)');
    const input_sell = document.querySelector('.backpack-tool input:nth-of-type(2)');

    running = !running;

    startBtn.innerHTML= running ? '脚本运行中,点击关闭交易' : '启动脚本,点击开始交易';
    startBtn.classList.toggle('bg-redText');
    input_buy.disabled = running;
    input_sell.disabled = running;
    input_buy.classList.toggle('bg-black/25');
    input_sell.classList.toggle('bg-black/25');

    console.log(running ? 'start' : 'stop');
    running && startTrading();

    if (!running) {
      getPriceElement('Buy').classList.remove('border');
      getPriceElement('Sell').classList.remove('border');
    }
  });
  return startBtn;
}

const createInput = (type) => {
  const input = document.createElement('input');
  input.value = tradingParams[type];
  input.type = 'number';
  input.min= 1;
  input.max = 20;
  input.step = 1;
  input.classList.add('w-12', 'h-2', 'py-2', 'text-center', 'bg-black', {Buy: 'text-greenText', Sell: 'text-redText'}[type]);
  input.addEventListener('input', e => {
    let value = parseInt(e.target.value);
    if (value > 20) value = 20;
    if (value < 1 || isNaN(value)) value = 1;
    tradingParams[type] = Math.max(1, Math.min(20, value));
    e.target.value = value;
  });
  return input;
}
const createTools = () => {
  const fragment = document.createDocumentFragment();
  const div = document.createElement('div');
  div.style.cssText = 'position: fixed;top: 10px;left:50%;transform: translateX(-50%);z-index: 1000;grid-template-areas: "a b c" "a d e"';
  div.classList.add('backpack-tool', 'grid', 'gap-2', 'text-sm', 'text-white', 'bg-base-700', 'p-2', 'rounded');
  div.appendChild(createStartBtn());
  div.appendChild(document.createTextNode('第几个买入:'));
  div.appendChild(createInput('Buy'));
  div.appendChild(document.createTextNode('第几个卖出:'));
  div.appendChild(createInput('Sell'));
  document.body.appendChild(div);
}

(function () {
  createTools()
})();

function getChineseText(text) {
  switch (text) {
    case "Market":
      return "市场";
    case "Max":
      return "最大";
    case "Buy":
      return "购买";
    case "Sell":
      return "出售";
    default:
      return text;
  }
}