Pinescript //#version=5, trying to combine 2 EMAs and PSAR and add buy/sell signals - algorithmic-trading

im really new at coding, so i know it doesnt run, but this what i got.
I want to show buy signal when PSAR goes below the chart and the EMAs are below the chart(EMA200 below EMA20)
I want to show sellsignal when PSAR goes above the chart and the EMAs are above the chart(EMA200 above EMA20)
I find it really good automated startegy with R.R=2 .
if you can help me run the code i reall appreciate your time and effort.
my effort is below - THANKS AGAIN :
strategy("PSAR 2EMAs Strategy",shorttitle="PSAR Buy/Sell" ,overlay=true )
indicator(title="Parabolic SAR", shorttitle="SAR", overlay=true, timeframe="",
timeframe_gaps=true)
start = input(0.02)
increment = input(0.02)
maximum = input(0.2, "Max Value")
out3 = ta.sar(start, increment, maximum)
plot(out3, "ParabolicSAR", style=plot.style_cross, color=#2962FF)
indicator(title="Moving Average Exponential", shorttitle="EMA1", overlay=true,
timeframe="", timeframe_gaps=true)
len = input.int(20, minval=1, title="Length")
src = input(close, title="Source")
offset = input.int(title="Offset", defval=0, minval=-500, maxval=500)
out = ta.ema(src, len)
plot(out, title="EMA", color=color.yellow, offset=offset)
ma(source, length, type) =>
switch type
"SMA" => ta.sma(source, length)
"EMA" => ta.ema(source, length)
"SMMA (RMA)" => ta.rma(source, length)
"WMA" => ta.wma(source, length)
"VWMA" => ta.vwma(source, length)
typeMA = input.string(title = "Method", defval = "SMA", options=["SMA", "EMA", "SMMA
(RMA)", "WMA", "VWMA"], group="Smoothing")
smoothingLength = input.int(title = "Length", defval = 5, minval = 1, maxval = 100,
group="Smoothing")
smoothingLine = ma(out, smoothingLength, typeMA)
plot(smoothingLine, title="Smoothing Line", color=#f37f20, offset=offset,
display=display.none)
indicator(title="Moving Average Exponential", shorttitle="EMA2", overlay=true,
timeframe="", timeframe_gaps=true)
len2 = input.int(200, minval=1, title="Length")
src2 = input(close, title="Source")
offset2 = input.int(title="Offset", defval=0, minval=-500, maxval=500)
out2 = ta.ema(src, len)
plot(out2, title="EMA", color=color.blue, offset2=offset2)
ma(source, length, type) =>
switch type
"SMA" => ta.sma(source, length)
"EMA" => ta.ema(source, length)
"SMMA (RMA)" => ta.rma(source, length)
"WMA" => ta.wma(source, length)
"VWMA" => ta.vwma(source, length)
typeMA = input.string(title = "Method", defval = "SMA", options=["SMA", "EMA", "SMMA
(RMA)", "WMA", "VWMA"], group="Smoothing")
smoothingLength = input.int(title = "Length", defval = 5, minval = 1, maxval = 100,
group="Smoothing")
smoothingLine = ma(out, smoothingLength, typeMA)
plot(smoothingLine, title="Smoothing Line", color=#f37f20, offset=offset,
display=display.none)
//the strategy goes like this: WHEN PSAR gets below the chart and EMA200 is below EMA20
and chart is above the 2 EMAs: "BUY"
// WHEN PSAR gets above the chart and EMA200 is above EMA20
and chart is below the 2 EMAs: "SELL"
if ta.change("PSAR Buy/Sell") < 0 and EMA1 below EMA2
strategy.entry("My Long Entry Id", strategy.long)
if ta.change("PSAR Buy/Sell") > 0 and EMA1 above EMA2
strategy.entry("My Short Entry Id", strategy.short)

Related

Create Box or vertical line offsetting session time which splits using Fibonacci ratio

I have completed the main objective of dividing the day into "cycles". Now, I am having trouble with creating a "sub cycle" within each zone that is defined. I basically am trying to take a cycle (sesionTime1) and split that at 0.38 and 0.62 be it with a vertical line that only goes from the overall session high/low, or just create another box where the start of the box is at the 0.38 and the end of the box is at 0.62. I have tried defining sessionTime1 * 0.38, but thats not working for me. And, using bar_indez(X) only focuses on the bar movement which will change as the timeframe on chart is changed.
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © hitmanict
//#version=5
indicator("AMD", overlay=true)
//Get boolean input value (on/off buttons)
//Accumulation
inputAcc = input.bool(title = "Accumulation", defval = true, tooltip = "Turn On/Off Accumulation & Select Color", inline = "1", group = "Accumulation")
inputAccColor = input.color(title = "Box", defval = color.new(#4caf50, 90), inline = "2", group = "Accumulation")
InputAccBorder = input.color(title = "Border", defval = color.rgb(0, 0, 0, 95), inline = "2", group = "Accumulation")
inputAccSub = input.bool(title = "Accumulation Fractal", defval = true, group = "Accumulation")
sessionTime1 = input.session("1845-0330", title = "Session Time")
sessionZone1 = input.string("GMT-5", title = "Session Time Zone")
//Manipulation
inputMan = input.bool(title = "Manipulation", defval = true, tooltip = "Turn On/Off Manipulation & Select Color", inline = "3", group = "Manipulation")
inputManColor = input.color(title = "Box", defval = color.new(#ffcc80,80), inline = "4", group = "Manipulation")
InputManBorder = input.color(title = "Border", defval = color.rgb(0, 0, 0, 95), inline = "4", group = "Manipulation")
sessionTime2 = input.session("0330-0900", title = "Session Time")
sessionZone2 = input.string("GMT-5", title = "Session Time Zone")
//Distribution
inputDistro = input.bool(title = "Distribution", defval = true, tooltip = "Turn On/Off Distribution & Select Color", inline = "5", group = "Distribution")
inputDistColor = input.color(title = "Box", defval = color.new(#2962ff,95), inline = "6", group = "Distribution")
InputDistBorder = input.color(title = "Border", defval = color.rgb(0, 0, 0, 95), inline = "6", group = "Distribution")
sessionTime3 = input.session("0900-1845", title = "Session Time")
sessionZone3 = input.string("GMT-5", title = "Session Time Zone")
//InSession() returns 'true' when the current bar happens inside
//the specified session, corrected for the given time zone (optional).
//Returns 'false' when the bar doesn't happen in that time period,
//or when the chart's time frame is 1 day or higher.
InSession1(sessionTime1, sessionZone1=syminfo.timezone) => not na(time(timeframe.period, sessionTime1, sessionZone1))
InSession2(sessionTime2, sessionZone1=syminfo.timezone) => not na(time(timeframe.period, sessionTime2, sessionZone2))
InSession3(sessionTime3, sessionZone1=syminfo.timezone) => not na(time(timeframe.period, sessionTime3, sessionZone3))
//See if the session is currently active and just started
inSession1 = InSession1(sessionTime1, sessionZone1) and timeframe.isintraday
session1Start = inSession1 and not inSession1[1]
inSession2 = InSession2(sessionTime2, sessionZone2) and timeframe.isintraday
session2Start = inSession2 and not inSession2[1]
inSession3 = InSession3(sessionTime3, sessionZone3) and timeframe.isintraday
session3Start = inSession3 and not inSession3[1]
//Create variables
var session1HighPrice = 0.0
var session1LowPrice = 0.0
var session2HighPrice = 0.0
var session2LowPrice = 0.0
var session3HighPrice = 0.0
var session3LowPrice = 0.0
//When a new session starts, set high/low to the data of the bar in the session.
if session1Start
session1HighPrice := high
session1LowPrice := low
if session2Start
session2HighPrice := high
session2LowPrice := low
if session3Start
session3HighPrice := high
session3LowPrice := low
//Else, during the session, track the highest high and lowest low
else if inSession1
session1HighPrice := math.max(session1HighPrice, high)
session1LowPrice := math.min(session1LowPrice, low)
else if inSession2
session2HighPrice := math.max(session2HighPrice, high)
session2LowPrice := math.min(session2LowPrice, low)
else if inSession3
session3HighPrice := math.max(session3HighPrice, high)
session3LowPrice := math.min(session3LowPrice, low)
//Create persistent variable for the box identifier
var box session1Box = na
var box session2Box = na
var box session3Box = na
//When a session begins, make a new box for that session
if session1Start
session1Box := inputAcc ? box.new(left=bar_index, top = na, right = na, bottom = na, bgcolor = inputAccColor, border_color = InputAccBorder) : na
if session2Start
session2Box := inputMan ? box.new(left=bar_index, top = na, right = na, bottom = na, bgcolor = inputManColor, border_color = InputManBorder) : na
if session3Start
session3Box := inputDistro ? box.new(left=bar_index, top = na, right = na, bottom = na, bgcolor = inputDistColor, border_color = InputDistBorder) : na
//During the session, update that session's existing box
if inSession1
box.set_top(session1Box, session1HighPrice)
box.set_bottom(session1Box, session1LowPrice)
box.set_right(session1Box, bar_index + 1)
if inSession2
box.set_top(session2Box, session2HighPrice)
box.set_bottom(session2Box, session2LowPrice)
box.set_right(session2Box, bar_index + 1)
if inSession3
box.set_top(session3Box, session3HighPrice)
box.set_bottom(session3Box, session3LowPrice)
box.set_right(session3Box, bar_index + 1)
*//Sub AMD Section*
//Create persistent variable for the sub box identifier
var box session1BoxSub = na
var box session2BoxSub = na
var box session3BoxSub = na
if session1Start
session1BoxSub := inputAcc == inputAccSub ? box.new(left = bar_index, top = na, right = na, bottom = na, bgcolor = color.rgb(0, 187, 212, 100), border_color = color.rgb(171, 173, 177), border_style = line.style_dotted, border_width = 2) : na
if inSession1
box.set_top(session1BoxSub, session1HighPrice)
box.set_bottom(session1BoxSub, session1LowPrice)
box.set_right(session1BoxSub, bar_index + 1)
I am attempting this addition at the very bottom unde3r SUB AMD SECTION. Any help/guidance is greatly appreciated.

Ticker labels after plot

I would really appreciate some help adding a ticker label after my plot from the code below. Below is an extract of the main code - I've only used the lines for 1 ticker but in reality, I'll have 32 symbols in total so I've omitted the unnecessary code duplication for the other tickers for the purposes of this query.
Any improvements on the rest of the code would also be appreciated. I'm using ticker.new as 1) I don't need the inputs and the plot only seemed to display properly when the session was listed as extended (even though the chart was already set to extended)
//#version=5
indicator('NASDAQ Trend', overlay=true)
// SYMBOLS //
s01 = ticker.new("NASDAQ", "AAL", session.extended)
// CALCULATIONS //
screener_func() =>
//STACKED EMAs
MA1 = ta.ema(close, 5)
MA2 = ta.ema(close, 8)
MA3 = ta.ema(close, 13)
MA4 = ta.ema(close, 21)
MA5 = ta.ema(close, 34)
MA_Stack_Up = (MA1 > MA2) and (MA2 > MA3) and (MA3 > MA4) and (MA4 > MA5)
//CONDITIONS
Uptrend = MA_Stack_Up
Reversal = ((MA1 < MA2) and (MA2 > MA3)) or ((MA1 > MA2) and (MA2 < MA3))
//COLOR CODING
Bar_Color = Uptrend ? color.new(color.green, 25) : Reversal ? color.new(color.yellow, 25) : color.new(color.red, 25)
[Bar_Color]
// Security call
[TS01]= request.security(s01, timeframe.period, screener_func())
// PLOTS //
l_width = 3
shape = plot.style_circles
plot(1, color=TS01, style=shape, linewidth=l_width)
//LABELS//
L1= label.new(bar_index, 1, text=s01, style=label.style_none, textcolor=color.new(color.white, 0), size=size.small)
label.delete(L1[1])
My problem is the resulting label is ={"session":"extended","symbol":"NASDAQ:AAL"}. Ideally, the label should be just AAL
You can write a function that extracts the part you are interested from that string. If your string ALWAYS has the same format ={"session":"extended","symbol":"NASDAQ:AAL"}.
Step 1: Split the string using : as a delimeter. You will then have 4 sub strings.
={"session"
"extended","symbol"
"NASDAQ
AAL"} <-- This is what you want (index: 3)
Step 2: Remove the last two chars. Since the last two chars will always be "}, return a string until last two chars.
getName(_str) =>
string[] _pair = str.split(_str, ":")
string[] _chars = str.split(array.get(_pair, 3), "") // Index 3
int _len = array.size(_chars) - 2 // Don't get the last two chars
string[] _substr = array.new_string(0)
_substr := array.slice(_chars, 0, _len)
string _return = array.join(_substr, "")
Then call this function when you create a label:
//LABELS//
L1= label.new(bar_index, 1, text=getName(s01), style=label.style_none, textcolor=color.new(color.white, 0), size=size.small)
label.delete(L1[1])
No sense in doing all those string gymnastics when the ticker is available. Try this:
//#version=5
indicator('NASDAQ Trend', overlay=true)
// CALCULATIONS // {
// hey look – it's now foldable....
screener_func() =>
// STACKED EMAs
MA1 = ta.ema(close, 5)
MA2 = ta.ema(close, 8)
MA3 = ta.ema(close, 13)
MA4 = ta.ema(close, 21)
MA5 = ta.ema(close, 34)
// CONDITIONS - no sense in allocating extra variables when hidden in function
Uptrend = (MA1 > MA2) and (MA2 > MA3) and (MA3 > MA4) and (MA4 > MA5)
Reversal = ((MA1 < MA2) and (MA2 > MA3)) or ((MA1 > MA2) and (MA2 < MA3))
// DETERMINE COLOR CODING - just return the results
// vs assigning to a variable and then return the variable...
[Uptrend ? color.new(color.green, 25) : Reversal ? color.new(color.yellow, 25) : color.new(color.red, 25)]
// }
// Define tickers and set up labels on last bar
// Note: request security limits the max number of tickers to 40
var tickers = array.from("AA","AAL","AAPL")
// use the index of the symbol in the ticker array as price level to plot...
if barstate.islast
for item in tickers
label.new(bar_index+ 5, array.indexof(tickers,item), item, style=label.style_none, textcolor=color.new(color.white, 0), size=size.small)
// Since the ticker symbol must be know at complile time aka simple string,
// we have to call each symbol separately - what a pain...
// style variations here in case we want to change
var aStyle = plot.style_circles
var aLinewidth = 3
// AA <-- Yep this is definitely not NASDAQ material...
temp1 = ticker.new("NYSE", "AA", session.extended)
[temp2] = request.security(temp1, timeframe.period, screener_func())
plot(0, color= temp2, style=aStyle, linewidth=aLinewidth)
// AAL
temp3 = ticker.new("NASDAQ", "AAL", session.extended)
[temp4] = request.security(temp3, timeframe.period, screener_func())
plot(1, color= temp4, style=aStyle, linewidth=aLinewidth)
// AAPL
temp5 = ticker.new("NASDAQ", "AAPL", session.extended)
[temp6] = request.security(temp5, timeframe.period, screener_func())
plot(2, color= temp6, style=aStyle, linewidth=aLinewidth)
output image

Invalid Date whilst using Moment() and Linq

I am having a problem where I have a 12 month period but beginning from zero index and its causing me to have an invalid date. Below is a picture of both my date array and chart js. Basically, because the months are zero indexed, they are out by one
and the below is the Linq query I am using, if anyone can help me fix this that would be great
var solicitor = _db.Records
.Where(j => j.Requestor == "Solicitor" && EF.Functions.DateDiffMonth(j.Request_Date, DateTime.Now) == 0 && EF.Functions.DateDiffMonth(j.Request_Date, DateTime.Now) <= 12)
.GroupBy(g => new { g.Request_Date.Value.Year, g.Request_Date.Value.Month }).OrderBy(d => d.Key.Year).ThenBy(d => d.Key.Month)
.Select(group => new
{
Dates = group.Key,
Count = group.Count()
});
var solicitorCount = solicitor.Select(n => n.Count).ToArray();
var date = solicitor.Select(n => n.Dates).ToArray();
and the code inside my chart js to format as moment
let newArr = []
for (let i = 0; i < simpleData[0].date.length; i++) {
var calDate = moment(simpleData[0].date[i]).format('MMM YYYY');
console.log(calDate)
newArr.push(calDate)
}
You can change your code like this:
let newArr = []
for (let i = 0; i < simpleData[0].date.length; i++) {
data[i].month -= 1;
var calDate = moment(simpleData[0].date[i]).format('MMM YYYY');
console.log(calDate)
newArr.push(calDate)
}
newArr result:

Stuck filling an array using VBscript and a For Loop

I have created an array to store some excel cell addresses, but while running through a portion of the array with a For Loop (because the values are in order for that portion of the data and its easier than doing each one at a time), but I get an error at line 22,(saData(i,1) = "D" count), right at the "count" variable but I cant figure out why.
'LOADING EXCEL CELL ADDRESS INTO INPUT ARRAY
saData(0,1) = "C3"
saData(1,1) = "F3"
saData(2,1) = "C4"
saData(3,1) = "F4"
saData(4,1) = "F6"
saData(5,1) = "C7"
saData(6,1) = "F7"
saData(7,1) = "C8"
saData(8,1) = "C9"
saData(9,1) = "F9"
saData(10,1) = "C11"
saData(12,1) = "F11"
saData(13,1) = "C13"
saData(14,1) = "F13"
Dim count : count = 16
For i = 15 to 54
saData(i,1) = "D" count
count = count + 1
next'
saData(55,1) = "G59"
saData(56,1) = "F60"
saData(57,1) = "B64"
saData(58,1) = "E64"
For i = 0 to 59
Msgbox saData(i,1)
next
Just try concatenating saData(i,1) = "D"&count

Sorting a Table Containing Tables

I can sort a table with two pieces of information (the name and a second piece, such as age) with the following code:
t = {
Steve = 4,
Derek = 1,
Mike = 5,
Steph = 10,
Mary = 7,
Danny = 2
}
function pairsByKeys (t,f)
local a = {}
for x in pairs (t) do
a[#a + 1] = x
end
table.sort(a,f)
local i = 0
return function ()
i = i + 1
return a[i], t[a[i]]
end
end
for a,t in pairsByKeys (t) do
print (a,t)
end
Result:
Danny 2
Derek 1
Mary 7
Mike 5
Steph 10
Steve 4
I have a scenario where at a convention each person's name tag contains a barcode. This barcode, when scanned, enters four pieces of information about each person into a table database. This database is made up of the following pieces:
t = {
{name = "Mike", addr = "738 Rose Rd", age = 30, phone = "333-902-6543"}
{name = "Steph", addr = "1010 Mustang Dr", age = 28, phone = "555-842-0606"}
{name = "George", addr = "211 Glass St", age = 34, phone = "111-294-9903"}
}
But how would I change my code to sort all four entries (name, addr, age, phone) by age and keep all variables in line with one another?
I've been trying to experiment and am getting the hang of sorting a table by pairs and have a better idea how to perform table.sort. But now I want to take this another step.
Can I please receive some help from one of the programming gurus here?! It is greatly appreciated guys! Thanks!
You could use the age as the key of your table:
t = {
[30] = {name = "Mike", addr = "738 Rose Rd", age = 30, phone = "333-902-6543"},
[28] = {name = "Steph", addr = "1010 Mustang Dr", age = 28, phone = "555-842-0606"},
[34] = {name = "George", addr = "211 Glass St", age = 34, phone = "111-294-9903"},
}
function pairsByKeys (t,f)
local a = {}
for x in pairs (t) do
a[#a + 1] = x
end
table.sort(a,f)
local i = 0
return function ()
i = i + 1
return a[i], t[a[i]]
end
end
for a,t in pairsByKeys (t) do
print (t.name, t.addr, t.age, t.phone)
end
EDIT
Otherwise, if you don't want to change the structure of t, you could change your iterator generating function to keep track of the indexing:
t = {
{name = "Mike", addr = "738 Rose Rd", age = 30, phone = "333-902-6543"},
{name = "Steph", addr = "1010 Mustang Dr", age = 28, phone = "555-842-0606"},
{name = "George", addr = "211 Glass St", age = 34, phone = "111-294-9903"},
}
function pairsByAgeField(t,f)
local a = {}
local index = {}
for _, x in pairs(t) do
local age = x.age
a[#a + 1] = age
index[age] = x
end
table.sort(a,f)
local i = 0
return function ()
i = i + 1
return a[i], index[a[i]]
end
end
for a,t in pairsByAgeField(t) do
print (t.name, t.addr, t.age, t.phone)
end
Of course this makes pairsByAgeField less generally applicable than your original pairsByKeys (it assumes that the table being iterated has a given structure), but this is not a problem if you often have to deal with tables such as t in your application.

Resources