vb net exclude periods between two datetime - vb.net

Hello I am new with datetimes in VB net and I am trying to calculate time for some operations in productions. For example:
starTtime="01.12.2018 07:00"
endTime ="01.12.2018 15:00"
I have example two periods without working:
Pause1Start="01.12.2018 10:00"
Pause1Stop="01.12.2018 10:30"
Pause2Start="01.12.2018 14:00"
Pause2Stop="01.12.2018 14:30"
How to calculate used time for operation?
It is not always this example, it is necessary to check is time for pause is included between two datetime or if there is end of working day, weekends, etc...
So operation can start in one day and finish day after.
I need idea how to work with this?
Thanks

Try this code. I suggest you to define lists of pause startings and endings, then loop through them, check if particular pause was during the working time and add that time in seconds to variable holding total seconds:
Sub Main()
Dim startTime = New DateTime(2018, 11, 1, 7, 0, 0)
Dim endTime = New DateTime(2018, 11, 1, 17, 0, 0)
Dim pauseStarts = New List(Of DateTime)
pauseStarts.Add(New DateTime(2018, 11, 1, 16, 0, 0))
pauseStarts.Add(New DateTime(2018, 11, 1, 10, 0, 0))
Dim pauseEnds = New List(Of DateTime)
' Add respective pause endings
pauseEnds.Add(New DateTime(2018, 11, 1, 18, 0, 0))
pauseEnds.Add(New DateTime(2018, 11, 1, 11, 30, 0))
Dim pauseSeconds As Long = 0
For i = 0 To pauseStarts.Count - 1
If pauseStarts(i) < endTime AndAlso pauseEnds(i) > startTime Then
' get the minimum from two times
Dim starting = If(startTime > pauseStarts(i), startTime, pauseStarts(i))
' get maximum from two times
Dim ending = If(endTime < pauseEnds(i), endTime, pauseEnds(i))
' add seconds during pause
pauseSeconds += (ending - starting).TotalSeconds
End If
Next
End Sub

Related

Pine script setting timestamp for last quarter not working

I wrote a simple strategy in pine scrip, which is based on crossover/crossunder for two different SMAs.
It is important for me to test my strategy in some time frames, especially in the last quarter. It doesn't work. I got only a few results. I should get results for whole period (colored on green), when SMAs crossed.
Unwanted result
My script is working very well, when I don't use time range or when I set dateCond on true value.
Below I present source code:
//#version=4
strategy("Moving Average Cross 1", initial_capital=1000, overlay=true)
start = timestamp(syminfo.timezone, 2021, 1, 1, 0, 0)
end = timestamp(syminfo.timezone, 2021, 4, 1, 0, 0)
fastSMA = sma(close, 9)
slowSMA = sma(close, 50)
long = crossover(fastSMA, slowSMA)
short = crossunder(fastSMA, slowSMA)
orderSize = floor(strategy.equity / close)
plot(fastSMA, title="20", color=#00ffaa, linewidth=3)
plot(slowSMA, title="50", color=#FFC1CC, linewidth=2)
dateCond = time > start
// dateCond = true
bgcolor(dateCond ? #00ffaa : na)
if dateCond
strategy.entry("long", strategy.long, qty=orderSize, when = long)
strategy.entry("short", strategy.short, qty=orderSize, when = short)
strategy.close("long", when = short)
strategy.close("short", when = long)
I tried with different time ranges (when I set start date on the 1 January 2020 it works very well). I additionally colored a background to check condition, but coloring it also work good. I haven't more ideas why for the last quarter it isn't working properly. I will appreciate any help.
I tested script mainly for pair ETH/USDT (Binance)
Here we use larger capital and close positions before entering a new one. This way the whole position is closed before a new one is opened:
//#version=4
strategy("Moving Average Cross 1", initial_capital=100000, overlay=true)
start = timestamp(syminfo.timezone, 2021, 1, 1, 0, 0)
end = timestamp(syminfo.timezone, 2021, 4, 1, 0, 0)
fastSMA = sma(close, 9)
slowSMA = sma(close, 50)
long = crossover(fastSMA, slowSMA)
short = crossunder(fastSMA, slowSMA)
orderSize = floor(strategy.equity / close)
plot(fastSMA, title="20", color=#00ffaa, linewidth=3)
plot(slowSMA, title="50", color=#FFC1CC, linewidth=2)
dateCond = time > start
// dateCond = true
bgcolor(dateCond ? #00ffaa : na)
strategy.close("long", when = short)
strategy.close("short", when = long)
if dateCond
strategy.entry("long", strategy.long, qty=orderSize, when = long)
strategy.entry("short", strategy.short, qty=orderSize, when = short)

Is there a way to sort a list of numbers whilst maintaining their original indexes in VB.net?

I need to sort a list of numbers but I need to keep their initial indexes.
I had previously just created an array of the numbers and then another array of the indexes which I sorted at the same time like so:
Dim AverageSuccess(23) As Decimal
Dim intervalList() As Integer = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}
x = 2
Do
Sorted = True
For i = 23 To x Step -1
If AverageSuccess(i) < AverageSuccess(i - 1) Then
TempNum = AverageSuccess(i)
AverageSuccess(i) = AverageSuccess(i - 1)
AverageSuccess(i - 1) = TempNum
TempIndex = intervalList(i)
intervalList(i) = intervalList(i - 1)
intervalList(i - 1) = TempIndex
Sorted = False
End If
Next
x += 1
Loop Until Sorted
however this is for a project and my teacher informed me that this is bad programming practise and I should be using a list instead.
I have struggled to find a simple example of how to use a list in VB.net for this purpose, so if someone could give me an example I would appreciate it.
I don't know how much you have covered about lists in class...
Let us create a list with some integers in:
Dim nums As New List(Of Integer) From {9, 8, 4, 5}
Now, we want to store the original indices of those numbers. We can do that with the Select method, which has an optional parameter that will give the index of the current item, and create a new entity with items which we can give names to, say "Num" and "Idx":
Dim numsWithIndex = nums.Select(Function(n, i) New With {.Num = n, .Idx = i})
Then we can use the LINQ method OrderBy to get those entities in the desired order:
Dim sortedNums = numsWithIndex.OrderBy(Function(nwi) nwi.Num)
And we can have a look at what we have constructed with
Console.WriteLine(String.Join(vbCrLf, sortedNums))
which outputs:
{ Num = 4, Idx = 2 }
{ Num = 5, Idx = 3 }
{ Num = 8, Idx = 1 }
{ Num = 9, Idx = 0 }
(It shows the names we gave to the properties of the anonymous type created with New earlier.)
Here is the whole thing as a console app you can copy-and-paste to investigate with on your computer:
Module Module1
Sub Main()
Dim nums As New List(Of Integer) From {9, 8, 4, 5}
Dim numsWithIndex = nums.Select(Function(n, i) New With {.Num = n, .Idx = i})
Dim sortedNums = numsWithIndex.OrderBy(Function(nwi) nwi.Num)
Console.WriteLine(String.Join(vbCrLf, sortedNums))
Console.ReadLine()
End Sub
End Module

How to change date in IF statement

I wish to change startDate depending on the day of the week. Here is what I've tried, the error I get is BC30311: Value of type 'Integer' cannot be converted to 'Date'.
Dim curr As Date = Date.Now
Dim day As String = Date.Today.DayOfWeek.ToString()
Dim startTime As New Date
If day="saturday" Then
startTime=(curr.Year, curr.Month, curr.Day, 17, 0, 0)
Else
startTime=(curr.Year, curr.Month, curr.Day, 13, 0, 0)
End If
Dim endTime As New Date(curr.Year, curr.Month, curr.Day, 21, 59, 0)
If (curr >= startTime) And (curr <= endTime) Then
'''Some Code
I simply need to change startDate to 13:00 hours for Saturdays. Any help appreciated
This is a better way to write code to do what you appear to want to do:
Dim currentDay = Date.Today
Dim startTime = currentDay.AddHours(If(currentDay.DayOfWeek = DayOfWeek.Saturday, 17, 13))
Dim endTime = currentDay.AddHours(21).AddMinutes(59)
Dim currentTime = Date.Now
If currentTime >= startTime AndAlso currentTime <= endTime Then

In vb.net, how do I convert this number 1421165664.0892897 to date time?

In vb.net,
how do I convert this number 1421165664.0892897 to date time?
Its a Unix timestamp.
Is there a date function to do this?
Taken from here:
static DateTime ConvertFromUnixTimestamp(double timestamp)
{
DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
return origin.AddSeconds(timestamp);
}
In other words unix time is seconds since 1970-01-01 0:0:0, so start at that time in .NET, and add the seconds.
Try this:
Public Shared Function UnixTimeStampToDateTime(unixTimeStamp As Double) As DateTime
' Unix timestamp is seconds past epoch
Dim dtDateTime As System.DateTime = New DateTime(1970, 1, 1, 0, 0, 0, _
0, System.DateTimeKind.Utc)
dtDateTime = dtDateTime.AddSeconds(unixTimeStamp).ToLocalTime()
Return dtDateTime
End Function

How to check time range

I implmented a function to check time range in vb.net. But it is giving me wrong output.
My starttime is everyday at 11.00 Pm and end Time is 5.00 AM. My function if i pass 1.10 AM does not return me true output as this falls under that time range. Not sure what iam doing wrong.
Private Function CheckTimeRange() As Boolean
Dim retValue As Boolean = True
Try
Dim Dt As DateTime = DateTime.Now
Dim StartDt As DateTime = Convert.ToDateTime("11.00 PM")
Dim EndDt As DateTime = Convert.ToDateTime("5.00 AM")
Dim startTime As New TimeSpan(StartDt.Hour, StartDt.Minute, 0)
Dim endTime As New TimeSpan(EndDt.Hour, EndDt.Minute, 0)
Dim now As TimeSpan = DateTime.Now.TimeOfDay
If (now > startTime) AndAlso (now < endTime) Then
retValue = True
Else
retValue = False
End If
Return retValue
Catch ex As Exception
End Try
End Function
I think you're overcomplicating your code. You could do:
Private Function CheckTimeRange() As Boolean
Return DateTime.Now.Hour >= 23 OrElse DateTime.Now.Hour < 5
End Function
Edit:
If the start and end times are entered by the user, you should first convert the string values into TimeSpan objects, then you could use a more flexible method which takes date, min time and max time as parameters:
Private Function CheckTimeRange(myDate As DateTime, minTime as TimeSpan, maxTime As TimeSpan) As Boolean
If minTime > maxTime Then
Return myDate.TimeOfDay >= minTime OrElse myDate.TimeOfDay < maxTime
Else
Return myDate.TimeOfDay >= minTime AndAlso myDate.TimeOfDay < maxTime
End If
End Function
Example usage:
Dim minTime As New TimeSpan(23, 0, 0) 'Should be converted from 11.00 PM
Dim maxTime As New TimeSpan(5, 0, 0) 'Should be converted from 5.00 AM
CheckTimeRange(New Date(2012, 1, 1, 15, 0, 0), minTime, maxTime) '==> false
CheckTimeRange(New Date(2012, 1, 1, 22, 30, 0), minTime, maxTime) '==> false
CheckTimeRange(New Date(2012, 1, 1, 23, 00, 0), minTime, maxTime) '==> true
CheckTimeRange(New Date(2012, 1, 2, 1, 10, 0), minTime, maxTime) '==> true
CheckTimeRange(New Date(2012, 1, 2, 4, 59, 0), minTime, maxTime) '==> true
CheckTimeRange(New Date(2012, 1, 2, 5, 10, 0), minTime, maxTime) '==> false
If you have trouble converting string values to TimeSpan you should ask a new question for this specific task.
You're working with TimeSpan objects, and you'll find that 1.10 AM is never greater than 11.00pm without the date.
Meta-Knight has the better solution.