DaysOnMarket Client Auto-increment Proposal #140
Replies: 10 comments 10 replies
-
It sounds like discussion on this may be moved to transport, so here's the original write-up I added to the Data Dictionary General Discussion Forum, so it's in one place. I’ve read through the various DOM discussions in this space and would like to add to the discussion. I have a proposal that
The proposal adds two fields to DD
And defines the calculation for “actual/current DOM” as
The full proposal is currently here: https://gist.github.com/bryanburgers/c74870723e81f2d4d9e0404123f469b9 We’ve been using this internally for a while and we have found it to be effective and general across the MLSes we work with. I’d love to hear your thoughts and questions on it! |
Beta Was this translation helpful? Give feedback.
-
A summary of discussion on the Data Dictionary General Dicussion Forum
|
Beta Was this translation helpful? Give feedback.
-
Elegant work - and the only comment I have is centered around the "Must" include on DaysOnMarketAccumulatingYN field. What happens when the client doesn't get DaysOnMarket? We have a couple custom clients that don't get the DaysOnMarket field. I would suggest the "Must" include for DaysOnMarketAccumulatingYN be dependent on the existence DaysOnMarket in the client's feed. |
Beta Was this translation helpful? Give feedback.
-
The primary takeaway from the September 2024 Transport meeting is that this proposal will change from using the existing (Hopefully that captures the discussion accurately.)
Update: I was asked after the meeting not to follow up on the action item I was given to update the proposal. |
Beta Was this translation helpful? Give feedback.
-
Zenlist
|
Beta Was this translation helpful? Give feedback.
-
The problem with Days on Market, a narrativeEveryone say hello to Connie 👋. Connie is new to the real estate industry, but is building out a brilliant new product that everyone is excited about. Connie has a few core beliefs when it comes to her product. First, she wants to be a good friend to the MLSs and be a good steward of their data. Second, she wants to use RESO Standards to reduce her time to market. And third, she wants to show accurate and up-to-date listing data. But mostly, Connie just wants her product to succeed. Basic timestamp replicationConnie decides to retrieve data using RESO Web APIs and quickly comes to the conclusion that basic timestamp replication would be the best for her. For the three MLSs that she's starting with – OneMLS, TwoMLS, and ThreeMLS – she sets up a schedule to query for new updates to listings frequently throughout the day. Connie is quite pleased with the way this works. All of the listings that she shows on her website come from her own database which makes her site super fast, but because any changes to the listings in the MLS make it into her database quickly, she's still being a good steward of the data. She doesn't even have to modify or interpret the data at all; her website shows the address, the status, the list price, and a bunch of other information using Data Dictionary standards. Things are looking good. 😞 But things aren't good. A few days later, she receives a call from an agent telling her that her site is displaying the wrong Days on Market. How can that be? She's displaying exactly what she's receiving from the MLS! That approach works for addresses. That approach works for statuses. That approach works for list prices. What's going on here? Ah yes. Connie realizes that unlike the rest of the values she receives in a listing payload, Days on Market isn't really a fixed value that can be cached in her database; it's more of a fluid value that is dependent on both data and rules that are internal to the MLS and – especially – dependent on the passage of time. Always go to the sourceConnie, knowing that the true source for Days on Market is the MLS, decides the only way to 100% faithfully represent the Days on Market is to always consult the true source. She does a little digging with OneMLS's API and realizes that when she queries for the listing the agent told her about now, the data she gets back accurately represents Days on Market changes, but the ModificationTimestamp she uses for replication hasn't changed change. "Is that right?" she wonders as she re-reads the description of the ModificationTimestamp field. But she decides maybe the listing wasn't modified per se, only the passage of time has occurred. Whatever. Connie doesn't have time for philosophy; she has a budding business to run and a bug to fix! Anyway, with the discovery that whenever she queries OneMLS's API it gives her the current value for Days on Market, Connie tweaks her website a bit. When a request to one of her listing pages comes in, all of the data except Days on Market comes from her database – still super fast – but the Days on Market widget sends off a separate request to the MLS to get the most up-to-date value. The few listings she checks look accurate so she deploys the fix. 🤕 Thirty-seven minutes later she receives a call from OneMLS asking why her site is flooding their server with API requests. They're glad her site seems to be getting good traffic, but if she doesn't stop sending requests immediately, she'll be either rate limited or the MLS will be forced to cut off her access entirely. Oof. Big, embarrassing mistake. Connie realizes that while she was trying to stay on the MLS's good side by being a good steward of the MLS's data, she ended up being on their bad side because she wasn't being a good steward of the MLS's resources. So even though the MLS is the source of truth, Connie realizes that if her site is going to show listing data to a non-trivial number of visitors, her site really does need to cache MLS data in a local database. Reconcile active listings once a dayFortunately for Connie, the solution is right there in the name of the field. It's Days on Market. Not Minutes on Market. Not Hours on Market. Days on Market. Connie only needs to go back to the MLS once a day to get an up-to-date Days on Market value for all the active listings she's showing. "But wait," Connie thinks, "when do MLSs actually update their Days on Market?" Let's all give a hand for Connie because she's thinking ahead. So one night, she finds an active listing, stays up until midnight, and then every 5 minutes requeries the API for that listing. Midnight: not updated. 12:05: nope. 12:10: nada. 12:15: wow, still no? Tired but persistent, she keeps at it. Ah, there it is, between 1:10 and 1:15 the Days on Market updated – oh that's right, that MLS is in the next timezone West. So Connie sets up three new daily schedules, based on what timezones she believes each MLS to be in, and sets them to run at 1am local time for each – to give each MLS ample time to make sure all of the listings are updated. Displaying the wrong Days on Market value for about an hour a day makes Connie feel like she's violating her "be a good steward of the data" values, but she mollifies herself by thinking most people are sleeping at that time of night anyway. And she also doesn't like that she now needs a custom schedule for each MLS – that feels kinda non-standard – but if it gets the job done, great! 😬 Things are mostly good, until the same agent gives her another call. He has three active listings that now all look correct, but he has one listing that is under contract with the wrong Days on Market. He doesn't particularly care, but he thought Connie might care so he called to give her a heads up. Ah, that's right. Connie only reconciled active listings. Other listings also probably change their Days on Market, too. Connie thinks that can't be too hard to fix. Reconcile more statuses once a day"What statuses do need to be reconciled?" Connie wonders. Looking through the existing standards doesn't yield much, just that every MLS has their own rules. And she's not surprised to find out that there's no place any of the rules are published. But that lingering fear of misusing the MLSs' resources again lingers, so she's determined not to reconcile every listing. By this time, she has amassed information about a lot of closed listings, and surely they don't have incrementing Days on Market, do they? She hopes not. Not wanting to pull another all-nighter, Connie decides to call her contacts at the three MLSs. While they can't divulge their full rules, they do tell her which statuses factor into the calculation. Unfortunately for Connie, the statuses from OneMLS that she needs to use when reconciling and the statuses from TwoMLS that she needs to use when reconciling are different statuses. Connie once again writes more MLS-specific code into her reconciler code for each MLS she works with so that she is reconciling the correct statuses. And she quietly hopes the MLSs don't change their rules without telling her. The next morning, she checks the under contract listing and it has the right Days on Market value, so her reconciliation code is working great! Time to schedule a long-overdue night out with some of her friends! 😮💨 When she wakes up the next morning, she has a voicemail from another agent. Hoping she didn't make any calls she doesn't remember, she listens. Ah good, no ill-advised calls, but this agent is saying that Days on Market for ThreeMLS has been wrong on her site for weeks – active listings, under contract listings, pending listings, pretty much all of them except closed listings. What? Is her reconciler not working like she thought? But she checked the results from OneMLS and everything was looking good? Not all APIs work the same wayConnie starts digging into the API for ThreeMLS more closely. Really closely. She looks at her code. She looks at her data. She looks at her logs. And finally, she sees it. The API for ThreeMLS behaves differently from the APIs for OneMLS and TwoMLS. The API for ThreeMLS only updates the Days on Market field when there is an unrelated change that causes the ModificationTimestamp field to update. Is that standards compliant? Connie has no idea. What Connie does know is that this is the API ThreeMLS has given her access to and she can't change it's behavior. What Connie does know is that she has customers that use this MLS and she can't leave them hanging. What Connie does know is that she needs to figure out a way to make this work. Aside: the Rolodex analogyConnie decides to call her friend Melissa at ThreeMLS. So Connie gets out her trusty Rolodex and finds Melissa's information. Yes, apparently this story takes place in some sort of a time anomaly where RESO Web API standards exist but people still commonly use a Rolodex. Don't ask. Preparing to chit-chat, Connie refreshes all of the info she knows about Melissa – the names of her kids, that she likes to play tennis, and— huh, Connie wrote down that she's been at ThreeMLS for 2 years. But when did she write that? When Connie wrote that information makes a big difference. If she wrote it 3 years ago, that would mean Melissa has been at ThreeMLS for 2+3=5 years. But if Connie wrote it yesterday (apparently the RESO/Rolodex time anomaly also sometimes affects Connie's memory) then Melissa has been at ThreeMLS for only 2+0=2 years. Connie has an epiphany. The next time she talks to Melissa, she's going to ask her how long she's been at ThreeMLS and she's going to write down both the answer she gets back and when she received that answer! With those two bits of information together, she can always be accurate when talking to her friend. And for Days on Market... Combining DaysOnMarket and ModificationTimestampConnie doesn't even call Melissa. Friends can wait, she has a solution. She puts on a pot of coffee and starts working late into the evening. For ThreeMLS, she has two bits of useful information she can use. The data doesn't tell her what the Days on Market value is, it tells her what the Days on Market value was at a particular time, and that particular time is the ModificationTimestamp. If Days on Market was 7, and it was that as of 4 days ago, then Days on Market now is 7+4=11. So she writes up some code to calculate the number of days between the ModificationTimestamp and now, and add that to the number of Days on Market. She checks it against a few of listings in ThreeMLS, and it looks like it's working. Surely she has everything figured out now, right? 🤔 The next day, she receives another call from her agent friend. Before she answers, she immediately knows what she did wrong. She applied this code to all of the MLSs she works with, but now both OneMLS and TwoMLS are over-counting because their Days on Market values are as of this morning, not as of their old ModificationTimestamp values. For OneMLS and TwoMLS, she has data telling her what the Days on Market value was, but not an associated time for when it was that value; ModificationTimestamp is certainly not the right timestamp. Calculate based on when the data is fetchedWell, that's a pretty simple problem to fix, Connie decides. Instead of using the ModificationTimestamp, she'll use the time at which she fetched the data. That will work for both OneMLS and TwoMLS because she reconciles the data every day, giving her an up-to-date Days on Market and an up-to-date fetch date. And it will work for ThreeMLS because the fetch date will always be very close to the ModificationTimestamp. Connie has now sunk a lot of time into being as accurate as possible with Days on Market, and she is feeling pretty good about the system she has put in place – custom MLS code and all. Success. 😏 You know exactly where this is going, don't you reader? It was not success. There is yet another problem. And that problem is intermediaries. IntermediariesConnie's business is booming and she decides to bring on a fourth MLS – FourMLS. She determines what statuses she would need to reconcile on. She throws that information away because she determines that FourMLS's API behaves like ThreeMLS's API so reconciliation isn't an option. She also determines that the API she gets data from is not run by FourMLS, it's run by an intermediary. Apparently that's because FourMLS still uses RETS internally. Connie doesn't know what RETS is, but that information doesn't seem like it should matter anyway, so she files it away. She rolls out FourMLS and gets a bunch of new customers. Things are going well. 😠 And then, one day, suddenly, all of the Days on Market calculations for FourMLS are wrong. Aside: Rolodex revisitedConnie has no idea what's wrong. To figure it out, she realizes she needs to call somebody at FourMLS. But she also realizes she doesn't have a contact there. So instead Connie calls Melissa at ThreeMLS again. After chitchatting (and making sure to update her information about how long she's been working at the ThreeMLS – 4 years!) Connie asks if Melissa has a contact at FourMLS. Melissa does! Her old high school friend Melvin works there. Melissa looks at her own Rolodex (still a time anomaly) and starts spewing information at Connie: Melvin doesn't have any children but he does have two cats; he's big into knitting; he's been at FourMLS for 2 years. "Wait a second," Connie interrupts, "you say you have written on your Rolodex that he's been at FourMLS for 2 years, but when did you write that?" Melissa doesn't know, and doesn't quite understand what Connie is getting at. Again, epiphany. Connie realizes that the intermediary API that FourMLS uses sometimes updates listings because they have changed in FourMLS directly. And sometimes the API updates listings because of work done in the API itself, like updating a schema mapping. But what the intermediary API doesn't do is record any value that Connie can use as the when for calculating Days on Market. Connie can track the fetch time when she fetched from the intermediary API, but if the intermediary doesn't track its own fetch time, Connie still can't be accurate. The Final Chapter?With this fresh knowledge and no idea how to solve this problem, Connie has her greatest realization yet. She stops trying to stay in sync on Days on Market entirely and instead changes the label on her site from "Days on Market" to "Days on Connie's Site", using the number of days between when her site first saw the listing and now. While that doesn't match any of the MLSs' calculations, at least she can work on her next big feature. Recap
|
Beta Was this translation helpful? Give feedback.
-
Reconciliation and auto-incrementDuring the Transport Working Group discussion there was some talk about whether we can re-use the Much of that discussion centered around the fact that for some MLSes, Much of the focus of this proposal has been around not requiring reconciliation at all (especially since reconciliation is not always possible). However, I am convinced this proposal and reconciliation work together nicely. For APIs that do support reconciliation by calculating on output, does it make sense for @SergioDelRioT4Bi @grispin I think you two were heavily in the "lets not re-use DaysOnMarket" camp. I'm curious if calculating |
Beta Was this translation helpful? Give feedback.
-
I am certainly not dead-set against re-using the same field. From my perspective, it was really more about isolating this change and to come up with more appropriately named fields for the future so it may be more understandable that this field needs special care and handling. I think it works just as you have outlined here. |
Beta Was this translation helpful? Give feedback.
-
My reason for not wanting to reuse the DOM field is to have the new DOM model strictly follow the replication standards. The current DOM field is tainted with all sorts of special handling and rules (don't touch timestamps when changing, no entity events, etc.) that producers and consumers implicitly know. This coupled with the change in The change in behaviours on the field are going to take some time to implement so we are going to need a deprecation period where both exist while consumers migrate from one solution to the new one and provider have both implemented to allow for this migration window. The new DOM needs to follow all of the record handling rules that we have in the specification to make the replication issue easier to solve. Changes to the DOM start value, Timestamp and YN fields must trigger modification timestamp updates, entity events, webhook subscriptions, etc. Without this requirement we are not fully addressing the pain point that generating this issue. The goal is a DOM that is easily replication from a provider to a consumer without the consumer having to constantly check the data is accurate. Consistent replication was why I was arguing against the the dynamic Timestamp field. If I pull the record yesterday, today and tomorrow and the modification timestamp has not changed, then neither should the records data fields. The fact that the data fields can change without notice makes replication more complex and causes the call back behaviors we see today. The new DOM fields should fallow all the modification timestamp and entity event rules to make replication easier. For this reason, the DOM fields should only be touched as infrequently as possible to reduce modification events to keep replication overhead low. The DOM fields should really only need to be changed when one of the fields that affect DOM rules are touched. |
Beta Was this translation helpful? Give feedback.
-
Issue created. See #150. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
The Days on Market auto-increment proposal is a proposal that adds three new fields to the Property resource of the Data Dictionary, and defines how those three fields work together to help MLSes, data providers, and consumers stay in sync with respect to Days on Market.
Key points of emphasis
There are two key points of emphasis regarding this proposal.
Point 1. This proposal does not try to standardize how the MLS calculates Days on Market nor does it require the MLS to share their method of calculating Days on Market or require the MLS to share all of the data points that go into calculating the Days on Market. The MLS remains the source of truth for Days on Market.
Point 2. This proposal does require that when an MLS provides a Days on Market value, it also provides an associated reference timestamp. By using these two values, consumers are able to interpolate the Days on Market value in the time between updates to a listing.
Age and record keeping
How old are you? It's a question you probably know the answer to. In a way, your age is one of data points that make up who you are.
And when communicating with humans, telling someone your age (although sometimes taboo) is far more convenient than telling them what year you were born.
That said, you likely have a driver's license or an identity card of some sort. If you look at it, you won't find your age written anywhere on it. Why not? Because if it was, you'd have to get a new one every year.
Instead, what you will see is your birthdate, a reference date that can be used to calculate your age no matter what day it is.
When we store and retrieve records, it's typically more accurate to store data points independent of time.
Days on Market is more complicated than your age, but the idea for this proposal is the same: instead of giving out an age (the exact number of days a listing has been on market) at a particular point in time, this proposal provides a way to give out three pieces of reference data that make it easy to increment the number Days on Market since the last data fetch no matter how long it has been since that data fetch.
The new fields
How it works
Whenever a listing gets updated via an API call (whenever the
ModificationTimestamp
changes), the MLS provides three values that represent the instantaneous Days on Market at that point:DomIncrementBase
– a number of days that form the base of the increment calculation; typically the number of days on market at the point the listing was updated.DomIncrementTimestamp
– a timestamp to use when calculating how many days to add to the base number.DomIncrementYN
– whether the listing should have an incrementing Days on Market.Every time a listing is updated in the source system, these three values also get updated, giving the consumer an up-to-date view of Days on Market.
Between listing updates – especially if several days elapse between listing updates – the consumer is able to increment the number of Days on Market using the three values to stay in sync with the MLS.
The constant case is when
DomIncrementYN
isfalse
(this is common for Closed listings, but may also befalse
for Pending listings depending on MLS Rules). In this case, Days on Market isDomIncrementBase
. (It's constant with respect time time.)The incrementing case is when
DomIncrementYN
istrue
(this is common for Active listings). In this case, for a consumer to display the same value as what the MLS displays, the consumer must calculate the number of full days sinceDomIncrementTimestamp
(e.g. ifDomIncrementTimestamp
is more than 3 days ago but less than 4 days ago, this difference is 3), and add value to theDomIncrementBase
.Further reading
DaysOnMarket
case studies: https://gist.github.com/bryanburgers/8a450ac2ec584e80c1226163ae234ee8Example
We'll start with a new listing, listed by an agent on April 21. According to the local rules of the MLS in this example, the listing starts with a Days on Market value of 1.
DomIncrementYN
true
DomIncrementBase
1
DomIncrementTimestamp
2024-04-21T00:00-07:00
ModificationTimestamp
, and in this case it is midnight local time of the day represented byDomIncrementBase
.On the day that the listing is posted, we can use the calculation to determine the current Days on Market. We start our calculation with the base, which is 1 according to
DomIncrementBase
. And then we add the total number of full days betweenDomIncrementTimestamp
and now. The day the listing was posted, this value is 0. So 1 + 0 is 1.The next day, April 22, the consumer hasn't received another listing update yet. So the base is still 1 according to
DomIncrementBase
. However, on April 22, the number of full days sinceDomIncrementTimestamp
is now 1, so the calculation yields 1 + 1 = 2.Until the consumer recives another listing update, the calculation continues on. On April 23, the calculation yields 1 + 2 = 3. Note that we're essentially incrementing Days on Market by 1 each day until we receive more information from the MLS.
At the start of April 24, we still haven't received a listing update, so our calculation continues to yield
DomIncrementBase
(1) + days sinceDomIncrementTimestamp
(3) = 4.Later on April 24, an agent makes an update to the listing's price. This causes the listing to be updated, which causes the consumer to refetch the listing and get an updated listing payload.
At this point,
DomIncrementBase
,DomIncrementTimestamp
, andDomIncrementYN
get new values.DomIncrementYN
true
DomIncrementBase
4
DomIncrmentTimestamp
2024-04-24T00:00-07:00
With the new values, on April 24, there are 0 full days between now and
DomIncrementTimestamp
so days on Market is 4 + 0 = 4. Note that although the values for these fields changed, the resulting calculation did not. Both before and after the update, the value the consumer calculates is 4.At this point, April 25 shouldn't be a surprise.
On April 26, the listing changes status to pending. The local rules for the MLS in this example dicate that Days on Market does not increase while a listing is in the pending status. Because of that, the values returned are
DomIncrementYN
false
false
which indicates that Days on Market will not increase every day.DomIncrementBase
6
DomIncrementYN
isfalse
.DomIncrementTimestamp
2024-04-26T00:00-07:00
For the entire rest of April 26, Days on Market is equal to
DomIncrementBase
.On April 27, Days on Market is also equal to
DomIncrementBase
. No extra days are added to the value, becauseDomIncrementYN
isfalse
.Days on Market will continue to be 6 until we receive a new listing update that indicates otherwise.
On April 28, the listing is still in a pending state and
DomIncrementYN
is still false, so the Days on Market is still 6.Later on April 28, the listing comes back on market. The Days on Market values in the listing update include:
DomIncrementYN
true
DomIncrementBase
6
DomIncrementTimestamp
2024-04-28T00:00-07:00
On April 28 after the update, there are 0 full days between
DomIncrementTimestamp
and now, so Days on Market is 6 + 0 = 6.On April 29 at Midnight local time, there is 1 full day between
DomIncrementTimestamp
and now, so Days on Market is 6 + 1 = 7.On April 30 at Midnight local time, there are 2 full days between
DomIncrementTimestamp
and now, so days on Market is 6 + 2 = 8.Beta Was this translation helpful? Give feedback.
All reactions