From 832d29dca8ef81d32916c291ea919d8f58312c9a Mon Sep 17 00:00:00 2001 From: Zahrun <10415894+Zahrun@users.noreply.github.com> Date: Sat, 10 Dec 2022 23:39:26 +0100 Subject: [PATCH 1/4] feat: import pionex trades --- src/parsers/trades/index.ts | 3 ++ src/parsers/trades/pionex/index.ts | 72 ++++++++++++++++++++++++++++++ src/types/locations.ts | 12 +++-- 3 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 src/parsers/trades/pionex/index.ts diff --git a/src/parsers/trades/index.ts b/src/parsers/trades/index.ts index 30b720d..da11c59 100644 --- a/src/parsers/trades/index.ts +++ b/src/parsers/trades/index.ts @@ -6,6 +6,7 @@ import geminiParser from './gemini'; import krakenParser from './kraken'; import poloniexParser from './poloniex'; import revolutParser from './revolut'; +import {pionexParser, pionexDustParser} from './pionex'; const parserMapping: {[key in EXCHANGES]: any} = { [EXCHANGES.Binance]: binanceParser, @@ -14,6 +15,8 @@ const parserMapping: {[key in EXCHANGES]: any} = { [EXCHANGES.Kraken]: krakenParser, [EXCHANGES.Poloniex]: poloniexParser, [EXCHANGES.Revolut]: revolutParser, + [EXCHANGES.Pionex]: pionexParser, + [EXCHANGES['Pionex dust collector']]: pionexDustParser, } export default async function processTradesImport(importDetails: IImport): Promise { diff --git a/src/parsers/trades/pionex/index.ts b/src/parsers/trades/pionex/index.ts new file mode 100644 index 0000000..b8b0a4c --- /dev/null +++ b/src/parsers/trades/pionex/index.ts @@ -0,0 +1,72 @@ +import { getCSVData } from '../../'; +import { EXCHANGES, IImport, IPartialTrade, ITrade } from '../../../types'; +import { createDateAsUTC, createID } from '../../utils'; + +interface IPionex { + 'date(UTC+0)': string; + amount: string; + price: string; + order_price: string; + side: string; + symbol: string; + state: string; + fee: string; + strategy_type: string; +} + +export async function pionexParser(importDetails: IImport): Promise { + const data: IPionex[] = await getCSVData(importDetails.data) as IPionex[]; + const internalFormat: ITrade[] = []; + for (const trade of data) { + const tradeToAdd: IPartialTrade = { + date: createDateAsUTC(new Date(trade['date(UTC+0)'])).getTime(), + exchange: EXCHANGES.Pionex, + }; + if (trade.side === 'BUY') { + const [boughtCurrency, soldCurrency] = trade.symbol.split('_'); + tradeToAdd.boughtCurrency = boughtCurrency; + tradeToAdd.soldCurrency = soldCurrency; + tradeToAdd.amountSold = parseFloat(trade.amount); + tradeToAdd.rate = parseFloat(trade.price); + } else if (trade.side === 'SELL') { + const [soldCurrency, boughtCurrency] = trade.symbol.split('_') + tradeToAdd.soldCurrency = soldCurrency; + tradeToAdd.boughtCurrency = boughtCurrency; + tradeToAdd.amountSold = parseFloat(trade.amount) / parseFloat(trade.price); + tradeToAdd.rate = 1 / parseFloat(trade.price); + } else { + console.error('Trade side unknown'); + continue; + } + tradeToAdd.ID = createID(tradeToAdd); + internalFormat.push(tradeToAdd as ITrade); + } + return internalFormat; +} + + +interface IPionexDust { + 'date(UTC+0)': string; + amount: string; + coin: string; + price: string; + swap_value: string; +} + +export async function pionexDustParser(importDetails: IImport): Promise { + const data: IPionexDust[] = await getCSVData(importDetails.data) as IPionexDust[]; + const internalFormat: ITrade[] = []; + for (const trade of data) { + const tradeToAdd: IPartialTrade = { + date : createDateAsUTC(new Date(trade['date(UTC+0)'])).getTime(), + exchange : EXCHANGES['Pionex dust collector'], + boughtCurrency : 'USDT', + soldCurrency : trade.coin, + amountSold : parseFloat(trade.amount), + rate : 1 / parseFloat(trade.price), + }; + tradeToAdd.ID = createID(tradeToAdd); + internalFormat.push(tradeToAdd as ITrade); + } + return internalFormat; +} diff --git a/src/types/locations.ts b/src/types/locations.ts index c0053d4..507addb 100644 --- a/src/types/locations.ts +++ b/src/types/locations.ts @@ -1,11 +1,13 @@ export type Location = EXCHANGES | string; export enum EXCHANGES { + Binance = 'BINANCE', Bittrex = 'BITTREX', Gemini= 'GEMINI', - Poloniex = 'POLONIEX', Kraken = 'KRAKEN', - Binance = 'BINANCE', + Pionex = 'PIONEX', + 'Pionex dust collector' = 'PIONEX_DUST', + Poloniex = 'POLONIEX', Revolut = 'REVOLUT', } @@ -14,10 +16,12 @@ export enum IncomeImportTypes { } export enum ExchangesTradeHeaders { + BINANCE = '4d0d5df894fe488872e513f6148dfa14ff29272e759b7fb3c86d264687a7cf99', BITTREX = '07230399aaa8d1f15e88e38bd43a01c5ef1af6c1f9131668d346e196ff090d80', GEMINI = '996edee25db7f3d1dd16c83c164c6cff8c6d0f5d6b3aafe6d1700f2a830f6c9e', - POLONIEX = 'd7484d726e014edaa059c0137ac91183a7eaa9ee5d52713aa48bb4104b01afb0', KRAKEN = '85bf27e799cc0a30fe5b201cd6a4724e4a52feb433f41a1e8b046924e3bf8dc5', - BINANCE = '4d0d5df894fe488872e513f6148dfa14ff29272e759b7fb3c86d264687a7cf99', + PIONEX = 'a09d295de934a0015f3c3abf40c87de620adcc4e41af8c684581a8f3c04952f1', + PIONEX_DUST = 'be6b0243d74515e9ed1c01488e37b1ea169caf7e00dbddc70c99ef3596e77509', + POLONIEX = 'd7484d726e014edaa059c0137ac91183a7eaa9ee5d52713aa48bb4104b01afb0', REVOLUT = 'ef10a780b82fdd31bb5b5f4f21eb7332c46b324513ab15418448f360f268e37c', } From 17e94934c0fb74e6a32424b899d0031dc7f7ff40 Mon Sep 17 00:00:00 2001 From: Zahrun <10415894+Zahrun@users.noreply.github.com> Date: Sat, 17 Dec 2022 23:20:26 +0100 Subject: [PATCH 2/4] fix: pionex trades and dust collector on same location + trades fees --- components/TradesTable/index.tsx | 2 ++ src/parsers/trades/index.ts | 5 ++--- src/parsers/trades/pionex/index.ts | 19 +++++++++++++++---- src/types/locations.ts | 5 ++--- src/types/trade.ts | 2 ++ 5 files changed, 23 insertions(+), 10 deletions(-) diff --git a/components/TradesTable/index.tsx b/components/TradesTable/index.tsx index c92de88..d244c28 100644 --- a/components/TradesTable/index.tsx +++ b/components/TradesTable/index.tsx @@ -55,6 +55,7 @@ export class TradesTable extends React.Component [ @@ -66,6 +67,7 @@ export class TradesTable extends React.Component{trade.boughtCurrency}, {(trade.amountSold / trade.rate).toFixed(8)}, {`${trade.transactionFee} ${trade.transactionFeeCurrency}`}, + {`${trade.tradeFee} ${trade.tradeFeeCurrency}`}, , ])} /> diff --git a/src/parsers/trades/index.ts b/src/parsers/trades/index.ts index da11c59..dbd0dd3 100644 --- a/src/parsers/trades/index.ts +++ b/src/parsers/trades/index.ts @@ -6,7 +6,7 @@ import geminiParser from './gemini'; import krakenParser from './kraken'; import poloniexParser from './poloniex'; import revolutParser from './revolut'; -import {pionexParser, pionexDustParser} from './pionex'; +import pionexParser from './pionex'; const parserMapping: {[key in EXCHANGES]: any} = { [EXCHANGES.Binance]: binanceParser, @@ -16,7 +16,6 @@ const parserMapping: {[key in EXCHANGES]: any} = { [EXCHANGES.Poloniex]: poloniexParser, [EXCHANGES.Revolut]: revolutParser, [EXCHANGES.Pionex]: pionexParser, - [EXCHANGES['Pionex dust collector']]: pionexDustParser, } export default async function processTradesImport(importDetails: IImport): Promise { @@ -27,7 +26,7 @@ export default async function processTradesImport(importDetails: IImport): Promi const headers = importDetails.data.substr(0, importDetails.data.indexOf('\n')); const headersHash = crypto.createHash('sha256').update(headers).digest('hex'); for (const key in ExchangesTradeHeaders) { - if (ExchangesTradeHeaders[key] === headersHash) { + if (ExchangesTradeHeaders[key].split(';').includes(headersHash)) { return processTradesImport({ ...importDetails, location: key, diff --git a/src/parsers/trades/pionex/index.ts b/src/parsers/trades/pionex/index.ts index b8b0a4c..0738785 100644 --- a/src/parsers/trades/pionex/index.ts +++ b/src/parsers/trades/pionex/index.ts @@ -2,6 +2,11 @@ import { getCSVData } from '../../'; import { EXCHANGES, IImport, IPartialTrade, ITrade } from '../../../types'; import { createDateAsUTC, createID } from '../../utils'; +enum PionexOrderSide { + SELL = 'SELL', + BUY = 'BUY', +} + interface IPionex { 'date(UTC+0)': string; amount: string; @@ -14,7 +19,11 @@ interface IPionex { strategy_type: string; } -export async function pionexParser(importDetails: IImport): Promise { +export default async function pionexParser(importDetails: IImport): Promise { + if (importDetails.data.split(',')[2] === '\"coin\"') { + console.log('Detected Pionex dust collector') + return pionexDustParser(importDetails); + } const data: IPionex[] = await getCSVData(importDetails.data) as IPionex[]; const internalFormat: ITrade[] = []; for (const trade of data) { @@ -22,13 +31,13 @@ export async function pionexParser(importDetails: IImport): Promise { date: createDateAsUTC(new Date(trade['date(UTC+0)'])).getTime(), exchange: EXCHANGES.Pionex, }; - if (trade.side === 'BUY') { + if (trade.side.toUpperCase() === PionexOrderSide.BUY) { const [boughtCurrency, soldCurrency] = trade.symbol.split('_'); tradeToAdd.boughtCurrency = boughtCurrency; tradeToAdd.soldCurrency = soldCurrency; tradeToAdd.amountSold = parseFloat(trade.amount); tradeToAdd.rate = parseFloat(trade.price); - } else if (trade.side === 'SELL') { + } else if (trade.side.toUpperCase() === PionexOrderSide.SELL) { const [soldCurrency, boughtCurrency] = trade.symbol.split('_') tradeToAdd.soldCurrency = soldCurrency; tradeToAdd.boughtCurrency = boughtCurrency; @@ -38,6 +47,8 @@ export async function pionexParser(importDetails: IImport): Promise { console.error('Trade side unknown'); continue; } + tradeToAdd.tradeFee = parseFloat(trade.fee); + tradeToAdd.tradeFeeCurrency = tradeToAdd.boughtCurrency; tradeToAdd.ID = createID(tradeToAdd); internalFormat.push(tradeToAdd as ITrade); } @@ -59,7 +70,7 @@ export async function pionexDustParser(importDetails: IImport): Promise Date: Sat, 17 Dec 2022 23:23:20 +0100 Subject: [PATCH 3/4] fix: pionex trades detected as dups --- src/parsers/trades/pionex/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/parsers/trades/pionex/index.ts b/src/parsers/trades/pionex/index.ts index 0738785..7fe3792 100644 --- a/src/parsers/trades/pionex/index.ts +++ b/src/parsers/trades/pionex/index.ts @@ -50,6 +50,7 @@ export default async function pionexParser(importDetails: IImport): Promise Date: Sun, 18 Dec 2022 23:24:51 +0100 Subject: [PATCH 4/4] fix: ignore canceled pionex trades --- src/parsers/trades/pionex/index.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/parsers/trades/pionex/index.ts b/src/parsers/trades/pionex/index.ts index 7fe3792..8eecf30 100644 --- a/src/parsers/trades/pionex/index.ts +++ b/src/parsers/trades/pionex/index.ts @@ -31,6 +31,10 @@ export default async function pionexParser(importDetails: IImport): Promise