Mismatched Input-Ternary Operator (PineScript) - pine-script-v5

On using ternary operator in Plotchar() , the true condition is not fully recognized (in spite of placing it in "()" brackets). Mismatched inpur error is given(refer image).
How to resolve this ?
Code:
k = ta.sma(...)
plotchar((k < 20) ? (xUp , "Go Long", "▲", location.bottom, color.lime, size = size.tiny) : na)
Image:

The ternary operator uses the series (xUp : na) only for conditionals,not the entire plotchar parameters.
k = ta.sma(...)
plotchar(k < 20 ? xUp: na , "Go Long", "▲", location.bottom, color.lime, size = size.tiny)

Related

OBV Calculation

obv = cum(change(src) > 0 ? volume : change(src) < 0 ? -volume : 0*volume)
obv2 = cum(sign(change(src)) * volume )
obv and obv2 return different results
ta.obv(df['close'], df['volume']) returns the same result as obv2
I will also need the return value of obv calculation with talib
OBV calculation
Thanks in advance for your help.
I've added an OBV indicator to TradingView, opened it's sources and found
obv = ta.cum(math.sign(ta.change(src)) * volume)
Then I cloned the indicator and replaced this line with
obv = ta.cum(ta.change(src) > 0 ? volume : ta.change(src) < 0 ? -volume : 0*volume)
And added it as a second indicator. I've got a different results. But also I've got a warning:
line 9: The function 'ta.change' should be called on each calculation
for consistency. It is recommended to extract the call from the
ternary operator or from the scope
So, I replaced the line with
c = ta.change(src)
obv = ta.cum(c > 0 ? volume : c < 0 ? -volume : 0*volume)
And got exactly the same results as original OBV!
So your code for obv is incorrect and you shall google for explanation of this warning. For example: The function should be called on each calculation for consistency, console output?

ag-grid filter not working with formatted number values?

I'm using ag grid with angularjs and the filter does not work with formatted numbers. I use formatted numbers with currency values.
Below is the columndef code:
{ headerName:"GBO", field: "GBO", width: 200, editable:true, cellClass: "number-cell",filter:'agNumberColumnFilter',
cellRenderer : function(params){
if(params.value == "" || params.value == null)
return '-';
else return params.value;
}
}
Before assigning the data to the grid, I format the numbers using :
$scope.formatNumberOnly = function(num,c, d, t){
//console.log(num );
var n = getNumber(num);
//var n = this,
c = isNaN(c = Math.abs(c)) ? 2 : c,
d = d == undefined ? "." : d,
t = t == undefined ? "," : t,
s = n < 0 ? "-" : "",
i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "",
j = (j = i.length) > 3 ? j % 3 : 0;
return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
};
});
The problem here is that the filter doesn't work with these formatted numbers and only seems to be working for values upto 999.
Can anyone please help me with a solution to this filtering problem?
If you want the filter to work on these formatted values, you should use a valueGetter instead of a valueFormatter
You should implement the above formatter function as a valueGetter in column Definition.
Also a number filter won't work as in order for your formatted number to be interpreted, it should be a text filter.
Here is an example from official docs.

geotools filter CQLException: Encountered "t"

I am querying a simple feature type schema:
r:Long:index=join,*g:Point:srid=4326,di:Integer:index=join,al:Float,s:Float,b:Float,an:Float,he:Float,ve:Float,t:Float,m:Boolean,i:Boolean,ts:Long;geomesa.table.sharing='true',geomesa.indices='attr:4:3,records:2:3,z2:3:3',geomesa.table.sharing.prefix='\\u0001'
with the query expression: r = 31 AND di = 5 AND BBOX(g, -38.857822, -76.111145, -74.64091, -38.61907) AND al <= 39.407307 AND s <= 1.6442835 AND b <= 83.14717 AND an <= 87.0774 AND he <= 40.89476 AND ve <= 88.761566 AND t <= 44.786507 AND m = true AND i = true.
but it throws an exception saying Encountered "t" at line 1, column 195.
Here is my exception log detail:
org.geotools.filter.text.cql2.CQLException: Encountered "t" at line 1, column 195.
Was expecting one of:
<NOT> ...
<IDENTIFIER> ...
"include" ...
"exclude" ...
"(" ...
"[" ...
Parsing : r = 31 AND di = 5 AND BBOX(g, -38.857822, -76.111145, -74.64091, -38.61907) AND al <= 39.407307 AND s <= 1.6442835 AND b <= 83.14717 AND an <= 87.0774 AND he <= 40.89476 AND ve <= 88.761566 AND t <= 44.786507 AND m = true AND i = true.
at org.geotools.filter.text.cql2.CQLCompiler.compileFilter(CQLCompiler.java:106)
at org.geotools.filter.text.commons.CompilerUtil.parseFilter(CompilerUtil.java:196)
at org.geotools.filter.text.cql2.CQL.toFilter(CQL.java:134)
at org.geotools.filter.text.cql2.CQL.toFilter(CQL.java:113)
at com.hps.GeomesaClient.query(GeomesaClient.java:134)
at com.hps.Reader.run(Reader.java:69)
at java.lang.Thread.run(Thread.java:745)
I am not able to determine, why it's throwing an exception on querying with the attribute named t. Whereas if I remove attribute t from the query, it works as expected. Is t a reserved key? or I am missing something.
Ok, this is a limitation in the ECQL query parser. The letter 't' by itself (ignoring case) is the UTC token.
https://github.com/geotools/geotools/blob/master/modules/library/cql/src/main/jjtree/ECQLGrammar.jjt#L180-L187
The options are to work with the GeoTools team to fix this corner case or pick a different attribute name. Nice find!

Reducing the number of brackets in Swift

Does anyone know if there is a way to use some kind shorthand in swift? more specifically, leaving out the braces in things like IF statements... eg
if num == 0
// Do something
instead of
if num == 0
{
// Do something
}
Those braces become rather space consuming when you have a few nested IF's.
PS. I do know I can do the following:
if num == 0 {
// Do something }
But I'm still curious if that sort of thing is possible
You can do that :
let x = 10, y = 20;
let max = (x < y) ? y : x ; // So max = 20
And so much interesting things :
let max = (x < y) ? "y is greater than x" : "x is greater than y" // max = "y is greater than x"
let max = (x < y) ? true : false // max = true
let max = (x > y) ? func() : anotherFunc() // max = anotherFunc()
(x < y) ? func() : anotherFunc() // code is running func()
This following stack : http://codereview.stackexchange.com can be better for your question ;)
Edit : ternary operators and compilation
By doing nothing more than replacing the ternary operator with an if else statement, the build time was reduced by 92.9%.
https://medium.com/#RobertGummesson/regarding-swift-build-time-optimizations-fc92cdd91e31#.42uncapwc
In swift you have to add braces even if there is just one statement in if:
if num == 0 {
// Do something
}
You cannot leave the braces, that how swift if statement work.
You could use a shorthand if statement like you would in objective-c:
num1 < num2 ? DO SOMETHING IF TRUE : DO SOMETHING IF FALSE
Swift 2.0 update
Method 1:
a != nil ? a! : b
Method 2: Shorthand if
b = a ?? ""
Referance: Apple Docs: Ternary Conditional Operator
and it does work,
u.dob = (userInfo["dob"] as? String) != nil ? (userInfo["dob"] as! String):""
I am replacing a json string with blank string if it is nil.
Edit: Adding Gerardo Medina`s suggestion...we can always use shorthand If
u.dob = userInfo["dob"] as? String ?? ""
It is called shorthand if-else condition. If you are into iOS development in Swift, then you can also manipulate your UI objects' behaviour with this property.
For e.g. - I want my button to be enabled only when there is some text in the textfield. In other words, should stay disabled when character count in textfield is zero.
button.enabled = (textField.characters.count > 0) ? true : false
its very simple :
in Swift 4
playButton.currentTitle == "Play" ? startPlay() : stopPlay()
Original Code is
if playButton.currentTitle == "Play"{
StartPlay()
}else{
StopPlay()
}
You could always put the entire if on one line:
if num == 0 { temp = 0 }

How to sort fancytree nodes with folders at the top

I've reviewed the docs and examples for fancytree for hours soaking up all of fancytree's goodness like a sponge but I can't seem to figure how to sort my fancytree object with folders first by using the API calls. I've initially got around the problem by arranging my initial JSON data so that it's already sorted with folders at the top (a requirement of the project) but now I need to add a new folder to the tree and I need to re-sort the object making sure the newly added folder appears at the top of the tree with the others.
I notice there is a curious option for sortChildren() that allows for a defining a custom compare function but I'm having trouble wrapping my head around how to use it.
Any ideas would be much appreciated!
Snippet below on how I am doing things currently (I am populating the new child with data from some form elements):
//add the new foldername to the tree and re-order
var rootNode = jQuery("#document_objects").fancytree("getRootNode");
var childNode = rootNode.addChildren({
title: jQuery('#newfoldername').val(),
tooltip: jQuery('#description').val(),
folder: true
});
rootNode.sortChildren(null, true);
Thanks in advance!
sortChildren(cmp, deep) allows to pass a compare function:
http://www.wwwendt.de/tech/fancytree/doc/jsdoc/FancytreeNode.html#sortChildren
The default implementation (if you pass null or nothing for the cmp argument) is
function(a, b) {
var x = a.title.toLowerCase(),
y = b.title.toLowerCase();
return x === y ? 0 : x > y ? 1 : -1;
};
but you could add some prefix to force a different order, e.g.:
function(a, b) {
var x = (a.isFolder() ? "0" : "1") + a.title.toLowerCase(),
y = (b.isFolder() ? "0" : "1") + b.title.toLowerCase();
return x === y ? 0 : x > y ? 1 : -1;
};
Try below code:
var cmp= function(a, b) {
var x = (a.data.isFolder ? "0" : "1") + a.data.title.toLowerCase(),
y = (b.data.isFolder ? "0" : "1") + b.data.title.toLowerCase();
return x === y ? 0 : x > y ? 1 : -1;
};
node.sortChildren(cmp, true);