Why does pinescript place orders two candles after a trigger condition - orders

I'm having some issues where my pinescript algo is placing orders two candles after my trigger conditions. My friends are also having the same issue. Does anyone know why this is the case and what I can do to solve it?
My code (I'm using HullMA as the trigger)
/////////////////Trend Indicator/////////////////
malength = input(defval=26, title="Moving Average Length", minval=1)
tsrc = security(heikinashi(syminfo.tickerid),"15", close)
hullma(tsrc, len) =>
hma = wma(2 * wma(tsrc, len / 2) - wma(tsrc, len), round(sqrt(len)))
zlema =hullma(tsrc, malength)
col = zlema > zlema[1] ? color.green : color.red
plot(zlema,color=col, linewidth=4)
/////////////////Buy and Sell Orders/////////////////
//Order conditions
if col == color.green
strategy.entry(id="long", long=true)
if col == color.red
strategy.entry(id="short", long=false)
Problem:

Found the solution, pinescript waits for candle closes and doesn't immediately initialise solutions, hence it takes two candles after the initial trigger before there is a signal

Related

In Pine-Script, how do I code two conditions for my entry?

Could someone please help as I need entry conditions to include the BraidFilter indicator into my strategy. I only need a trade entry long when the green bars and short entry when the red bars cross over the filter line. This is what I did but it's not working and I'm getting a ton of error messages:
Please help. Thank you.
//-- Braid Filter
ma01 = ma(maType, close, Period1)
ma02 = ma(maType, open, Period2)
ma03 = ma(maType, close, Period3)
max = max(max(ma01, ma02), ma03)
min = min(min(ma01, ma02), ma03)
dif = max - min
filter = atr(14) * PipsMinSepPercent / 100
//-- Plots/=
//BraidColor = ma01 > ma02 and dif > filter ? color.green : ma02 > ma01 and dif > filter ? color.red : color.gray
//plot(dif, "Braid", BraidColor, 5, plot.style_columns)
//plot(filter, "Filter", color.blue, 2, plot.style_line)
//bgcolor(BraidColor)
// Condition
C1Price1 = 0.0
C1Price2 = 0.0
C1Price1 := ? ma01 > ma02 and dif > filter
C1Price2 := ? ma02 > ma01 and dif > filter
c1Cross_Long = crossover (C1Price1,C1Price2) and C1Price1 > filter
c1Cross_Short = crossover (C1Price1,C1Price2) and C1Price2 > filter
There are things missing in that code, first you have to define the script with a strategy, then define the maType variable, in addition to that:
C1Price1: =**?** ma01> ma02 and dif> filter
C1Price2: =**?** ma02> ma01 and dif> filter
prior to "?" There must be a condition to meet, I think something was deleted there, after correcting that you will have to write the entries.

Corona SDK: TableView index not updating

I've got a problem with Corona SDK and the tableview, but allow me to show the code first:
function functions.onRowTouch( event )
print("ONROWTOUCH EXECUTING")
if event.phase == "tap" or event.phase == "press" then
print("EVENT.TARGET.INDEX: " .. event.target.index)
editItemNum = event.target.index
print("editnum: " .. editItemNum)
print("ITEM tapped")
if saveData.names[event.target.index] ~= nil then
function functions.pressRow(event)
print("ROW NUM: " .. event.target.index)
print("EDITNUM = " .. editItemNum)
functions.pressItem()
return true
end
event.target:addEventListener("tap", functions.pressRow)
end
elseif event.phase == "swipeLeft" then
print("SWIPING LEFT")
tableView:deleteRows({event.target.index}, {slideLeftTransitionTime=450})
table.remove(saveData.names, editItemNum)
table.remove(saveData.dates, editItemNum)
table.remove(saveData.amounts, editItemNum)
loadsave.saveTable(saveData, "payMeBackTable.json")
print("ROW DELETED")
end
end
I'm sorry for the indentation, stackoverflow just kept changing it...
But here is my question:
in the event.phase == "tap", I'm assigning editItemNum to event.target.index. After that I delete a row that is tapped. This works great for the first time. I'm using this line of code to achieve that btw:
tableView:deleteRows({editItemNum}, {slideLeftTransitionTime=400} )
So the delete function knows what to delete because "editItemNum" gets the value of the row index.
But once I deleted the row, the index numbers of the rows are not adapting. So for example I've got 3 objects in my table: 1,2,3. Now I delete the middle one, so I should get: 1,2. But instead when I touch the second row, the index is still 3. So visually that'd look like: 1,3.
It just makes no sense in my eyes and I really don't see anything wrong with my code. I did find a post on the Corona SDK forums with a bug report for this issue, but that was 2 years ago and was resolved...
Any help? :)
Kind regards,
Bram

Make line chart with values and dates

In my app i use ios-charts library (swift alternative of MPAndroidChart).
All i need is to display line chart with dates and values.
Right now i use this function to display chart
func setChart(dataPoints: [String], values: [Double]) {
var dataEntries: [ChartDataEntry] = []
for i in 0..<dataPoints.count {
let dataEntry = ChartDataEntry(value: values[i], xIndex: i)
dataEntries.append(dataEntry)
}
let lineChartDataSet = LineChartDataSet(yVals: dataEntries, label: "Items count")
let lineChartData = LineChartData(xVals: dataPoints, dataSet: lineChartDataSet)
dateChartView.data = lineChartData
}
And this is my data:
xItems = ["27.05", "03.06", "17.07", "19.09", "20.09"] //String
let unitsSold = [25.0, 30.0, 45.0, 60.0, 20.0] //Double
But as you can see - xItems are dates in "dd.mm" format. As they are strings they have same paddings between each other. I want them to be more accurate with real dates. For example 19.09 and 20.09 should be very close. I know that i should match each day with some number in order to accomplish it. But i don't know what to do next - how i can adjust x labels margins?
UPDATE
After small research where i found out that many developers had asked about this feature but nothing happened - for my case i found very interesting alternative to this library in Swift - PNChart. It is easy to use, it solves my problem.
The easiest solution will be to loop through your data and add a ChartDataEntry with a value of 0 and a corresponding label for each missing date.
In response to the question in the comments here is a screenshot from one of my applications where I am filling in date gaps with 0 values:
In my case I wanted the 0 values rather than an averaged line from data point to data point as it clearly indicates there is no data on the days skipped (8/11 for instance).
From #Philipp Jahoda's comments it sounds like you could skip the 0 value entries and just index the data you have to the correct labels.
I modified the MPAndroidChart example program to skip a few data points and this is the result:
As #Philipp Jahoda mentioned in the comments the chart handles missing Entry by just connecting to the next data point. From the code below you can see that I am generating x values (labels) for the entire data set but skipping y values (data points) for index 11 - 29 which is what you want. The only thing remaining would be to handle the x labels as it sounds like you don't want 15, 20, and 25 in my example to show up.
ArrayList<String> xVals = new ArrayList<String>();
for (int i = 0; i < count; i++) {
xVals.add((i) + "");
}
ArrayList<Entry> yVals = new ArrayList<Entry>();
for (int i = 0; i < count; i++) {
if (i > 10 && i < 30) {
continue;
}
float mult = (range + 1);
float val = (float) (Math.random() * mult) + 3;// + (float)
// ((mult *
// 0.1) / 10);
yVals.add(new Entry(val, i));
}
What I did is fully feed the dates for x data even no y data for it, and just not add the data entry for the specific xIndex, then it will not draw the y value for the xIndex to achieve what you want, this is the easiest way since you just write a for loop and continue if you detect no y value there.
I don't suggest use 0 or nan, since if it is a line chart, it will connect the 0 data or bad things will happen for nan. You might want to break the lines, but again ios-charts does not support it yet (I also asked a feature for this), you need to write your own code to break the line, or you can live with connecting the 0 data or just connect to the next valid data.
The down side is it may has performance drop since many xIndex there, but I tried ~1000 and it is acceptable. I already asked for such feature a long time ago, but it took lot of time to think about it.
Here's a function I wrote based on Wingzero's answer (I pass NaNs for the entries in the values array that are empty) :
func populateLineChartView(lineChartView: LineChartView, labels: [String], values: [Float]) {
var dataEntries: [ChartDataEntry] = []
for i in 0..<labels.count {
if !values[i].isNaN {
let dataEntry = ChartDataEntry(value: Double(values[i]), xIndex: i)
dataEntries.append(dataEntry)
}
}
let lineChartDataSet = LineChartDataSet(yVals: dataEntries, label: "Label")
let lineChartData = LineChartData(xVals: labels, dataSet: lineChartDataSet)
lineChartView.data = lineChartData
}
The solution which worked for me is splitting Linedataset into 2 Linedatasets. First would hold yvals till empty space and second after emptyspace.
//create 2 LineDataSets. set1- till empty space set2 after empty space
set1 = new LineDataSet(yVals1, "DataSet 1");
set2= new LineDataSet(yVals2,"DataSet 1");
//load datasets into datasets array
ArrayList<ILineDataSet> dataSets = new ArrayList<ILineDataSet>();
dataSets.add(set1);
dataSets.add(set2);
//create a data object with the datasets
LineData data = new LineData(xVals, dataSets);
// set data
mChart.setData(data);

Outputting data from variables in coder

I'm working in PsychoPy to design an experiment. It's almost complete, but I'm trying to output a few variables that I created in a code component into my data file for the experiment, and I haven't been able to figure out how to do that. Here is some relevant code:
if branch == 1:
if money.keys == 'left':
feedback = 'You chose $10 immediately'
TotalNow = TotalNow + 10
add = (amount - 10)/2
amount = add + amount
elif money.keys == 'right':
feedback = 'You chose $%.2f in two weeks' %(amount)
TotalLater = TotalLater + amount
TLtext = '%.2f' %(TotalLater)
amount = (amount + 10)/2
elif money.keys in ['', [], None]:
feedback = 'You did not make a choice. No reward given.'
amount = amount
if branch == 2:
if money.keys == 'right':
feedback = 'You chose $10 immediately'
TotalNow = TotalNow + 10
add = (amount - 10)/2
amount = add + amount
elif money.keys == 'left':
feedback = 'You chose $%.2f in two weeks' %(amount)
TotalLater = TotalLater + amount
TLtext = '%.2f' %(TotalLater)
amount = (amount + 10)/2
elif money.keys in ['', [], None]:
feedback = 'You did not make a choice. No reward given.'
amount = amount
I would like to output the following variables into the data file: 'TotalLater', 'TotalNow', and 'amount'. I've tried a few things, but it doesn't seem that I'm close. Any help would be appreciated.
Use the addData() method of the current experiment handler (which by default is named thisExp in Builder:
# specify each column name and its associated variable:
thisExp.addData('TotalLater', TotalLater)
thisExp.addData('TotalNow', TotalNow)
thisExp.addData('amount', amount)
Do this at the end of the relevant routine to save the current values for that trial.
If you like writing your own code, and want to learn a bit more Python, look into dictionaries which store things as "key" and "value" pairs. You start somewhere are the beginning of your program to create the dictionary with all the keys you want, and then as the program runs you store the values in the dictionary. Before the first trial you can use a function to write the keys as the column headings of a spreadsheet, and then each trial add lines with the values. For instance:
import csv ; #to use the spreadsheet export
def createDataFile(fh,d):
#fh is the handle for a file you created
#d is the name of the dictionary you have created
cdw = csv.DictWriter(fh,fieldnames = d.keys(),quoting = csv.QUOTE_MINIMAL)
cdw.writeheader()
return(cdw)
Here are some example lines from a dictionary where I am setting the values for the conditions of an expriments, note that some of these lines have keys where the value is another dictionary - the dictionaries are nested.
dty['tstX'] = dty['xoffset']['r']
dty['cbCon'] = dict(r = dty['tstCon'], l = dty['stdCon'])
dty['cbOri'] = dict(r = dty['tstStrOri'], l = dty['stdStrOri'])
dty['stdX'] = dty['xoffset']['l']
In your case you would have values for dty['amt'] = amount and at the end of a trial, you would use the function writerow() to put the latest values in their right place in the spreadsheet.
I know this is a lot more detailed, and less intuitive then the above, but you can use dictionaries in lots of places, and they are pretty darn handy.
As I have been cutting and pasting from a file of ours, the above code will likely not work out of the box for you, but will hopefully provide some useful guide posts for your own explorations.

Matlab: Optimize this (pt 2)

Here's another one:
ValidFirings = ((DwellTimes > 30/(24*60*60)) | (GroupCount > 1));
for i = length(ValidFirings):-1:2
if(~ValidFirings(i))
DwellTimes(i-1) = DwellTimes(i)+DwellTimes(i-1);
GroupCount(i-1) = GroupCount(i)+GroupCount(i-1);
DwellTimes(i) = [];
GroupCount(i) = [];
ReducedWallTime(i) = [];
ReducedWallId(i) = [];
end
end
It appears that the intent is to sum up 'dwelltimes' based on whether or not the sensor firing is considered valid. So I have a vector of sensor firings that Im walking through backwards and summing into the previous row if the current row is not marked as valid.
I can visualize this in C/C++ but I don't know how to translate it into better Matlab vector notation. As it stands now, this loop is v slow.
EDIT:
Could I use some form of DwellTimes = DwellTimes( cumsum( ValidFirings ))?
As with your previous question, replacing the for loop should improve the performance.
%# Find the indices for invalid firings
idx = find(~(DwellTimes > 30/(24*60*60)) | (GroupCount > 1));
%# Index the appropriate elements and add them (start the addition
%# from the second element)
%# This eliminates the for loop
DwellTimes(idx(2:end)-1) = DwellTimes(idx(2:end)-1)+DwellTimes(idx(2:end));
GroupCount(idx(2:end)-1) = GroupCount(idx(2:end)-1)+GroupCount(idx(2:end));
%# Now remove all the unwanted elements (this removes the
%# first element if it was a bad firing. Modify as necessary)
GroupCount(idx)=[];
DwellTimes(idx)=[];
I would consolidate first as shown, then eliminate the invalid data. This avoids the constant resizing of the data. Note that you can't reverse the order of the FOR loop due to the way that the values propagate.
ValidFirings = ((DwellTimes > 30/(24*60*60)) | (GroupCount > 1));
for i = length(ValidFirings):-1:2
if (~ValidFirings(i))
DwellTimes(i-1) = DwellTimes(i) + DwellTimes(i-1);
GroupCount(i-1) = GroupCount(i) + GroupCount(i-1);
end
end
DwellTimes = DwellTimes(ValidFirings);
GroupCount = GroupCount(ValidFirings);
ReducedWallTime = ReducedWallTime(ValidFirings);
ReducedWallId = ReducedWallId(ValidFirings);