From 641f2315311bcc60be12181957fe1bae8ab7be77 Mon Sep 17 00:00:00 2001 From: Zahrun <10415894+Zahrun@users.noreply.github.com> Date: Sun, 11 Dec 2022 18:38:56 +0100 Subject: [PATCH 1/4] feat: support gate.io trades import --- src/parsers/trades/gate.io/index.ts | 94 +++++++++++++++++++++++++++++ src/parsers/trades/index.ts | 2 + src/types/locations.ts | 2 + 3 files changed, 98 insertions(+) create mode 100644 src/parsers/trades/gate.io/index.ts diff --git a/src/parsers/trades/gate.io/index.ts b/src/parsers/trades/gate.io/index.ts new file mode 100644 index 0000000..187d7d4 --- /dev/null +++ b/src/parsers/trades/gate.io/index.ts @@ -0,0 +1,94 @@ +import { getCSVData } from '../../'; +import { EXCHANGES, IImport, IPartialTrade, ITrade } from '../../../types'; +import { createDateAsUTC, createID } from '../../utils'; + +interface IGateIO { + No: string; + 'Account Type': string; + Time: string; + 'Action type': string; + Currency: string; + 'Order id': string; + 'Change amount': string; + Amount: string; + 'Additional Info': string; +} + +export default async function processData(importDetails: IImport): Promise { + const data: IGateIO[] = await getCSVData(importDetails.data) as IGateIO[]; + const internalFormat: ITrade[] = []; + if (data.length < 1) { + return internalFormat; + } + let feeTrade = data[0]; + let filledTrade = data[0]; + let pointTrade = data[0]; + let lineContinuity = 0; + for (const trade of data) { + const tradeToAdd: IPartialTrade = { + date : createDateAsUTC(new Date(trade.Time)).getTime(), + exchangeID : trade['Order id'], + exchange = EXCHANGES.GateIO, + }; + switch (trade['Action type']) { + case 'Trading Fees': { + lineContinuity = 1; + feeTrade = trade; + continue; + } + case 'Order Filled': { + if (lineContinuity++ !== 1) { + console.error('Error parsing Gate.io trade lineContinuity++ !== 1 lineContinuity=${lineContinuity}'); + lineContinuity = 0; + break; + } + filledTrade = trade; + continue; + } + case 'Order Placed': { + if (lineContinuity !== 2) { + console.error('Error parsing Gate.io trade lineContinuity !== 2 lineContinuity=${lineContinuity}'); + lineContinuity = 0; + break; + } + lineContinuity = 0; + tradeToAdd.boughtCurrency = filledTrade.Currency; + tradeToAdd.soldCurrency = trade.Currency; + tradeToAdd.amountSold = Math.abs(parseFloat(trade['Change amount'])); + tradeToAdd.rate = Math.abs(parseFloat(trade['Change amount']) / parseFloat(filledTrade['Change amount'])); + tradeToAdd.transactionFeeCurrency = feeTrade.Currency; + tradeToAdd.transactionFee = Math.abs(parseFloat(feeTrade['Change amount'])); + break; + } + case 'Points Purchase': { + switch (lineContinuity) { + case 0: { + pointTrade = trade; + lineContinuity = 1; + continue; + } + case 1: { + lineContinuity = 0; + tradeToAdd.boughtCurrency = pointTrade.Currency; + tradeToAdd.soldCurrency = trade.Currency; + tradeToAdd.amountSold = Math.abs(parseFloat(trade['Change amount'])); + tradeToAdd.rate = Math.abs(parseFloat(trade['Change amount']) / parseFloat(pointTrade['Change amount'])); + break; + } + default: { + console.error(`Error parsing Gate.io trade lineContinuity=${lineContinuity}`); + break; + } + } + break; + } + default: { + console.log(`Ignored Gate.io trade of type ${trade['Action type']}`); + continue; + } + } + tradeToAdd.ID = createID(tradeToAdd); + internalFormat.push(tradeToAdd as ITrade); + } + return internalFormat; +} diff --git a/src/parsers/trades/index.ts b/src/parsers/trades/index.ts index 30b720d..8bc6537 100644 --- a/src/parsers/trades/index.ts +++ b/src/parsers/trades/index.ts @@ -2,6 +2,7 @@ import { EXCHANGES, ExchangesTradeHeaders, IImport, ITrade } from '@types'; import * as crypto from 'crypto'; import binanceParser from './binance'; import bittrexParser from './bittrex'; +import gateIOParser from './gate.io'; import geminiParser from './gemini'; import krakenParser from './kraken'; import poloniexParser from './poloniex'; @@ -10,6 +11,7 @@ import revolutParser from './revolut'; const parserMapping: {[key in EXCHANGES]: any} = { [EXCHANGES.Binance]: binanceParser, [EXCHANGES.Bittrex]: bittrexParser, + [EXCHANGES.GateIO]: gateIOParser, [EXCHANGES.Gemini]: geminiParser, [EXCHANGES.Kraken]: krakenParser, [EXCHANGES.Poloniex]: poloniexParser, diff --git a/src/types/locations.ts b/src/types/locations.ts index c0053d4..c727be3 100644 --- a/src/types/locations.ts +++ b/src/types/locations.ts @@ -2,6 +2,7 @@ export type Location = EXCHANGES | string; export enum EXCHANGES { Bittrex = 'BITTREX', + GateIO = 'GATE_IO', Gemini= 'GEMINI', Poloniex = 'POLONIEX', Kraken = 'KRAKEN', @@ -15,6 +16,7 @@ export enum IncomeImportTypes { export enum ExchangesTradeHeaders { BITTREX = '07230399aaa8d1f15e88e38bd43a01c5ef1af6c1f9131668d346e196ff090d80', + GATE_IO = '99ff90ddaa0826df50d15296f504ca71e4b04dff45ae7798e7ba5f688fec9209', GEMINI = '996edee25db7f3d1dd16c83c164c6cff8c6d0f5d6b3aafe6d1700f2a830f6c9e', POLONIEX = 'd7484d726e014edaa059c0137ac91183a7eaa9ee5d52713aa48bb4104b01afb0', KRAKEN = '85bf27e799cc0a30fe5b201cd6a4724e4a52feb433f41a1e8b046924e3bf8dc5', From d408c9f87cb3a31079847adb72db871e4c5d29ac Mon Sep 17 00:00:00 2001 From: Zahrun <10415894+Zahrun@users.noreply.github.com> Date: Sat, 17 Dec 2022 13:46:02 +0100 Subject: [PATCH 2/4] feat: better support gate.io trades import --- src/parsers/trades/gate.io/index.ts | 93 ++++++++++++----------------- 1 file changed, 37 insertions(+), 56 deletions(-) diff --git a/src/parsers/trades/gate.io/index.ts b/src/parsers/trades/gate.io/index.ts index 187d7d4..039a117 100644 --- a/src/parsers/trades/gate.io/index.ts +++ b/src/parsers/trades/gate.io/index.ts @@ -14,76 +14,57 @@ interface IGateIO { 'Additional Info': string; } +interface IGateIOGroup { + [key: string]: IGateIO[]; +} + +function groupByOrderID(group: IGateIOGroup, line: IGateIO) { + group[line['Order id']] = group[line['Order id']] ?? []; + group[line['Order id']].push(line); + return group; +} + export default async function processData(importDetails: IImport): Promise { const data: IGateIO[] = await getCSVData(importDetails.data) as IGateIO[]; const internalFormat: ITrade[] = []; - if (data.length < 1) { - return internalFormat; - } - let feeTrade = data[0]; - let filledTrade = data[0]; - let pointTrade = data[0]; - let lineContinuity = 0; - for (const trade of data) { + const grouped = data.reduce(groupByOrderID, {}); + for (const order in grouped) { + const trades = grouped[order]; const tradeToAdd: IPartialTrade = { - date : createDateAsUTC(new Date(trade.Time)).getTime(), - exchangeID : trade['Order id'], - exchange = EXCHANGES.GateIO, + date : createDateAsUTC(new Date(trades[0].Time)).getTime(), + exchangeID : order, + exchange : EXCHANGES.GateIO, }; - switch (trade['Action type']) { + switch (trades[0]['Action type']) { case 'Trading Fees': { - lineContinuity = 1; - feeTrade = trade; - continue; - } - case 'Order Filled': { - if (lineContinuity++ !== 1) { - console.error('Error parsing Gate.io trade lineContinuity++ !== 1 lineContinuity=${lineContinuity}'); - lineContinuity = 0; - break; - } - filledTrade = trade; - continue; - } - case 'Order Placed': { - if (lineContinuity !== 2) { - console.error('Error parsing Gate.io trade lineContinuity !== 2 lineContinuity=${lineContinuity}'); - lineContinuity = 0; - break; + if (trades[1]['Action type'] !== 'Order Filled' || trades[2]['Action type'] !== 'Order Placed') { + console.error(`Error parsing ${tradeToAdd.exchange} trade + trades[1]['Action type'] = ${trades[1]['Action type']} + trades[2]['Action type'] = ${trades[2]['Action type']}`); } - lineContinuity = 0; - tradeToAdd.boughtCurrency = filledTrade.Currency; - tradeToAdd.soldCurrency = trade.Currency; - tradeToAdd.amountSold = Math.abs(parseFloat(trade['Change amount'])); - tradeToAdd.rate = Math.abs(parseFloat(trade['Change amount']) / parseFloat(filledTrade['Change amount'])); - tradeToAdd.transactionFeeCurrency = feeTrade.Currency; - tradeToAdd.transactionFee = Math.abs(parseFloat(feeTrade['Change amount'])); + tradeToAdd.boughtCurrency = trades[1].Currency; + tradeToAdd.soldCurrency = trades[2].Currency; + tradeToAdd.amountSold = Math.abs(parseFloat(trades[2]['Change amount'])); + tradeToAdd.rate = Math.abs(parseFloat(trades[2]['Change amount']) / parseFloat(trades[1]['Change amount'])); + tradeToAdd.transactionFeeCurrency = trades[0].Currency; + tradeToAdd.transactionFee = Math.abs(parseFloat(trades[0]['Change amount'])); break; } case 'Points Purchase': { - switch (lineContinuity) { - case 0: { - pointTrade = trade; - lineContinuity = 1; - continue; - } - case 1: { - lineContinuity = 0; - tradeToAdd.boughtCurrency = pointTrade.Currency; - tradeToAdd.soldCurrency = trade.Currency; - tradeToAdd.amountSold = Math.abs(parseFloat(trade['Change amount'])); - tradeToAdd.rate = Math.abs(parseFloat(trade['Change amount']) / parseFloat(pointTrade['Change amount'])); - break; - } - default: { - console.error(`Error parsing Gate.io trade lineContinuity=${lineContinuity}`); - break; - } + if (trades[1]['Action type'] !== 'Points Purchase') { + console.error(`Error parsing ${tradeToAdd.exchange} points purchase + trades[1]['Action type'] = ${trades[1]['Action type']}`); } + tradeToAdd.boughtCurrency = trades[0].Currency; + tradeToAdd.soldCurrency = trades[1].Currency; + tradeToAdd.amountSold = Math.abs(parseFloat(trades[1]['Change amount'])); + tradeToAdd.rate = Math.abs(parseFloat(trades[1]['Change amount']) / + parseFloat(trades[0]['Change amount'])); break; } + // TODO: Deposits, Airdrop, Withdrawals, Points With Expiration, Quant- Transferred In, Quant- Transferred Out default: { - console.log(`Ignored Gate.io trade of type ${trade['Action type']}`); + console.log(`Ignored Gate.io trade of type ${trades[0]['Action type']}`); continue; } } From 7d9ef95c343701fb051d021b0a412fdc7a08281d Mon Sep 17 00:00:00 2001 From: Zahrun <10415894+Zahrun@users.noreply.github.com> Date: Sat, 17 Dec 2022 13:53:05 +0100 Subject: [PATCH 3/4] feat: support gate.io trade fees --- components/TradesTable/index.tsx | 2 ++ src/parsers/trades/gate.io/index.ts | 4 ++-- src/types/trade.ts | 2 ++ 3 files changed, 6 insertions(+), 2 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/gate.io/index.ts b/src/parsers/trades/gate.io/index.ts index 039a117..884fbbf 100644 --- a/src/parsers/trades/gate.io/index.ts +++ b/src/parsers/trades/gate.io/index.ts @@ -46,8 +46,8 @@ export default async function processData(importDetails: IImport): Promise Date: Sat, 17 Dec 2022 14:34:36 +0100 Subject: [PATCH 4/4] feat: support gate.io different trades having the same 'Order id' --- src/parsers/trades/gate.io/index.ts | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/parsers/trades/gate.io/index.ts b/src/parsers/trades/gate.io/index.ts index 884fbbf..f9f5128 100644 --- a/src/parsers/trades/gate.io/index.ts +++ b/src/parsers/trades/gate.io/index.ts @@ -37,17 +37,22 @@ export default async function processData(importDetails: IImport): Promise