From cc3bdccd9a22df3a07e59b4c046dd3cb4d8a9fb9 Mon Sep 17 00:00:00 2001 From: Sirttas Date: Sat, 13 Jun 2026 12:31:01 +0200 Subject: [PATCH] call mammon for single scan --- docs/mammon-api.yml | 354 ++++++++++++++++++++++++++++------ src/generated/mammon/api.ts | 180 ++++++++++++----- src/market/scan/scan.ts | 29 +-- src/pages/market/TypeInfo.vue | 18 +- 4 files changed, 453 insertions(+), 128 deletions(-) diff --git a/docs/mammon-api.yml b/docs/mammon-api.yml index dc7f8a8..1966de8 100644 --- a/docs/mammon-api.yml +++ b/docs/mammon-api.yml @@ -19,7 +19,7 @@ paths: required: true schema: type: string - format: uuid + default: "" responses: "200": description: The rule book @@ -29,6 +29,13 @@ paths: $ref: "#/components/schemas/RuleBookResponse" "404": description: No rule book with this id + content: + '*/*': + schema: + type: string + additionalProperties: + default: "" + default: "" put: tags: - rule-book @@ -41,7 +48,7 @@ paths: required: true schema: type: string - format: uuid + default: "" requestBody: description: New state of the rule book content: @@ -61,6 +68,13 @@ paths: Returned when: - the request is invalid (e.g. blank name) - the rule book is the default rule book, which cannot be modified + content: + '*/*': + schema: + type: string + additionalProperties: + default: "" + default: "" delete: tags: - rule-book @@ -73,15 +87,29 @@ paths: required: true schema: type: string - format: uuid + default: "" responses: "204": description: The rule book was deleted + content: + '*/*': + schema: + type: string + additionalProperties: + default: "" + default: "" "400": description: |- Returned when: - the rule book is associated to a character - the rule book is the default rule book, which cannot be deleted + content: + '*/*': + schema: + type: string + additionalProperties: + default: "" + default: "" /ledgers/main/{ledgerId}: put: tags: @@ -95,7 +123,7 @@ paths: required: true schema: type: string - format: uuid + default: "" requestBody: description: New state of the main ledger content: @@ -115,8 +143,22 @@ paths: Returned when: - the ledger is not a main ledger - the request is invalid + content: + '*/*': + schema: + type: string + additionalProperties: + default: "" + default: "" "404": description: No ledger with this id + content: + '*/*': + schema: + type: string + additionalProperties: + default: "" + default: "" /ledgers/combined/{ledgerId}: put: tags: @@ -130,7 +172,7 @@ paths: required: true schema: type: string - format: uuid + default: "" requestBody: description: New state of the combined ledger content: @@ -150,8 +192,22 @@ paths: Returned when: - the ledger is not a combined ledger - the request is invalid + content: + '*/*': + schema: + type: string + additionalProperties: + default: "" + default: "" "404": description: No ledger with this id + content: + '*/*': + schema: + type: string + additionalProperties: + default: "" + default: "" /characters/{characterId}/rule-book: get: tags: @@ -164,8 +220,8 @@ paths: description: Id of the character required: true schema: - type: integer - format: int64 + type: string + default: "" responses: "200": description: The rule book assignment of the character @@ -175,8 +231,22 @@ paths: $ref: "#/components/schemas/CharacterRuleBookResponse" "400": description: Invalid character id + content: + '*/*': + schema: + type: string + additionalProperties: + default: "" + default: "" "404": description: No rule book assigned to this character + content: + '*/*': + schema: + type: string + additionalProperties: + default: "" + default: "" put: tags: - character-rule-book @@ -188,8 +258,8 @@ paths: description: Id of the character required: true schema: - type: integer - format: int64 + type: string + default: "" requestBody: description: Rule book and ledger bindings to assign content: @@ -211,6 +281,13 @@ paths: - a bound ledger does not exist - a bound ledger is not a main or system ledger - a required ledger binding is missing + content: + '*/*': + schema: + type: string + additionalProperties: + default: "" + default: "" /rule-books: get: tags: @@ -246,14 +323,26 @@ paths: description: URL of the created rule book style: simple schema: - type: string - format: uri + type: array + contains: + default: "" + items: + default: "" + unevaluatedItems: + default: "" content: '*/*': schema: $ref: "#/components/schemas/RuleBookResponse" "400": description: Invalid request (e.g. blank name) + content: + '*/*': + schema: + type: string + additionalProperties: + default: "" + default: "" /process-activities: post: tags: @@ -284,14 +373,26 @@ paths: description: URL of the created main ledger style: simple schema: - type: string - format: uri + type: array + contains: + default: "" + items: + default: "" + unevaluatedItems: + default: "" content: '*/*': schema: $ref: "#/components/schemas/MainLedgerResponse" "400": description: Invalid request (e.g. blank name) + content: + '*/*': + schema: + type: string + additionalProperties: + default: "" + default: "" /ledgers/combined: post: tags: @@ -313,8 +414,13 @@ paths: description: URL of the created combined ledger style: simple schema: - type: string - format: uri + type: array + contains: + default: "" + items: + default: "" + unevaluatedItems: + default: "" content: '*/*': schema: @@ -322,6 +428,13 @@ paths: "400": description: "Invalid request (e.g. blank name, a member ledger missing\ \ or already contained)" + content: + '*/*': + schema: + type: string + additionalProperties: + default: "" + default: "" /activity/fetch: post: tags: @@ -343,13 +456,20 @@ paths: description: Id of the character required: true schema: - type: integer - format: int64 + type: string + default: "" responses: "200": description: New activities fetched and stored "400": description: No character with this id + content: + '*/*': + schema: + type: string + additionalProperties: + default: "" + default: "" /rule-books/script-definitions: get: tags: @@ -363,6 +483,65 @@ paths: text/plain: schema: type: string + /market/{marketTypeId}/scan: + get: + tags: + - market + summary: "Scan a single market type, returning its volume-weighted price quartiles" + operationId: scanMarketType + parameters: + - name: marketTypeId + in: path + description: The market type id to scan + required: true + schema: + type: string + default: "" + - name: days + in: query + description: Number of most recent days of history to analyse + required: false + schema: + type: integer + format: int32 + default: 365 + minimum: 1 + - name: brokerFee + in: query + description: "Broker fee as a fraction (e.g. 0.015 for 1.5%), paid on both\ + \ buy and sell orders" + required: false + schema: + type: number + default: 0.015 + maximum: 1 + minimum: 0 + - name: salesTax + in: query + description: "Sales tax as a fraction (e.g. 0.036 for 3.6%), paid on sell\ + \ orders" + required: false + schema: + type: number + default: 0.036 + maximum: 1 + minimum: 0 + responses: + "200": + description: The scan result for the requested market type + content: + '*/*': + schema: + $ref: "#/components/schemas/MarketScanResponse" + "400": + description: The days parameter is not greater than 0 + content: + '*/*': + schema: + type: string + additionalProperties: + default: "" + default: "" /market/{marketTypeId}/history: get: tags: @@ -375,8 +554,8 @@ paths: description: Id of the market type required: true schema: - type: integer - format: int64 + type: string + default: "" - name: days in: query description: Optional number of most recent days to return; omit for the full @@ -385,6 +564,7 @@ paths: schema: type: integer format: int32 + default: "" minimum: 1 responses: "200": @@ -397,6 +577,13 @@ paths: $ref: "#/components/schemas/MarketHistoryResponse" "400": description: The days parameter is not greater than 0 + content: + '*/*': + schema: + type: string + additionalProperties: + default: "" + default: "" /market/scan: get: tags: @@ -445,6 +632,13 @@ paths: $ref: "#/components/schemas/MarketScanResponse" "400": description: The days parameter is not greater than 0 + content: + '*/*': + schema: + type: string + additionalProperties: + default: "" + default: "" /market/prices: get: tags: @@ -458,10 +652,8 @@ paths: description: "Market type ids to price, e.g. types=34,35" required: true schema: - type: array - items: - type: integer - format: int64 + type: string + default: "" responses: "200": description: "The order book for each requested type, one entry per type" @@ -476,6 +668,13 @@ paths: Returned when: - the types parameter is missing - a types value is not a numeric id + content: + '*/*': + schema: + type: string + additionalProperties: + default: "" + default: "" /ledgers: get: tags: @@ -504,7 +703,7 @@ paths: required: true schema: type: string - format: uuid + default: "" responses: "200": description: The ledger @@ -514,8 +713,22 @@ paths: $ref: "#/components/schemas/LedgerResponse" "400": description: The ledger cannot be exposed (system ledger) + content: + '*/*': + schema: + type: string + additionalProperties: + default: "" + default: "" "404": description: No ledger with this id + content: + '*/*': + schema: + type: string + additionalProperties: + default: "" + default: "" /ledgers/{ledgerId}/transactions: get: tags: @@ -529,7 +742,7 @@ paths: required: true schema: type: string - format: uuid + default: "" responses: "200": description: All transactions in the ledger @@ -541,6 +754,13 @@ paths: $ref: "#/components/schemas/TransactionResponse" "404": description: No ledger with this id + content: + '*/*': + schema: + type: string + additionalProperties: + default: "" + default: "" /ledgers/{ledgerId}/balance: get: tags: @@ -554,7 +774,7 @@ paths: required: true schema: type: string - format: uuid + default: "" responses: "200": description: The balance of the ledger @@ -564,6 +784,13 @@ paths: $ref: "#/components/schemas/BalanceResponse" "404": description: No ledger with this id + content: + '*/*': + schema: + type: string + additionalProperties: + default: "" + default: "" /characters: get: tags: @@ -620,9 +847,14 @@ components: type: boolean ledgerRefs: type: array + contains: + default: "" items: type: string + default: "" pattern: "[a-z][a-zA-Z0-9]*" + unevaluatedItems: + default: "" script: type: string required: @@ -642,9 +874,14 @@ components: type: boolean ledgerRefs: type: array + contains: + default: "" items: type: string + default: "" pattern: "[a-z][a-zA-Z0-9]*" + unevaluatedItems: + default: "" script: type: string required: @@ -772,9 +1009,14 @@ components: type: boolean ledgerRefs: type: array + contains: + default: "" items: type: string + default: "" pattern: "[a-z][a-zA-Z0-9]*" + unevaluatedItems: + default: "" script: type: string required: @@ -802,35 +1044,6 @@ components: required: - memberLedgerIds - name - MarketHistoryResponse: - type: object - properties: - marketTypeId: - type: integer - format: int64 - date: - type: string - format: date - average: - type: number - highest: - type: number - lowest: - type: number - orderCount: - type: integer - format: int64 - volume: - type: integer - format: int64 - required: - - average - - date - - highest - - lowest - - marketTypeId - - orderCount - - volume MarketScanResponse: type: object properties: @@ -864,6 +1077,35 @@ components: - score - sell - totalVolume + MarketHistoryResponse: + type: object + properties: + marketTypeId: + type: integer + format: int64 + date: + type: string + format: date + average: + type: number + highest: + type: number + lowest: + type: number + orderCount: + type: integer + format: int64 + volume: + type: integer + format: int64 + required: + - average + - date + - highest + - lowest + - marketTypeId + - orderCount + - volume MarketPriceResponse: type: object properties: @@ -883,6 +1125,7 @@ components: - orderCount - sell LedgerResponse: + default: null discriminator: propertyName: type mapping: @@ -960,6 +1203,7 @@ components: - transactionId - transfers TransferResponse: + default: null discriminator: propertyName: type mapping: diff --git a/src/generated/mammon/api.ts b/src/generated/mammon/api.ts index 5246d91..034d805 100644 --- a/src/generated/mammon/api.ts +++ b/src/generated/mammon/api.ts @@ -296,11 +296,11 @@ export const ActivityApiAxiosParamCreator = function (configuration?: Configurat /** * * @summary Fetch new activities for a character from the EVE API - * @param {number} characterId Id of the character + * @param {string} characterId Id of the character * @param {*} [options] Override http request option. * @throws {RequiredError} */ - fetchNewActivitiesForCharacter: async (characterId: number, options: RawAxiosRequestConfig = {}): Promise => { + fetchNewActivitiesForCharacter: async (characterId: string, options: RawAxiosRequestConfig = {}): Promise => { // verify required parameter 'characterId' is not null or undefined assertParamExists('fetchNewActivitiesForCharacter', 'characterId', characterId) const localVarPath = `/activity/fetch/{characterId}` @@ -316,6 +316,7 @@ export const ActivityApiAxiosParamCreator = function (configuration?: Configurat const localVarHeaderParameter = {} as any; const localVarQueryParameter = {} as any; + localVarHeaderParameter['Accept'] = '*/*'; setSearchParams(localVarUrlObj, localVarQueryParameter); let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; @@ -350,11 +351,11 @@ export const ActivityApiFp = function(configuration?: Configuration) { /** * * @summary Fetch new activities for a character from the EVE API - * @param {number} characterId Id of the character + * @param {string} characterId Id of the character * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async fetchNewActivitiesForCharacter(characterId: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + async fetchNewActivitiesForCharacter(characterId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { const localVarAxiosArgs = await localVarAxiosParamCreator.fetchNewActivitiesForCharacter(characterId, options); const localVarOperationServerIndex = configuration?.serverIndex ?? 0; const localVarOperationServerBasePath = operationServerMap['ActivityApi.fetchNewActivitiesForCharacter']?.[localVarOperationServerIndex]?.url; @@ -381,11 +382,11 @@ export const ActivityApiFactory = function (configuration?: Configuration, baseP /** * * @summary Fetch new activities for a character from the EVE API - * @param {number} characterId Id of the character + * @param {string} characterId Id of the character * @param {*} [options] Override http request option. * @throws {RequiredError} */ - fetchNewActivitiesForCharacter(characterId: number, options?: RawAxiosRequestConfig): AxiosPromise { + fetchNewActivitiesForCharacter(characterId: string, options?: RawAxiosRequestConfig): AxiosPromise { return localVarFp.fetchNewActivitiesForCharacter(characterId, options).then((request) => request(axios, basePath)); }, }; @@ -408,11 +409,11 @@ export class ActivityApi extends BaseAPI { /** * * @summary Fetch new activities for a character from the EVE API - * @param {number} characterId Id of the character + * @param {string} characterId Id of the character * @param {*} [options] Override http request option. * @throws {RequiredError} */ - public fetchNewActivitiesForCharacter(characterId: number, options?: RawAxiosRequestConfig) { + public fetchNewActivitiesForCharacter(characterId: string, options?: RawAxiosRequestConfig) { return ActivityApiFp(this.configuration).fetchNewActivitiesForCharacter(characterId, options).then((request) => request(this.axios, this.basePath)); } } @@ -551,11 +552,11 @@ export const CharacterRuleBookApiAxiosParamCreator = function (configuration?: C /** * * @summary Find the rule book assigned to a character - * @param {number} characterId Id of the character + * @param {string} characterId Id of the character * @param {*} [options] Override http request option. * @throws {RequiredError} */ - findCharacterRuleBookByCharacterId: async (characterId: number, options: RawAxiosRequestConfig = {}): Promise => { + findCharacterRuleBookByCharacterId: async (characterId: string, options: RawAxiosRequestConfig = {}): Promise => { // verify required parameter 'characterId' is not null or undefined assertParamExists('findCharacterRuleBookByCharacterId', 'characterId', characterId) const localVarPath = `/characters/{characterId}/rule-book` @@ -585,12 +586,12 @@ export const CharacterRuleBookApiAxiosParamCreator = function (configuration?: C /** * * @summary Assign a rule book to a character - * @param {number} characterId Id of the character + * @param {string} characterId Id of the character * @param {SetCharacterRuleBookRequest} setCharacterRuleBookRequest Rule book and ledger bindings to assign * @param {*} [options] Override http request option. * @throws {RequiredError} */ - setCharacterRuleBookForCharacter: async (characterId: number, setCharacterRuleBookRequest: SetCharacterRuleBookRequest, options: RawAxiosRequestConfig = {}): Promise => { + setCharacterRuleBookForCharacter: async (characterId: string, setCharacterRuleBookRequest: SetCharacterRuleBookRequest, options: RawAxiosRequestConfig = {}): Promise => { // verify required parameter 'characterId' is not null or undefined assertParamExists('setCharacterRuleBookForCharacter', 'characterId', characterId) // verify required parameter 'setCharacterRuleBookRequest' is not null or undefined @@ -645,11 +646,11 @@ export const CharacterRuleBookApiFp = function(configuration?: Configuration) { /** * * @summary Find the rule book assigned to a character - * @param {number} characterId Id of the character + * @param {string} characterId Id of the character * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async findCharacterRuleBookByCharacterId(characterId: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + async findCharacterRuleBookByCharacterId(characterId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { const localVarAxiosArgs = await localVarAxiosParamCreator.findCharacterRuleBookByCharacterId(characterId, options); const localVarOperationServerIndex = configuration?.serverIndex ?? 0; const localVarOperationServerBasePath = operationServerMap['CharacterRuleBookApi.findCharacterRuleBookByCharacterId']?.[localVarOperationServerIndex]?.url; @@ -658,12 +659,12 @@ export const CharacterRuleBookApiFp = function(configuration?: Configuration) { /** * * @summary Assign a rule book to a character - * @param {number} characterId Id of the character + * @param {string} characterId Id of the character * @param {SetCharacterRuleBookRequest} setCharacterRuleBookRequest Rule book and ledger bindings to assign * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async setCharacterRuleBookForCharacter(characterId: number, setCharacterRuleBookRequest: SetCharacterRuleBookRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + async setCharacterRuleBookForCharacter(characterId: string, setCharacterRuleBookRequest: SetCharacterRuleBookRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { const localVarAxiosArgs = await localVarAxiosParamCreator.setCharacterRuleBookForCharacter(characterId, setCharacterRuleBookRequest, options); const localVarOperationServerIndex = configuration?.serverIndex ?? 0; const localVarOperationServerBasePath = operationServerMap['CharacterRuleBookApi.setCharacterRuleBookForCharacter']?.[localVarOperationServerIndex]?.url; @@ -690,22 +691,22 @@ export const CharacterRuleBookApiFactory = function (configuration?: Configurati /** * * @summary Find the rule book assigned to a character - * @param {number} characterId Id of the character + * @param {string} characterId Id of the character * @param {*} [options] Override http request option. * @throws {RequiredError} */ - findCharacterRuleBookByCharacterId(characterId: number, options?: RawAxiosRequestConfig): AxiosPromise { + findCharacterRuleBookByCharacterId(characterId: string, options?: RawAxiosRequestConfig): AxiosPromise { return localVarFp.findCharacterRuleBookByCharacterId(characterId, options).then((request) => request(axios, basePath)); }, /** * * @summary Assign a rule book to a character - * @param {number} characterId Id of the character + * @param {string} characterId Id of the character * @param {SetCharacterRuleBookRequest} setCharacterRuleBookRequest Rule book and ledger bindings to assign * @param {*} [options] Override http request option. * @throws {RequiredError} */ - setCharacterRuleBookForCharacter(characterId: number, setCharacterRuleBookRequest: SetCharacterRuleBookRequest, options?: RawAxiosRequestConfig): AxiosPromise { + setCharacterRuleBookForCharacter(characterId: string, setCharacterRuleBookRequest: SetCharacterRuleBookRequest, options?: RawAxiosRequestConfig): AxiosPromise { return localVarFp.setCharacterRuleBookForCharacter(characterId, setCharacterRuleBookRequest, options).then((request) => request(axios, basePath)); }, }; @@ -728,23 +729,23 @@ export class CharacterRuleBookApi extends BaseAPI { /** * * @summary Find the rule book assigned to a character - * @param {number} characterId Id of the character + * @param {string} characterId Id of the character * @param {*} [options] Override http request option. * @throws {RequiredError} */ - public findCharacterRuleBookByCharacterId(characterId: number, options?: RawAxiosRequestConfig) { + public findCharacterRuleBookByCharacterId(characterId: string, options?: RawAxiosRequestConfig) { return CharacterRuleBookApiFp(this.configuration).findCharacterRuleBookByCharacterId(characterId, options).then((request) => request(this.axios, this.basePath)); } /** * * @summary Assign a rule book to a character - * @param {number} characterId Id of the character + * @param {string} characterId Id of the character * @param {SetCharacterRuleBookRequest} setCharacterRuleBookRequest Rule book and ledger bindings to assign * @param {*} [options] Override http request option. * @throws {RequiredError} */ - public setCharacterRuleBookForCharacter(characterId: number, setCharacterRuleBookRequest: SetCharacterRuleBookRequest, options?: RawAxiosRequestConfig) { + public setCharacterRuleBookForCharacter(characterId: string, setCharacterRuleBookRequest: SetCharacterRuleBookRequest, options?: RawAxiosRequestConfig) { return CharacterRuleBookApiFp(this.configuration).setCharacterRuleBookForCharacter(characterId, setCharacterRuleBookRequest, options).then((request) => request(this.axios, this.basePath)); } } @@ -1279,11 +1280,11 @@ export const MarketApiAxiosParamCreator = function (configuration?: Configuratio /** * * @summary Return the current Jita order book (highest buy, lowest sell, order count) for each requested market type - * @param {Array} types Market type ids to price, e.g. types=34,35 + * @param {string} types Market type ids to price, e.g. types=34,35 * @param {*} [options] Override http request option. * @throws {RequiredError} */ - currentPrices: async (types: Array, options: RawAxiosRequestConfig = {}): Promise => { + currentPrices: async (types: string, options: RawAxiosRequestConfig = {}): Promise => { // verify required parameter 'types' is not null or undefined assertParamExists('currentPrices', 'types', types) const localVarPath = `/market/prices`; @@ -1298,7 +1299,7 @@ export const MarketApiAxiosParamCreator = function (configuration?: Configuratio const localVarHeaderParameter = {} as any; const localVarQueryParameter = {} as any; - if (types) { + if (types !== undefined) { localVarQueryParameter['types'] = types; } @@ -1316,12 +1317,12 @@ export const MarketApiAxiosParamCreator = function (configuration?: Configuratio /** * * @summary Find the market history of a type, most recent first - * @param {number} marketTypeId Id of the market type + * @param {string} marketTypeId Id of the market type * @param {number} [days] Optional number of most recent days to return; omit for the full history * @param {*} [options] Override http request option. * @throws {RequiredError} */ - findHistory: async (marketTypeId: number, days?: number, options: RawAxiosRequestConfig = {}): Promise => { + findHistory: async (marketTypeId: string, days?: number, options: RawAxiosRequestConfig = {}): Promise => { // verify required parameter 'marketTypeId' is not null or undefined assertParamExists('findHistory', 'marketTypeId', marketTypeId) const localVarPath = `/market/{marketTypeId}/history` @@ -1392,6 +1393,55 @@ export const MarketApiAxiosParamCreator = function (configuration?: Configuratio let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Scan a single market type, returning its volume-weighted price quartiles + * @param {string} marketTypeId The market type id to scan + * @param {number} [days] Number of most recent days of history to analyse + * @param {number} [brokerFee] Broker fee as a fraction (e.g. 0.015 for 1.5%), paid on both buy and sell orders + * @param {number} [salesTax] Sales tax as a fraction (e.g. 0.036 for 3.6%), paid on sell orders + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + scanMarketType: async (marketTypeId: string, days?: number, brokerFee?: number, salesTax?: number, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'marketTypeId' is not null or undefined + assertParamExists('scanMarketType', 'marketTypeId', marketTypeId) + const localVarPath = `/market/{marketTypeId}/scan` + .replace('{marketTypeId}', encodeURIComponent(String(marketTypeId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (days !== undefined) { + localVarQueryParameter['days'] = days; + } + + if (brokerFee !== undefined) { + localVarQueryParameter['brokerFee'] = brokerFee; + } + + if (salesTax !== undefined) { + localVarQueryParameter['salesTax'] = salesTax; + } + + localVarHeaderParameter['Accept'] = '*/*'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + return { url: toPathString(localVarUrlObj), options: localVarRequestOptions, @@ -1409,11 +1459,11 @@ export const MarketApiFp = function(configuration?: Configuration) { /** * * @summary Return the current Jita order book (highest buy, lowest sell, order count) for each requested market type - * @param {Array} types Market type ids to price, e.g. types=34,35 + * @param {string} types Market type ids to price, e.g. types=34,35 * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async currentPrices(types: Array, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + async currentPrices(types: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { const localVarAxiosArgs = await localVarAxiosParamCreator.currentPrices(types, options); const localVarOperationServerIndex = configuration?.serverIndex ?? 0; const localVarOperationServerBasePath = operationServerMap['MarketApi.currentPrices']?.[localVarOperationServerIndex]?.url; @@ -1422,12 +1472,12 @@ export const MarketApiFp = function(configuration?: Configuration) { /** * * @summary Find the market history of a type, most recent first - * @param {number} marketTypeId Id of the market type + * @param {string} marketTypeId Id of the market type * @param {number} [days] Optional number of most recent days to return; omit for the full history * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async findHistory(marketTypeId: number, days?: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + async findHistory(marketTypeId: string, days?: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { const localVarAxiosArgs = await localVarAxiosParamCreator.findHistory(marketTypeId, days, options); const localVarOperationServerIndex = configuration?.serverIndex ?? 0; const localVarOperationServerBasePath = operationServerMap['MarketApi.findHistory']?.[localVarOperationServerIndex]?.url; @@ -1448,6 +1498,22 @@ export const MarketApiFp = function(configuration?: Configuration) { const localVarOperationServerBasePath = operationServerMap['MarketApi.scanMarket']?.[localVarOperationServerIndex]?.url; return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); }, + /** + * + * @summary Scan a single market type, returning its volume-weighted price quartiles + * @param {string} marketTypeId The market type id to scan + * @param {number} [days] Number of most recent days of history to analyse + * @param {number} [brokerFee] Broker fee as a fraction (e.g. 0.015 for 1.5%), paid on both buy and sell orders + * @param {number} [salesTax] Sales tax as a fraction (e.g. 0.036 for 3.6%), paid on sell orders + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async scanMarketType(marketTypeId: string, days?: number, brokerFee?: number, salesTax?: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.scanMarketType(marketTypeId, days, brokerFee, salesTax, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['MarketApi.scanMarketType']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, } }; @@ -1460,22 +1526,22 @@ export const MarketApiFactory = function (configuration?: Configuration, basePat /** * * @summary Return the current Jita order book (highest buy, lowest sell, order count) for each requested market type - * @param {Array} types Market type ids to price, e.g. types=34,35 + * @param {string} types Market type ids to price, e.g. types=34,35 * @param {*} [options] Override http request option. * @throws {RequiredError} */ - currentPrices(types: Array, options?: RawAxiosRequestConfig): AxiosPromise> { + currentPrices(types: string, options?: RawAxiosRequestConfig): AxiosPromise> { return localVarFp.currentPrices(types, options).then((request) => request(axios, basePath)); }, /** * * @summary Find the market history of a type, most recent first - * @param {number} marketTypeId Id of the market type + * @param {string} marketTypeId Id of the market type * @param {number} [days] Optional number of most recent days to return; omit for the full history * @param {*} [options] Override http request option. * @throws {RequiredError} */ - findHistory(marketTypeId: number, days?: number, options?: RawAxiosRequestConfig): AxiosPromise> { + findHistory(marketTypeId: string, days?: number, options?: RawAxiosRequestConfig): AxiosPromise> { return localVarFp.findHistory(marketTypeId, days, options).then((request) => request(axios, basePath)); }, /** @@ -1490,6 +1556,19 @@ export const MarketApiFactory = function (configuration?: Configuration, basePat scanMarket(days?: number, brokerFee?: number, salesTax?: number, options?: RawAxiosRequestConfig): AxiosPromise> { return localVarFp.scanMarket(days, brokerFee, salesTax, options).then((request) => request(axios, basePath)); }, + /** + * + * @summary Scan a single market type, returning its volume-weighted price quartiles + * @param {string} marketTypeId The market type id to scan + * @param {number} [days] Number of most recent days of history to analyse + * @param {number} [brokerFee] Broker fee as a fraction (e.g. 0.015 for 1.5%), paid on both buy and sell orders + * @param {number} [salesTax] Sales tax as a fraction (e.g. 0.036 for 3.6%), paid on sell orders + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + scanMarketType(marketTypeId: string, days?: number, brokerFee?: number, salesTax?: number, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.scanMarketType(marketTypeId, days, brokerFee, salesTax, options).then((request) => request(axios, basePath)); + }, }; }; @@ -1500,23 +1579,23 @@ export class MarketApi extends BaseAPI { /** * * @summary Return the current Jita order book (highest buy, lowest sell, order count) for each requested market type - * @param {Array} types Market type ids to price, e.g. types=34,35 + * @param {string} types Market type ids to price, e.g. types=34,35 * @param {*} [options] Override http request option. * @throws {RequiredError} */ - public currentPrices(types: Array, options?: RawAxiosRequestConfig) { + public currentPrices(types: string, options?: RawAxiosRequestConfig) { return MarketApiFp(this.configuration).currentPrices(types, options).then((request) => request(this.axios, this.basePath)); } /** * * @summary Find the market history of a type, most recent first - * @param {number} marketTypeId Id of the market type + * @param {string} marketTypeId Id of the market type * @param {number} [days] Optional number of most recent days to return; omit for the full history * @param {*} [options] Override http request option. * @throws {RequiredError} */ - public findHistory(marketTypeId: number, days?: number, options?: RawAxiosRequestConfig) { + public findHistory(marketTypeId: string, days?: number, options?: RawAxiosRequestConfig) { return MarketApiFp(this.configuration).findHistory(marketTypeId, days, options).then((request) => request(this.axios, this.basePath)); } @@ -1532,6 +1611,20 @@ export class MarketApi extends BaseAPI { public scanMarket(days?: number, brokerFee?: number, salesTax?: number, options?: RawAxiosRequestConfig) { return MarketApiFp(this.configuration).scanMarket(days, brokerFee, salesTax, options).then((request) => request(this.axios, this.basePath)); } + + /** + * + * @summary Scan a single market type, returning its volume-weighted price quartiles + * @param {string} marketTypeId The market type id to scan + * @param {number} [days] Number of most recent days of history to analyse + * @param {number} [brokerFee] Broker fee as a fraction (e.g. 0.015 for 1.5%), paid on both buy and sell orders + * @param {number} [salesTax] Sales tax as a fraction (e.g. 0.036 for 3.6%), paid on sell orders + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public scanMarketType(marketTypeId: string, days?: number, brokerFee?: number, salesTax?: number, options?: RawAxiosRequestConfig) { + return MarketApiFp(this.configuration).scanMarketType(marketTypeId, days, brokerFee, salesTax, options).then((request) => request(this.axios, this.basePath)); + } } @@ -1692,6 +1785,7 @@ export const RuleBookApiAxiosParamCreator = function (configuration?: Configurat const localVarHeaderParameter = {} as any; const localVarQueryParameter = {} as any; + localVarHeaderParameter['Accept'] = '*/*'; setSearchParams(localVarUrlObj, localVarQueryParameter); let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; @@ -1864,7 +1958,7 @@ export const RuleBookApiFp = function(configuration?: Configuration) { * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async deleteRuleBook(ruleBookId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + async deleteRuleBook(ruleBookId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<{ [key: string]: any; }>> { const localVarAxiosArgs = await localVarAxiosParamCreator.deleteRuleBook(ruleBookId, options); const localVarOperationServerIndex = configuration?.serverIndex ?? 0; const localVarOperationServerBasePath = operationServerMap['RuleBookApi.deleteRuleBook']?.[localVarOperationServerIndex]?.url; @@ -1947,7 +2041,7 @@ export const RuleBookApiFactory = function (configuration?: Configuration, baseP * @param {*} [options] Override http request option. * @throws {RequiredError} */ - deleteRuleBook(ruleBookId: string, options?: RawAxiosRequestConfig): AxiosPromise { + deleteRuleBook(ruleBookId: string, options?: RawAxiosRequestConfig): AxiosPromise<{ [key: string]: any; }> { return localVarFp.deleteRuleBook(ruleBookId, options).then((request) => request(axios, basePath)); }, /** diff --git a/src/market/scan/scan.ts b/src/market/scan/scan.ts index 6c0b127..9f3f61e 100644 --- a/src/market/scan/scan.ts +++ b/src/market/scan/scan.ts @@ -1,4 +1,4 @@ -import { getHistory, getHistoryQuartils, HistoryQuartils, MarketType, MarketTypePrice } from "@/market"; +import { MarketType } from "@/market"; import { MarketScanResponse } from "@/generated/mammon"; export type ScanResult = { @@ -13,14 +13,6 @@ export type ScanResult = { score: number; } -// Mirrors mammon's MarketScoreCalculator so the client-side path matches the backend scan. -export const calculateScore = (quartils: HistoryQuartils, profit: number, orderCount: number, days: number): number => { - if (profit <= 0) { - return 0; - } - return Math.sqrt((Math.pow(quartils.totalVolume, 1.1) * Math.pow(quartils.q1, 1.2) * Math.pow(profit, 0.5) * Math.pow(Math.max(1, orderCount), -0.7)) / days); -} - export const toScanResult = (res: MarketScanResponse, type: MarketType): ScanResult => ({ type, buy: res.buy, @@ -32,22 +24,3 @@ export const toScanResult = (res: MarketScanResponse, type: MarketType): ScanRes profit: res.profit, score: res.score, }); - -// Client-side scan result for a single type (used where the scan endpoint can't be queried per-type). -export const buildScanResult = async (price: MarketTypePrice, days: number, calculateProfit: (buy: number, sell: number) => number): Promise => { - const history = await getHistory(price.type.id); - const quartils = getHistoryQuartils(history, days); - const profit = quartils.q1 === 0 || quartils.q3 === 0 ? 0 : calculateProfit(quartils.q1, quartils.q3); - - return { - type: price.type, - buy: price.buy, - sell: price.sell, - q1: quartils.q1, - median: quartils.median, - q3: quartils.q3, - totalVolume: quartils.totalVolume, - profit, - score: calculateScore(quartils, profit, price.orderCount, days), - }; -} diff --git a/src/pages/market/TypeInfo.vue b/src/pages/market/TypeInfo.vue index ee69098..aa83496 100644 --- a/src/pages/market/TypeInfo.vue +++ b/src/pages/market/TypeInfo.vue @@ -2,7 +2,8 @@ import {ClipboardButton} from '@/components'; import {getMarketType, MarketType, MarketTypeInput, useApraisalStore, useMarketTaxStore} from "@/market"; import {AcquisitionResultTable, BuyModal, useAcquiredTypesStore} from '@/market/acquisition'; -import {buildScanResult, ScanResultTable} from '@/market/scan'; +import {ScanResultTable, toScanResult} from '@/market/scan'; +import {marketApi} from "@/mammon"; import {ShoppingCartIcon} from '@heroicons/vue/24/outline'; import log from "loglevel"; import {computed, ref, watch} from "vue"; @@ -21,7 +22,20 @@ const apraisalStore = useApraisalStore(); const marketTaxStore = useMarketTaxStore(); const days = useStorage('market-scan-days', 365); const price = computedAsync(() => item.value ? apraisalStore.getPrice(item.value) : undefined); -const result = computedAsync(async () => price.value ? await buildScanResult(price.value, days.value, marketTaxStore.calculateProfit) : undefined); +const result = computedAsync(async () => { + if (!item.value) { + return undefined; + } + + const { data } = await marketApi.scanMarketType( + String(item.value.id), + days.value, + marketTaxStore.brokerFee / 100, + marketTaxStore.scc / 100 + ); + + return toScanResult(data, item.value); +}); const acquiredTypesStore = useAcquiredTypesStore(); const acquisitions = computed(() => {