Skip to content

Commit

Permalink
Actually preroll the period store
Browse files Browse the repository at this point in the history
  • Loading branch information
notVitaliy committed Nov 27, 2020
1 parent e046e56 commit 3169b20
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 24 deletions.
30 changes: 18 additions & 12 deletions src/store/period.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ interface PeriodConf {
}

enum PERIOD_STATE {
PREROLL,
STOPPED,
RUNNING,
}
Expand Down Expand Up @@ -40,10 +41,14 @@ export class PeriodStore {
/* istanbul ignore next */
if (this.periods.has(idStr)) return

logger.debug(`Adding ${idStr} to period store.`)

this.periods.set(idStr, [])
this.periodConfigs.set(idStr, conf)
this.tradeEventTimeouts.set(idStr, null)

this.periodStates.set(idStr, PERIOD_STATE.PREROLL)

const tradeListener: EventBusListener<Trade> = eventBus.get(EVENT.XCH_TRADE)(exchange)(symbol).listen
/* istanbul ignore next */
tradeListener((trade: Trade) => this.addTrade(idStr, trade))
Expand All @@ -57,7 +62,10 @@ export class PeriodStore {
const idStr = this.makeIdStr(storeOpts)
this.periodStates.set(idStr, PERIOD_STATE.RUNNING)

this.periodTimer.set(idStr, setTimeout(() => this.publishPeriod(idStr), this.getPeriodTimeout(idStr)))
this.periodTimer.set(
idStr,
setTimeout(() => this.publishPeriod(idStr), this.getPeriodTimeout(idStr))
)
}

public stop(storeOpts: StoreOpts) {
Expand All @@ -66,21 +74,19 @@ export class PeriodStore {
}

public addTrade(idStr: string, trade: Trade) {
if (this.periodStates.get(idStr) !== PERIOD_STATE.RUNNING) return
const periodState = this.periodStates.get(idStr)

if (periodState === PERIOD_STATE.STOPPED) return

const { period } = this.periodConfigs.get(idStr)
const periods = this.periods.get(idStr)
const { amount, price, timestamp } = trade
const bucket = timebucket(timestamp)
.resize(period)
.toMilliseconds()
const bucket = timebucket(timestamp).resize(period).toMilliseconds()

// aka prerolled data
const tradeBasedPeriodChange = !periods.length || periods[0].time < bucket

if (tradeBasedPeriodChange) {
this.newPeriod(idStr, bucket)
}
if (tradeBasedPeriodChange) this.newPeriod(idStr, bucket)

// special handling if the trade is the first within the period
if (!periods[0].open) periods[0].open = price
Expand Down Expand Up @@ -125,7 +131,7 @@ export class PeriodStore {
* @param idStr period identifier
*/
private emitTrades(idStr: string) {
if (this.periodStates.get(idStr) !== PERIOD_STATE.RUNNING) return
if (this.periodStates.get(idStr) === PERIOD_STATE.STOPPED) return

if (this.tradeEventTimeouts.has(idStr)) return
const fn = () => this.emitTradeImmediate(idStr)
Expand All @@ -138,7 +144,7 @@ export class PeriodStore {
* @param idStr period identifier
*/
private emitTradeImmediate(idStr: string) {
if (this.periodStates.get(idStr) !== PERIOD_STATE.RUNNING) return
if (this.periodStates.get(idStr) === PERIOD_STATE.STOPPED) return

const periods = this.periods.get(idStr)
this.updateEmitters.get(idStr)([...periods])
Expand Down Expand Up @@ -168,7 +174,7 @@ export class PeriodStore {

/* istanbul ignore next */
private checkPeriodWithoutTrades(idStr: string) {
if (this.periodStates.get(idStr) !== PERIOD_STATE.RUNNING) return
if (this.periodStates.get(idStr) === PERIOD_STATE.STOPPED) return

const periods = this.periods.get(idStr)
if (periods.length < 2) return
Expand All @@ -191,7 +197,7 @@ export class PeriodStore {
/* istanbul ignore next */
private publishPeriod(idStr: string) {
clearTimeout(this.periodTimer.get(idStr))
if (this.periodStates.get(idStr) !== PERIOD_STATE.RUNNING) return
if (this.periodStates.get(idStr) === PERIOD_STATE.STOPPED) return

this.checkPeriodWithoutTrades(idStr)
// Publish period to event bus
Expand Down
8 changes: 7 additions & 1 deletion src/store/trade.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Trade } from 'ccxt'
import { EventBusEmitter } from '@magic8bot/event-bus'
import { dbDriver, eventBus, EVENT } from '@lib'
import { StoreOpts } from '@m8bTypes'
import { logger } from '../util'

const singleton = Symbol()

Expand All @@ -22,6 +23,8 @@ export class TradeStore {
/* istanbul ignore next */
if (this.tradesMap.has(idStr)) return

logger.debug(`Adding ${idStr} to trade store.`)

this.tradesMap.set(idStr, 0)
this.emitters.set(idStr, eventBus.get(EVENT.XCH_TRADE)(exchange)(symbol).emit)
}
Expand All @@ -43,7 +46,10 @@ export class TradeStore {

public async insertTrades({ exchange, symbol }: StoreOpts, newTrades: Trade[]) {
try {
await dbDriver.trade.insertMany(newTrades.map((trade) => ({ ...trade, exchange, symbol })), { ordered: false })
await dbDriver.trade.insertMany(
newTrades.map((trade) => ({ ...trade, exchange, symbol })),
{ ordered: false }
)
} catch {
// ヽ(。_°)ノ
}
Expand Down
23 changes: 12 additions & 11 deletions src/strategy/strategies/macd/macd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,10 @@ export class Macd extends BaseStrategy<MacdOptions, { rsi: number; signal: numbe
// prettier-ignore
const { periods: [{ signal, rsi }] } = this

/* istanbul ignore next */
logger.debug(`calculated: ${JSON.stringify({ rsi: rsi !== null ? rsi.toPrecision(4) : null, signal: signal !== null ? signal.toPrecision(6) : null })}`)
if (!this.isPreroll) {
/* istanbul ignore next */
logger.debug(`calculated: ${JSON.stringify({ rsi: rsi !== null ? rsi.toPrecision(4) : null, signal: signal !== null ? signal.toPrecision(6) : null })}`)
}

return { rsi, signal }
}
Expand Down Expand Up @@ -172,8 +174,6 @@ export class Macd extends BaseStrategy<MacdOptions, { rsi: number; signal: numbe

const { rsi, avgGain, avgLoss } = RSI.calculate(preAvgGain, preAvgLoss, periods, this.options.overboughtRsiPeriods)

logger.debug(JSON.stringify({ rsi, avgGain, avgLoss, preAvgGain, preAvgLoss }))

this.periods[0].rsi = rsi
this.periods[0].avgGain = avgGain

Expand All @@ -182,21 +182,22 @@ export class Macd extends BaseStrategy<MacdOptions, { rsi: number; signal: numbe
}

public onPeriod() {
logger.debug(`Periods: ${this.periods.length}`)

/* istanbul ignore next */
const signal = this.overboughtSell() ? 'sell' : this.getSignal()
/* istanbul ignore next */
if (this.periods.length) {
logger.debug(
`
if (!this.isPreroll) {
if (this.periods.length) {
logger.debug(
`
MACD: ${this.periods[0].macd ? this.periods[0].macd.toPrecision(5) : null}
EMA: ${this.periods[0].emaMacd ? this.periods[0].emaMacd.toPrecision(5) : null}
Signal: ${this.periods[0].signal ? this.periods[0].signal.toPrecision(6) : null}
RSI ${this.periods[0].rsi ? this.periods[0].rsi.toPrecision(4) : null}`
)
)
}

logger.verbose(`Period finished => Signal: ${signal === null ? 'no signal' : signal}`)
}
logger.verbose(`Period finished => Signal: ${signal === null ? 'no signal' : signal}`)
this.newPeriod()
return signal
}
Expand Down

0 comments on commit 3169b20

Please sign in to comment.