[BOT] Pool system eingeführt

This commit is contained in:
darkeye 2025-02-14 11:27:05 +01:00
parent 4ecba91489
commit edd68e31d0
7 changed files with 182 additions and 57 deletions

View File

@ -45,6 +45,11 @@ export default class TradingBot {
*/ */
#transactions = []; #transactions = [];
/**
* @type {Map<string, number>}
*/
#activeTransactionPerPoolCounter = new Map();
/** /**
* @type {Transaction[]} * @type {Transaction[]}
*/ */
@ -100,7 +105,7 @@ export default class TradingBot {
this.#logger = new Logger(this.#config.getLogDirectory()); this.#logger = new Logger(this.#config.getLogDirectory());
this.#dataCollector = new AssetDataCollector(this.#logger, this.#config); this.#dataCollector = new AssetDataCollector(this.#logger, this.#config);
this.#api = new BinanceApiClient(this.#config.getApiConfig(), this.#logger); this.#api = new BinanceApiClient(this.#config.getApiConfig(), this.#logger);
if(this.#config.isRestInterfaceEnabled()){ if (this.#config.isRestInterfaceEnabled()) {
this.#restInterfaceBinding = new TradingBotRestDataProvider(this); this.#restInterfaceBinding = new TradingBotRestDataProvider(this);
this.#restClient = new RestClient(this.#config.getRestInterfacePort()); this.#restClient = new RestClient(this.#config.getRestInterfacePort());
this.#restClient.start(this.#restInterfaceBinding); this.#restClient.start(this.#restInterfaceBinding);
@ -108,7 +113,7 @@ export default class TradingBot {
} }
start() { start() {
if(this.#isRunning){ if (this.#isRunning) {
this.#isTradingStarted = true; this.#isTradingStarted = true;
return; return;
} }
@ -119,16 +124,16 @@ export default class TradingBot {
this.#api.subscribeBalanceChanges(); this.#api.subscribeBalanceChanges();
this.#api.requestBalances(); this.#api.requestBalances();
this.#api.requestAccountInformation(); this.#api.requestAccountInformation();
this.#loadTransactions();
this.#loadWorker(); this.#loadWorker();
this.#loadTransactions();
this.#worker.forEach(worker => { this.#worker.forEach(worker => {
this.#registerTradingPair(worker.getTradingPair()); this.#registerTradingPair(worker.getTradingPair());
worker.init(this.#logger, this.#config.getDataDirectory(), this); worker.init(this.#logger, this.#config.getDataDirectory(), this);
}); });
this.#transactions.forEach(transaction => { this.#transactions.forEach(transaction => {
if(transaction.buySettings != null && (transaction.phase === TransactionPhase.INITIAL || transaction.phase === TransactionPhase.BUY_IN_PROGRESS)){ if (transaction.buySettings != null && (transaction.phase === TransactionPhase.INITIAL || transaction.phase === TransactionPhase.BUY_IN_PROGRESS)) {
this.#api.requestTransactionUpdate(transaction, 'buy'); this.#api.requestTransactionUpdate(transaction, 'buy');
} else if(transaction.sellSettings != null){ } else if (transaction.sellSettings != null) {
this.#api.requestTransactionUpdate(transaction, 'sell'); this.#api.requestTransactionUpdate(transaction, 'sell');
} }
}); });
@ -150,14 +155,14 @@ export default class TradingBot {
/** /**
* @returns {AbstractWorker[]} * @returns {AbstractWorker[]}
*/ */
getWorker(){ getWorker() {
return this.#worker; return this.#worker;
} }
/** /**
* @returns {boolean} * @returns {boolean}
*/ */
isTradingUp(){ isTradingUp() {
return this.#isTradingStarted; return this.#isTradingStarted;
} }
@ -187,14 +192,14 @@ export default class TradingBot {
/** /**
* @returns {Transaction[]} * @returns {Transaction[]}
*/ */
getTransactions(){ getTransactions() {
return this.#transactions; return this.#transactions;
} }
/** /**
* @returns {Transaction[]} * @returns {Transaction[]}
*/ */
getClosedTransactions(){ getClosedTransactions() {
return this.#transactionHistory; return this.#transactionHistory;
} }
@ -219,7 +224,7 @@ export default class TradingBot {
this.#worker.set(worker.getId(), worker); this.#worker.set(worker.getId(), worker);
this.#saveWorker(); this.#saveWorker();
if(this.#isRunning){ if (this.#isRunning) {
worker.init(this.#logger, this.#config.getDataDirectory()); worker.init(this.#logger, this.#config.getDataDirectory());
this.#registerTradingPair(worker.getTradingPair()); this.#registerTradingPair(worker.getTradingPair());
} }
@ -268,10 +273,10 @@ export default class TradingBot {
handleAssetUpdate(assetUpdateEvent) { handleAssetUpdate(assetUpdateEvent) {
this.#dataCollector.pushAssetEvent(assetUpdateEvent); this.#dataCollector.pushAssetEvent(assetUpdateEvent);
if(assetUpdateEvent.eventType == APIEventType.ORDER_BOOK_UPDATE if (assetUpdateEvent.eventType == APIEventType.ORDER_BOOK_UPDATE
&& (!this.#orderBookUpdateTime.has(assetUpdateEvent.tradingPair.getKey()) && (!this.#orderBookUpdateTime.has(assetUpdateEvent.tradingPair.getKey())
|| this.#orderBookUpdateTime.get(assetUpdateEvent.tradingPair.getKey()) < Date.now() - 120000) || this.#orderBookUpdateTime.get(assetUpdateEvent.tradingPair.getKey()) < Date.now() - 120000)
){ ) {
this.#api.requestOrderBook(assetUpdateEvent.tradingPair); this.#api.requestOrderBook(assetUpdateEvent.tradingPair);
this.#orderBookUpdateTime.set(assetUpdateEvent.tradingPair.getKey(), Date.now()); this.#orderBookUpdateTime.set(assetUpdateEvent.tradingPair.getKey(), Date.now());
} }
@ -317,12 +322,13 @@ export default class TradingBot {
if (TransactionPhase.BUY_DONE === nextTransactionPhase) { if (TransactionPhase.BUY_DONE === nextTransactionPhase) {
this.#calculateTradeValues(transaction.symbol, transaction.buySettings, event.fills); this.#calculateTradeValues(transaction.symbol, transaction.buySettings, event.fills);
} else if (TransactionPhase.isFinalPhase(nextTransactionPhase)) { } else if (TransactionPhase.isFinalPhase(nextTransactionPhase)) {
if(TransactionPhase.CANCELED != nextTransactionPhase) { if (TransactionPhase.CANCELED != nextTransactionPhase) {
this.#calculateTradeValues(transaction.symbol, transaction.sellSettings, event.fills); this.#calculateTradeValues(transaction.symbol, transaction.sellSettings, event.fills);
transaction.result = (transaction.sellSettings.quantity * transaction.sellSettings.price) - (transaction.buySettings.quantity * transaction.buySettings.price) transaction.result = (transaction.sellSettings.quantity * transaction.sellSettings.price) - (transaction.buySettings.quantity * transaction.buySettings.price)
} }
this.#transactionHistory.push(transaction); this.#transactionHistory.push(transaction);
this.#transactions.splice(index, 1); this.#transactions.splice(index, 1);
this.#updateTransactionsPerPoolCounter(this.#worker.get(transaction.initiator).getPool(), -1);
} }
transaction.phase = nextTransactionPhase; transaction.phase = nextTransactionPhase;
@ -348,9 +354,9 @@ export default class TradingBot {
priceSum += fill.price * fill.quantity; priceSum += fill.price * fill.quantity;
quantity += fill.quantity; quantity += fill.quantity;
if(fill.commissionAsset != null && fill.commissionAsset.toLowerCase() == tradingpair.getFirstCurrency().getSymbol().toLowerCase()){ if (fill.commissionAsset != null && fill.commissionAsset.toLowerCase() == tradingpair.getFirstCurrency().getSymbol().toLowerCase()) {
commissionAsset1 += fill.commission; commissionAsset1 += fill.commission;
} else if(fill.commissionAsset != null && fill.commissionAsset.toLowerCase() == tradingpair.getSecondCurrency().getSymbol().toLowerCase()){ } else if (fill.commissionAsset != null && fill.commissionAsset.toLowerCase() == tradingpair.getSecondCurrency().getSymbol().toLowerCase()) {
commissionAsset2 += fill.commission; commissionAsset2 += fill.commission;
} }
}); });
@ -376,8 +382,12 @@ export default class TradingBot {
* @param {number} quantity * @param {number} quantity
* @param {number} price * @param {number} price
*/ */
requestBuy(worker, quantity, price){ requestBuy(worker, quantity, price) {
if(this.#config.getUsdTradeLimit() / this.#config.getPerTradeLimit() <= this.#transactions.length){ console.log("Open transactions in pool '" + worker.getPool() + "': " + this.#activeTransactionPerPoolCounter.get(worker.getPool()));
if (
this.#activeTransactionPerPoolCounter.get(worker.getPool()) != null
&& this.#config.getUsdTradeLimit() / this.#config.getPerTradeLimit() <= this.#activeTransactionPerPoolCounter.get(worker.getPool())
) {
return; return;
} }
@ -385,6 +395,7 @@ export default class TradingBot {
transaction.buySettings = new TransactionSettings(price, this.#config.getPerTradeLimit() / price); transaction.buySettings = new TransactionSettings(price, this.#config.getPerTradeLimit() / price);
transaction.lockedForUpdate = true; transaction.lockedForUpdate = true;
this.#transactions.push(transaction); this.#transactions.push(transaction);
this.#updateTransactionsPerPoolCounter(worker.getPool(), 1);
this.#saveTransactions(); this.#saveTransactions();
this.#api.requestBuy(transaction); this.#api.requestBuy(transaction);
@ -395,8 +406,8 @@ export default class TradingBot {
* @param {Transaction} transaction * @param {Transaction} transaction
* @param {number} price * @param {number} price
*/ */
requestSell(worker, transaction, price){ requestSell(worker, transaction, price) {
if(transaction.lockedForUpdate){ if (transaction.lockedForUpdate) {
this.#logger.warn("Attempt to sell a locked transaction!", transaction.id); this.#logger.warn("Attempt to sell a locked transaction!", transaction.id);
return; return;
} }
@ -409,27 +420,42 @@ export default class TradingBot {
* @param {AbstractWorker} worker * @param {AbstractWorker} worker
* @param {Transaction} transaction * @param {Transaction} transaction
*/ */
requestCancle(worker, transaction){ requestCancle(worker, transaction) {
if(transaction.lockedForUpdate){ if (transaction.lockedForUpdate) {
this.#logger.warn("Attempt to cancel a locked transaction!", transaction.id); this.#logger.warn("Attempt to cancel a locked transaction!", transaction.id);
return; return;
} }
if(transaction.buySettings != null && transaction.phase == TransactionPhase.BUY_IN_PROGRESS){ if (transaction.buySettings != null && transaction.phase == TransactionPhase.BUY_IN_PROGRESS) {
transaction.lockedForUpdate = true; transaction.lockedForUpdate = true;
this.#api.requestBuyCancel(transaction); this.#api.requestBuyCancel(transaction);
} }
if(transaction.sellSettings != null && transaction.phase == TransactionPhase.SELL_IN_PROGRESS){ if (transaction.sellSettings != null && transaction.phase == TransactionPhase.SELL_IN_PROGRESS) {
transaction.lockedForUpdate = true; transaction.lockedForUpdate = true;
this.#api.requestSellCancel(transaction); this.#api.requestSellCancel(transaction);
} }
} }
/**
* @param {string} pool
* @param {number} changeValue
*/
#updateTransactionsPerPoolCounter(pool, changeValue) {
if (this.#activeTransactionPerPoolCounter.has(pool)) {
this.#activeTransactionPerPoolCounter.set(pool, Math.max(0, this.#activeTransactionPerPoolCounter.get(pool) + changeValue));
} else {
this.#activeTransactionPerPoolCounter.set(pool, Math.max(0, changeValue));
}
}
#loadTransactions() { #loadTransactions() {
try { try {
this.#transactions = SerializableHelper.load(this.#config.getDataDirectory(), 'transactions.sjson', Transaction); this.#transactions = SerializableHelper.load(this.#config.getDataDirectory(), 'transactions.sjson', Transaction);
this.#transactions = this.#transactions.filter(t => t.phase != TransactionPhase.INITIAL); this.#transactions = this.#transactions.filter(t => t.phase != TransactionPhase.INITIAL);
this.#transactions.forEach(t => t.lockedForUpdate = false); this.#transactions.forEach(t => {
t.lockedForUpdate = false;
this.#updateTransactionsPerPoolCounter(this.#worker.get(t.initiator).getPool(), 1);
});
} catch (e) { } catch (e) {
this.#logger.warn("Bot was unable to load any transactions. Assuming no active transactions existing!", e); this.#logger.warn("Bot was unable to load any transactions. Assuming no active transactions existing!", e);
} }

View File

@ -97,6 +97,16 @@ export default class AggregatedDataPoint {
*/ */
ema5min = 0; ema5min = 0;
/**
* @type {number}
*/
sma1h = 0;
/**
* @type {number}
*/
ema1h = 0;
/** /**
* @type {number[]} * @type {number[]}
*/ */

View File

@ -60,8 +60,10 @@ export default class AssetDataAggregator {
tmpSlot.ema5min = AssetInstrumentCalculator.calculateEMA(this.#perMinuteDataPoints.slice(-1 * Math.min(5, this.#perMinuteDataPoints.length))); tmpSlot.ema5min = AssetInstrumentCalculator.calculateEMA(this.#perMinuteDataPoints.slice(-1 * Math.min(5, this.#perMinuteDataPoints.length)));
tmpSlot.sma15min = AssetInstrumentCalculator.calculateSMA(this.#perMinuteDataPoints.slice(-1 * Math.min(15, this.#perMinuteDataPoints.length))); tmpSlot.sma15min = AssetInstrumentCalculator.calculateSMA(this.#perMinuteDataPoints.slice(-1 * Math.min(15, this.#perMinuteDataPoints.length)));
tmpSlot.ema15min = AssetInstrumentCalculator.calculateEMA(this.#perMinuteDataPoints.slice(-1 * Math.min(15, this.#perMinuteDataPoints.length))); tmpSlot.ema15min = AssetInstrumentCalculator.calculateEMA(this.#perMinuteDataPoints.slice(-1 * Math.min(15, this.#perMinuteDataPoints.length)));
tmpSlot.sma1h = AssetInstrumentCalculator.calculateSMA(this.#perMinuteDataPoints.slice(-1 * Math.min(60, this.#perMinuteDataPoints.length)));
tmpSlot.ema1h = AssetInstrumentCalculator.calculateEMA(this.#perMinuteDataPoints.slice(-1 * Math.min(60, this.#perMinuteDataPoints.length)));
} else { } else {
tmpSlot.sma5min = tmpSlot.ema5min = tmpSlot.sma15min = tmpSlot.ema15min = tmpSlot.avgPrice; tmpSlot.sma5min = tmpSlot.ema5min = tmpSlot.sma15min = tmpSlot.ema15min = tmpSlot.sma1h = tmpSlot.ema1h = tmpSlot.avgPrice;
} }
this.#lastOneMinUpdate = timestamp; this.#lastOneMinUpdate = timestamp;

View File

@ -19,6 +19,11 @@ export default class AbstractWorker extends Serializable {
*/ */
#name = ""; #name = "";
/**
* @type {string} pool name. All workes in same pool shares same balance
*/
#pool = "default";
/** /**
* @type {TradingPair} tradingpair * @type {TradingPair} tradingpair
*/ */
@ -44,7 +49,7 @@ export default class AbstractWorker extends Serializable {
* @param {TradingPair} tradingPair * @param {TradingPair} tradingPair
* @param {AbstractStrategy} strategy * @param {AbstractStrategy} strategy
*/ */
constructor(name, tradingPair, strategy){ constructor(name, tradingPair, strategy) {
super(); super();
this.#name = name; this.#name = name;
this.#tradingpair = tradingPair; this.#tradingpair = tradingPair;
@ -57,10 +62,10 @@ export default class AbstractWorker extends Serializable {
* @param {string} dataPath * @param {string} dataPath
* @param {WorkerTradingApiProvider} apiProvider * @param {WorkerTradingApiProvider} apiProvider
*/ */
init(logger, dataPath, apiProvider){ init(logger, dataPath, apiProvider) {
this.#logger = logger; this.#logger = logger;
this.#apiProvider = apiProvider; this.#apiProvider = apiProvider;
if(this.#strategy != null){ if (this.#strategy != null) {
this.#strategy.init(logger); this.#strategy.init(logger);
} }
this.onInit(dataPath); this.onInit(dataPath);
@ -69,70 +74,84 @@ export default class AbstractWorker extends Serializable {
/** /**
* @returns {string} * @returns {string}
*/ */
getName(){ getName() {
return this.#name; return this.#name;
} }
/** /**
* @param {string} name * @param {string} name
*/ */
setName(name){ setName(name) {
this.#name = name; this.#name = name;
} }
/** /**
* @returns {string} * @returns {string}
*/ */
getId(){ getPool() {
return this.#pool;
}
/**
* @param {string} pool
*/
setPool(pool) {
this.#pool = pool;
}
/**
* @returns {string}
*/
getId() {
return this.#id; return this.#id;
} }
/** /**
* @returns {TradingPair} * @returns {TradingPair}
*/ */
getTradingPair(){ getTradingPair() {
return this.#tradingpair; return this.#tradingpair;
} }
/** /**
* @param {TradingPair} tradingPair * @param {TradingPair} tradingPair
*/ */
setTradingPair(tradingPair){ setTradingPair(tradingPair) {
this.#tradingpair = tradingPair; this.#tradingpair = tradingPair;
} }
/** /**
* @returns {AbstractStrategy} * @returns {AbstractStrategy}
*/ */
getStrategy(){ getStrategy() {
return this.#strategy; return this.#strategy;
} }
/** /**
* @param {AbstractStrategy} strategy * @param {AbstractStrategy} strategy
*/ */
setStrategy(strategy){ setStrategy(strategy) {
this.#strategy = strategy; this.#strategy = strategy;
} }
/** /**
* @returns {Logger} * @returns {Logger}
*/ */
getLogger(){ getLogger() {
return this.#logger; return this.#logger;
} }
/** /**
* @returns {WorkerTradingApiProvider} * @returns {WorkerTradingApiProvider}
*/ */
getApiProvider(){ getApiProvider() {
return this.#apiProvider; return this.#apiProvider;
} }
/** /**
* @param {string} dataPath path to data directory * @param {string} dataPath path to data directory
*/ */
onInit(dataPath){ onInit(dataPath) {
// TODO implement in specific worker // TODO implement in specific worker
} }
@ -141,7 +160,7 @@ export default class AbstractWorker extends Serializable {
* @param {Transaction[]} transactions * @param {Transaction[]} transactions
* @param {number} transactionlimit * @param {number} transactionlimit
*/ */
onUpdate(assetData, transactions, transactionlimit){ onUpdate(assetData, transactions, transactionlimit) {
// TODO implement update // TODO implement update
} }
@ -152,12 +171,12 @@ export default class AbstractWorker extends Serializable {
* @returns {any} attribute value or null * @returns {any} attribute value or null
* @throws {Error} if the requested attribute is not supported by the worker instance * @throws {Error} if the requested attribute is not supported by the worker instance
*/ */
getAttribute(attributeName){ getAttribute(attributeName) {
// implement in worker // implement in worker
return {}; return {};
} }
#generateId(){ #generateId() {
return "W-" + this.#name + "-" + Date.now() + "-" + Math.floor(Math.random() * 8999999 + 1000000); return "W-" + this.#name + "-" + Date.now() + "-" + Math.floor(Math.random() * 8999999 + 1000000);
} }
@ -168,6 +187,7 @@ export default class AbstractWorker extends Serializable {
const obj = JSON.parse(super.toJson()); const obj = JSON.parse(super.toJson());
obj.id = this.#id; obj.id = this.#id;
obj.name = this.#name; obj.name = this.#name;
obj.pool = this.#pool;
obj.tradingPair = SerializableHelper.serialize(this.#tradingpair); obj.tradingPair = SerializableHelper.serialize(this.#tradingpair);
obj.strategy = SerializableHelper.serialize(this.#strategy); obj.strategy = SerializableHelper.serialize(this.#strategy);
@ -187,6 +207,9 @@ export default class AbstractWorker extends Serializable {
worker.#name = obj.name; worker.#name = obj.name;
worker.#tradingpair = SerializableHelper.deserialize(obj.tradingPair); worker.#tradingpair = SerializableHelper.deserialize(obj.tradingPair);
worker.#strategy = SerializableHelper.deserialize(obj.strategy); worker.#strategy = SerializableHelper.deserialize(obj.strategy);
if (obj.pool != null) {
worker.#pool = obj.pool;
}
return worker; return worker;
} }

View File

@ -5,6 +5,7 @@ import WebViewDataProvider from "./WebViewDataProvider.js";
import ConverterFactory from "./converter/ConverterFactory.js"; import ConverterFactory from "./converter/ConverterFactory.js";
import AggregatedDataPointConverter from "./converter/converters/AggregatedDataPointConverter.js"; import AggregatedDataPointConverter from "./converter/converters/AggregatedDataPointConverter.js";
import TransactionConverter from "./converter/converters/TransactionConverter.js"; import TransactionConverter from "./converter/converters/TransactionConverter.js";
import WorkerConverter from "./converter/converters/WorkerConverter.js";
export default class RestClient { export default class RestClient {
@ -78,31 +79,45 @@ export default class RestClient {
}); });
this.#service.get("/asset/:symbol/aggregated", (req, res, next) => { this.#service.get("/asset/:symbol/aggregated", (req, res, next) => {
res.json(this.#getAggregatedAssetData(req.params.symbol, req.query.startTime, req.query.duration)); res.json(this.#getAggregatedAssetData(req.params.symbol, req.query.startTime, req.query.duration, req.query.allowUnfilled));
}); });
this.#service.get("/asset/:symbol/balance", (req, res, next) => { this.#service.get("/asset/:symbol/balance", (req, res, next) => {
res.json(this.#getBalances(req.params.symbol)); res.json(this.#getBalances(req.params.symbol));
}); });
this.#service.get("/worker", (req, res, next) => {
res.json(this.#getWorker());
});
this.#service.get("/worker/:name/attribute/:attr", (req, res, next) => { this.#service.get("/worker/:name/attribute/:attr", (req, res, next) => {
res.json(this.#getWorkerAttribute(req.params.name, req.params.attr)); res.json(this.#getWorkerAttribute(req.params.name, req.params.attr));
}); });
/*this.#service.get("/transactions", (req, res, next) => {
res.json(this.#getAssetOrderBook(req.params.symbol));
});*/
} }
#registerSetters(){ #registerSetters(){
this.#service.get("/asset/:symbol/transaction/:transactionID/sell", (req, res, next) => {
// TODO sell transaction if status still same as before (query parameter: old status)
//res.json(this.#getTransactions(req.params.symbol, req.query.type));
});
this.#service.get("/asset/:symbol/transaction/:transactionID/cancel", (req, res, next) => {
// TODO cancle transaction if status still same as before (query parameter: old status)
//res.json(this.#getTransactions(req.params.symbol, req.query.type));
});
this.#service.get("/asset/:symbol/transaction/:transactionID/delete", (req, res, next) => {
// TODO sell transaction if status still same as before (query parameter: old status)
//res.json(this.#getTransactions(req.params.symbol, req.query.type));
});
} }
#getAggregatedAssetData(asset, starttime, duration){ #getAggregatedAssetData(asset, starttime, duration, allowUnfilled){
const st = starttime != null ? starttime : -1; const st = starttime != null ? starttime : -1;
const d = duration != null ? duration : 3600000; const d = duration != null ? duration : 3600000;
const allowUnfinished= allowUnfilled != null ? allowUnfilled == "true" : false;
const data = this.#dataProvider.getAssetData(asset).getAggregatedData(d, st); const data = this.#dataProvider.getAssetData(asset).getAggregatedData(d, st, allowUnfinished);
const converter = new AggregatedDataPointConverter(); const converter = new AggregatedDataPointConverter();
const result = []; const result = [];
@ -164,6 +179,16 @@ export default class RestClient {
return orderBooks; return orderBooks;
} }
#getWorker(){
const workerConverter = new WorkerConverter();
let result = [];
this.#dataProvider.getWorkers().forEach(w => {
result.push(workerConverter.toRestObject(w));
});
return result;
}
#getWorkerAttribute(name, attributeName){ #getWorkerAttribute(name, attributeName){
let result = null; let result = null;
this.#dataProvider.getWorkers().forEach(w => { this.#dataProvider.getWorkers().forEach(w => {

View File

@ -3,12 +3,14 @@ import OrderBookEntry from "../../apiwrapper/orderbook/OrderBookEntry.js";
import Transaction from "../../apiwrapper/transaction/Transaction.js"; import Transaction from "../../apiwrapper/transaction/Transaction.js";
import TransactionSettings from "../../apiwrapper/transaction/TransactionSettings.js"; import TransactionSettings from "../../apiwrapper/transaction/TransactionSettings.js";
import AggregatedDataPoint from "../../tradingbot/data/asset/AggregatedDataPoint.js"; import AggregatedDataPoint from "../../tradingbot/data/asset/AggregatedDataPoint.js";
import AbstractWorker from "../../tradingbot/worker/AbstractWorker.js";
import AbstractConverter from "./AbstractConverter.js"; import AbstractConverter from "./AbstractConverter.js";
import AggregatedDataPointConverter from "./converters/AggregatedDataPointConverter.js"; import AggregatedDataPointConverter from "./converters/AggregatedDataPointConverter.js";
import OrderBookConverter from "./converters/OrderBookConverter.js"; import OrderBookConverter from "./converters/OrderBookConverter.js";
import OrderBookEntryConverter from "./converters/OrderBookEntryConverter.js"; import OrderBookEntryConverter from "./converters/OrderBookEntryConverter.js";
import TransactionConverter from "./converters/TransactionConverter.js"; import TransactionConverter from "./converters/TransactionConverter.js";
import TransactionSettingsConverter from "./converters/TransactionSettingsConverter.js"; import TransactionSettingsConverter from "./converters/TransactionSettingsConverter.js";
import WorkerConverter from "./converters/WorkerConverter.js";
export default class ConverterFactory { export default class ConverterFactory {
static OBJECT_TYPE_ORDER_BOOK = 'order_book'; static OBJECT_TYPE_ORDER_BOOK = 'order_book';
@ -16,6 +18,7 @@ export default class ConverterFactory {
static OBJECT_TYPE_AGGREGATED_DATA_POINT = 'aggregated_data_point'; static OBJECT_TYPE_AGGREGATED_DATA_POINT = 'aggregated_data_point';
static OBJECT_TYPE_TRANSACTION = 'transaction'; static OBJECT_TYPE_TRANSACTION = 'transaction';
static OBJECT_TYPE_TRANSACTION_SETTINGS = 'transaction_settings'; static OBJECT_TYPE_TRANSACTION_SETTINGS = 'transaction_settings';
static OBJECT_TYPE_ABSTRACT_WORKER = 'abstract_worker';
/** /**
* @param {any} obj * @param {any} obj
@ -34,12 +37,14 @@ export default class ConverterFactory {
return new OrderBookConverter(); return new OrderBookConverter();
} else if (obj instanceof OrderBookEntry) { } else if (obj instanceof OrderBookEntry) {
return new OrderBookEntryConverter(); return new OrderBookEntryConverter();
} else if (obj instanceof AggregatedDataPoint){ } else if (obj instanceof AggregatedDataPoint) {
return new AggregatedDataPointConverter(); return new AggregatedDataPointConverter();
} else if (obj instanceof Transaction){ } else if (obj instanceof Transaction) {
return new TransactionConverter(); return new TransactionConverter();
} else if (obj instanceof TransactionSettings){ } else if (obj instanceof TransactionSettings) {
return new TransactionSettingsConverter(); return new TransactionSettingsConverter();
} else if (obj instanceof AbstractWorker) {
return new WorkerConverter();
} }
throw new Error("No converter defined for: " + JSON.stringify(obj)); throw new Error("No converter defined for: " + JSON.stringify(obj));
@ -61,6 +66,8 @@ export default class ConverterFactory {
return new TransactionConverter(); return new TransactionConverter();
case this.OBJECT_TYPE_TRANSACTION_SETTINGS: case this.OBJECT_TYPE_TRANSACTION_SETTINGS:
return new TransactionSettingsConverter(); return new TransactionSettingsConverter();
case this.OBJECT_TYPE_ABSTRACT_WORKER:
return new WorkerConverter();
default: default:
throw new Error("No converter defined for type: " + type); throw new Error("No converter defined for type: " + type);
} }

View File

@ -0,0 +1,32 @@
import AbstractWorker from "../../../tradingbot/worker/AbstractWorker.js";
import AbstractConverter from "../AbstractConverter.js";
import ConverterFactory from "../ConverterFactory.js";
export default class WorkerConverter extends AbstractConverter {
constructor(){
super();
}
/**
* @param {AbstractWorker} obj
* @returns {object}
*/
toRestObject(obj) {
return {
_objectType: ConverterFactory.OBJECT_TYPE_ABSTRACT_WORKER,
id: obj.getId(),
name: obj.getName(),
symbol: obj.getTradingPair().getKey(),
strategy: obj.getStrategy().constructor.name
};
}
/**
* @param {object} obj
* @returns {AbstractWorker}
*/
fromRestObject(obj) {
return null;
}
}