TSM4 Deep Dive: Logic Functions & Value Sources

Logic Functions

Many users have become somewhat aware of the check() function in TSM3 thanks to the popularity of BilisOnyxia’s sniper string. In my own personal experience, check() is definitely something that at times can be hard to wrap your brain around. I’m pretty sure I used TSM for over a year before I fully understood it!

To quickly explain check(), you can feed it 2 to 3 values in the format of check(a, b, c) where “c” can be optional. These 3 values can be any value TSM recognizes, from custom prices to flat gold values, to simple price source references like DBMarket. The check() function then takes a look at “a”, and looks to see if it is valid and greater than 0. If “a” is not valid, the custom price returns invalid. If “a” is greater than 0, the custom price will give you the value of “b” back, otherwise it gives the value for “c”. If you did not supply a value for “c” and “a” is not is not greater than 0, then the whole thing is treated as invalid.

In TSM4, one of our main goals was to expand on the logic-based functionality of the check() function and make it easier and more intuitive for our users to incorporate logic in their custom prices. With that in mind, TSM4 adds the following new functions:

ifgt() – “If Greater Than”
ifgte() – “If Greater Than or Equal To”
iflt() – “If Less Than”
iflte() – “If Less Than or Equal To”
ifeq()- “If Equal”
round() – “Standard Rounding”
roundup() – “Always Round Up – aka Ceiling”
rounddown() – “Always Round Down – aka Floor”

The “IF” functions are all used in the same way. You can send in 3 to 4 values in the format of ifgt(a, b, c, d) where d can be optional. TSM4 checks if “a” and “b” are valid in the same method used for check() above. TSM4 then looks at which “IF” function you are using, in our example I am using “if greater than”, so it checks if “a is greater than b”. If it is, the value of “c” is given back to us. If it is not, the value of “d” is given back if one was supplied, otherwise the whole thing is treated as invalid.

The “Round” functions also follow a similar usage to each other. You can send in 1 to 2 values in the format round(a, b). The first value “a” is the number you want to round and the second value “b” is the factor you would like to round to.  For example, “round(crafting, 10s)” would return the crafting cost rounded to the nearest 10 silver. If no value of “b” is sent in, then the functions round to the nearest copper, as appropriate.

Value Sources

We currently offer many different prices from various sources including AuctionDB, Accounting, and more, but we recognize that these are not the only values that are important to TSM users when configuring their operations. We currently provide other pieces of data such as sale rate and number of expires in item tooltips, but there is currently no way to use this data in custom prices directly.

In TSM4, our goal is to expose as many values as possible for use directly in custom prices. Not all of these values are prices, hence the new name of “value sources.” These are the value sources that will be available with the launch of TSM4 for use in custom prices:



Below are a few examples which demonstrate the power of the new custom prices changes coming with TSM4.

iflt(DBRegionSoldPerDay, 100, DBMarket, DBRegionMarketAvg)

The above function will return the DBMarket if DBRegionSoldPerDay is less than 100, otherwise it’ll return DBRegionMarketAvg.

round(DBRegionMarketAvg, ifeq(ItemQuality, 4, 1000g, 1g))

This second example will round DBRegionMarketAvg to the nearest 1000g for epic quality items (ItemQuality 4) or to the nearest 1g otherwise.


I cannot wait to get all of these new tools into the hands of our amazing community! If you want to ensure you get into the beta as soon as possible, you can go ahead and sign up for an invite here. If you like what we do and want to support the continued development of TradeSkillMaster and also get priority access to all of our betas, please consider becoming a TSM Premium user.

8 CommentsLeave a comment

  • Interesting features to add, and quite powerful indeed.

    However, i feel like these will only be made useful by the power users (and it seems to be directly pointed at the snipers). As excited as i am about this, it doesnt really seem in line with the ‘simpler more straightforward’ approach you boasted when TSM4 was announced. Guess we’ll have to wait to see more.

    • We certainly spent a lot of time making TSM easier to jump in to, especially with the new overall design philosophy. But we did announce that there were new tools and features for the power users being implemented at the same time. The two things aren’t mutually exclusive and we want to make TSM a better addon for everyone, whether they’re brand new and starting out or a veteran goblin.

      • It was fortunate that with the check(a,b,c) I realized it was a quirky if, then, else statement… lol

  • As a metrologist, I’m wondering if, for standard rounding (round()) if they’re using NIST (National Institute of Standards and Technology) standards for rounding which is to round to the nearest even. This is used because our historical method of rounding injects a bias in rounding, which is basically defined in roundup() which if the number ends in 5 the process goes up, so 2.5 would be 3, and 3.5 would be 4, and conversely for round down. NIST’s method is to round to nearest even, thus 2.5 would be 2, and 3.5 would be 4, which is statistically sound. As the average of rounding 2.5 and 3.5 would be 3. Ex: without rounding, (2.5+3.5)/2 = 6/2 = 3. As well as with rounding 2.5=2, 3.5=4, and (2+4)/2 = 6/2 = 3. The reasoning being that if working statistical operations as in accounting on a large list of rounded numbers produce the smallest error possible when rounding.

    So, back to the question. Does round() use the NIST standard “round to the nearest even number?

    • That seems like a sound question, but I suspect is just uses the classical round based on 0.5. However, it would be interesting if they just implement a roundnist() as well, and people could do a comparison on larger data sets to validate the reasoning.

  • This is a really great improvement.

    With all those new cool logical functions: Can we maybe use them to influence the stack size when posting something on the AH or buying something?

    Some question not directly related to this article but to TSM4: What always bothers me with TSM3 is the expiration counter. When a single auction with 200 items expires, it is counted as 1 expiration and when you have 3 auctions posted at the same time expireing it counts as 3 expirations, but this is not really the same. For example, I like to have as few groups for selling legacy stuff as possible, so I only have 2 groups, one for selling items in stacks and one for selling them as single items. I can use the “ignore after x expirations” function for the first group, but not for the second one, when I post the same item 17 times because I got 17 while doing some old content.

  • Thank you thank you thank you for that logic-based functionality! I am levelling my enchanter, and she can only disenchant up to a certain level, so it will be very helpful to be able to set a custom price to something like “max (200% vendorSell, 33% dbMarket, iflte(RequiredLevel, 69, 120% Destroy, 0))”