diff --git a/source/includes/_data_api.md b/source/includes/_data_api.md index 3f8493d..8f118a3 100644 --- a/source/includes/_data_api.md +++ b/source/includes/_data_api.md @@ -21,12 +21,97 @@ Example: [https://data.api.drift.trade/contracts](https://data.api.drift.trade/c Returns the last 30 days of funding rates by marketName or marketIndex. +```python +import requests + +def get_funding_rates(market_symbol='SOL-PERP'): + url = f'https://data.api.drift.trade/fundingRates' + params = {'marketName': market_symbol} + + response = requests.get(url, params=params) + return response.json()['fundingRates'] + +# Example usage, print the funding rates for SOL-PERP +market_symbol = 'SOL-PERP' +rates = get_funding_rates(market_symbol) + +print(f"Funding Rates for {market_symbol}:") +for rate in rates: + funding_rate = float(rate['fundingRate']) / 1e9 + # ... any logic here, for example... + print(f"Slot: {rate['slot']}, Funding Rate: {funding_rate:.9f}") + +``` +```typescript +interface FundingRate { + slot: number; + fundingRate: string; + // Other fields... (view the response section for the full list) +} + +async function getFundingRates(marketSymbol: string = 'SOL-PERP'): Promise { + const url = `https://data.api.drift.trade/fundingRates?marketName=${marketSymbol}`; + + try { + const response = await fetch(url); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const data = await response.json(); + return data.fundingRates; + } catch (error) { + console.error('Error fetching funding rates:', error); + return []; + } +} + +async function main() { + const marketSymbol = 'SOL-PERP'; + const rates = await getFundingRates(marketSymbol); + + console.log(`Funding Rates for ${marketSymbol}:`); + rates.forEach(rate => { + const fundingRate = parseFloat(rate.fundingRate) / 1e9; + // ... any logic here, for example... + console.log(`Slot: ${rate.slot}, Funding Rate: ${fundingRate.toFixed(9)}`); + }); +} + +main().catch(error => console.error('An error occurred:', error)); +``` + + + + | Parameter | Description | Optional | Values | | ---------------- | ------------------------------------------------ | -------- | --------------------------------------------------- | | marketName or marketIndex | The market name or index for the perp market | NO | | Example: [https://data.api.drift.trade/fundingRates?marketName=SOL-PERP](https://data.api.drift.trade/fundingRates?marketName=SOL-PERP) +### Response +The response is a json object with a `fundingRates` array. Each funding rate entry contains the following fields: + +| Field | Type | Description | +|-------|------|-------------| +| `txSig` | string | Transaction signature | +| `slot` | integer | Slot number | +| `ts` | string | Timestamp | +| `recordId` | string | Record identifier | +| `marketIndex` | integer | Market index | +| `fundingRate` | string | Funding rate (divide by 1e9 for actual rate) | +| `cumulativeFundingRateLong` | string | Cumulative funding rate for long positions | +| `cumulativeFundingRateShort` | string | Cumulative funding rate for short positions | +| `oraclePriceTwap` | string | Oracle price time-weighted average price | +| `markPriceTwap` | string | Mark price time-weighted average price | +| `fundingRateLong` | string | Funding rate for long positions | +| `fundingRateShort` | string | Funding rate for short positions | +| `periodRevenue` | string | Revenue for the period | +| `baseAssetAmountWithAmm` | string | Base asset amount with AMM | +| `baseAssetAmountWithUnsettledLp` | string | Base asset amount with unsettled LP | + ## `GET /DRIFT/` diff --git a/source/includes/_historicaldata.md b/source/includes/_historicaldata.md index 6857e64..0682e18 100644 --- a/source/includes/_historicaldata.md +++ b/source/includes/_historicaldata.md @@ -40,13 +40,217 @@ mainnet-beta: `https://drift-historical-data-v2.s3.eu-west-1.amazonaws.com/prog | candleResolution | | 1M | -## Examples -Get historical trades on `SOL-PERP` for August 5, 2023: +## Example: Trades for market +```python +import requests + + +URL_PREFIX = 'https://drift-historical-data-v2.s3.eu-west-1.amazonaws.com/program/dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH' + +market_symbol = 'SOL-PERP' +year = '2024' +month = '01' +day = '01' + +# Method 1: using pandas (this is the easiest and fastest way) +import pandas as pd +df = pd.read_csv(f'{URL_PREFIX}/market/{market_symbol}/tradeRecords/{year}/{year}{month}{day}') +print(df) + +# Method 2: using csv reader +import csv +from io import StringIO + +response = requests.get(f'{URL_PREFIX}/market/{market_symbol}/tradeRecords/{year}/{year}{month}{day}') +response.raise_for_status() + +csv_data = StringIO(response.text) +reader = csv.reader(csv_data) +for row in reader: + print(row) + +``` + +```typescript +import { parse } from 'csv-parse/sync'; + +const URL_PREFIX = 'https://drift-historical-data-v2.s3.eu-west-1.amazonaws.com/program/dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH'; + +async function fetchAndParseCSV(marketSymbol: string, year: string, month: string, day: string): Promise { + const url = `${URL_PREFIX}/market/${marketSymbol}/tradeRecords/${year}/${year}${month}${day}`; + + try { + const response = await fetch(url); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const csvText = await response.text(); + const records = parse(csvText, { + skip_empty_lines: true + }); + + records.forEach((row: string[]) => { + console.log(row); + }); + } catch (error) { + console.error('Error fetching or parsing CSV:', error); + } +} + +async function main() { + const marketSymbol = 'SOL-PERP'; + const year = '2024'; + const month = '01'; + const day = '01'; + + await fetchAndParseCSV(marketSymbol, year, month, day); +} + +main().catch(error => console.error('An error occurred:', error)); +``` + +Get historical trades on `SOL-PERP` for a given date (ex. 2024-01-01): ``` https://drift-historical-data-v2.s3.eu-west-1.amazonaws.com/program/dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH/market/SOL-PERP/tradeRecords/2024/20240101 ``` + +## Example: Trades for date range +```python +import requests +import csv +from io import StringIO +from datetime import date, timedelta +import pandas as pd + +URL_PREFIX = 'https://drift-historical-data-v2.s3.eu-west-1.amazonaws.com/program/dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH' + +# Method 1: using pandas +def get_trades_for_range_pandas(account_key, start_date, end_date): + all_trades = [] + current_date = start_date + while current_date <= end_date: + year = current_date.year + month = current_date.month + day = current_date.day + url = f"{URL_PREFIX}/user/{account_key}/tradeRecords/{year}/{year}{month:02}{day:02}" + + try: + df = pd.read_csv(url) + all_trades.append(df) + except requests.exceptions.RequestException as e: + print(f"Error fetching data for {current_date}: {e}") + except pd.errors.EmptyDataError: + print(f"No data available for {current_date}") + + current_date += timedelta(days=1) + + if all_trades: + return pd.concat(all_trades, ignore_index=True) + else: + return pd.DataFrame() + +# Method 2: using csv reader +def get_trades_for_range_csv(account_key, start_date, end_date): + all_trades = [] + current_date = start_date + while current_date <= end_date: + year = current_date.year + month = current_date.month + day = current_date.day + url = f"{URL_PREFIX}/user/{account_key}/tradeRecords/{year}/{year}{month:02}{day:02}" + response = requests.get(url) + response.raise_for_status() + + csv_data = StringIO(response.text) + reader = csv.reader(csv_data) + for row in reader: + all_trades.append(row) + + current_date += timedelta(days=1) + + return all_trades + + +# Example usage +account_key = "" +start_date = date(2024, 1, 24) +end_date = date(2024, 1, 26) + +trades = get_trades_for_range(account_key, start_date, end_date) +``` + +```typescript +import { parse } from 'csv-parse/sync'; + +const URL_PREFIX = 'https://drift-historical-data-v2.s3.eu-west-1.amazonaws.com/program/dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH'; + +interface Trade { + // Define the structure of a trade record here + // For example: + // date: string; + // amount: number; + // price: number; + [key: string]: any; +} + +async function getTradesForRange(accountKey: string, startDate: Date, endDate: Date): Promise { + const allTrades: Trade[] = []; + let currentDate = new Date(startDate); + + while (currentDate <= endDate) { + const year = currentDate.getFullYear(); + const month = (currentDate.getMonth() + 1).toString().padStart(2, '0'); + const day = currentDate.getDate().toString().padStart(2, '0'); + + const url = `${URL_PREFIX}/user/${accountKey}/tradeRecords/${year}/${year}${month}${day}`; + + try { + const response = await fetch(url); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const csvText = await response.text(); + const records = parse(csvText, { + skip_empty_lines: true, + columns: true + }); + + allTrades.push(...records); + } catch (error) { + console.error(`Error fetching or parsing CSV for ${year}-${month}-${day}:`, error); + } + + currentDate.setDate(currentDate.getDate() + 1); + } + + return allTrades; +} + +async function main() { + const accountKey = ""; + const startDate = new Date(2024, 0, 24); // Note: month is 0-indexed in JavaScript + const endDate = new Date(2024, 0, 26); + + try { + const trades = await getTradesForRange(accountKey, startDate, endDate); + console.log(`Total trades fetched: ${trades.length}`); + console.log('First few trades:', trades.slice(0, 5)); + } catch (error) { + console.error('An error occurred:', error); + } +} + +main(); +``` + +> Note: To speed this up, you could download the data in parallel (Promise.all or asyncio). + +We can write a script to download all the data, one by one, for a given account in a given date range. + ## Records Columns Below are definitions of the columns in each record type.