Documentation JT-Lab
GitHubJT-Lab
  • Overview
  • JT-Lab Dashboard
    • User Zone
    • Developer Zone
  • JT-Trader
    • Runtime
    • Code Editor
    • Tester
    • Config
      • Connect gate.io via API key
  • JT-LIB
    • Overview
    • API Specification
    • Script Execution
    • Best Practice
  • Insights
    • Symbol (Ticker Symbol)
Powered by GitBook
On this page
  • Example: GridBot
  • Strategy
  • GribBasket
  1. JT-LIB

Best Practice

PreviousScript ExecutionNextInsights

Last updated 6 months ago

Our vision is that the Strategy class acts as the origin for all global variables, including Event Emitters, Trigger Services, Storage, Orders Baskets, and Reports.

  • The OrdersBasket class encapsulates all the trading strategy logic.

  • Each instance of OrdersBasket operates independently and is not influenced by other instances.

  • The Strategy class serves as a starting point for all associated classes and objects. It can monitor the state of OrdersBasket instances and interact with them as needed.

Example: GridBot

Description:

  • In the tester:

    • 10 scenarios will be created for each symbol in the symbols list.

    • A full report will aggregate statistics across all scenarios, simulating the conditions as if they were running all together at runtime.

  • At runtime:

    • A single scenario will be created, and within the script, ten Orders Baskets will be instantiated for each symbol in the symbols list.

OrdersBasket Logic: The logic of the strategy is defined within the OrdersBasket class:

  • Start (onInit):

    • Opens a long position upon the first launch.

    • Creates a limit buy order at a price offset from the current price by a percentage specified by the parameter gridStepPercent.

  • Order Grid Creation:

    • The grid of orders is created sequentially.

    • Each new order is only placed after the previous order is closed (onOrderChange).

    • Orders are placed at a percentage offset from the current price.

  • Profit-Taking (onTick):

    • Profit is secured when the price reaches a specific percentage above the entry price.

This structure ensures modularity and efficient management of trading logic, making it scalable for both testing and live execution environments.

Strategy

class Strategy extends Script {
  static definedArgs = [
     {
      key: 'symbols',
      defaultValue: 'BCH/USDT,BTC/USDT,ADA/USDT,ETH/USDT,XRP/USDT,TRX/USDT,SOL/USDT,LTC/USDT,BNB/USDT,DOGE/USDT',
    },
    {
      key: 'gridStepPercent',
      defaultValue: 5,
    },
  ];
  baskets: Record<string, GribBasket> = {};
  private reportLayout: StandardReportLayout;

  async onInit() {
    this.reportLayout = new StandardReportLayout();

    globals.triggers.addTaskByTime({
      callback: this.createBaskets,
      triggerTime: currentTime() + 60 * 1000,
      name: 'createBaskets',
    });
  }

  // Create a basket for each symbol
  createBaskets = async () => {
    for (const symbol of this.symbols) {
      this.baskets[symbol] = new GribBasket({
        symbol,
        connectionName: this.connectionName,
      });

      await this.baskets[symbol].init();
    }
  };
}

GribBasket


export class GribBasket extends OrdersBasket {
  usdSize: number = getArgNumber('usdSize', 100); //$
  gridStepPercent = getArgNumber('gridStepPercent', 5); //% 
  basketProfit = getArgNumber('basketProfit', 5); //%

  async init() {
    await super.init();

    if (this.isInit) {
      let orders = await this.getOpenOrders();

      if ((await this.getPositionBySide('long')).contracts === 0) {
        await this.buyMarket(this.getContractsAmount(this.usdSize));
      }

      if (orders.length === 0) {
        await this.createLimitByStep();
      }
    }
  }
  


  async onTick() {
    let position = await this.getPositionBySide('long');

    if (position.entryPrice && percentDifference(this.close(), position.entryPrice) > this.basketProfit) {
      await this.closePosition('long');
      await this.cancelAllOrders();
      await this.buyMarket(this.getContractsAmount(this.usdSize));
      await this.createLimitByStep();
    }
  }

  async onOrderChange(order: Order) {
    if (order.status === 'closed' && order.reduceOnly === false) {
      await this.createLimitByStep();
    }
  }

  async createLimitByStep() {
    let triggerPrice = this.close() * (1 - this.gridStepPercent / 100);
    let amount = this.getContractsAmount(this.usdSize);
    let order = await this.buyLimit(amount, triggerPrice);
    warning('createLimitByStep', '', { order });
  }
}

GridBot - crypto robot with grid strategy that could be running for multiple .

symbols