受動的収入の書き方:JSで質の高いトレードボットを書く(パート1)

Binance暗号交換で実行されるトレーディングボットの作成を始めましょう。ボットは次のことができるはずです。





  1. 自分で取引し、ある種の収入をもたらす





  2. さまざまな取引戦略の作成と展開に便利なはずです





  3. 履歴データで戦略をテストする





アーキテクチャから始めましょう

素晴らしいAPIを備えたBinanceエクスチェンジがあります。したがって、アーキテクチャは次のようになります。





「より安く購入する」方法と「より高価に販売する」方法をいくつか呼び出します。しかし、私たちの仕事は、条件付きのプログラマー-トレーダーが収益性のための新しい戦略を作成してテストできるボットを作成することです。したがって、トレーディングロジックを他のすべてから分離する必要があります。また、ロジックモジュールは、実際のAPIまたは疑似API(テスト用)のどちらに接続されているかを気にする必要はありません。これらすべてを考慮に入れると、次のようなアーキテクチャが得られます。





ベースはPostgreSQLによって選択されました。ここには秘密の意図はありません。どれでも使えます。 





各モジュールは注目に値するという事実のため、これらすべてが1つの記事に収まることはありません。そのため、私はミニシリーズ「JSで高品質のトレードボットを書く」を始めています。したがって、サブスクライブして、快適にしましょう-始めましょう





ログのサービス

, log



error



. :





class LoggerService {
  constructor(prefix) {
    this.logPrefix = prefix
  }

  log(...props) {
    console.log(new Date().toISOString().substr(0, 19), this.logPrefix, ...props)
  }

  error(...props) {
    console.error(new Date().toISOString().substr(0, 19), this.logPrefix, ...props)
  }
}
      
      



yarn add node-binance-api
      
      



BaseApiService. Binance SDK, LoggerService. Binance , . , futuresExchangeInfo()



. getAssetPricePrecision



getAssetQuantityPrecision



.





class BaseApiService {
  constructor({ client, secret }) {
    const { log, error } = new Logger('BaseApiService')
    this.log = log
    this.error = error

    this.api = new NodeBinanceApi().options({
      APIKEY: client,
      APISECRET: secret,
      hedgeMode: true,
    })
    this.exchangeInfo = {}
  }

  async init() {
    try {
      this.exchangeInfo = await this.api.futuresExchangeInfo()
    } catch (e) {
      this.error('init error', e)
    }
  }

  getAssetQuantityPrecision(symbol) {
    const { symbols = [] } = this.exchangeInfo
    const s = symbols.find(s => s.symbol === symbol) || { quantityPrecision: 3 }
    return s.quantityPrecision
  }

  getAssetPricePrecision(symbol) {
    const { symbols = [] } = this.exchangeInfo
    const s = symbols.find(s => s.symbol === symbol) || { pricePrecision: 2 }
    return s.pricePrecision
  }
}
      
      



, :





async futuresOrder(side, symbol, qty, price, params={}) {
  try {
    qty = Number(qty).toFixed(this.getAssetQuantityPrecision(symbol))
    price = Number(price).toFixed(this.getAssetPricePrecision(symbol))
    if (!params.type) {
      params.type = ORDER.TYPE.MARKET
    }
    const res = await this.api.futuresOrder(side, symbol, qty, price || false, params)
    this.log('futuresOrder', res)
    return res
  } catch (e) {
    console.log('futuresOrder error', e)
  }
}
      
      



. , . TradeService.





class TradeService {
  constructor({client, secret}) {
    const { log, error } = new LoggerService('TradeService')
    this.log = log
    this.error = error
    this.api = new NodeBinanceApi().options({
      APIKEY: client,
      APISECRET: secret,
      hedgeMode: true,
    })
    this.events = new EventEmitter()
  }

  marginCallCallback = (data) => this.log('marginCallCallback', data)

  accountUpdateCallback = (data) => this.log('accountUpdateCallback', data)

  orderUpdateCallback = (data) => this.emit(data)

  subscribedCallback = (data) => this.log('subscribedCallback', data)

  accountConfigUpdateCallback = (data) => this.log('accountConfigUpdateCallback', data)

  startListening() {
    this.api.websockets.userFutureData(
      this.marginCallCallback,
      this.accountUpdateCallback,
      this.orderUpdateCallback,
      this.subscribedCallback,
      this.accountConfigUpdateCallback,
    )
  }

  subscribe(cb) {
    this.events.on('trade', cb)
  }

  emit = (data) => {
    this.events.emit('trade', data)
  }
}
      
      



SDK this.api.websockets.userFutureData



. this.orderUpdateCallback



. . EventEmitter



, , subscribe



.





? , . . /. . sequlize. 





yarn add sequelize-cli -D
yarn add sequelize
npx sequelize-cli init
      
      



docker-compose.yml :





version: '3.1'

services:
  db:
    image: 'postgres:12'
    restart: unless-stopped
    volumes:
      - ./volumes/postgresql/data:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: root
      POSTGRES_PASSWORD: example
      POSTGRES_DB: bot
    ports:
      - 5432:5432
    networks:
      - postgres


networks:
  postgres:
    driver: bridge
      
      



. User



, Order







つづく。





次の記事では、これらすべてのパーツを接続してボットを取引するコアを作成します。








All Articles