Skip to content
This repository has been archived by the owner on Aug 15, 2023. It is now read-only.

Commit

Permalink
feat: Add funding rate history (#91)
Browse files Browse the repository at this point in the history
* feat: add funding rate db objects and initial data
* chore: add support sql quesries
* chore: add funding rate repo
* chore: add funding rate handling
* test: add funding rate repo tests
* feat: add funding yields over few tenors
* fix: fix data insert in case table exists
* fix: including services folder to build
* fix: insertion of exchange id foreign key
Co-authored-by: Sebastien Verreault <[email protected]>
  • Loading branch information
sebastienverreault authored Apr 26, 2022
1 parent f765828 commit 76b93e6
Show file tree
Hide file tree
Showing 27 changed files with 4,244 additions and 8 deletions.
5 changes: 5 additions & 0 deletions dealer/migrations/20220408054021677_aggregate-mul-func.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- Up Migration
CREATE AGGREGATE mul(decimal) ( SFUNC = numeric_mul, STYPE=decimal );

-- Down Migration
DROP AGGREGATE IF EXISTS mul(decimal);
10 changes: 10 additions & 0 deletions dealer/migrations/20220408065022794_exchanges.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
-- Up Migration
CREATE TABLE "dealer"."exchanges" (
"id" serial PRIMARY KEY,
"exchange_name" varchar(64) NOT NULL UNIQUE,
"updated_timestamp" varchar(256) DEFAULT current_timestamp NOT NULL,
"created_timestamp" varchar(256) DEFAULT current_timestamp NOT NULL
);

-- Down Migration
DROP TABLE IF EXISTS "dealer"."exchanges" CASCADE;
16 changes: 16 additions & 0 deletions dealer/migrations/20220408065036915_init-exchanges.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
-- Up Migration
INSERT INTO "dealer"."exchanges"
("exchange_name")
VALUES
( 'bitmex' ),
( 'okex' ),
( 'deribit' ),
( 'kraken' ),
( 'ftx' ),
( 'bitfinex' ),
( 'binance' ),
( 'bybit' ),
( 'huobi' );

-- Down Migration
TRUNCATE TABLE "dealer"."exchanges";
23 changes: 23 additions & 0 deletions dealer/migrations/20220408065042990_funding-rates.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
-- Up Migration
CREATE TABLE "dealer"."funding_rates" (
"id" serial PRIMARY KEY,

"timestamp" timestamptz NOT NULL,
"funding_time" bigint NOT NULL,
"instrument_id" varchar(64) NOT NULL,
"exchange_id" integer NOT NULL,

"funding_rate" DECIMAL NOT NULL,

"updated_timestamp" timestamptz DEFAULT current_timestamp NOT NULL,
"created_timestamp" timestamptz DEFAULT current_timestamp NOT NULL,

CONSTRAINT fk_exchange_id FOREIGN KEY(exchange_id) REFERENCES dealer.exchanges(id)

);
CREATE INDEX "funding_rates_time_instrument_exchange_idx" ON "dealer"."funding_rates" ("funding_time", "instrument_id", "exchange_id");

-- Down Migration
DROP INDEX "dealer"."funding_rates_time_instrument_exchange_idx";
DROP TABLE IF EXISTS "dealer"."funding_rates" CASCADE;

3,123 changes: 3,123 additions & 0 deletions dealer/migrations/20220408065056920_init-funding-rates.sql

Large diffs are not rendered by default.

78 changes: 78 additions & 0 deletions dealer/src/Dealer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ import {
UpdatedPosition,
} from "./HedgingStrategyTypes"
import {
ExchangeNames,
FundingFeesMetrics,
FundingRate,
FundingYieldMetrics,
InFlightTransfer,
TradingFeesMetrics,
Transaction,
Expand All @@ -22,6 +25,7 @@ import { createHedgingStrategy } from "./HedgingStrategyFactory"
import {
FetchFundingAccountBalanceResult,
GetAccountAndPositionRiskResult,
GetFundingRateHistoryParameters,
GetTransactionHistoryParameters,
} from "./ExchangeTradingType"
import {
Expand Down Expand Up @@ -532,6 +536,48 @@ export class Dealer {
return result.value
}

public async getFundingYieldMetrics(): Promise<FundingYieldMetrics> {
const ret: FundingYieldMetrics = {
fundingYield1d: NaN,
fundingYield1W: NaN,
fundingYield2W: NaN,
fundingYield3W: NaN,
fundingYield1M: NaN,
fundingYield2M: NaN,
fundingYield3M: NaN,
fundingYield6M: NaN,
fundingYield1Y: NaN,
fundingYield2Y: NaN,
fundingYield3Y: NaN,
fundingYield5Y: NaN,
}
const tenors = [
{ tenor: "1d", numberOfDays: 1 },
{ tenor: "1W", numberOfDays: 7 },
{ tenor: "2W", numberOfDays: 2 * 7 },
{ tenor: "3W", numberOfDays: 3 * 7 },
{ tenor: "1M", numberOfDays: 30 },
{ tenor: "2M", numberOfDays: 2 * 30 },
{ tenor: "3M", numberOfDays: 3 * 30 },
{ tenor: "6M", numberOfDays: 6 * 30 },
{ tenor: "1Y", numberOfDays: 365 },
{ tenor: "2Y", numberOfDays: 2 * 365 },
{ tenor: "3Y", numberOfDays: 3 * 365 },
{ tenor: "5Y", numberOfDays: 5 * 365 },
]
for (const tenor of tenors) {
const result = await database.fundingRates.getFundingYield(
ExchangeNames.Okex,
tenor.numberOfDays,
)
if (!result.ok) {
return ret
}
ret[`fundingYield${tenor.tenor}`] = Number(result.value)
}
return ret
}

public async getFundingAccountBalance(): Promise<FetchFundingAccountBalanceResult> {
const result = await this.strategy.getFundingAccountBalance()
if (!result.ok) {
Expand Down Expand Up @@ -575,4 +621,36 @@ export class Dealer {
await database.transactions.insert(transaction)
}
}

private async fetchFundingRateHistory(
args: GetFundingRateHistoryParameters,
): Promise<FundingRate[]> {
const result = await this.strategy.fetchFundingRateHistory(args)
if (!result.ok) {
return []
}
return result.value
}

public async fetchAndLoadFundingRates() {
// get latest id we saved in db
let lastFundingTime
const result = await database.fundingRates.getLastFundingTime()
if (!result.ok) {
this.logger.error(
"Couldn't get last fundingTime from database, continuing with blank id...",
)
} else if (result.value) {
lastFundingTime = result.value
}

// fetch and insert fundingRates since last
const args: GetFundingRateHistoryParameters = {
beforeFundingTime: lastFundingTime,
}
const fundingRates = await this.fetchFundingRateHistory(args)
for (const fundingRate of fundingRates) {
await database.fundingRates.insert(fundingRate)
}
}
}
6 changes: 6 additions & 0 deletions dealer/src/ExchangeBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import {
GetTransactionHistoryParameters,
GetTransactionHistoryResult,
FetchFundingAccountBalanceResult,
GetFundingRateHistoryParameters,
GetFundingRateHistoryResult,
} from "./ExchangeTradingType"
import { ErrorLevel, Result } from "./Result"
import ccxt, { ExchangeId } from "ccxt"
Expand Down Expand Up @@ -709,4 +711,8 @@ export abstract class ExchangeBase {
abstract fetchTransactionHistory(
args: GetTransactionHistoryParameters,
): Promise<Result<GetTransactionHistoryResult>>

abstract fetchFundingRateHistory(
args: GetFundingRateHistoryParameters,
): Promise<Result<GetFundingRateHistoryResult>>
}
14 changes: 13 additions & 1 deletion dealer/src/ExchangeTradingType.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Params } from "ccxt"
import { Transaction } from "./database/models"
import { FundingRate, Transaction } from "./database/models"

export enum TradeCurrency {
BTC = "BTC",
Expand Down Expand Up @@ -102,6 +102,18 @@ export interface GetTransactionHistoryResult {
transactions: Transaction[]
}

export interface GetFundingRateHistoryParameters {
instrumentId?: string
afterFundingTime?: number
beforeFundingTime?: number
limit?: number
}

export interface GetFundingRateHistoryResult {
originalResponseAsIs
fundingRates: FundingRate[]
}

export interface DepositOnLightningParameters {
currency: TradeCurrency
amountInSats: number
Expand Down
7 changes: 6 additions & 1 deletion dealer/src/HedgingStrategyTypes.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Transaction } from "./database/models"
import { FundingRate, Transaction } from "./database/models"
import {
FetchFundingAccountBalanceResult,
FetchTickerResult,
GetAccountAndPositionRiskResult,
GetFundingRateHistoryParameters,
GetTransactionHistoryParameters,
} from "./ExchangeTradingType"
import { Result } from "./Result"
Expand Down Expand Up @@ -56,6 +57,10 @@ export interface HedgingStrategy {
args: GetTransactionHistoryParameters,
): Promise<Result<Transaction[]>>

fetchFundingRateHistory(
args: GetFundingRateHistoryParameters,
): Promise<Result<FundingRate[]>>

isDepositCompleted(address: string, amountInSats: number): Promise<Result<boolean>>
isWithdrawalCompleted(address: string, amountInSats: number): Promise<Result<boolean>>
updatePosition(
Expand Down
Loading

0 comments on commit 76b93e6

Please sign in to comment.