|
@ -1,12 +1,20 @@ |
|
|
|
|
|
import { BenchmarkService } from '@ghostfolio/api/app/benchmark/benchmark.service'; |
|
|
import { SymbolService } from '@ghostfolio/api/app/symbol/symbol.service'; |
|
|
import { SymbolService } from '@ghostfolio/api/app/symbol/symbol.service'; |
|
|
import { ConfigurationService } from '@ghostfolio/api/services/configuration.service'; |
|
|
import { ConfigurationService } from '@ghostfolio/api/services/configuration.service'; |
|
|
|
|
|
import { PropertyService } from '@ghostfolio/api/services/property/property.service'; |
|
|
import { |
|
|
import { |
|
|
|
|
|
PROPERTY_BENCHMARKS, |
|
|
ghostfolioFearAndGreedIndexDataSource, |
|
|
ghostfolioFearAndGreedIndexDataSource, |
|
|
ghostfolioFearAndGreedIndexSymbol |
|
|
ghostfolioFearAndGreedIndexSymbol |
|
|
} from '@ghostfolio/common/config'; |
|
|
} from '@ghostfolio/common/config'; |
|
|
import { resolveFearAndGreedIndex } from '@ghostfolio/common/helper'; |
|
|
import { |
|
|
|
|
|
resolveFearAndGreedIndex, |
|
|
|
|
|
resolveMarketCondition |
|
|
|
|
|
} from '@ghostfolio/common/helper'; |
|
|
|
|
|
import { UniqueAsset } from '@ghostfolio/common/interfaces'; |
|
|
import { Injectable, Logger } from '@nestjs/common'; |
|
|
import { Injectable, Logger } from '@nestjs/common'; |
|
|
import { isSunday } from 'date-fns'; |
|
|
import { isSunday } from 'date-fns'; |
|
|
|
|
|
import * as roundTo from 'round-to'; |
|
|
import { TwitterApi, TwitterApiReadWrite } from 'twitter-api-v2'; |
|
|
import { TwitterApi, TwitterApiReadWrite } from 'twitter-api-v2'; |
|
|
|
|
|
|
|
|
@Injectable() |
|
|
@Injectable() |
|
@ -14,7 +22,9 @@ export class TwitterBotService { |
|
|
private twitterClient: TwitterApiReadWrite; |
|
|
private twitterClient: TwitterApiReadWrite; |
|
|
|
|
|
|
|
|
public constructor( |
|
|
public constructor( |
|
|
|
|
|
private readonly benchmarkService: BenchmarkService, |
|
|
private readonly configurationService: ConfigurationService, |
|
|
private readonly configurationService: ConfigurationService, |
|
|
|
|
|
private readonly propertyService: PropertyService, |
|
|
private readonly symbolService: SymbolService |
|
|
private readonly symbolService: SymbolService |
|
|
) { |
|
|
) { |
|
|
this.twitterClient = new TwitterApi({ |
|
|
this.twitterClient = new TwitterApi({ |
|
@ -48,7 +58,16 @@ export class TwitterBotService { |
|
|
symbolItem.marketPrice |
|
|
symbolItem.marketPrice |
|
|
); |
|
|
); |
|
|
|
|
|
|
|
|
const status = `Current Market Mood: ${emoji} ${text} (${symbolItem.marketPrice}/100)\n\n#FearAndGreed #Markets #ServiceTweet`; |
|
|
let status = `Current Market Mood: ${emoji} ${text} (${symbolItem.marketPrice}/100)`; |
|
|
|
|
|
|
|
|
|
|
|
const benchmarkListing = await this.getBenchmarkListing(3); |
|
|
|
|
|
|
|
|
|
|
|
if (benchmarkListing?.length > 1) { |
|
|
|
|
|
status += '\n\n'; |
|
|
|
|
|
status += '±% from ATH\n'; |
|
|
|
|
|
status += benchmarkListing; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
const { data: createdTweet } = await this.twitterClient.v2.tweet( |
|
|
const { data: createdTweet } = await this.twitterClient.v2.tweet( |
|
|
status |
|
|
status |
|
|
); |
|
|
); |
|
@ -62,4 +81,36 @@ export class TwitterBotService { |
|
|
Logger.error(error, 'TwitterBotService'); |
|
|
Logger.error(error, 'TwitterBotService'); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private async getBenchmarkListing(aMax: number) { |
|
|
|
|
|
const benchmarkAssets: UniqueAsset[] = |
|
|
|
|
|
((await this.propertyService.getByKey( |
|
|
|
|
|
PROPERTY_BENCHMARKS |
|
|
|
|
|
)) as UniqueAsset[]) ?? []; |
|
|
|
|
|
|
|
|
|
|
|
const benchmarks = await this.benchmarkService.getBenchmarks( |
|
|
|
|
|
benchmarkAssets |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
const benchmarkListing: string[] = []; |
|
|
|
|
|
|
|
|
|
|
|
for (const [index, benchmark] of benchmarks.entries()) { |
|
|
|
|
|
if (index > aMax - 1) { |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
benchmarkListing.push( |
|
|
|
|
|
`${benchmark.name} ${roundTo( |
|
|
|
|
|
benchmark.performances.allTimeHigh.performancePercent * 100, |
|
|
|
|
|
1 |
|
|
|
|
|
)}%${ |
|
|
|
|
|
benchmark.marketCondition !== 'NEUTRAL_MARKET' |
|
|
|
|
|
? ' ' + resolveMarketCondition(benchmark.marketCondition).emoji |
|
|
|
|
|
: '' |
|
|
|
|
|
}` |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return benchmarkListing.join('\n'); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|