Calculating Weekly Returns from Daily Time Series of Prices v2 - vba

This is a slightly adjusted version of the question here: Calculating Weekly Returns from Daily Time Series of Prices which was answered by #Scott Craner:
I want to calculate weekly returns of a mutual fund from a time series of daily prices. My data looks like this:
A B C D E
DATE WEEK W.DAY MF.PRICE WEEKLY RETURN
02/01/12 1 1 2,7587 -0,0108
03/01/12 1 2 2,7667
04/01/12 1 3 2,7892
05/01/12 1 4 2,7666
06/01/12 1 5 2,7391
09/01/12 2 1 2,7288 0,0067
10/01/12 2 2 2,6707
11/01/12 2 3 2,7044
12/01/12 2 4 2,7183
13/01/12 2 5 2,7619
16/01/12 3 1 2,7470 0,0511
17/01/12 3 2 2,7878
18/01/12 3 3 2,8156
19/01/12 3 4 2,8310
20/01/12 3 5 2,8760
23/01/12 4 1 2,8875
The date is (dd/mm/yy) format and "," is decimal separator. This would be done by using this formula: (Price for first weekday of next week - Price for first weekday of current week)/(Price for first weekday of current week). For example the return for the first week is (2,7288 - 2,7587)/2,7587 = -0,0108 and for the second is (2,7470 - 2,7288)/2,7288 = 0,0067.
The problem is that the list goes on for a year, and some weeks have less than five working days due to holidays or other reasons. Some weeks start with weekday 2, some end with weekday 3. So I can't simply copy and paste the formula above. I added the extra two columns for week number and week day using WEEKNUM and WEEKDAY functions, thought it might help. I want to automate this with a formula and hope to get a table like this:
WEEK RETURN
1 -0,0108
2 0,0067
3 0,0511
.
.
.
I'm looking for a way to tell excel to "find the prices that correspond to the min weekdays of two consecutive weeks and apply the formula "(Price for first weekday of next week - Price for first weekday of current week)/(Price for first weekday of current week)".
I would appreciate any help! (I have 5 separate worksheets for consecutive years, each with daily prices of 20 mutual funds)

It seems to me that you can generate your column E with this formula in E2 :
=IF(B2=B1, "", (VLOOKUP(1+B2, B3:D9, 3, FALSE) - D2)/D2)
It's a VLookup limited on the next 7 rows from each row that declares a new week.
Copying into all cells will give the result indicated in your first tableau. To transform this result into to the list (Week, Return) is a matter of a filter that hides blanks from E.
Notice that a problem could occur if the WeekNum restarts from one when a new year is reached, but since you say that each of your sheets is for one (calendar) year, it shouldn't happen.

Related

Redshift SQL SUM over fixed number days

I'm currently stucked on an issue. I have daily data and I want to SUM all the data for the next 30 days over a year.
Date
Views
28-01-2021
1
29-01-2021
5
30-01-2021
1
31-01-2021
5
And I want to have the number of views starting the 28th for the next 30 days, then the next 30 days etc... over a year (or twelve times)
So basically what I want to see is something like this, Series being the series of 30 days (first 30 days, second 30 days etc...)
Series
Views
1 (from 28-01 to 28-02)
250
2 (from 01-03 to 30-03)
200
3 (from 31-04 to 29-04)
300
4 (from 30-04 to 29-05)
550
Thank you if anyone can help.
Regards
Assuming you have one row for each day, you can use a window function:
select t.*,
sum(views) over (order by date
rows between current row and 29 following
) as views_30days
from t;
Note: This interprets "next 30 days" as really being "today plus the next 29 days". If you don't want the current day, then the window frame would be:
rows between 1 following and 29 following

Display target value for week when targets are in 4 week increments

I have a targets table which goes up in increments of 4 weeks like so
Week
Target
1
12345
5
67890
9
12345
I then have a calendar table from which I would display all 52 weeks of a year. I would like to list the target for the higher week where the week number is between 2 week numbers. E.g. Week 4 will use the target for week 5 as it is between 1 & 5.
I have tried CTEs and left joins but this will not bring back every number in the calendar table, only those found in the target table. I have also tried cross apply and a number of ways to join. I am stumped at this point
You can just join with arithmetic:
select . . .
from calendar c join
targets t
on ceiling((c.week - 1) / 4.0) * 4 + 1 = t.week

QV - Count days in a year in script

In the script I need a counter to give the same day (in different years) a number, and when a new year begin it will start from 1 again. So when I reload my script I want a table that look like this:
Date Number
01/01/2015 1
...... ...
10/30/2015 303
10/31/2015 304
11/01/2015 305
.... ...
12/31/2015 365
01/01/2016 1
01/02/2016 2
.... ....
How can I do this?
DayNumberOfYear(date[,firstmonth])
Returns the day number of the year according to a timestamp with the first millisecond of the first day of the year containing date. The function always uses years based on 366 days.
By specifying a firstmonth between 1 and 12 (1 if omitted), the beginning of the year may be moved forward to the first day of any month. If you e.g. want to work with a fiscal year starting March 1, specify firstmonth = 3.
You could try subtracting the Date from the beginning of the year of the Date
Date-makedate(year(Date),1,1)+1 as Number
You'll need a bit more maths if leap years are going to matter in you analysis.

Need Excel Sheet to Calculate Complex Vacation Accrual and Use of Vacation Time

I've been working on this for a while and trying different styles... I need to develop a tracking spreadsheet (for 50 employees) that will calculate accruing vacation time and vacation time used based on the following parameters:
*Employees who have worked less than 3 years but past the 90 day anniversary with the company (at which they start accruing) (there is one more caveat on this... the accrual day is the 1st of the month of the month past the 90 days)[I figured this 90 day item out on my excel sheet] it will accrue at:
- 4 hours a month, at the end of the month, with a MAX cap of 72 hours that they can have stored (but if they use vacation time and fall below the 72 hours they can continue to accrue again up to 72 hours...)
*Employees who have worked more than 3 years but less than 6 years with the company carry over their prior vacation and begin to accrue from here onward at:
- 6.8 hours a month, at the end of the month, with a MAX cap of 122.4 hours that they can have stored (but if they use vacation time and fall below the 122.4 hours they can continue to accrue again up to 122.4 hours...)
*Employees 6 years and over with the company carry over their prior vacation and begin to accrue from here onward at:
- 10 hours a month, at the end of the month, with a MAX cap of 180 hours that they can have stored (but if they use vacation time and fall below the 180 hours they can continue to accrue again up to 180 hours....)
& yes, I need to be able to deduct vacation time used.
Does anyone have any suggestions for layout or for a formula that can do part of these functions? I appreciate any advice or suggestion on what else I can use!
I have created a test sheet, and was accruing based on these conditions for the first and started on the second set of rules (for years 3+).
However when I accrue to the max of 72 hours on the first policy, it no longer accrues correctly if they used vacation and fall under the 72 hours cap again.
I know this is a overcomplicated policy, but that is what the company wants and they will not budge.... Any help or advice is appreciated. I know my sheet isn't great.. but I'm trying options.
Below is the equation I used for the 90 day:
=IF(F2<TODAY()-90, F2+90, "90 Day Period")
Then to get the first day of the month after I used:
=IF(G2="90 Day Period","N/A",DATE(YEAR(G2),MONTH(G2)+1,1))
I tried using for the accrual of the first rule (but it has issues...):
=IF(N2="N/A","N/A",IF(N2<=36,MIN(72,((N2*4)-P2),72),(72-P2)))
For second rule:
=IF(AND(N2>36,N2<=72),MIN(122.4,((N2-36)*6.8)+Q2-S2),0)
Let
column A EmpName
column B EntryDate
Column C DaysSpent for the current month
Column D capped Accruel buffer at end of month
repeat Columns C and D month after month
example
01-Sep-2013 01-Oct-2013
EmpName EntryDate spent buffer spent buffer ... etc ...
.-------.-----------.-----------.------.-----------.------.
me 01-Jan-2010 0 12 0 18.8
you 01-Jun-2013 0 4 0 4
In order not to get spaghetti formulas I recommend to create some user defined functions in VBA, like
Function GetCap(EntryDate, ThisDate) As Single
Function GetMonthly(EntryDate, ThisDate) As Single
By experience it's easier to debug/maintain 2-3 nested If's or Select Case's in VBA than 92 character long formulas with no blanks, no comments etc. in the sheet. Should the business logic change, there's one code block to review - instead of dozens/hundreds of formula in a sheet that has grown for 3x12 months x 50 users.
The above functions may want the help of e.g.
Function EndOfMonth(MyDate) as Date
Function BeginOfNextMonth(MyDate) as Date
so that in the sheet you just
manually enter hours spent month after month
calculate new buffer as = MIN([oldbuffer] - [Spent] + GetMonthly(...), GetCap(...))
carefully use relative/absolute addressing to make the formula "copyable" across columns/rows, e.g.
row-absolute on ThisDate got from the header when copying downwards
column-absolute on EntryDate for each Emp when copying rightwards
You can of course use =GetCap(...) and =GetMonthly(...) directly in cells of your sheet to display intermediate results and for debugging purposes.
Be carefull when you compare dates
Tips:
3 years later is not always 365x3 days later
check what the VBA DateSerial() functions does for months > 12 and months < 0
the end of next month always is the first days of 2 months ahead minus 1 ... even in February of a leap year ggg
and post more questions if you get stuck on these functions.

Select dates within the last week

I want to perform an operation in crystal report.
I have a db table contains a date column.
I want to filter and get the rows having data created in last week(last sunday to last saturday = 7 days).For example if today is 24th August Wednesday, then I need data from 14th August(Sunday) to 20th August(Saturday).
Basically I want to find 2 dates and filter the date column.
Date1 = Date(CurrentDate)-Day(7 + WeekDayinNum(CurrentDate)) ; (Ex:for my example it will be 10)
Date2 = Date(CurrentDate)-Day(WeekDayinNum(CurrentDate))
I do not know the Date APIs properly,can anybody help me in this.
This is a common enough date range that CR provides it for you. In your record selection formula, you can just add {table.date} in LastFullWeek
From CR, "LastFullWeek specifies a range of Date values that includes all dates from Sunday to Saturday of the previous week."
Add this to the record selection formula:
{table.date_field} IN Last7Days
If today is Sunday(1) you want rows that are between 7 and 1 days old,
If today is Monday(2) you want rows that are between 8 and 2 days old,
If today is Tuesday(3) you want rows that are between 9 and 3 days old,
etc.
SELECT *
FROM `tablename`
WHERE `somedatefield` >= DATE_SUB(NOW(),INTERVAL (DAYOFWEEK(NOW()) + 6) DAY)
AND `somedatefield` <= DATE_SUB(NOW(),INTERVAL (DAYOFWEEK(NOW())) DAY)