jack-richards / bptf-autopricer

Automatically prices items using listing data from backpack.tf, with data from prices.tf acting as a baseline.
MIT License
24 stars 6 forks source link
backpacktf bptf-autopricer node pricestf team-fortress-2 tf2 tf2-autopricer tf2-trading-bot

bptf-autopricer

logo

#

[![Version](https://img.shields.io/github/v/release/jack-richards/bptf-autopricer.svg)](https://github.com/jack-richards/bptf-autopricer/releases) [![GitHub forks](https://img.shields.io/github/forks/jack-richards/bptf-autopricer)](https://github.com/jack-richards/bptf-autopricer/network/members) [![GitHub Repo stars](https://img.shields.io/github/stars/jack-richards/bptf-autopricer)](https://github.com/jack-richards/bptf-autopricer/stargazers) [![GitHub issues](https://img.shields.io/github/issues/jack-richards/bptf-autopricer)](https://github.com/jack-richards/bptf-autopricer/issues) [![License](https://img.shields.io/github/license/jack-richards/bptf-autopricer.svg)](https://opensource.org/licenses/MIT) [![Known Vulnerabilities](https://snyk.io/test/github/jack-richards/bptf-autopricer/badge.svg)](https://snyk.io/test/github/jack-richards/bptf-autopricer)

An open-source solution that generates item prices for selected items by utilising listing data from backpack.tf. Each price created is a result of the meticulous evaluation of both the underlying data and the actual prices, incorporating multiple checks and balances to counteract potential price manipulation.

Features

Requirements

Configuration

To configure the application you need to specify the values for all the fields in config.json.

{
    "bptfAPIKey": "your bptf api key",
    "bptfToken": "your bptf token",
    "steamAPIKey": "your steam api key",
    "database": {
        "schema": "tf2",
        "host": "localhost",
        "port": 5432,
        "name": "bptf-autopricer",
        "user": "postgres",
        "password": "database password"
    },
    "pricerPort": 3456,
    "maxPercentageDifferences": {
        "buy": 5,
        "sell": -8
    },
    "alwaysQuerySnapshotAPI": true,
    "excludedSteamIDs": [
        "76561199384015307"
    ],
    "trustedSteamIDs": [
        "76561199110778355"
    ],
    "excludedListingDescriptions": [
        "exorcism",
    ]
}

The majority of these fields are self-explanatory. I will explain the ones that may not be.

maxPercentageDifferences

Contains two fields, buy and sell. These values represent the maximum difference from the baseline (prices.tf) you will accept before a price is rejected. Adjust the maximum percentage differences for buy and sell according to your preferences.

The default in the config is the settings I used while using this auto pricer with a trading bot.

"maxPercentageDifferences": {
  "buy": 5,
  "sell": -8
}

excludedSteamIDs

A list of Steam ID 64s that you don't want to use the listings of in pricing calculations. This is useful for stopping bad actors that you know of from attempting to manipulate the prices created. It's important to note that this is not a fool-proof solution and because of this other methods are also used to reduce the risks of price manipulation.

"excludedSteamIDs": [
    "76561199384015307"
]

trustedSteamIDs

A list of Steam ID 64s used to prioritise listings owned by these IDs over others during pricing calculations. This feature is beneficial when you want to give preference to bots or users that consistently provide accurate pricing data.

"trustedSteamIDs": [
    "76561199110778355"
]

excludedListingDescriptions

A list of descriptions that, when detected within a listing's details, causes the listing to be disregarded and not used during pricing calculations. This is useful for excluding listings involving items with 'special attributes,' such as spells, when calculating prices. Leaving such listings in the calculations can risk affecting the average price in unexpected ways.

"excludedListingDescriptions": [
    "exorcism",
]

alwaysQuerySnapshotAPI

This setting determines whether the pricer should consistently call the snapshot API for each item during the pricing process, regardless of the number of listings available in the database. By default, this setting is set to true.

Behavior:

Trade-offs:

  1. Accuracy vs. Speed: By setting alwaysQuerySnapshotAPI to false, the pricing process becomes faster but may use a smaller pool of listings to calculate prices. The logic ensures that if there are at least 10 buy listings and 1 sell listing, no further data retrieval is attempted.

  2. Timeliness of Data: When the API is not called every time, there's a risk of using listings with prices that are up to approximately 35 minutes old, in the worst-case scenario.

Benefits:

Consider your requirements for pricing accuracy, speed, and data freshness when configuring this setting.

"alwaysQuerySnapshotAPI": true

API Routes & Socket IO

The socket io server will emit events called 'price' with an item object as the value. The item objects are structured like the following:

{
  "name": "Strange Australium Minigun",
  "sku": "202;11;australium",
  "source": "bptf",
  "time": 1700403492,
  "buy": {
    "keys": 25,
    "metal": 21.33
  },
  "sell": {
    "keys": 26,
    "metal": 61.77
  }
}

# Now I'll highlight the different API routes you can make queries to, and what responses you can expect to receive.\ Please note that both the Socket IO server and API run locally (localhost) on the port defined in config.json. #

GET /items/:sku

Retrieves a particular item object from the pricelist using the Stock Keeping Unit (SKU) provided. Item object returned contains the prices for the item.

Request:

Response:

Response:

Request:

Response:

Request:

Response:

Request:

Response:

Running the Auto Pricer

Once all the requirements have been met, and you have provided the values required in config.json, simply run:

node bptf-autopricer.js

If you want to use PM2 to run the application even after closing the terminal run:

pm2 start bptf-autopricer.js

Adding Items to Price.

Each item name given should be the same as the one used for its listings on backpack.tf. For example, Non-Craftable Tour of Duty Ticket NOT Uncraftable Tour of Duty Ticket.