I'm creating system for a company renting apartments. All pricing setup is based on some periods. For example an apartment in category 'Junior Studio' there are price periods:
30.05.2016 - 31.01.2017: 3000 EUR
01.02.2017 - Infinity: 4000 EUR
There are also additional periods like: taxes, seasonal price(plus/minus some percent value), and fees based on other periods. So prices can vary often, for example:
31.05.2016 - 30.06.2016 (3500EUR because of some seasonal price period)
01.07-31.08.2016 (5000EUR other seasonal price period)
01.09.2016 - 31.01.2017 (3000 EUR)
01.02.2017 - 4000 EUR.
Also, if someone wants to rent an apartment, for example less than 15 days, there is additional fee, let's say 15% - all this is set up dynamically.
Now the problem is on our page we should let user find apartments based on their price. For example some users want to find only apartments where the price varies between 3000 - 4000 EUR and rent an apartment for 6 months. As I said price can change for example 5 times on those periods so I'm looking to calculate an average price.
Have you any idea how implement this algorithm to incorporate all the specified periods? We assume there can be for example 500 possible records so computing this dynamically could probably cause performance issues.
UPDATE
Here is some code to take periods related to one apartment category for one building:
private RentPriceAggregatedPeriodsDto prepareRentPriceAggregator(Long buildingId, Long categoryId, LocalDate dateFrom, LocalDate dateTo, Integer duration) {
List<CategoryPricePeriod> pricePeriods = categoryPricePeriodRepository.findCategoryPricePeriods(buildingId, categoryId, dateFrom, dateTo);
List<SeasonalPricePeriod> seasonalPricePeriods = seasonalPricePeriodRepository.findSeasonalPricePeriods(buildingId, categoryId, dateFrom, dateTo);
List<LastMinuteRatePeriod> lastMinuteRatePeriods = lastMinuteRatePeriodRepository.findLastMinuteRatePeriods(buildingId, categoryId, dateFrom, dateTo);
List<TaxesDefinitionPeriodDto> taxesDefinition = taxesDefinitionService.findTaxPeriodsForBuildingAndCategory(buildingId, categoryId, TaxTypeCode.VAT,
dateFrom, dateTo);
Optional<SurchargePolicy> surcharge = surchargePolicyRepository.findForDurationAndRentalObjectCategoryIds(categoryId, buildingId, duration);
return new RentPriceAggregatedPeriodsDto(pricePeriods, seasonalPricePeriods, lastMinuteRatePeriods, taxesDefinition, surcharge);
}
Based on all those periods I prepare list of unique price periods: dateFrom, dateTo, currency, value. After those steps I have list of unique prices for one category. Then I need to compute how many days of booking is in each of those unique price periods and multiply it, maybe round + multiply by tax and sum it to have final price for booking. Now re-run those steps, let's say, 500 times (multiple categories in multiple buildings).
As mentioned in the comments, averaging 6 numbers 500 times on the fly should not cause any performance issues.
Even then, if you'd want O(1) performance on computation of price (i.e. the calculation should not depend on the number of price switches in the mentioned period), you could preprocess by defining a date as day 0, and computing the amount of total rent that would be required for all days beyond that. When a user requests the average rent between a period, subtract the total rent till day zero from the two days, giving you the rent for the period in between. Dividing this by the number of days will give you the average rent. You can also add suitable multipliers depending on duration of stay (to add the 15% charge), etc. This is similar to finding the sum of values between two indices in an array in O(1). This is not a memory friendly suggestion, although one can modify it to use less memory.
The advantage is that the computation to give results will not depend on the number of price switches. However, every additional change in apartment rents will cause some amount of preprocessing.
I think you actually need two algorithms. One for representing and querying the object price at any given time. And another one for computing the price for renting an object for a given time period.
As for the representation of the object price, you should make a decision about the temporal granularity you want to support, e.g., days or months. Then create a lookup table or a decision tree, a neural network or anything to lookup the price at the given day or month for the given object or object class. You can factor in all the variables you'd like to have in there. If you want to support special prices for renting full calendar months, have another data structure for this different granularity, which you query with months instead of dates.
Then, given a period of time, you need to generate the corresponding series of dates or months, query for the individual daily or monthly prices and then compute the sum to get the total price. If you want to, you can then compute an average daily/monthly price.
I don't think performance will be an issue here. At least no issue you should address before coming up with an actual solution (because, premature optimization). If it is, consider scaling up your database.
Related
I can get bid and ask data from my market data provider but I want to convert this in OHLC values.
What is the good calculation using bid/ask? I saw in a post that for a specific period:
Open = (first bid + first ask) / 2.
High = Highest bid
Low = Lower ask
Close = (last bid + last ask) / 2
Is it true?
You are getting confused with terminology. In forex:
Ask is the price that you, the trader, can currently buy at.
Bid is the price that you, the trader, can currently sell at.
OHLC are historical prices for a predetermined period of time (common time periods at 1 min, 5 min, 15 min, 30 min, 1 hour, 4 hour, daily and weekly) and are usually used to plot candle stick charts (and tend to be based on the Bid price only).
Open - This is the bid price at the commencement of the time period.
High - This is the highest bid price that was quoted during the time period.
Low - This is the lowest bid price that was quoted during the time period
Close - This is the last bid price at the end of the time period.
Conversion between the two is not always straightforward or even possible. What many beginners (including myself) stumble upon:
Ohlc data represents trades that did actually happen. Bid and ask represent requests for trades that might never happen.
Simplified example:
Let's say investor A wants to sell 100 shares of a specific company for 20$ each, so he places ask(100,20) on the market. Investor B wants to buy 100 shares of the same company, but only wants to pay 18$ each, so he places bid(100,18).
If both are not willing to change their price, no trade will happen and no ohlc data will be generated (if no other trades occur in this timeframe).
Of course, one can assume that if trades happen in a specific time frame, h will be the highest price someone is willing to pay (highest bid) and l will be the lowest price someone is willing to sell for (lowest ask), as those orders have the highest chance of being met. But I think o and c values really depend on which bids/asks actually turned into a trade.
From POWER BI table containing a simple series of yearly results (profit or loss), I'm trying to calculate yearly taxable income. For that,
losses from one or several previous years can be deducted from current profit
if the amount of previous losses exceeds the amount of current profit, that excess can be applied to profit
however, the excess of profit over losses can not be applied to further losses
Therefore, taxable income in a loss year is always =0, and always >=0 in a profit year.
The outcome I´m after might be something like this:
Taxable income calculation
The issue here is that "Previous losses compensation" depends on "Previous losses balance" and viceversa, generating a circular dependency. I've tried with both measures and calculated columns, to no avail.
Any suggestion will be very much appreciated. Thanks in advance.
For what it's worth, I think I came out with some sort of solution here. Data lie in [Tabla5], and I defined
Year's result = SUM(Tabla5[RCAT])
In the first place, I considered that every time there's a positive result immediately after a loss, there must be a compensation:
Last year's loss compensation =VAR _Comp=
SUMX(Tabla5,
VAR _CurrentResult= [Year's result]
VAR _LastResult=MAXX(FILTER(ALL(Tabla5),Tabla5[Year]=EARLIER(Tabla5[Year])-1),[Year's result])
RETURN
IF(
AND(_LastResult<0, _CurrentResult>0),
MIN(_CurrentResult,ABS(_LastResult)),0
)
)RETURN_Comp
Secondly, we need to find out the amount of tax credit available after this first compensation, by means of:
Cumm First compensation = CALCULATE([Last year's loss compensation], FILTER(ALL(Tabla5),Tabla5[Year]<=MAX(Tabla5[Year])))
and
Prior losses = SUMX(FILTER(ALL(Tabla5),Tabla5[Year]<MAX(Tabla5[Year])),IF([Year's result]<0,ABS([Year's result]),0))
and
Tax credit available = [Prior losses]-[Cumm First compensation]
The third step would be comparing this tax credit still available to the amount of profit available for compensation:
Profit available for compensation = IF(
AND([Year's result]>0, [Tax credit available]>0),
[Year's result]-[Last year's loss compensation],0
)
and
Cumm Second Compensation = MIN(SUMX(FILTER(ALL(Tabla5),Tabla5[Year]<=MAX(Tabla5[Year])),IF(AND([Year's result]>0, [Tax credit available]>0),[Profit available for compensation])),[Tax credit available])
The difference between years of this last measure will bring the value of the current year´s second compensation:
Prior years losses compensation = [Cumm Second Compensation]- MAXX(FILTER(ALL(Tabla5), Tabla5[Year]=MAX(Tabla5[Year])-1),[Cumm Second Compensation])
Finally, we just need to sum both compensations and substract that value from current year's profit in order to find taxable income:
Total compensation = [Last year's loss compensation]+[Prior years losses compensation]
and
Taxable income = IF([Year's result]>0, [Year's result]-[Total compensation],0)
The outcome would be something like
Outcome
I've been trying to buid a one-measure-only solution, but I came across with some row/filter context issues that made it too complicated to me. Maybe someone could sort this out.
I want to create a stock exchange simulation using C# programming language. But I couldn't decide on how to specify the price of an asset.
For example, the following table is an order book for an asset:
Buy Sell
----------------------------- ----------------------------
ID Time Size Price ID Price Size Time
4 8:00:04 250 100 1 101 750 8:00:01
6 8:00:10 500 100 5 101 500 8:00:05
2 8:00:01 750 97 8 101 750 8:00:30
7 8:00:10 150 96 3 102 250 8:00:02
The simplest order book matching algorithm is a price-time-priority algorithm. That means that the matching priority firstly is price and then time. The participants are rewarded for offering the best price and coming early.
Every asset has a current price in stock exchanges. But how can I calculate the price of this asset? Is there any algorithm for this?
An exchange will usually show the 'top of the book', showing best bid (the highest number someone is willing to buy at) and ask (the lowest price someone is willing to sell at).
Where you see an exchange offering a single price, it is derived in one of two ways:
if there have been recent (valid) trades, then it is the last traded price
otherwise, it is the reference price
What is a Reference Price?
Most equity and derivatives exchanges maintain a reference price for each book. This is used to prevent acceptance of orders which would be too far from the reference price - aka 'extreme trading range'.
Usually the reference price is set to the last traded price during the day, but how is it set in the first place before any trading happens?
The reference price is usually determined after each trading reset (e.g. start of day, start of week or start of a new book) as one of the following in order of precedence:
price discovered during an initial auction period (usually only in equity markets)
if no auction, then last traded (or settled, depending on the market) price
use a price from another market operator running the same book
or the market operator can use it's own 'reasonable' method to determine a reference price, e.g. for an initial listing of a new security
How to apply this?
So if you want to set a new 'current price' in BTC but you don't yet have any trades on your book, then because BTC is already widely traded you can:
use the last price traded on binance for the pair you're running
take a mean or median of last prices from multiple BTC books run by others
manually set some other price you think will attract both buyers and sellers
I want to graph a portfolio of stock trades over a period of say one year.
I will have many trades with many different stocks. The question becomes, what is the best way to calculate the value of the profile over the year.
1) Query for all transactions before or on the start of the period.
2) Calculate their price and totals on that day.
Now, what would be the best method?
Do I loop through each day in the period selected, then find and sum all transactions on a stock before that day.
Loop through all the stocks, sum, store and then do it again for the next day?
How do the pros do this? Curious.
Similarly to what happens in reality, you should go day by day.
You move to the next day only after you summed all the transactions on all stocks at a certain day.
This will allow you to impose portfolio-level restrictions and allocation.
Some examples:
You trade 30 stocks. Capital is equally shared between all stocks. If one stock goes below $5, you don't trade it. Then, you allocate all the capital to the other 29 stocks.
You observe the correlation between the stocks. If 5 stocks are highly correlated, you allocated less capital to each.
You have 30 stocks in your symbol universe, but you only trade up to 10 stocks in parallel, according to relative performance of trades you took on each stock.
This kind of management will be possible only when you calculate all transactions per day before moving to the next.
Sorry if the title is confusing, I'll just try to describe here I want to achieve.
I want to optimize my database design that handles delivery, and ending inventory. Delivery is done anytime of the week and is group by week number, orders can be done anytime of the day; orders quantity are then subtracted to the total no of delivery per week to get the ending inventory. What's the best database design for this, and programming approach?
What I have:
Deliveries table with quantity, weekNo, weekYr
Orders table with quantity, weekNo, weekYr
Everytime I want to get the ending inventory I will get and group the data base on weekYr and weekNo and subtract total Deliveries quantity minus Orders quantity. But my problem is the ending inventory will be carried out to the next week. What's the best and optimized way to do it?
Thanks,
czetsuya
Your current approach seems sound to me, so you might clarify what the actual problem is. Your last sentence is confusing--does the product spoil at the end of the week? It's not clear why you would need to group by week at all. If you get 100 products via delivery, and sell 10 products per week for the next three weeks, you have 70 products left.
My best guess is you have a case where there are other factors to consider besides the simple math of what was received minus what was sold. Perhaps you lose inventory due to spoilage (maybe you sell some sort of food) or shrinkage (maybe you sell retail goods that get stolen). One solution would be to have a separate table called "shrinkage" or "spoilage" that also gets subtracted out of deliveries to arrive at your actual inventory. Of course, this table will need to be updated as product is removed from the shelves due to spoilage, or when the shrinkage is realized.