Trying to plot a shape on the previous week's high, but having difficulty getting it to plot. Hope someone can help here
indicator("My script", overlay = true)
previousWeekHigh = request.security(syminfo.tickerid, 'W', high[1],lookahead=barmerge.lookahead_on, gaps = barmerge.gaps_off)
isNewWeek = timeframe.change("W")
anchor_point() =>
float anchor = na
if isNewWeek
anchor := previousWeekHigh
anchor
anchorBar = anchor_point()
plotshape(anchorBar, style=shape.xcross)```
You cannot really use the plotshape() for this purpose as the position of the weekly high bar will be dynamic.
I would just use two var variables, one for the price and one for the "bars since" count. You don't even need the security() here.
Here is an example:
//#version=5
indicator("My script", overlay=true)
is_new_week = ta.change(time("W"))
bgcolor(is_new_week ? color.new(color.blue, 85) : na)
var label weekly_high_lbl = label.new(na, na, "Weekly\nHigh", yloc=yloc.abovebar, style=label.style_label_down, color=color.green, textcolor=color.white)
var line weekly_high_line = line.new(na, na, na, na, extend=extend.right, color=color.green)
var float weekly_high_price = na
var int weekly_high_barssince = 0
if (is_new_week)
// Update the label and line first
label.set_xy(weekly_high_lbl, bar_index - weekly_high_barssince, weekly_high_price)
line.set_xy1(weekly_high_line, bar_index - weekly_high_barssince, weekly_high_price)
line.set_xy2(weekly_high_line, bar_index, weekly_high_price)
// Reset the variables
weekly_high_price := high
weekly_high_barssince := 0
else
// Check for new high
if (high >= weekly_high_price)
weekly_high_price := high
weekly_high_barssince := 1
else
weekly_high_barssince := weekly_high_barssince + 1 // Increase the counter
Related
I've created an AFL script that sends Buy, Stoploss, and Target values directly to my telegram with the help of a telegram bot. I've made it call the telegram sender function when the buy is true. But the problem is that since buy will be true for a whole candle so when I switch to for example 5 minute candle it sends me that buy signal 5 times (since I'm backtesting with a 1minute bar replay)
I tried using additional variables to set the telegram parameters value to zero when buy is not true and then process telegram sender only when the set parameter has non zero value, but still since buy will be true for the whole candle so the parameter is getting non-zero value for each tick for if the tick belonging to the same candle. For your reference here is the complete code. (With Bot API's removed)
_SECTION_BEGIN("5min EMA Longing");
FirstTradeTime = 094500;
LastTradeTime = 151500;
function writecsv( pricetowrite, wrtitethis )
{
if (StrFind(pricetowrite,"0.000"))
{
}
else
{
fh = fopen( "C:\\Users\\<username>\\Desktop\\newfile.csv", "a");
if(fh)
{
fputs(wrtitethis+"\n", fh );
fclose(fh);
ih = InternetOpenURL("https://api.telegram.org/bot<ChatID>:<API>/sendMessage?chat_id=1487299238&text="+wrtitethis);
InternetClose(ih);
}
else
{
printf("Error opening file");
}
}
}
//Current candle data
CandleOpen = TimeFrameGetPrice("O",in5Minute); //as it is fixed
CandleHigh = TimeFrameGetPrice("H",in5Minute); //as it is fixed
CandleLow = TimeFrameGetPrice("L",in5Minute); //as it is fixed
CandleClose = TimeFrameGetPrice("C",in5Minute); //as it is fixed
//Prev candle's data
PrevCanOpen = TimeFrameGetPrice("H",in5Minute,-1);
PrevCanHigh = TimeFrameGetPrice("H",in5Minute,-1);
PrevCanLow = TimeFrameGetPrice("L",in5Minute,-1);
PrevCanClose = TimeFrameGetPrice("C",in5Minute,-1);
Ema5 = ref(EMA(Close,5),-1); //5 period EMA
HighNotLow = PrevCanHigh-PrevCanLow;
Ema20 = EMA(close,20);
Rsi15 = RSI(14);
EMA20_Slope = Ema20 - ref(EMA(Close,20),-6);
//EMA20_Slope = 0;
indicator1 = PrevCanOpen<Ema5 AND PrevCanHigh<Ema5 AND PrevCanLow<Ema5 AND PrevCanClose<Ema5 AND CandleHigh>=PrevCanHigh; //main 5EMA strategy
indicator2 = EMA20_Slope>=0; //20 EMA slope or RSI indicating buy zone
BUY = indicator1 AND indicator2 AND HighNotLow>0 AND (TimeNum() >=FirstTradeTime AND TimeNum()<= LastTradeTime);
BuyPrice = HighestSince(Buy,Ref(H,-1));
stopLevelLong = ValueWhen(Buy, Ref(Low,-1));
PriceBuy = ValueWhen(Buy, BuyPrice); //entry price
stopAmountLong = PriceBuy-stopLevelLong;
targetAmountLong = 2*stopAmountLong;
Stoploss = stopAmountLong;
Target = targetAmountLong;
Plot(PriceBuy ,"Bought Price",colorGreen); //drawing entry price
Plot(PriceBuy-Stoploss ,"Stoploss",colorAqua); //drawing entry price
Plot(PriceBuy+Target ,"Target",colorYellow); //drawing entry price
ApplyStop(Type=0,Mode=2,Amount=Stoploss);
ApplyStop(Type=1,Mode=2,Amount=Target);
Sell = (((HighestSince(Buy,H)>PriceBuy+Target) OR (LOWESTSince(Buy,L)<PriceBuy-Stoploss)) AND (TimeNum() >=FirstTradeTime AND TimeNum()<= LastTradeTime)) OR TimeNum()>= LastTradeTime;
BUY = ExRem(BUY,Sell);
timenow = ValueWhen(Buy, TimeNum());
priceto = IIf(Buy,PriceBuy,null);
timenow = NumToStr(timenow,1);
timenow = StrReplace(timenow,",",".");
//logging
wrtitethis =Name()+" "+timenow +", BUY: "+NumToStr(PriceBuy)+", SL: "+NumToStr(PriceBuy-Stoploss)+", TG: "+NumToStr(PriceBuy+Target);
writecsv( NumToStr(LastValue(priceto)),wrtitethis);
//logging
Sell = ExRem(Sell,buy);
PlotShapes(IIf(Buy,shapeUpArrow,shapeNone),colorYellow,0,L,offset=-50);
PlotShapes(IIf(Sell AND (HighestSince(Buy,H)>PriceBuy+Target),shapedownArrow,shapeNone),colorGreen,0,H,offset=-50);
PlotShapes(IIf(Sell AND (LOWESTSince(Buy,L)<PriceBuy-Stoploss),shapedownArrow,shapeNone),colorRed,0,H,offset=-50);
PlotShapes(IIf(Sell AND TimeNum()>= LastTradeTime,shapedownArrow,shapeNone),colorAqua,0,H,offset=-50);
//Show bar index on selection
bi = BarIndex();
sar1 = SAR(0.01);
sarsigs = C < sar1 AND Ref(C,-1) > Ref(sar1,-1);
// Here I changed SelectedValue() to LastValue()
lastSarSiggBarNum = LastValue(ValueWhen(sarsigs, bi));
_TRACE("Last Bar Num for sarsigs: " + lastSarSiggBarNum);
PlotText(StrFormat("%1.0f", lastSarSiggBarNum), lastSarSiggBarNum, sar1[lastSarSiggBarNum], colorWhite, colorRed);
currentlySelectedBarNum = SelectedValue(bi);
_TRACE("Currently selected BarNum " + currentlySelectedBarNum);
// plot the current bar text at the close price level
PlotText(StrFormat("%1.0f", currentlySelectedBarNum), currentlySelectedBarNum, C[currentlySelectedBarNum], colorBlack, colorAqua, 10);
//Show bar index on selection
_SECTION_END();
I'm trying to this code in the Script Editor of Google Sheets to insert today's date along with a consistent piece of text, and it was working fine up until Jan 31, 2021, when it started inserting 2021-02-32, 2021-02-33, etc. instead of 2021-02-01, 2021-02-02, etc. Here's the code I'm running:
function daily() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName("Social Tracker");
var date = Utilities.formatDate(new Date(), "GMT", "YYYY-MM-DD");
var aValues = sh.getRange("A1:A").getValues();
var aLast = aValues.filter(String).length;
// Assuming A and B have same last row, no need for B
// If different, need to calculate separately
var bValues = sh.getRange("B1:B").getValues();
var bLast = bValues.filter(String).length;
// If A and B are the same, use setValues
sh.getRange(aLast + 1, 1, 1, 2).setValues([[date,'handle']]);
var sheet = SpreadsheetApp.getActiveSheet();
var followers = sheet.getRange(2,5,sheet.getLastRow()).getValues();
var nextRowJ = getFirstEmptyRow('J');
var following = sheet.getRange(2,6,sheet.getLastRow()).getValues();
var nextRowK = getFirstEmptyRow('K');
var engagement = sheet.getRange(2,7,sheet.getLastRow()).getValues();
var nextRowL = getFirstEmptyRow('L');
var likes = sheet.getRange(2,8,sheet.getLastRow()).getValues();
var nextRowM = getFirstEmptyRow('M');
var comments = sheet.getRange(2,9,sheet.getLastRow()).getValues();
var nextRowN = getFirstEmptyRow('N');
var posts = sheet.getRange(2,4,sheet.getLastRow()).getValues();
var nextRowO = getFirstEmptyRow('O');
// Record current balance and timestamp at end of columns B & C
sheet.getRange(nextRowO, 15, 1, 1).setValues([[posts]]);
sheet.getRange(nextRowJ, 10, 1, 1).setValues([[followers]]);
sheet.getRange(nextRowK, 11, 1, 1).setValues([[following]]);
sheet.getRange(nextRowL, 12, 1, 1).setValues([[engagement]]);
sheet.getRange(nextRowM, 13, 1, 1).setValues([[likes]]);
sheet.getRange(nextRowN, 14, 1, 1).setValues([[comments]]);
}
// From https://stackoverflow.com/a/9102463/1677912
function getFirstEmptyRow(columnLetter) {
columnLetter = columnLetter || 'A';
var rangeA1 = columnLetter + ':' + columnLetter;
var spr = SpreadsheetApp.getActiveSpreadsheet();
var column = spr.getRange(rangeA1);
var values = column.getValues(); // get all data in one call
var ct = 0;
while ( values[ct][0] != "" ) {
ct++;
}
And here's an image of the cells that are being filled in by the script. I'm assuming my issue is with the line:
sh.getRange(aLast + 1, 1, 1, 2).setValues([[date,'consistent piece of text']]);
How can I adjust this to make sure it follows the next date in A1, ie. inserts 2021-02-01 instead of 2021-02-32?
Use:
var date = Utilities.formatDate(new Date(), "GMT", "yyyy-MM-dd");
Reason:
Utilities.formatDate(date, timeZone, format) follows this format guidelines
When you use "DD", you specify the Day in a year. If you want to specify the Day of the month you need to use dd
In addition, when you use "YYYY" you are referring to a Week year. If you want to get the actual year use "yyyy" instead.
If you find using Java SE Simple Date Format counterintuitive and you are using Google Apps Script V8 runtime instead of using Utilities.formatdate() you might use to Date.prototype.toLocaleDateString
Instead of "YYYY-MM-DD" use "yyyy-MM-dd"
YYYY stands for 4 digit weak year (the first/last week of the year it might return a number different of what you are expecting.
yyyy stands for 4 digit year
DD stands for day year (32 is February 1st)
MM stands for 2 digit month (02 is February)
mm stats for 2 digit minutes
I'm pretty new to IDL and as a way to learn I have tried to create a number guessing game. I have a Widget with three buttons: One that tells the program the number you are thinking of is larger than the one the computer asks about, one if it's smaller and one if it's correct.
My problem is that once you have pushed i.e. the larger button, if you press it again it won't do anything. E.g. the program starts to guess 500, if I press larger it guesses 750. If I now press larger again, the program doesn't respond.
My code is like this:
PRO test1_event, ev
WIDGET_CONTROL, ev.top, GET_UVALUE = stash
minimum = 0
maximum = 1000
IF (ev.Id EQ largerbutton) THEN BEGIN
minimum = (minimum+maximum)/2
maximum = maximum
ENDIF
IF (ev.Id EQ smallerbutton) THEN BEGIN
maximum = (minimum+maximum)/2
minimum = minimum
ENDIF
IF (ev.Id EQ correctbutton) THEN BEGIN
help2 = string('I got it!') ;This prints to a text widget
ENDIF
END
PRO test1
wBase = WIDGET_BASE(X_SCROLL_SIZE = 512, Y_SCROLL_SIZE = 512)
;wDraw = WIDGET_WINDOW(wBase, X_SCROLL_SIZE = 512, Y_SCROLL_SIZE = 512)
Lower = WIDGET_BUTTON(wBase, VALUE = 'Smaller', XOFFSET = 60, YOFFSET = 250)
Higher = WIDGET_BUTTON(wBase, VALUE = 'Larger', XOFFSET = 225, YOFFSET = 250)
Correct = WIDGET_BUTTON(wBase, VALUE = 'Correct', XOFFSET = 380, YOFFSET = 250)
minimum = 0
maximum = 1000
help1 = string('Please think of a number between' + string(minimum) + ' and ' + string(maximum))
help2 = string('Is your number ' + string((minimum + maximum)/2) + '?')
wText = WIDGET_TEXT(wBase, VALUE = ['Welcome to my little game. I will now try and guess a number you are thinking of.'], XSIZE = 63,XOFFSET = 50, YOFFSET = 100)
wText1 = WIDGET_TEXT(wBase, VALUE = help1, XSIZE = 63,XOFFSET = 50, YOFFSET = 120)
wText2 = WIDGET_TEXT(wBase, VALUE = help2, XSIZE = 63,XOFFSET = 50, YOFFSET = 140)
stash = {text1:wText, text2:wText1, text3:wText2, $
lower:Lower, higher:Higher, correct:Correct, minimum:minimum, maximum:maximum}
WIDGET_CONTROL, wBase, SET_UVALUE = stash, /REALIZE
XMANAGER, 'test1', wBase
end
I have tried using a while loop and also REPEAT, but then the program just goes right up to 999 if I press the larger button and to 0 if I press the smaller.
Any ideas to what I can do?
EDIT: Added the rest of the program
I think the buttons are working fine but your event handler doesn't actually do anything. First, I needed to change largerbutton, smallerbutton, and correctbutton to be stash.higher, stash.lower, stash.correct. Then, your code calculates the new minimum & maximum but it doesn't actually do anything with them.
I put a print statement into the event code and it's definitely getting the button presses.
In your event handler you probably want to use widget_control to update the text box with the new guess.
I am trying to add markers on my stacked bar chart programmatically and they do not seem to show up. In reality, I need to show a marker on the average of the datapoint but right now, I cannot even show a simple marker on the chart.
What am I doing wrong ?
Code:
Dim chart As New Chart
chart.ID = DtDistinct.Rows(I)("CourseSisID")
Dim chartareas As New ChartArea
chart.ChartAreas.Add(chartareas)
chart.Series.Clear()
chart.DataBindCrossTable(DtRecords.DefaultView, "Outcomescore", "ShortName", "RecordsPerGroup", "")
chart.ChartAreas(0).AxisY.Interval = 1
chart.ChartAreas(0).AxisY.Enabled = AxisEnabled.False
chart.Palette = ChartColorPalette.None
chart.PaletteCustomColors = New Color() {ColorTranslator.FromHtml("#DF5B59"), ColorTranslator.FromHtml("#E0D773 "), ColorTranslator.FromHtml("#8AAC53"), ColorTranslator.FromHtml("#6A843F")}
chart.ChartAreas(0).AxisX.MajorGrid.Enabled = False
chart.ChartAreas(0).AxisY.MajorGrid.Enabled = False
For Each cs As Series In chart.Series
cs.ChartType = SeriesChartType.StackedBar
cs.Points().FindMaxByValue.MarkerColor = Color.AliceBlue
cs.Points().FindMaxByValue.MarkerSize = 13
cs.Points().FindMaxByValue.MarkerStyle = MarkerStyle.Diamond
Next
pnlcharts.Controls.Add(chart)
Here is an image of what I am trying to do. I know that the above code will not give me the below image but I was trying to find a workaround with the above code, before I realized that markers cannot appear on bar charts.
I would like to see that striped line on the bar chart. The striped line should appear on the calculated average of the points.
So, an another way I could do was to use annotations since markers are not supported by stackedbar charts. I wrote the following code to add an annotation line, but it still does not give me the output I need only because I do not know how to do it for each Y value on the chart.
Here is my code:
Dim chart As New Chart
chart.ID = DtDistinct.Rows(I)("CourseSisID")
Dim chartareas As New ChartArea
chart.ChartAreas.Add(chartareas)
chart.DataBindCrossTable(DtRecords.DefaultView, "OutcomeScore", "ShortName", "RecordsPerGroup", "Label=RecordsPerGroup")
chart.Palette = ChartColorPalette.None
chart.PaletteCustomColors = New Color() {ColorTranslator.FromHtml("#DF5B59"), ColorTranslator.FromHtml("#E0D773 "), ColorTranslator.FromHtml("#8AAC53"), ColorTranslator.FromHtml("#6A843F")}
chart.ChartAreas(0).AxisX.MajorGrid.Enabled = False
chart.ChartAreas(0).AxisY.MajorGrid.Enabled = False
Dim charttitle As New Title
charttitle.Text = DtDistinct.Rows(I)("CourseSisID")
chart.Titles.Add(charttitle)
For Each cs As Series In chart.Series
cs.ChartType = SeriesChartType.StackedBar
Next
Dim ann1 As New VerticalLineAnnotation()
ann1.AxisX = chart.ChartAreas(0).AxisX
ann1.AxisY = chart.ChartAreas(0).AxisY
ann1.IsSizeAlwaysRelative = False
ann1.X = chart.DataManipulator.Statistics.Mean(chart.Series(0).Name)
ann1.IsInfinitive = True
ann1.ClipToChartArea = chart.ChartAreas(0).Name
ann1.LineColor = Color.Coral
ann1.LineWidth = 3
ann1.AnchorX = 1
ann1.AnchorY = 5
chart.Annotations.Add(ann1)
ann1.LineDashStyle = ChartDashStyle.Dash
pnlcharts.Controls.Add(chart)
Here is what I get with the above code:
Here is what I need : Notice how the strip line is at a different value for each bar.
Dim annotation2 As New LineAnnotation()
annotation2.IsSizeAlwaysRelative = False
annotation2.AxisX = chart.ChartAreas(0).AxisX
annotation2.AxisY = chart.ChartAreas(0).AxisY
annotation2.Height = 1
annotation2.Width = 0
annotation2.LineWidth = 1.5
annotation2.StartCap = LineAnchorCapStyle.None
annotation2.EndCap = LineAnchorCapStyle.None
annotation2.AnchorX = AvgVar
annotation2.ToolTip = "Average=" & AvgVar
Select Case row
Case 1
annotation2.AnchorY = 4.5
Case 2
annotation2.AnchorY = 3.5
Case 3
annotation2.AnchorY = 2.5
Case 4
annotation2.AnchorY = 1.5
Case 5
annotation2.AnchorY = 0.5
End Select
' <- your point
annotation2.LineColor = Color.Gray
annotation2.LineDashStyle = ChartDashStyle.Dash
' <- your color
chart.Annotations.Add(annotation2)
How do I custom the cluster options so that the markers aren't clustered by the default Leaflet markerOptions(count of markers), but by a function (mean, maximum or whatelse) that I choose?
For Java i could find tons of examples, but for R I couldn't find anything.
Only thing I could find is something that has to do with
"iconCreateFunction" and "JS()", but I don't know if it's right and how it works..
leaflet(data) %>%
addTiles() %>%
addMarkers(lng=data$lon, lat=data$lat, clusterOptions = list(iconCreateFunction = JS(...
Can somebody help me? Thanks in advance
Replying to old question however some users still may find this useful.
You need to pass custom iconCreateFunction javascript formula to markerClusterOptions()
The main challenge is how you pass data to the markers so that you can apply a formula to data which are in the cluster of markers. I have tried to read the javascript code which is on the example website, but since I don't know js I could only find a workaround.
Example website: http://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-custom.html
The user is adding data into marker[i].number in populate() function.
If anyone knows how this work please add your solution which I assume will be better than what I currently use.
My workaround is to store data into addMarkers(... , title=myData, ...) or addCircleMarkers(... , weight=myData , ...)
library(leaflet)
# sample data to pass to markers
myData <- sample(x=1:1000, size=1000, replace=TRUE)
# add some NaN which may occur in real data
myData[sample(x=1:1000, size=100, replace=FALSE)] <- NaN
circle.colors <- sample(x=c("red","green","gold"),size=1000,replace=TRUE)
avg.formula =
"function (cluster) {
var markers = cluster.getAllChildMarkers();
var sum = 0;
var count = 0;
var avg = 0;
var mFormat = ' marker-cluster-';
for (var i = 0; i < markers.length; i++) {
if(markers[i].options.weight != undefined){
sum += markers[i].options.weight;
count += 1;
}
}
avg = Math.round(sum/count);
if(avg<333) {mFormat+='small'} else if (avg>667){mFormat+='large'}else{mFormat+='medium'};
return L.divIcon({ html: '<div><span>' + avg + '</span></div>', className: 'marker-cluster'+mFormat, iconSize: L.point(40, 40) });
}"
# in the above we loop through every marker in cluster access the options.weight
# which is our data, if data is not undefined (not NA or NaN) then we sum data
# and count occurrence
# at the end of code we check if average is more/less to assign default
# marker icons marker-cluster-small marker-cluster-medium marker-cluster-large
# for green yellow red respectively
# stroke = FALSE is a must if you store data in weights !!!
leaflet(quakes) %>% addTiles() %>%
addCircleMarkers(lng=~long,lat=~lat,radius=10,stroke=FALSE,fillOpacity=0.9,
fillColor = circle.colors,weight=myData,
popup=as.character(myData),
clusterOptions = markerClusterOptions(iconCreateFunction=JS(avg.formula)))
for any other custom formula you need to adjust
for (var i = 0; i < markers.length; i++) {
if(markers[i].options.weight != undefined){
sum += markers[i].options.weight;
count += 1;
}
}
Kind regards,
Peter