I struggle to code an if statement in Pine.
The idea is that the stop-loss is tightened when a waring signal is triggered.
This tighter stop should replace the regular stop-loss and trailing-stop. I hoped is was a simple syntax error, but I can't seem to fix it by editing indents and spaces. Is there something more fundamental I'm overlooking?
Thanks for taking the time to read this!
longLossPerc = input(title="Long Stop Loss (%)", minval=0.0, step=0.1, defval=3.4) * 0.01
longTrailPerc = input(title="Long Trail Loss (%)", minval=0.0, step=0.1, defval=2.5) * 0.01
longTightStopPerc = input(title="Long K Loss (%)", minval=0.0, step=0.1, defval=0.6) * 0.01
longStopPrice = strategy.position_avg_price * (1 - longLossPerc)
longTrailPrice = strategy.position_avg_price * (1 - longTrailPerc)
longTightStop = high * (1 - longTightStopPerc)
stopValueLong = 0.0
if (Signal)
stopValueLong = longTightStop
else
stopValueLong = max(longStopPrice, longTailPrice)
else
0
You'll need something more or less of the following form, which supposes you have state variables to know the distinction between when you are in a trade or not:
var stopValueLong = 0.0
if (Signal)
stopValueLong := longTightStop
else if inTrade
stopValueLong := max(longStopPrice, longTailPrice)
else if closeTrade
stopValueLong := na
The := operator is important to assign values to your stopValueLong variable from with an if statement's local scopes. See:
https://www.tradingview.com/pine-script-docs/en/v4/language/Expressions_declarations_and_statements.html#variable-assignment
Related
Hello is there a way to generate params in GMPL as example io have a funcion
min:c[i]*x[i] and constrains that looks like A[i][j]*x[i]=b[i]. Where A[i][j]=1/(i+j-1) and i,j=1,2....,n. c[i]=b[i]=sum(j=1,...,n)1/(i+j-1) where i=1,...,n.
So there is a question is there a way to generate matrix A from equation? or do i need to make this matrix manual in data section ? and one more question is there a good way to find (n) maximum size of this problem when with precision of 2 numbers without modifying objective function ?
param n := 3;
set I := 1..n;
param A{i in I, j in I} := 1/(i+j-1);
param c{i in I} := sum{j in I} 1/(i+j-1);
# or better (may be):
# param c{i in I} := sum{j in I} A[i,j];
display A,c;
end;
The output should look like:
Reading model section from x.mod...
9 lines were read
Display statement at line 8
A[1,1] = 1
A[1,2] = 0.5
A[1,3] = 0.333333333333333
A[2,1] = 0.5
A[2,2] = 0.333333333333333
A[2,3] = 0.25
A[3,1] = 0.333333333333333
A[3,2] = 0.25
A[3,3] = 0.2
c[1] = 1.83333333333333
c[2] = 1.08333333333333
c[3] = 0.783333333333333
GMPL is a subset of AMPL. You may want to read the AMPL book to understand more about the syntax.
I am afraid I don't understand your second question.
I want to execute two commands as part of a single-line If -statement:
Though below snippet runs without error, variable $F_Akr_Completed is not set to 1, but the MsgBox() is displayed properly (with "F is 0").
$F_Akr_Completed = 0
$PID_Chi = Run($Command)
If $F_Akr_Completed = 0 And Not ProcessExists($PID_Chi) Then $F_Akr_Completed = 1 And MsgBox(1,1,"[Info] Akron parser completed. F is " & $F_Akr_Completed)
Any idea why there is no syntax-error reported when it's not functional?
There is no error, because
If x = x Then x And x
is a valid statement, and x And x is a logical expression. There are many ways you can do this, e.g.:
If Not ($F_Akr_Completed And ProcessExists($PID_Chi)) Then $F_Akr_Completed = 1 + 0 * MsgBox(1,1,"[Info] Akron parser completed. F is " & 1)
But that is a bad style of coding. AutoIt is a mostly verbose language and I recommend to seperate multiple statements.
You can also assign values using the ternary operator:
$F_Akr_Completed = (Not ($F_Akr_Completed And ProcessExists($PID_Chi))) ? 1 : 0
which is the same as
$F_Akr_Completed = Int(Not ($F_Akr_Completed And ProcessExists($PID_Chi)))
I'm trying to figure out how I would go about formatting a large number to the shorter version by appending 'k' or 'm' using Lua. Example:
17478 => 17.5k
2832 => 2.8k
1548034 => 1.55m
I would like to have the rounding in there as well as per the example. I'm not very good at Regex, so I'm not sure where I would begin. Any help would be appreciated. Thanks.
Pattern matching doesn't seem like the right direction for this problem.
Assuming 2 digits after decimal point are kept in the shorter version, try:
function foo(n)
if n >= 10^6 then
return string.format("%.2fm", n / 10^6)
elseif n >= 10^3 then
return string.format("%.2fk", n / 10^3)
else
return tostring(n)
end
end
Test:
print(foo(17478))
print(foo(2832))
print(foo(1548034))
Output:
17.48k
2.83k
1.55m
Here a longer form, which uses the hint from Tom Blodget.
Maybe its not the perfect form, but its a little more specific.
For Lua 5.0, replace #steps with table.getn(steps).
function shortnumberstring(number)
local steps = {
{1,""},
{1e3,"k"},
{1e6,"m"},
{1e9,"g"},
{1e12,"t"},
}
for _,b in ipairs(steps) do
if b[1] <= number+1 then
steps.use = _
end
end
local result = string.format("%.1f", number / steps[steps.use][1])
if tonumber(result) >= 1e3 and steps.use < #steps then
steps.use = steps.use + 1
result = string.format("%.1f", tonumber(result) / 1e3)
end
--result = string.sub(result,0,string.sub(result,-1) == "0" and -3 or -1) -- Remove .0 (just if it is zero!)
return result .. steps[steps.use][2]
end
print(shortnumberstring(100))
print(shortnumberstring(200))
print(shortnumberstring(999))
print(shortnumberstring(1234567))
print(shortnumberstring(999999))
print(shortnumberstring(9999999))
print(shortnumberstring(1345123))
Result:
> dofile"test.lua"
100.0
200.0
1.0k
1.2m
1.0m
10.0m
1.3m
>
And if you want to get rid of the "XX.0", uncomment the line before the return.
Then our result is:
> dofile"test.lua"
100
200
1k
1.2m
1m
10m
1.3m
>
I am trying to calculate the average disorder in ID trees. My code is below:
Republican_yes = yes.count('Republican')
Democrat_yes = yes.count('Democrat')
Republican_no = no.count('Republican')
Democrat_no = no.count('Democrat')
Indep_yes = yes.count('Independent')
Indep_no = no.count('Independent')
disorder_yes= Republican_yes/len(yes)*(math.log(float(Republican_yes)/len(yes),2))+ Democrat_yes/len(yes)*(math.log(float(Democrat_yes)/len(yes),2))+Indep_yes/len(yes)*(math.log(float(Indep_yes)/len(yes),2))
disorder_no= Republican_no/len(no)*(math.log(float(Republican_no)/len(no),2))+Democrat_no/len(no)*(math.log(float(Democrat_no)/len(no),2))+Indep_no/len(no)*(math.log(float(Indep_no)/len(no),2))
avgdisorder = -len(yes)/(len(yes)+len(no))*disorder_yes - len(no)/(len(yes)+len(no))*disorder_no
return avgdisorder
why do I keep getting math domain error?
Check if the lengths are 0 or not, else you will get MathError.
if len(yes):
disorder_yes= Republican_yes/len(yes)*(math.log(float(Republican_yes)/len(yes),2))+ Democrat_yes/len(yes)*(math.log(float(Democrat_yes)/len(yes),2))+Indep_yes/len(yes)*(math.log(float(Indep_yes)/len(yes),2))
if len(no):
disorder_no= Republican_no/len(no)*(math.log(float(Republican_no)/len(no),2))+Democrat_no/len(no)*(math.log(float(Democrat_no)/len(no),2))+Indep_no/len(no)*(math.log(float(Indep_no)/len(no),2))
if len(yes) or len(no):
avgdisorder = -len(yes)/(len(yes)+len(no))*disorder_yes - len(no)/(len(yes)+len(no))*disorder_no
If you want, you can always add the else clause for all 3 if statements as per your requirement.
EDIT: Thank to Joe's advice, I will make my question more specific. Actually I need to code a function in Stata which takes variables A,B,C,D,... as inputs and a variable Y as output which can be evaluated with usual Stata functions/commands like "generate dummy=2*myfun(X) if ..."
The function itself contains numerical calculations. A pseudo Stata code will look like
myfun(X)
gen Y=0.5*X if X==1
replace Y=31-X if X==2
replace Y=X-2 if X==3
.... a long list
return(Y)
Notice that X can be a huge set of different Stata variables and the numerical calculations are rather long inside the function. That's why I would like to use a function. I guess that the native "program" command in Stata is not suitable for this type of problem because it cannot take variables as input/output.
(ANSWER TO ORIGINAL QUESTION)
I have never used SAS, but at a wild guess you want something like
foreach v in A B C D {
gen test`v' = 0.5 * (`v' == 1) + 0.6 * (`v' == 2) + 0.7 * (`v' == 3)
}
or
foreach v in A B C D {
gen test`v' = cond(`v' == 1, 0.5, cond(`v' == 2, 0.6, cond(`v' == 3, 0.7, .)))
}
But hang on; that middle line also looks like
gen test`v' = (4 + `v') / 10
(ANSWER TO COMPLETELY DIFFERENT REVISED QUESTION)
This can be done in various ways. As above you could have a loop
foreach v in A B C D {
gen test`v' = 0.5 * `v' if `v' == 1
replace test`v' = 31 - `v' if `v' == 2
replace test`v' = `v' - 2 if `v' == 3
}
The question says "I guess that the native "program" command in Stata is not suitable for this type of problem because it cannot take variables as input/output." That guess is completely incorrect. You could write a program to do this too. This example is schematic, not definitive. A real program would include more checks and error messages to match any incorrect input. For detailed advice, you really need to read the documentation. One answer on SO can't teach you all you need to know even to write simple Stata programs. In any case, the example is evidently frivolous and/or incomplete, so a complete working example would be pointless or impossible.
program myweirdexample
version 13
syntax varlist(numeric), Generate(namelist)
local nold : word count `varlist'
local nnew : word count `generate'
if `nold' != `nnew' {
di as err "`generate' does not match `varlist'"
exit 198
}
local i = 1
quietly foreach v of local varlist {
local new : word `i' of `generate'
gen `new' = 0.5 * `v' if `v' == 1
replace `new' = 31 - `v' if `v' == 2
replace `new' = `v' - 2 if `v' == 3
local ++i
}
end
Footnote on terminology: The question uses the term function more broadly than it is used in Stata. In Stata, commands and functions are distinct; "function" is not a synonym for command.
Second footnote: Check out recode. It may be what you need, but it is best for mapping integer codes to other integer codes.
Third footnote: An example of a needed check is that the argument of generate() should be variable names that are legal and new.