Pine script setting timestamp for last quarter not working - scripting

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)

Related

Pinescript conditional line end/delete

I’m trying to create lines that auto plot at certain intervals using the line.new() function. So for example every new monthly open there will be lines plotted 5% and 10% above and beneath price. They’re then extended to the right indefinitely.
I then want to have the lines end once high/low has breached the line. I can’t seem to figure how to do this using the line.delete() function, although I doubt this is the correct path to take anyway due to the fact this deletes the entire line rather than just end it at breach point.
Due to the fact lines are extended indefinitely/until price has breached, there may be instances in which lines are never touched and are only removed once the 500 max line limit is reached. So I haven’t figured a way to use array references for lines to find a solution - and the 40 plot limit for pine plots isn’t really a sufficient amount of lines.
If this isn’t possible then just deleting the entire line upon breach is a backup option but I haven’t figure how to do this either!
Any help is much appreciated, thanks in advance!
You can use additional arrays to track the price values and their crossed state more easily. Each element of the arrays corresponds to the values associated with the same line. We add, remove or modify them based on whether a particular line's price value has been crossed or the line limit has been exceeded.
//#version=5
indicator("Monthly Interval Lines", overlay = true, max_lines_count = 500)
var float[] interval_prices = array.new_float()
var line[] interval_lines = array.new_line()
var bool[] intervals_crossed = array.new_bool()
new_month = timeframe.change("M")
if new_month
array.unshift(interval_lines, line.new(x1 = bar_index, y1 = open * 1.05, x2 = bar_index + 1, y2 = open * 1.05, extend = extend.right, color = color.green))
array.unshift(interval_prices, open * 1.05)
array.unshift(intervals_crossed, false)
array.unshift(interval_lines, line.new(x1 = bar_index, y1 = open * 1.10, x2 = bar_index + 1, y2 = open * 1.10, extend = extend.right, color = color.green))
array.unshift(interval_prices, open * 1.10)
array.unshift(intervals_crossed, false)
array.unshift(interval_lines, line.new(x1 = bar_index, y1 = open * 0.95, x2 = bar_index + 1, y2 = open * 0.95, extend = extend.right, color = color.red))
array.unshift(interval_prices, open * 0.95)
array.unshift(intervals_crossed, false)
array.unshift(interval_lines, line.new(x1 = bar_index, y1 = open * 0.90, x2 = bar_index + 1, y2 = open * 0.90, extend = extend.right, color = color.red))
array.unshift(interval_prices, open * 0.90)
array.unshift(intervals_crossed, false)
size = array.size(intervals_crossed)
if size > 0
if size > 500
for i = size - 1 to 500
line.delete(array.pop(interval_lines))
array.pop(intervals_crossed)
size := array.size(intervals_crossed)
for i = 0 to size - 1
price_val = array.get(interval_prices, i)
already_crossed = array.get(intervals_crossed, i)
crossed_price_val = low < price_val and high > price_val
gapped_price_val = (close[1] < price_val and open > price_val) or (close[1] > price_val and open < price_val)
if not already_crossed and (crossed_price_val or gapped_price_val)
array.set(intervals_crossed, i, true)
interval_line = array.get(interval_lines, i)
line.set_extend(interval_line, extend.none)
line.set_x2(interval_line, bar_index)

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

vb net exclude periods between two datetime

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

How to exit after certain days from `strategy.entry`

I can't seem to figure out the syntax for exit a trade from a certain time interval from the trade entry. Any help would be greatly appreciated.
if (crossover(delta, 0))
strategy.entry("Long", strategy.long, comment="Long")
strategy.exit("Exit", "Long", when = 15)
The code above I want to exit the long position after 15 days. But it doesn't seem to work.
Try barssince
// Example - Buy when the price closes below 22
myEntry = close < 22
strategy.entry(id= "sample", long = strategy.long, when= myEntry)
// Close 10 bar periods after the condition that triggered the entry
strategy.close(id = "sample", when = barssince(myEntry) >= 10)
I figured it out one solution. I created another if statement but offset by 15 days to trigger. I also set the crossover to a variable. See code:
buy = (crossover(delta, 0))
if (buy)
strategy.entry("Long", strategy.long, comment="Long")
if (buy[15])
strategy.close("Long")

vb.net chart with week numbers as X Axis

I know a similar question was asked before, but it wasn't answered.
I have a chart where I use week numbers as its X-axis, that are retrieved as part of the SQL query.
It works fine up until a new year starts. In such a case, even though the weeks are ordered correctly when retrieved (for example, 49, 50, 51, 52, 1, 2, 3), they appear on the axis numerically ordered: 1, 2, 3, 49, 50, 51, 52.
Is there a way to fix that?
The relevant sql query part is:
SELECT DATEPART(year, start_charge_time),
DATEPART(week, start_charge_time) week_num,
COUNT(*) num_sessions
FROM parking_log
GROUP BY DATEPART(year, start_charge_time),
DATEPART(week, start_charge_time)
ORDER BY DATEPART(year, start_charge_time),
DATEPART(week, start_charge_time)
The Chart is:
Dim SeriesParkingRev As Series
SeriesParkingRev = ChartParkingSummery.Series("SeriesParkingRev")
' Set series chart type
SeriesParkingRev.ChartType = SeriesChartType.Line
SeriesParkingRev.MarkerStyle = MarkerStyle.Square
SeriesParkingRev.MarkerSize = 10
SeriesParkingRev.BorderWidth = 3
SeriesParkingRev.Color = Color.Red
SeriesParkingRev.IsValueShownAsLabel = True
SeriesParkingRev.IsVisibleInLegend = True
'' Set series members names for the X and Y values
SeriesParkingRev.XValueMember = "week_num"
SeriesParkingRev.YValueMembers = "total_charge"
SeriesParkingRev.LegendText = "Parking Revenue"
'' --------------------------
' Create the destination series and add it to the chart
'Dim SeriesParkingTime As New Series("SeriesParkingTime")
'ChartParkingSummery.Series.Add(SeriesParkingTime)
Dim SeriesParkingTime As Series
SeriesParkingTime = ChartParkingSummery.Series("SeriesParkingTime")
' Ensure the destination series is a Line or Spline chart type
SeriesParkingTime.ChartType = SeriesChartType.Line
SeriesParkingTime.MarkerStyle = MarkerStyle.Diamond
SeriesParkingTime.MarkerSize = 12
SeriesParkingTime.BorderWidth = 3
SeriesParkingTime.IsValueShownAsLabel = True
SeriesParkingTime.Color = Color.Blue
' Assign the series to the same chart area as the column chart
SeriesParkingTime.ChartArea = ChartParkingSummery.Series("SeriesParkingRev").ChartArea
' Assign this series to use the secondary axis and set its maximum to be 100%
SeriesParkingTime.YAxisType = AxisType.Secondary
ChartParkingSummery.Series("SeriesParkingTime").XValueMember = "week_num"
ChartParkingSummery.Series("SeriesParkingTime").YValueMembers = "avg_time"
ChartParkingSummery.Series("SeriesParkingTime").LegendText = "Average Time"
'' ----------------------------------------
'Dim SeriesCars As New Series("SeriesCars")
'ChartParkingSummery.Series.Add(SeriesCars)
Dim SeriesCars As Series
SeriesCars = ChartParkingSummery.Series("SeriesCars")
SeriesCars.ChartType = SeriesChartType.Point
SeriesCars.MarkerStyle = MarkerStyle.Triangle
SeriesCars.MarkerSize = 8
SeriesCars.BorderWidth = 3
SeriesCars.IsValueShownAsLabel = True
SeriesCars.MarkerStyle = MarkerStyle.Triangle
SeriesCars.MarkerSize = 15
SeriesCars.MarkerColor = Color.Green
ChartParkingSummery.Series("SeriesCars").XValueMember = "week_num"
ChartParkingSummery.Series("SeriesCars").YValueMembers = "num_cars"
ChartParkingSummery.Series("SeriesCars").LegendText = "Cars"
'' ----------------------------------------
ChartParkingSummery.Legends.Add(New Legend("Default"))
' Set legend style
ChartParkingSummery.Legends("Default").LegendStyle = LegendStyle.Table
' Set table style if legend style is Table
' Set legend docking
ChartParkingSummery.Legends("Default").Docking = Docking.Right
' Set legend alignment
ChartParkingSummery.Legends("Default").Alignment = StringAlignment.Center
ChartParkingSummery.Titles.Add("Revenue, Avg Time & Cars")