[#27] Ausbau von TimedAssetData und erstzung durch AggregatedData

This commit is contained in:
darkeye 2025-01-11 20:35:16 +01:00
parent e002eeec44
commit adbe4f30c8
15 changed files with 76 additions and 609 deletions

View File

@ -25,8 +25,8 @@ try{
const tradingBot = new TradingBot("C:/Users/Wlad/Projekte/BinanceBot/binance_bot/data/conf", "config-test.sjson");
const galaWorker = new DefaultWorker("default_gala", TradingPairs.GALAUSDT, new AbstractStrategy());
const statWorker = new StatisticWorker("gala_stats", TradingPairs.GALAUSDT, new TestStrategy());
//tradingBot.registerWorker(galaWorker);
//tradingBot.registerWorker(statWorker);
tradingBot.registerWorker(galaWorker);
tradingBot.registerWorker(statWorker);
tradingBot.start();
} catch (e){
console.log(e);

View File

@ -2,7 +2,6 @@ import BinanceApiConfig from "../../apis/binance/BinanceApiConfig.js";
import APIConfig from "../../apiwrapper/APIConfig.js";
import Serializable from "../../util/Serializable.js";
import SerializableHelper from "../../util/SerializableHelper.js";
import AssetDataCollectionConfig from "../data/asset/AssetDataCollectionConfig.js";
export default class BotConfig extends Serializable {
/**
@ -30,11 +29,6 @@ export default class BotConfig extends Serializable {
*/
#apiConfig = new BinanceApiConfig();
/**
* @type {AssetDataCollectionConfig}
*/
#dataCollectionConfig = new AssetDataCollectionConfig(['1s', '1m', '15m', '1h']);
/**
* @type {string} chrono unit string; Time until trading should start
*/
@ -211,20 +205,6 @@ export default class BotConfig extends Serializable {
this.#restInterfacePort = port;
}
/**
* @param {AssetDataCollectionConfig} conf
*/
setDataCollectionConfig(conf){
this.#dataCollectionConfig = conf;
}
/**
* @returns {AssetDataCollectionConfig}
*/
getDataCollectionConfig(){
return this.#dataCollectionConfig;
}
/**
* @returns {string} chrono time string
*/
@ -253,7 +233,6 @@ export default class BotConfig extends Serializable {
obj.singleTradeLimit = this.#maxUSDPerTrade;
obj.restInterfaceEnabled = this.#enableRestInterface;
obj.restInterfacePort = this.#restInterfacePort;
obj.assetDataCollectionConfig = SerializableHelper.serialize(this.#dataCollectionConfig);
obj.rampupTime = this.#rampupTime;
return JSON.stringify(obj);
@ -276,7 +255,6 @@ export default class BotConfig extends Serializable {
conf.#maxUSDPerTrade = obj.singleTradeLimit;
conf.#enableRestInterface = obj.restInterfaceEnabled;
conf.#restInterfacePort = obj.restInterfacePort;
conf.#dataCollectionConfig = SerializableHelper.deserialize(obj.assetDataCollectionConfig);
conf.#rampupTime = obj.rampupTime;
return conf;

View File

@ -148,7 +148,6 @@ export default class AggregatedDataPoint {
this.#priceValues.forEach(p => priceSum += p);
this.avgPrice = priceSum / this.#priceValues.length;
}
console.log(this.minPrice, this.maxPrice, this.avgPrice, this.minPrice <= this.avgPrice, this.avgPrice <= this.maxPrice);
this.#priceValues = [];
}

View File

@ -5,21 +5,14 @@ import Ticker24hEvent from "../../../apiwrapper/event/Ticker24hEvent.js";
import OrderBook from "../../../apiwrapper/orderbook/OrderBook.js";
import OrderBookEntry from "../../../apiwrapper/orderbook/OrderBookEntry.js";
import AssetDataAggregator from "./AssetDataAggregator.js";
import AssetDataCollectionConfig from "./AssetDataCollectionConfig.js";
import PeakDetector from "./PeakDetector.js";
import TimedAssetData from "./TimedAssetData.js";
export default class AssetData extends TimedAssetData {
export default class AssetData {
/**
* @type {TradingPair}
*/
#tradingPair = null;
/**
* @type {AssetDataCollectionConfig}
*/
#config = null;
/**
* @type {number}
*/
@ -73,16 +66,13 @@ export default class AssetData extends TimedAssetData {
/**
* @type {AssetDataAggregator}
*/
assetDataAggregator = new AssetDataAggregator();
#assetDataAggregator = new AssetDataAggregator();
/**
* @param {TradingPair} tradingPair
* @param {AssetDataCollectionConfig} collectionConfig
*/
constructor(tradingPair, collectionConfig) {
super([31536000000, ...collectionConfig.getTimePeriodsInMs()]);
constructor(tradingPair) {
this.#tradingPair = tradingPair;
this.open();
}
/**
@ -103,8 +93,7 @@ export default class AssetData extends TimedAssetData {
* @param {KLineEvent} klineEvent
*/
updateKline(klineEvent) {
this.push(klineEvent.high, klineEvent.low, klineEvent.open, klineEvent.close);
this.assetDataAggregator.pushKLine(klineEvent.timestamp, klineEvent.low, klineEvent.high, klineEvent.open, klineEvent.close);
this.#assetDataAggregator.pushKLine(klineEvent.timestamp, klineEvent.low, klineEvent.high, klineEvent.open, klineEvent.close);
}
/**
@ -112,11 +101,9 @@ export default class AssetData extends TimedAssetData {
*/
updateOrderBook(orderBookUpdateEvent){
this.#orderBook.update(orderBookUpdateEvent);
this.pushBestBid(this.#orderBook.getBestBid());
this.pushBestAsk(this.#orderBook.getBestAsk());
this.#peakDetector.push(this.#orderBook.getBestAsk());
this.assetDataAggregator.pushBestAsk(this.#orderBook.getBestAsk());
this.assetDataAggregator.pushBestBid(this.#orderBook.getBestBid());
this.#assetDataAggregator.pushBestAsk(this.#orderBook.getBestAsk());
this.#assetDataAggregator.pushBestBid(this.#orderBook.getBestBid());
}
/**
@ -183,28 +170,16 @@ export default class AssetData extends TimedAssetData {
return this.#trades24h;
}
/**
* @param {number} high
* @param {number} low
* @param {number} open
* @param {number} close
*/
push(high, low, open, close) {
super.push(high, low, open, close);
const slots = this.getSubData();
for(let i = slots.length - 2; i >= 0; i--){
slots[i].removeSubData();
}
}
/**
* @param {number} time
* @param {number} price
* @param {number} quantity
*/
pushTrade(time, price, quantity) {
super.pushTrade(time, price, quantity);
this.assetDataAggregator.pushTrade(time, price, quantity);
this.#assetDataAggregator.pushTrade(time, price, quantity);
}
getAggregatedData(duration, timeOffset = -1){
return this.#assetDataAggregator.getData(duration, timeOffset);
}
}

View File

@ -1,54 +0,0 @@
import Serializable from "../../../util/Serializable.js";
import UnitHelper from "../../util/UnitHelper.js";
export default class AssetDataCollectionConfig extends Serializable{
/**
* @type {number[]}
*/
#timePeriods = [];
/**
* @param {string[]|number[]|null} timePeriods
*/
constructor(timePeriods = null) {
super();
this.setTimePeriods(timePeriods);
}
/**
* @param {string[]|number[]|null} timePeriods
*/
setTimePeriods(timePeriods){
if(timePeriods != null){
for (const timePeriod of timePeriods) {
this.#timePeriods.push(UnitHelper.formatedDurationToMs(timePeriod));
}
}
}
getTimePeriodsInMs(){
return [...this.#timePeriods.sort((a, b) => a - b)];
}
/**
* @returns {string} string representation of this object
*/
toJson() {
const obj = JSON.parse(super.toJson());
obj.timePeriods = this.#timePeriods;
return JSON.stringify(obj);
}
/**
* @param {string} objString
* @returns {AssetDataCollectionConfig}
*/
static fromJson(objString) {
const obj = JSON.parse(objString);
const timePeriodConfig = new AssetDataCollectionConfig(obj.timePeriods);
return timePeriodConfig;
}
}

View File

@ -1,6 +0,0 @@
export default class AssetStatisticValue{
min1 = 0;
min15 = 0;
min30 = 0;
min60 = 0;
}

View File

@ -1,369 +0,0 @@
import OrderBookEntry from "../../../apiwrapper/orderbook/OrderBookEntry.js";
import UnitHelper from "../../util/UnitHelper.js";
import TimedAssetDataMerger from "./TimedAssetDataMerger.js";
export default class TimedAssetData {
/**
* @type {number}
*/
#duration = 0;
/**
* @type {number}
*/
#startTime = 0;
/**
* @type {number}
*/
#endTime = 0;
/**
* @type {boolean}
*/
#closed = false;
/**
* @type {number}
*/
#open = 0;
/**
* @type {number}
*/
#close = 0;
/**
* @type {number}
*/
#high = Number.MIN_VALUE;
/**
* @type {number}
*/
#low = Number.MAX_VALUE;
/**
* @type {number}
*/
#volume = 0;
/**
* @type {number}
*/
#trades = 0;
/**
* @type {OrderBookEntry}
*/
#bestBid = null;
/**
* @type {OrderBookEntry}
*/
#bestAsk = null;
/**
* @type {TimedAssetData[]}
*/
#subSlots = [];
/**
* @type {number[]}
*/
#subSlotDurations = [];
/**
* @param {number[]} durations
*/
constructor(durations) {
this.#duration = durations.pop();
this.#subSlotDurations = [...durations];
}
/**
* @param {number} startTime
*/
open(startTime) {
if (startTime != null) {
this.#startTime = startTime;
} else {
this.#startTime = Date.now();
}
this.#closed = false;
}
/**
* @param {number} endTime
*/
close(endTime) {
if (this.#closed) {
return;
}
if (endTime != null) {
this.#endTime = endTime;
} else {
this.#endTime = Date.now();
}
this.#closed = true;
if (this.#subSlots != null && this.#subSlots.length > 0) {
this.#subSlots[this.#subSlots.length - 1].close(endTime);
}
}
removeSubData() {
if (!this.#closed) {
return;
}
this.#subSlots.forEach(slot => {slot.close(); slot.removeSubData()});
this.#subSlots = [];
}
/**
* @returns {TimedAssetData[]}
*/
getSubData() {
return this.#subSlots;
}
/**
* @type {TimedAssetData}
*/
getSlotForPeriode(chronoString){
const periode = UnitHelper.formatedDurationToMs(chronoString);
if(this.getDuration() <= periode){
return this;
}
if(this.#subSlotDurations == null || this.#subSlotDurations.length == 0){
return null;
}
const subSlotDuration = this.#subSlotDurations[this.#subSlotDurations.length - 1];
if(subSlotDuration > periode){
const lastSlotIndex = this.#subSlots.length - 1;
if((this.#subSlots[lastSlotIndex].getEndTime() - this.#subSlots[lastSlotIndex].getStartTime()) >= periode * 0.7){
return this.#subSlots[lastSlotIndex].getSlotForPeriode(periode);
} else {
return this.#subSlots[Math.max(lastSlotIndex-1), 0].getSlotForPeriode(periode);
}
}
const merger = new TimedAssetDataMerger();
for(let i = this.#subSlots.length - 1, duration = 0; i >= 0 && duration < periode; i--){
merger.push(this.#subSlots[i]);
duration += this.#subSlots[i].getEndTime() - this.#subSlots[i].getStartTime();
}
return merger.merge(periode);
}
/**
* @returns {number}
*/
getDuration() {
return this.#duration;
}
/**
* @param {number} duration
*/
setDuration(duration){
this.#duration = duration;
}
/**
* @returns {number}
*/
getStartTime() {
return this.#startTime;
}
/**
* @returns {number}
*/
getEndTime() {
return this.#endTime != 0 ? this.#endTime : Date.now();
}
/**
* @returns {number}
*/
getOpen() {
return this.#open;
}
/**
* @returns {number}
*/
getClose() {
return this.#close;
}
/**
* @returns {number}
*/
getHigh() {
return this.#high;
}
/**
* @returns {number}
*/
getLow() {
return this.#low;
}
/**
* @returns {number}
*/
getVolume() {
return this.#volume;
}
/**
* @returns {number}
*/
getTrades() {
return this.#trades;
}
/**
* @returns {OrderBookEntry}
*/
getBestBid() {
return this.#bestBid;
}
/**
* @returns {OrderBookEntry}
*/
getBestAsk() {
return this.#bestAsk;
}
/**
* @param {number} time
* @returns {boolean}
*/
isInSlot(time) {
if (this.#closed) {
return false;
}
return (time - this.#startTime) < this.#duration;
}
/**
* @param {number} high
* @param {number} low
* @param {number} open
* @param {number} close
*/
push(high, low, open, close) {
this.#high = Math.max(this.#high, high);
this.#low = Math.min(this.#low, low);
this.#close = close;
if (this.#open <= 0) {
this.#open = open;
}
const subSlot = this.#getSubSlot();
if (subSlot) {
subSlot.push(high, low, open, close);
}
}
/**
*
* @param {number} time
* @param {number} price
* @param {number} quantity
*/
pushTrade(time, price, quantity) {
this.#trades ++;
this.#volume += quantity;
const subSlot = this.#getSubSlot();
if (subSlot) {
subSlot.pushTrade(time, price, quantity);
}
}
/**
* @param {number} count
* @param {number} avgPrice
* @param {number} quantity
*/
setTradeValues(count, avgPrice, quantity){
this.#trades = count;
this.#volume = quantity;
}
/**
*
* @param {OrderBookEntry} ask
*/
pushBestAsk(ask) {
if (this.#bestAsk == null || this.#bestAsk.price < ask.price) {
this.#bestAsk = ask;
}
const subSlot = this.#getSubSlot();
if (subSlot) {
subSlot.pushBestAsk(ask);
}
}
/**
*
* @param {OrderBookEntry} bid
*/
pushBestBid(bid) {
if (this.#bestBid == null || this.#bestBid.price > bid.price) {
this.#bestBid = bid;
}
const subSlot = this.#getSubSlot();
if (subSlot) {
subSlot.pushBestBid(bid);
}
}
/**
*
* @returns {TimeSlot}
*/
#getSubSlot() {
if (this.#subSlotDurations == null || this.#subSlotDurations.length < 1) {
return null;
}
let activeSubSlot = null;
if (this.#subSlots.length == 0) {
activeSubSlot = new TimedAssetData([...this.#subSlotDurations]);
activeSubSlot.open(Date.now());
this.#subSlots.push(activeSubSlot);
} else {
activeSubSlot = this.#subSlots[this.#subSlots.length - 1];
if (!activeSubSlot.isInSlot(Date.now())) {
activeSubSlot.close(Date.now());
activeSubSlot = new TimedAssetData([...this.#subSlotDurations]);
activeSubSlot.open(Date.now());
this.#subSlots.push(activeSubSlot);
}
}
return activeSubSlot;
}
}

View File

@ -1,70 +0,0 @@
import OrderBookEntry from "../../../apiwrapper/orderbook/OrderBookEntry.js";
import TimedAssetData from "./TimedAssetData.js";
export default class TimedAssetDataMerger {
/**
* @type {TimedAssetData[]}
*/
#slotsToMerge = []
/**
* @param {TimedAssetData} data
*/
push(data){
this.#slotsToMerge.push(data);
}
/**
* @param {number} expectedDuration duration of the new slot or null for sum of all given durations
* @returns {TimedAssetData}
*/
merge(expectedDuration = null){
if(this.#slotsToMerge.length == 0){
return null;
}
this.#slotsToMerge.sort((s1, s2) => s1.getStartTime() - s2.getStartTime());
const result = new TimedAssetData([0]);
let shortestSlotDuration = this.#slotsToMerge[0].getEndTime() - this.#slotsToMerge[0].getStartTime();
this.#slotsToMerge.forEach(s => {
shortestSlotDuration = Math.min(shortestSlotDuration, s.getEndTime() - s.getStartTime());
});
let newSlotDuration = 0;
let open = 0;
let close = 0;
let high = Number.MIN_VALUE;
let low = Number.MAX_VALUE;
let tradeCount = 0;
let tradeVolume = 0;
for(let i = this.#slotsToMerge.length - 1; i >= 0 && (expectedDuration == null || newSlotDuration < expectedDuration); i--){
let factor = this.#slotsToMerge[i].getDuration() / shortestSlotDuration;
if(expectedDuration != null && newSlotDuration + this.#slotsToMerge[i].getDuration() > expectedDuration){
factor /= this.#slotsToMerge[i].getDuration() / (expectedDuration - newSlotDuration);
}
open = (open == 0 || factor >= 0.6) ? this.#slotsToMerge[i].getOpen() : open;
close = close == 0 ? this.#slotsToMerge[i].getClose() : close;
high = (high == 0 || factor >= 0.6) ? Math.max(this.#slotsToMerge[i].getHigh(), high) : high;
low = (low == 0 || factor >= 0.6) ? Math.min(this.#slotsToMerge[i].getLow(), low) : low;
tradeCount += factor < 1 ? this.#slotsToMerge[i].getTrades() * factor : this.#slotsToMerge[i].getTrades();
tradeVolume += factor < 1 ? this.#slotsToMerge[i].getVolume() * factor : this.#slotsToMerge[i].getVolume();
if(factor >= 0.6){
result.pushBestAsk(this.#slotsToMerge[i].getBestAsk());
result.pushBestBid(this.#slotsToMerge[i].getBestBid());
}
}
result.open(this.#slotsToMerge[this.#slotsToMerge.length - 1].getEndTime() - newSlotDuration);
result.setDuration(newSlotDuration);
result.push(high, low, open, close);
result.setTradeValues(Math.round(tradeCount), 0, tradeVolume);
result.close(this.#slotsToMerge[this.#slotsToMerge.length - 1].getEndTime());
return result;
}
}

View File

@ -9,9 +9,6 @@ export default class AvgMinMaxStrategy extends AbstractStrategy {
this.#lastBuySuggestionTime = Date.now();
}
updateAssetData(assetData) {
}
/**
* @param {Transaction} transaction
* @returns {boolean}
@ -23,27 +20,26 @@ export default class AvgMinMaxStrategy extends AbstractStrategy {
return false;
}
const assetData15Min = this.getAssetData().getSlotForPeriode('15m');
const aggDataPoints = this.getAssetData().getAggregatedData('15m');
const price = this.getAssetData().getOrderBook().getBestBid().price;
const avg15m = (assetData15Min.getLow() + assetData15Min.getHigh()) / 2;
const avg15m = aggDataPoints.length > 0 ? aggDataPoints.map(v => v.avgPrice).reduce((a, b) => a+b, 0) / aggDataPoints.length : 0;
return avg15m * 1.005 <= price;
return avg15m != 0 && avg15m * 1.005 <= price;
}
/**
* @returns {boolean}
*/
shouldBuy() {
if(Date.now() < this.#lastBuySuggestionTime + 60000){
if(Date.now() < this.#lastBuySuggestionTime + 300000){
return false;
}
const assetData15Min = this.getAssetData().getSlotForPeriode('15m');
const aggDataPoints = this.getAssetData().getAggregatedData('15m');
const price = this.getAssetData().getOrderBook().getBestBid().price;
const avg15m = (assetData15Min.getLow() + assetData15Min.getHigh()) / 2;
const avg15m = aggDataPoints.length > 0 ? aggDataPoints.map(v => v.avgPrice).reduce((a, b) => a+b, 0) / aggDataPoints.length : 0;
if(avg15m * 0.995 >= price){
if(avg15m != 0 && avg15m * 0.995 >= price){
this.#lastBuySuggestionTime = Date.now();
return true;
}
@ -70,9 +66,9 @@ export default class AvgMinMaxStrategy extends AbstractStrategy {
/**
* @param {string} objString
* @returns {TestStrategy}
* @returns {AvgMinMaxStrategy2}
*/
static fromJson(objString) {
return new Simple24hStrategy();
return new AvgMinMaxStrategy();
}
}

View File

@ -9,9 +9,6 @@ export default class PossiblePeakStrategy extends AbstractStrategy {
this.#lastBuySuggestionTime = Date.now();
}
updateAssetData(assetData) {
}
/**
* @param {Transaction} transaction
* @returns {boolean}
@ -35,15 +32,19 @@ export default class PossiblePeakStrategy extends AbstractStrategy {
return false;
}
const assetData5Min = this.getAssetData().getSlotForPeriode('5m');
const assetData15Min = this.getAssetData().getSlotForPeriode('15m');
const avg5Min = (assetData5Min.getLow() + assetData5Min.getHigh()) / 2;
const avg15Min = (assetData15Min.getLow() + assetData15Min.getHigh()) / 2;
const m5min = assetData5Min.getClose() / assetData5Min.getOpen();
const dataPoints15m = this.getAssetData().getAggregatedData('15m');
if(dataPoints15m.length == 0){
return false;
}
const avg5Min = dataPoints15m.slice(-5).map(v => v.avgPrice).reduce((a, b) => a+b, 0) / dataPoints15m.length;;
const avg15Min = dataPoints15m.map(v => v.avgPrice).reduce((a, b) => a+b, 0) / dataPoints15m.length;
const m5min = dataPoints15m[0].startPrice / dataPoints15m[dataPoints15m.length - 1].endPrice;
if ((price < avg5Min && avg5Min > avg15Min)
|| (price < avg15Min && m5min > 0.9995)
|| (price < assetData5Min.getOpen() && price > avg5Min)
|| (price < dataPoints15m[dataPoints15m.length - 6].startPrice && price > avg5Min)
) {
this.#lastBuySuggestionTime = Date.now();
return true;

View File

@ -9,9 +9,6 @@ export default class Simple24hStrategy extends AbstractStrategy {
this.#lastBuySuggestionTime = Date.now();
}
updateAssetData(assetData) {
}
/**
* @param {Transaction} transaction
* @returns {boolean}
@ -26,14 +23,18 @@ export default class Simple24hStrategy extends AbstractStrategy {
if(winPercent < 0.6){
return false;
}
const grades = this.#getGrades();
const assetData15Min = this.getAssetData().getSlotForPeriode('15m');
const assetData60Min = this.getAssetData().getSlotForPeriode('1h');
if(grades == null){
return false;
}
const grad15min = grades[0];
const grad60min = grades[1];
const priceChangePercent24h = this.getAssetData().get24hPriceChangePercent();
const grad15min = assetData15Min.getClose() / assetData15Min.getOpen();
const grad60min = assetData60Min.getClose() / assetData60Min.getOpen();
return priceChangePercent24h < 0.05 || (grad15min < 0.995 && grad60min < 0.985);
return priceChangePercent24h < 0.05 || grad15min < grad60min * 0.97;
}
/**
@ -44,11 +45,15 @@ export default class Simple24hStrategy extends AbstractStrategy {
return false;
}
const assetData15Min = this.getAssetData().getSlotForPeriode('15m');
const assetData60Min = this.getAssetData().getSlotForPeriode('1h');
const grades = this.#getGrades();
if(grades == null){
return false;
}
const grad15min = grades[0];
const grad60min = grades[1];
const priceChangePercent24h = this.getAssetData().get24hPriceChangePercent();
const grad15min = (assetData15Min.getClose() - assetData15Min.getOpen()) / 15;
const grad60min = (assetData60Min.getClose() - assetData60Min.getOpen()) / 60;
// up trend
if(priceChangePercent24h > 2 && grad15min < 0 && grad60min > 0){
@ -65,6 +70,23 @@ export default class Simple24hStrategy extends AbstractStrategy {
return false;
}
/**
* @returns {[number, number] | null}
*/
#getGrades(){
const dataPoints1h = this.getAssetData().getAggregatedData('1h');
if(dataPoints1h.length < 60){
return null;
}
const endPrice = dataPoints1h[dataPoints1h.length - 1].endPrice;
const grad15min = (endPrice - dataPoints1h[dataPoints1h - 15].startPrice) / 15;
const grad60min = (endPrice - dataPoints1h[dataPoints1h - 60].startPrice) / 60;
return [grad15min, grad60min];
}
/**
* @param {Transaction} transaction
* @returns {boolean}

View File

@ -1,8 +1,6 @@
import Transaction from "../../apiwrapper/transaction/Transaction.js";
import AbstractStrategy from "./AbstractStrategy.js";
import AvgMinMaxStrategy from "./AvgMinMaxStrategy.js";
import PossiblePeakStrategy from "./PossiblePeakStrategy.js";
import Simple24hStrategy from "./Simple24hStrategy.js";
import AvgMinMaxStrategy2 from "./AvgMinMaxStrategy.js";
export default class TestStrategy extends AbstractStrategy {
@ -23,9 +21,7 @@ export default class TestStrategy extends AbstractStrategy {
constructor(){
super();
this.#strategies.push(new Simple24hStrategy());
this.#strategies.push(new PossiblePeakStrategy());
this.#strategies.push(new AvgMinMaxStrategy());
this.#strategies.push(new AvgMinMaxStrategy2());
}
/**

View File

@ -97,7 +97,7 @@ export default class StatisticWorker extends AbstractWorker {
}
onInit() {
this.getLogger().debug("Statistic worker " + this.getName() + " for " + this.getTradingPair().getKey() + " initialized!");
this.getLogger().debug("Statistic 2 worker " + this.getName() + " for " + this.getTradingPair().getKey() + " initialized!");
}
/**
@ -188,18 +188,19 @@ export default class StatisticWorker extends AbstractWorker {
return;
}
this.#lastTickTimestamp = Date.now();
const lastMinAssetData = assetData.getSlotForPeriode('1m');
const data = assetData.getAggregatedData('2m');
const lastMinAssetData = data != null && data.length > 1 ? data[1] : null;
if (lastMinAssetData == null || lastMinAssetData.getHigh() == Number.MIN_VALUE) {
if (lastMinAssetData == null) {
return;
}
const timestamp = Date.now()
const peaks = assetData.getPeakDetector().peaks;
this.#peackCount = peaks.length;
this.#tradeCount.push([timestamp, lastMinAssetData.getTrades()]);
this.#tradeVolume.push([timestamp, lastMinAssetData.getVolume()]);
this.#price.push([timestamp, lastMinAssetData.getHigh(), lastMinAssetData.getLow(), (lastMinAssetData.getHigh() + lastMinAssetData.getLow()) / 2]);
this.#tradeCount.push([timestamp, lastMinAssetData.tradeCount]);
this.#tradeVolume.push([timestamp, lastMinAssetData.tradeVolume]);
this.#price.push([timestamp, lastMinAssetData.maxPrice, lastMinAssetData.minPrice, lastMinAssetData.avgPrice]);
this.#peakEnd.push([timestamp, false]);
this.#peakStart.push([timestamp, false]);
this.#buys.push([timestamp, this.#buyCount]);
@ -240,7 +241,7 @@ export default class StatisticWorker extends AbstractWorker {
/**
* @param {string} objString
* @returns {AbstractWorker}
* @returns {StatisticWorker2}
*/
static fromJson(objString) {
return super.fromJson(objString, new StatisticWorker());

View File

@ -5,7 +5,6 @@ import TradingPair from "../apiwrapper/assets/TradingPair.js";
import Transaction from "../apiwrapper/transaction/Transaction.js";
import TransactionSettings from "../apiwrapper/transaction/TransactionSettings.js";
import BotConfig from "../tradingbot/config/BotConfig.js";
import AssetDataCollectionConfig from "../tradingbot/data/asset/AssetDataCollectionConfig.js";
import AbstractStrategy from "../tradingbot/strategy/AbstractStrategy.js";
import AvgMinMaxStrategy from "../tradingbot/strategy/AvgMinMaxStrategy.js";
import PossiblePeakStrategy from "../tradingbot/strategy/PossiblePeakStrategy.js";
@ -27,7 +26,6 @@ export default class Serializables {
['AbstractWorker', AbstractWorker],
['StatisticWorker', StatisticWorker],
['DefaultWorker', DefaultWorker],
['AssetDataCollectionConfig', AssetDataCollectionConfig],
['AbstractStrategy', AbstractStrategy],
['TestStrategy', TestStrategy],
['Simple24hStrategy', Simple24hStrategy],

View File

@ -85,7 +85,7 @@ export default class RestClient {
const st = starttime != null ? starttime : -1;
const d = duration != null ? duration : 3600000;
const data = this.#dataProvider.getAssetData(asset).assetDataAggregator.getData(d, st);
const data = this.#dataProvider.getAssetData(asset).getAggregatedData(d, st);
const converter = new AggregatedDataPointConverter();
const result = [];