diff --git a/src/js/index.js b/src/js/index.js index 54075c7..532130c 100644 --- a/src/js/index.js +++ b/src/js/index.js @@ -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); diff --git a/src/js/tradingbot/config/BotConfig.js b/src/js/tradingbot/config/BotConfig.js index a05532a..d5fffb4 100644 --- a/src/js/tradingbot/config/BotConfig.js +++ b/src/js/tradingbot/config/BotConfig.js @@ -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; diff --git a/src/js/tradingbot/data/asset/AggregatedDataPoint.js b/src/js/tradingbot/data/asset/AggregatedDataPoint.js index d8ef8c0..c8d5aea 100644 --- a/src/js/tradingbot/data/asset/AggregatedDataPoint.js +++ b/src/js/tradingbot/data/asset/AggregatedDataPoint.js @@ -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 = []; } diff --git a/src/js/tradingbot/data/asset/AssetData.js b/src/js/tradingbot/data/asset/AssetData.js index 68e3a8c..2cec5be 100644 --- a/src/js/tradingbot/data/asset/AssetData.js +++ b/src/js/tradingbot/data/asset/AssetData.js @@ -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); + } } \ No newline at end of file diff --git a/src/js/tradingbot/data/asset/AssetDataCollectionConfig.js b/src/js/tradingbot/data/asset/AssetDataCollectionConfig.js deleted file mode 100644 index bc021b5..0000000 --- a/src/js/tradingbot/data/asset/AssetDataCollectionConfig.js +++ /dev/null @@ -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; - } -} \ No newline at end of file diff --git a/src/js/tradingbot/data/asset/AssetStatisticValue.js b/src/js/tradingbot/data/asset/AssetStatisticValue.js deleted file mode 100644 index 740a6a2..0000000 --- a/src/js/tradingbot/data/asset/AssetStatisticValue.js +++ /dev/null @@ -1,6 +0,0 @@ -export default class AssetStatisticValue{ - min1 = 0; - min15 = 0; - min30 = 0; - min60 = 0; -} \ No newline at end of file diff --git a/src/js/tradingbot/data/asset/TimedAssetData.js b/src/js/tradingbot/data/asset/TimedAssetData.js deleted file mode 100644 index 9b17caa..0000000 --- a/src/js/tradingbot/data/asset/TimedAssetData.js +++ /dev/null @@ -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; - } -} \ No newline at end of file diff --git a/src/js/tradingbot/data/asset/TimedAssetDataMerger.js b/src/js/tradingbot/data/asset/TimedAssetDataMerger.js deleted file mode 100644 index 1e6689f..0000000 --- a/src/js/tradingbot/data/asset/TimedAssetDataMerger.js +++ /dev/null @@ -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; - } -} \ No newline at end of file diff --git a/src/js/tradingbot/strategy/AvgMinMaxStrategy.js b/src/js/tradingbot/strategy/AvgMinMaxStrategy.js index 976446e..2c1461c 100644 --- a/src/js/tradingbot/strategy/AvgMinMaxStrategy.js +++ b/src/js/tradingbot/strategy/AvgMinMaxStrategy.js @@ -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(); } } \ No newline at end of file diff --git a/src/js/tradingbot/strategy/PossiblePeakStrategy.js b/src/js/tradingbot/strategy/PossiblePeakStrategy.js index 66ce48c..2bf4f4c 100644 --- a/src/js/tradingbot/strategy/PossiblePeakStrategy.js +++ b/src/js/tradingbot/strategy/PossiblePeakStrategy.js @@ -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; diff --git a/src/js/tradingbot/strategy/Simple24hStrategy.js b/src/js/tradingbot/strategy/Simple24hStrategy.js index ee0edde..720c733 100644 --- a/src/js/tradingbot/strategy/Simple24hStrategy.js +++ b/src/js/tradingbot/strategy/Simple24hStrategy.js @@ -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} diff --git a/src/js/tradingbot/strategy/TestStrategy.js b/src/js/tradingbot/strategy/TestStrategy.js index 00677ab..c56fb94 100644 --- a/src/js/tradingbot/strategy/TestStrategy.js +++ b/src/js/tradingbot/strategy/TestStrategy.js @@ -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()); } /** diff --git a/src/js/tradingbot/worker/StatisticWorker.js b/src/js/tradingbot/worker/StatisticWorker.js index cb6aef3..66c6652 100644 --- a/src/js/tradingbot/worker/StatisticWorker.js +++ b/src/js/tradingbot/worker/StatisticWorker.js @@ -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()); diff --git a/src/js/util/Serializables.js b/src/js/util/Serializables.js index cb92f80..dee60f3 100644 --- a/src/js/util/Serializables.js +++ b/src/js/util/Serializables.js @@ -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], diff --git a/src/js/webview/RestClient.js b/src/js/webview/RestClient.js index 45935c4..6018fd2 100644 --- a/src/js/webview/RestClient.js +++ b/src/js/webview/RestClient.js @@ -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 = [];