Skip to content

Instantly share code, notes, and snippets.

@vladgovor77771
Created August 8, 2020 02:16
Show Gist options
  • Select an option

  • Save vladgovor77771/55d8019ab307824a239684090a7dfddf to your computer and use it in GitHub Desktop.

Select an option

Save vladgovor77771/55d8019ab307824a239684090a7dfddf to your computer and use it in GitHub Desktop.
const { TmItem, SteamItem, TmMetaAnalysis } = require('../../../models');
const { Op } = require('sequelize');
const getBotSettings = require('../get_bot_settings');
module.exports = run = async (job) => {
let { botId } = job.data;
let {
minPrice,
maxPrice,
buyDiscont,
sellFee,
needProfit,
safeProfit,
timeOffsetMonths,
minCount,
maxCount,
maxLootfarmPriceRate,
// minSteamPriceRate,
minPopularity,
maxConcurrentsByPopularity,
// stick,
// stickPlus
} = await getBotSettings(botId);
let items = await TmItem.findAll({
limit: 150,
order: [[ TmItem.metaAnalysis, 'profit', 'DESC' ]],
include: [
{ association: TmItem.sellOrders },
{ association: TmItem.buyOrders },
{
association: TmItem.metaAnalysis,
required: true,
where: {
timeOffsetMonths,
minCount: { [Op.gt]: minCount },
maxCount: { [Op.gt]: maxCount },
lootfarmPriceRate: { [Op.lte]: maxLootfarmPriceRate },
// steamPriceRate: { [Op.gte]: minSteamPriceRate },
average: {
[Op.and]: {
[Op.gte]: minPrice * buyDiscont,
[Op.lte]: maxPrice * buyDiscont
}
},
popularity: { [Op.gte]: minPopularity },
concurrentsByPopularity: { [Op.lte]: maxConcurrentsByPopularity }
},
}
]
})
console.log(items);
// calculate profit
// let profit = parseFloat((sellPrice * sellFee) / (buyPrice * buyDiscount) * 100).toFixed(2));
// somehow filter due to many bots
}
const { TmItem, SteamItem, TmMetaAnalysis } = require('../../models');
const moment = require('moment');
const _ = require('lodash');
const CurrencyManager = require('../../helpers/currency_manager');
module.exports = async (job) => {
let { itemId } = job.data;
await analyse(itemId);
}
const analyse = async (id) => {
let item = await TmItem.findByPk(id, {
include: [{
association: TmItem.sellings,
required: true,
order: [['date', 'DESC']]
}, {
association: TmItem.sellOrders,
required: true,
}, {
association: TmItem.buyOrders,
required: true,
}, {
association: TmItem.steamItem,
required: true,
include: [{
association: SteamItem.lootfarmItem,
}]
}, {
association: TmItem.metaAnalysis
}]
});
let meta2Months = calculateMeta(item);
meta2Months.totalPoints = item.sellings.length;
meta2Months.totalPopulatiry = Math.min(calculatePopularity(item), 100);
if (item.steamItem.lootfarmItem) {
meta2Months.lootfarmPriceRate = (await CurrencyManager.convertToUsd(meta2Months.sellPrice)) / item.steamItem.lootfarmItem.price;
meta2Months.steamPriceRate = meta2Months.lootfarmPriceRate * item.steamItem.lootfarmItem.steamRate;
} else {
meta2Months.steamPriceRate = (await CurrencyManager.convertToUsd(meta2Months.sellPrice)) / item.steamItem.price;
}
let existedAnalysis = item.metaAnalysis.find(anal => anal.timeOffsetMonths == 2);
if (existedAnalysis) await existedAnalysis.update(meta2Months);
else await TmMetaAnalysis.create({ itemId: item.id, ...meta2Months });
// let meta1Months = calculateMeta(item, moment().subtract(1, 'months').toDate());
// let meta3Months = calculateMeta(item, moment().subtract(3, 'months').toDate());
}
const calculateMeta = (item, timeFrom = moment().subtract(2, 'months').toDate()) => {
let overPriceDetect = 0.91; // отходим ко второму ордеру если первый дороже на 9%, постоянная?
let sellings = item.sellings.filter(selling => selling.date > timeFrom);
let sellingsCount = sellings.length;
let popularity = Math.min(calculatePopularity(sellings), 100);
let mounthAgo = Math.min(Math.round((popularity / 100) * (50 - 15) + 15), item.sellings.length);
let minest = Math.min.apply(null, item.sellings.slice(0, mounthAgo).map(item => item.price));
let { buyPrice, sellPrice, maxCount, minCount, average } = calculateBuySellPrice({ sellings: item.sellings, mounthAgo });
if (item.sellOrders.count > 0 && item.sellOrders.length >= 2 && item.sellOrders.bestOrder / item.sellOrders.value[1][0] < overPriceDetect) {
if (sellPrice > item.sellOrders.value[1][0]) sellPrice = item.sellOrders.value[1][0];
else if (sellPrice > item.sellOrders.bestOrder) sellPrice = item.sellOrders.bestOrder;
}
let sellConcurrents = 0;
item.sellOrders.value.map(e => { if (e[0] < sellPrice) sellConcurrents += e[1] });
if (item.buyOrders.length >= 2 && item.buyOrders.bestOrder / item.buyOrders.value[1][0] < overPriceDetect) {
if (buyPrice < item.buyOrders.value[1][0]) buyPrice = item.buyOrders.value[1][0];
else buyPrice = Math.max(buyPrice, item.buyOrders.bestOrder, minest);
}
let res = {
sellingsCount,
popularity,
buyPrice,
sellPrice,
sellConcurrents,
concurrentsByPopularity: sellConcurrents / popularity,
maxCount,
minCount,
average,
profit: sellPrice / buyPrice,
}
return res;
}
const calculatePopularity = (sellings) => {
return sellings.length / ((sellings[0].date - sellings[sellings.length - 1].date) / 1000 / 60 / 60 / 24);
}
const calculateAveragePrice = (sellings) => {
if (sellings.length < 1) return 0;
let sorted = _.sortBy(sellings, 'price');
if (sorted.length % 2 == 1) return sorted[Math.floor(sorted.length / 2)].price;
else return (sorted[Math.floor(sorted.length / 2) - 1].price + sorted[Math.floor(sorted.length / 2)].price) / 2;
}
const calculateBuySellPrice = ({ sellings, mounthAgo }) => {
let trendWeight = 0.05; // диапазон средних точек 0.08
let average = calculateAveragePrice(sellings.slice(0, mounthAgo));
let min = [];
let max = [];
let first = 0;
let last = 0;
let minEl = 0;
let maxEl = 0;
for(var j = 0; j < Math.floor(mounthAgo / 2); j++) {
if (sellings[j].price / average > 2 || sellings[j].price / average < 0.5) continue;
first += sellings[j].price;
if(sellings[j].price < sellings[minEl].price) minEl = j;
if(sellings[j].price > sellings[maxEl].price) maxEl = j;
}
first /= Math.floor(mounthAgo / 2);
for(var j = Math.floor(mounthAgo / 2); j < mounthAgo; j++) {
if (sellings[j].price / average > 2 || sellings[j].price / average < 0.5) continue;
last += sellings[j].price;
if(sellings[j].price < sellings[minEl].price) minEl = j;
if(sellings[j].price > sellings[maxEl].price) maxEl = j;
}
last /= mounthAgo - Math.floor(mounthAgo / 2);
let step = (last - first) / (mounthAgo - 1);
let range = sellings[maxEl].price - sellings[minEl].price;
for(var j = 0; j < mounthAgo; j++) {
let diff = sellings[j].price;
if (diff / average > 2 || diff / average < 0.5) continue;
let trend = first + j * step;
let normtrend = trend / range;
let normdiff = diff / range / normtrend;
if(normdiff < 1 + trendWeight && normdiff > 1 - trendWeight) continue;
if(normdiff > 1) max.push(sellings[j]);
else min.push(sellings[j]);
}
let buyPrice = calculateAveragePrice(min);
let sellPrice = calculateAveragePrice(max);
let maxCount = max.length;
let minCount = min.count;
return { buyPrice, sellPrice, maxCount, minCount, average }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment