A TypeScript tool that identifies profitable arbitrage opportunities for Counter-Strike 2 (CS2) items between the Steam Community Market and Skinport marketplace.
This tool analyzes price differentials between two major CS2 item marketplaces to find profitable trading opportunities. It evaluates both inbound (Skinport -> Steam) and outbound (Steam -> Skinport) strategies, accounting for marketplace fees and 7-day trade hold periods.
Inbound (Buy on Skinport, Sell on Steam)
- Target: Items priced significantly below Steam buy orders
- Fee consideration: 15% Steam marketplace fee
- Requires: 50+ Steam sales in past 7 days for reliable data
Outbound (Buy on Steam, Sell on Skinport)
- Target: Items where Skinport prices are close to Steam sell prices
- Fee consideration: 6-12% Skinport fee (6% for items GBP800+)
- Requires: 25+ Skinport sales in past 7 days for reliable data
- Fetches real-time price data from Steam and Skinport APIs
- Calculates 7-day price statistics (avg, min, max, volume, std dev)
- Computes profitability ratings based on configurable thresholds
- Analyzes order book depth with closeness coefficient
- Exports results to CSV for further analysis
- Rate limit handling with automatic retry logic
The tool supports multiple CS2 item categories:
- Cases (40+ different cases)
- Knives (Karambit, Bayonet, Bowie Knife with various finishes)
- Rifles (AK-47, AWP, M4A1-S, M4A4, and more)
- Heavy weapons (MAG-7, Nova, Sawed-Off, XM1014, M249, Negev)
- Bun runtime (v1.0+)
- Steam account with Community Market access
- Skinport API credentials
- Clone the repository:
git clone https://github.com/yourusername/steam-arbitrage-bot.git
cd steam-arbitrage-bot- Install dependencies:
bun install- Create environment file:
cp .env.example .env- Configure your
.envwith API credentials (see.env.examplefor details)
Run analysis for a specific category:
bun run start:case # Analyze CS2 cases
bun run start:knife # Analyze knives
bun run start:rifle # Analyze rifles
bun run start:heavy # Analyze heavy weaponsResults are saved to ./output/{date}/{category}/ with:
raw_data.csv- Complete data for all itemsinbound.csv- Top 10 inbound opportunitiesoutbound.csv- Top 10 outbound opportunities
src/
├── config.ts # Item catalogs and fee constants
├── type.d.ts # TypeScript type definitions
├── run.ts # Core orchestration logic
├── steam.repository.ts # Steam Market API client
├── skinport.repository.ts # Skinport API client
├── rating.util.ts # Profitability rating calculations
├── rating.constant.ts # Rating thresholds
├── price.util.ts # Price statistics calculations
├── order.util.ts # Order book analysis
├── result.util.ts # CSV export and data transformation
├── number.ts # Number formatting utility
├── runs/ # Category-specific entry points
│ ├── case.ts
│ ├── knife.ts
│ ├── rifle.ts
│ └── heavy.ts
└── data/
└── itemId.json # Pre-fetched Steam item ID cache
bun run lint # Run ESLint
bun run format # Format code with Prettier
bun run test # Run testsItems are rated based on profit potential (buy price vs Steam buy order):
- 1.0: 70%+ profit potential
- 0.8: 60-70% profit potential
- 0.6: 50-60% profit potential
- 0.4: 48-50% profit potential
Items are rated based on expected loss (Steam sell vs Skinport average):
- 1.0: 5% or less loss
- 0.8: 5-10% loss
- 0.6: 10-13% loss
- 0.4: 13-15% loss
- Steam: 15% seller fee
- Skinport: 12% fee (6% for items GBP800+)
- Steam session credentials expire and need periodic refresh
- API rate limits may require staggered execution
- 7-day trade hold affects arbitrage timing
- Price volatility during hold period creates risk
MIT