Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PFT-1261] [PFT-1314] Add order calculation functions #68

Merged
merged 3 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@parifi/sdk",
"version": "1.0.5-prod",
"version": "1.0.6",
"description": "Parifi SDK with common utility functions",
"files": [
"dist",
Expand Down
2 changes: 1 addition & 1 deletion src/core/data-fabric/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,4 @@ export const getAccruedBorrowFeesInMarket = (position: Position, market: Market)
.times(accruedFeesCumulative)
.div(new Decimal(100).times(new Decimal(10).pow(18)))
.ceil();
};
};
29 changes: 29 additions & 0 deletions src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import {
} from './data-fabric';
import { Contract, Signer } from 'ethers';
import {
calculateCollateralFromSize,
calculatePositionLeverage,
calculateSizeFromCollateral,
canBeSettled,
canBeSettledPriceId,
checkIfOrderCanBeSettledId,
Expand Down Expand Up @@ -55,6 +57,7 @@ export class Core {
////////////////////////////////////////////////////////////////
////////////////////// DATA FABRIC ///////////////////////
////////////////////////////////////////////////////////////////

getMarketUtilization = (market: Market, isLong: boolean): Decimal => {
return getMarketUtilization(market, isLong);
};
Expand Down Expand Up @@ -85,6 +88,32 @@ export class Core {
////////////////////// ORDER MANAGER /////////////////////
////////////////////////////////////////////////////////////////

calculateSizeFromCollateral(
amount: Decimal,
leverage: Decimal,
executionFeeInCollateral: Decimal,
openingFee: Decimal,
normalizedMarketPrice: Decimal,
normalizedCollateralPrice: Decimal,
) {
return calculateSizeFromCollateral(
amount,
leverage,
executionFeeInCollateral,
openingFee,
normalizedMarketPrice,
normalizedCollateralPrice,
);
}
calculateCollateralFromSize(
collateralSize: Decimal,
leverage: Decimal,
normalizedMarketPrice: Decimal,
normalizedCollateralPrice: Decimal,
): Decimal {
return calculateCollateralFromSize(collateralSize, leverage, normalizedMarketPrice, normalizedCollateralPrice);
}

getOrderManagerInstance = (): Contract => {
return getOrderManagerInstance(this.rpcConfig.chainId);
};
Expand Down
47 changes: 47 additions & 0 deletions src/core/order-manager/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -522,3 +522,50 @@ export const getLiquidationPrice = (
return new Decimal(position.avgPrice ?? 0).add(lossPerToken);
}
};

/**
* @name calculateCollateralFromSize
* @description This function calculates the collateral required based on the given size, leverage and normalized market price and collateral price.
* @param {number} collateralSize - The size of the collateral in eth unit.
* @param {number} leverage - The degree of financial leverage being used.
* @param {Decimal} normalizedMarketPrice - The normalized market price of the underlying asset.
* @param {Decimal} normalizedCollateralPrice - The normalized price of the collateral.
* @returns {Decimal} - The calculated collateral required to maintain the position.
*/

export const calculateCollateralFromSize = (
collateralSize: Decimal,
leverage: Decimal,
normalizedMarketPrice: Decimal,
normalizedCollateralPrice: Decimal,
) => {
return normalizedMarketPrice.mul(collateralSize).div(normalizedCollateralPrice).div(leverage);
};

/**
* @name calculateSizeFromCollateral
* @description Calculates the position size in the base asset given the collateral amount, leverage, execution fee in collateral, opening fee, and normalised market price and collateral price.
* @param {Decimal} amount - The collateral amount in eth units.
* @param {Decimal} leverage - The total leverage used for this position.
* @param {Decimal} executionFeeInCollateral - The execution fee on collateral units.
* @param {Decimal} openingFee - The opening fee for the trade.
* @param {Decimal} normalizedMarketPrice - The normalised price of the base asset in terms of the quote asset.
* @param {Decimal} normalizedCollateralPrice - The normalised price of the collateral asset in terms of the quote asset.
* @returns {Decimal} - The calculated position size in the base asset.
*/

export const calculateSizeFromCollateral = (
amount: Decimal,
leverage: Decimal,
executionFeeInCollateral: Decimal,
openingFee: Decimal,
normalizedMarketPrice: Decimal,
normalizedCollateralPrice: Decimal,
) => {
const collateralInUsd = amount.mul(normalizedCollateralPrice);
const executionFeeInUsd = executionFeeInCollateral.mul(normalizedCollateralPrice);

const sizeInUsd = collateralInUsd.sub(executionFeeInUsd).div(openingFee.add(1).div(leverage));

return sizeInUsd.div(normalizedMarketPrice);
};
11 changes: 10 additions & 1 deletion src/subgraph/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import {
getTopAccountsByReferralRewards,
} from './accounts';
import { LeaderboardUserData, ReferralRewardsInUsd, UserPortfolioData } from '../interfaces/sdkTypes';
import { getExecutionFee } from './protocol';

export * from './common';
export * from './markets';
Expand Down Expand Up @@ -168,7 +169,7 @@ export class Subgraph {
}

// @todo Add function to get multiple positions in a single call

public async getPositionById(positionId: string): Promise<Position> {
const subgraphEndpoint = this.getSubgraphEndpoint(this.rpcConfig.chainId);
return getPositionById(subgraphEndpoint, positionId);
Expand Down Expand Up @@ -288,4 +289,12 @@ export class Subgraph {
const subgraphEndpoint = this.getSubgraphEndpoint(this.rpcConfig.chainId);
return await getPoolVolume24h(subgraphEndpoint);
}

////////////////////////////////////////////////////////////////
///////////////////// PROTOCOL ///////////////////////////
////////////////////////////////////////////////////////////////
public async getExecutionFee(): Promise<{ executionFeeEth: Decimal; executionFeeUsdc: Decimal }> {
const subgraphEndpoint = this.getSubgraphEndpoint(this.rpcConfig.chainId);
return getExecutionFee(subgraphEndpoint);
}
}
28 changes: 28 additions & 0 deletions src/subgraph/protocol/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import request from 'graphql-request';
import { fetchExecutionFee } from './subgraphQueries';
import Decimal from 'decimal.js';
import { DECIMAL_ZERO } from '../../common';

export const getExecutionFee = async (
subgraphEndpoint: string,
): Promise<{ executionFeeEth: Decimal; executionFeeUsdc: Decimal }> => {
interface SubgraphResponseInterface {
protocolData: {
executionFeeEth: string;
executionFeeUsdc: string;
};
}

try {
let subgraphResponse: SubgraphResponseInterface = await request(subgraphEndpoint, fetchExecutionFee());

const executionFeeEth = new Decimal(subgraphResponse.protocolData.executionFeeEth);
const executionFeeUsdc = new Decimal(subgraphResponse.protocolData.executionFeeUsdc);

return { executionFeeEth, executionFeeUsdc };
} catch (error) {
// Return execution fee as zero in case of an error
console.log(error);
return { executionFeeEth: DECIMAL_ZERO, executionFeeUsdc: DECIMAL_ZERO };
}
};
11 changes: 11 additions & 0 deletions src/subgraph/protocol/subgraphQueries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { gql } from 'graphql-request';

// Fetch execution fee for protocol from subgraph
export const fetchExecutionFee = () => gql`
{
protocolData(id: "1") {
executionFeeEth
executionFeeUsdc
}
}
`;
11 changes: 11 additions & 0 deletions test/subgraph-tests/protocol.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { getParifiSdkInstanceForTesting } from '..';
import { TEST_MARKET_ID1 } from '../common/constants';

describe('Protocol data', () => {
it('should return correct execution fee', async () => {
const parifiSdk = await getParifiSdkInstanceForTesting();

const res = await parifiSdk.subgraph.getExecutionFee();
console.log(res);
});
});
Loading