# accumulate_distribute/util/schedule_tick.js

    'use strict'

    const _isFinite = require('lodash/isFinite')

    /**
     * Sets a timeout to emit the `self:interval_tick` event after the configured
     * slice interval passes, taking into account the configured interval
     * distortion for the AccumulateDistribute instance.
     *
     * If `catchUp` was enabled and the instance is behind with order fills, the
     * next tick is always scheduled in 200ms.
     *
     * @memberOf module:AccumulateDistribute
     * @see module:AccumulateDistribute~onSelfIntervalTick
     * @fires module:AccumulateDistribute.selfIntervalTick
     *
     * @param {AOInstance} instance - AO instance
     * @returns {Promise} p - resolves on completion
     */
    const scheduleTick = async (instance) => {
      const { state = {}, h = {} } = instance
      const { emitSelf, updateState, notifyUI } = h
      const { args = {} } = state
      const { sliceInterval, intervalDistortion, catchUp } = args
      let timeoutDelay = catchUp ? 200 : sliceInterval

      // Distort timeout interval if requested
      if (_isFinite(intervalDistortion) && !catchUp) {
        const m = Math.random() > 0.5 ? 1 : -1
        timeoutDelay *= 1 + (Math.random() * intervalDistortion * m)
      }

      const timeout = setTimeout(async () => { // schedule first tick
        /**
         * Triggers verification of the price target, and a potential atomic order
         * submit.
         *
         * @event module:AccumulateDistribute~selfIntervalTick
         */
        await emitSelf('interval_tick', timeoutDelay)
      }, timeoutDelay)

      await notifyUI('info', `scheduled tick in ~${(timeoutDelay / 1000).toFixed(4)}s`)

      return updateState(instance, {
        timeout,
        timeoutDelay,
        timeoutScheduledAt: Date.now()
      })
    }

    module.exports = {
      tick: scheduleTick
    } // exported within an object so we can be mocked