I am new to amibroker , just purchased it the last month . I am trying to make a basic ORB 15min breakout . where we buy at high of 15min / short at low of 15mins (without waiting for the candle to close) and exiting the position at end of day . i.e 15:15:00 .
Below is how much I could code it , but I seemed to have missed out something as its not giving me the right signals .
also which ever buy.sell triggers first , is what is carried till the end of day .
N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("Color", colorDefault ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() );
_SECTION_END();
_N(Title = StrFormat("{{NAME}} | {{INTERVAL}} | {{DATE}} | {{VALUES}}" ));
SetChartOptions(0,chartShowArrows|chartShowDates);
SetBarFillColor( IIf( C>=O, colorLime, colorRed ) );
Plot( Close, "Price", IIf( C >= O, colorLime, colorRed ), styleCandle );
//plotting of 15min high and low
tn = TimeNum();
orb_st = tn == 091500;
orb_end = tn == 091500;
signalstart = tn == 093000;
signalend = tn == 151000;
signalsquareoff = tn == 151500;
myH = ValueWhen(orb_end , HighestSince(orb_st, H));
myL = ValueWhen(orb_end, LowestSince(orb_st,L));
Plot(myH,"ORBH",colorYellow,styleDots);
Plot(myL,"ORBL",colorWhite,styleDots);
// buy/sell signal on break of 15min high and low
Buy = Cross(H,myH) AND tn < 151500;
Short = Cross(myL,L) AND tn < 151500;
Sell = TimeNum() == signalsquareoff;
Cover = TimeNum() == signalsquareoff;
// removing repeated signals
Buy = ExRem(Buy,Short);
Short = ExRem(Short,Buy);
// Plot Buy and Sell Signal Arrows
PlotShapes(IIf(Buy, shapeSquare, shapeNone),colorGreen, 0, L, Offset=-40);
PlotShapes(IIf(Buy, shapeSquare, shapeNone),colorLime, 0,L, Offset=-50);
PlotShapes(IIf(Buy, shapeUpArrow, shapeNone),colorWhite, 0,L, Offset=-45);
PlotShapes(IIf(Short, shapeSquare, shapeNone),colorRed, 0, H, Offset=40);
PlotShapes(IIf(Short, shapeSquare, shapeNone),colorOrange, 0,H, Offset=50);
PlotShapes(IIf(Short, shapeDownArrow, shapeNone),colorWhite, 0,H, Offset=-45);
// backtesting param for points based results
SetPositionSize(1,spsShares);
would be awesome if someone could help me pointing out the mistake I have done in the above codes . just realized apart from the official amibroker forums , there arent any other proper resources where there are discussions happening where newbies like me can learn ..
thanks and regards.
Fudge
N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("Color", colorDefault ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() );
_SECTION_END();
_N(Title = StrFormat("{{NAME}} | {{INTERVAL}} | {{DATE}} | {{VALUES}}" ));
SetChartOptions(0,chartShowArrows|chartShowDates);
SetBarFillColor( IIf( C>=O, colorLime, colorRed ) );
Plot( Close, "Price", IIf( C >= O, colorLime, colorRed ), styleCandle );
newday=day()!=ref(day(),-1);///// new code
//plotting of 15min high and low
tn = TimeNum();
orb_st = tn == 091500;
orb_end = tn == 091500;
signalstart = tn == 093000;
signalend = tn == 151000;
signalsquareoff = tn == 151500;
myH = ValueWhen(orb_end , HighestSince(orb_st, H));
myL = ValueWhen(orb_end, LowestSince(orb_st,L));
Plot(myH,"ORBH",colorYellow,styleDots);
Plot(myL,"ORBL",colorWhite,styleDots);
// buy/sell signal on break of 15min high and low
Buy = Cross(H,myH) AND tn < 151500;
Short = Cross(myL,L) AND tn < 151500;
buy=buy and sum(buy,barssince(newday))+sum(short,barssince(newday))<=1; //newcode
short=short and sum(buy,barssince(newday))+sum(short,barssince(newday))<=1; //newcode
Sell = TimeNum() == signalsquareoff;
Cover = TimeNum() == signalsquareoff;
// removing repeated signals
Buy = ExRem(Buy,Short);
Short = ExRem(Short,Buy);
// Plot Buy and Sell Signal Arrows
PlotShapes(IIf(Buy, shapeSquare, shapeNone),colorGreen, 0, L, Offset=-40);
PlotShapes(IIf(Buy, shapeSquare, shapeNone),colorLime, 0,L, Offset=-50);
PlotShapes(IIf(Buy, shapeUpArrow, shapeNone),colorWhite, 0,L, Offset=-45);
PlotShapes(IIf(Short, shapeSquare, shapeNone),colorRed, 0, H, Offset=40);
PlotShapes(IIf(Short, shapeSquare, shapeNone),colorOrange, 0,H, Offset=50);
PlotShapes(IIf(Short, shapeDownArrow, shapeNone),colorWhite, 0,H, Offset=-45);
// backtesting param for points based results
SetPositionSize(1,spsShares);
try the above. I just added 3 lines of code.. where I commented new code at the end of those lines
Related
I'm trying to make a strategy of an indicator, but I get the error: Line 73: Cannot call 'operator >' with argument 'expr0'='call 'alertcondition' (void)'. An argument of 'void' type was used but a 'const float' is expected. How can I change the code to get a correct boolean if statement for the trade entry? I'm very new to pine, hopefully someone can help me.
// This work is licensed under a Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) https://creativecommons.org/licenses/by-nc-sa/4.0/
// © LuxAlgo
//#version=5
// Umgeschrieben von JSt
strategy("Watson Strategie Nadaraya-Watson Envelope [JSt]",overlay=true,max_bars_back=1000,max_lines_count=500,max_labels_count=500)
length = input.float(500,'Window Size',maxval=500,minval=0)
h = input.float(8.,'Bandwidth')
mult = input.float(3.)
src = input.source(close,'Source')
up_col = input.color(#39ff14,'Colors',inline='col')
dn_col = input.color(#ff1100,'',inline='col')
//----
n = bar_index
var k = 2
var upper = array.new_line(0)
var lower = array.new_line(0)
lset(l,x1,y1,x2,y2,col)=>
line.set_xy1(l,x1,y1)
line.set_xy2(l,x2,y2)
line.set_color(l,col)
line.set_width(l,2)
if barstate.isfirst
for i = 0 to length/k-1
array.push(upper,line.new(na,na,na,na))
array.push(lower,line.new(na,na,na,na))
//----
line up = na
line dn = na
//----
cross_up = 0.
cross_dn = 0.
if barstate.islast
y = array.new_float(0)
sum_e = 0.
for i = 0 to length-1
sum = 0.
sumw = 0.
for j = 0 to length-1
w = math.exp(-(math.pow(i-j,2)/(h*h*2)))
sum += src[j]*w
sumw += w
y2 = sum/sumw
sum_e += math.abs(src[i] - y2)
array.push(y,y2)
mae = sum_e/length*mult
for i = 1 to length-1
y2 = array.get(y,i)
y1 = array.get(y,i-1)
up := array.get(upper,i/k)
dn := array.get(lower,i/k)
lset(up,n-i+1,y1 + mae,n-i,y2 + mae,up_col)
lset(dn,n-i+1,y1 - mae,n-i,y2 - mae,dn_col)
if src[i] > y1 + mae and src[i+1] < y1 + mae
label.new(n-i,src[i],'▼',color=#00000000,style=label.style_label_down,textcolor=dn_col,textalign=text.align_center)
if src[i] < y1 - mae and src[i+1] > y1 - mae
label.new(n-i,src[i],'▲',color=#00000000,style=label.style_label_up,textcolor=up_col,textalign=text.align_center)
cross_up := array.get(y,0) + mae
cross_dn := array.get(y,0) - mae
// TestUP = ta.crossover(src,cross_up) > 0
alertcondition(ta.crossover(src,cross_up),'Down','Down')
alertcondition(ta.crossunder(src,cross_dn),'Up','Up')
//---- Alarm für Webhook -----
plot(cross_up, color=#000000, transp=100) //Für den Alert, jedoch Darstellungsfehler → Transparent
plot(cross_dn, color=#000000, transp=100)
plotchar(cross_up, title="cross_up%", char="", location=location.top, color = color.green) // Damit der Wert in der Statusleiste dargestellt wird
plotchar(cross_dn, title="cross_dn%", char="", location=location.top, color = color.red)
//-------------------
// Start Date
// STEP 1. Create inputs that configure the backtest's date range
useDateFilter = input.bool(true, title="Begin Backtest at Start Date",
group="Backtest Time Period")
backtestStartDate = input.time(timestamp("1 Jan 2021"),
title="Start Date", group="Backtest Time Period",
tooltip="This start date is in the time zone of the exchange " +
"where the chart's instrument trades. It doesn't use the time " +
"zone of the chart or of your computer.")
// STEP 2. See if current bar happens on, or later than, the start date
inTradeWindow = not useDateFilter or time >= backtestStartDate
// ---------------
// Enter a long position when the entry rule is triggered
if inTradeWindow and ta.crossover(src,cross_up) > 0
strategy.entry('Long', strategy.long)
// Exit the Long position when the exit rule is triggered
if close > strategy.position_avg_price + 50
strategy.close("Long", comment = "TP")
else if close < strategy.position_avg_price - 50
strategy.close("Long", comment = "SL")
I tried the ta.crossover(src,cross_up) to compare it to zero, but it doesn't work.
ta.crossover() returns a bool value.
ta.crossover(source1, source2) → series bool
So, comparing its return value with some number does not make any sense and the compiler will complain: ta.crossover(src,cross_up) > 0.
You should just do:
if inTradeWindow and ta.crossover(src,cross_up)
strategy.entry('Long', strategy.long)
How to get an alert once on a supertrend trend,I think with while i can solve(but my knowledge is not enough),maybe is another way to solve my problem.
I need to skip the first signal(on down/up trend) and enter the second alert, and this signal alert one time per supertrend trend.
I describe signals below in the code.
//#version=5
indicator("My-Supertrend", overlay=true, timeframe="", timeframe_gaps=true)
atrPeriod = input(13, "ATR Length")
atrPeriod2 = input(21, "ATR Length2")
factor = input.float(3.0, "Factor", step = 0.01)
factor2 = input.float(7.0, "Factor2", step = 0.01)
[supertrend, direction] = ta.supertrend(factor, atrPeriod)
[supertrend2, direction2] = ta.supertrend(factor2, atrPeriod2)
//ST 1
bodyMiddle = plot((open + close) / 2, display=display.none)
upTrend = plot(direction < 0 ? supertrend : na, "Up Trend", color = #00cf42, style=plot.style_linebr,linewidth=1)
downTrend = plot(direction < 0? na : supertrend, "Down Trend", color = #bb2c01, style=plot.style_linebr,linewidth=1)
//ST 2
bodyMiddle2 = plot((open + close) / 2, display=display.none)
upTrend2 = plot(direction2 < 0 ? supertrend2 : na, "Up Trend", color = #00cf42, style=plot.style_linebr,linewidth=3)
downTrend2 = plot(direction2 < 0? na : supertrend2, "Down Trend", color = #bb2c01, style=plot.style_linebr,linewidth=3)
//ST1 color
fill(bodyMiddle, upTrend, color.new(#95bd06, 80), fillgaps=false)
fill(bodyMiddle, downTrend, color.new(#0692bd, 80), fillgaps=false)
//ST2 color
fill(bodyMiddle2, upTrend2, color.new(#5abd13, 70), fillgaps=false)
fill(bodyMiddle2, downTrend2, color.new(#bd3006,70), fillgaps=false)
//Logic
down_upTrend=direction>0 and direction2<0 and direction[1]<0
up_upTrend=direction<0 and direction2<0 and direction[1]>0
up_downTrend=direction<0 and direction2>0 and direction[1]>0
down_downTrend=direction>0 and direction2>0 and direction[1]<0
//For short
while direction2>0
up_downTrend
continue
down_downTrend
break
//For Long
while direction2<0
down_upTrend
continue
up_upTrend
break
plotshape(up_upTrend,style=shape.triangleup,location=location.belowbar,size=size.normal,color=color.rgb(27, 182, 27))
plotshape(up_downTrend,style=shape.triangleup,location=location.belowbar,size=size.normal,color=color.rgb(20, 112, 20))
plotshape(down_upTrend,style=shape.triangledown,location=location.abovebar,size=size.normal,color=color.rgb(255, 0, 0))
plotshape(down_downTrend,style=shape.triangledown,location=location.abovebar,size=size.normal,color=color.rgb(141, 21, 21))
alertcondition(up_upTrend or down_downTrend,"Long/Short","Signal")
I try to solve with while loop(and i describe my logic in while loop),but while dont work like I think.
Hi I am new to coding and i am trying to automate using the given code. I found an afl for intraday trading which sometime repaint signals. I want the system to wait for 30 seconds if its a 5min candle, 90 seconds for 15min candle so on.
I tried using
SecsSinceUpdateNum = DateTimeDiff(dateNowNum, lastSymbolDateNum);
timenum();
function to get the time of signal generated and compare whether the signal exists after 30sec if true plot buy or sell signals.
please help me with the code. thank you in advance
Odd=13;
CoefOdd=round(Odd/2);
Even=12;
Coefeven=Even/2;
Coefeven2=Coefeven+1;
CongestionPercent=2.8;
TriangularOdd=MA(MA(C,CoefOdd),CoefOdd);
TriangularEven=MA(MA(C,Coefeven),Coefeven2);
finalMov_avg=IIf(Odd > even,triangularOdd,TriangularEven);
Color=colorBrightGreen;
tickercolor=colorWhite;
Plot(finalMov_avg,"",IIf(C < finalmov_avg,colorRed,Color),styleLine|styleThick);
Plot(C,"",tickercolor,styleCandle);
Title=Name()+"..."+"( "+WriteIf(Odd > even,WriteVal(Odd,1),WriteVal(even,1))+" ) Period "+EncodeColor(Color)+"Triangular"+WriteIf(Odd > even,"ODD","EVEN")+" Moving Average"+"..."+EncodeColor(colorBlack)+ WriteIf(C < finalMov_avg,"Close is "+EncodeColor(colorRed)+"Below"+EncodeColor(colorBlack)+" Moving Average by ","Close is"+EncodeColor(colorBrightGreen)+" Above"+EncodeColor(colorBlack)+" Moving Average by ")+"("+WriteVal(((C/finalMov_avg)-1)*100,1.1)+"% )"+"\n"+WriteIf(finalmov_avg-Ref(finalmov_avg,-1)>0," Slope Of Average is UP : ","Slope Of Average is DOWN :")+WriteIf((((C/finalMov_avg)-1)*100 <= CongestionPercent AND ((C/finalMov_avg)-1)*100 >= -CongestionPercent),EncodeColor(colorYellow)+" with Price Congestion / Divergence to Average ","")+"\n"+WriteIf(Ref(C,-1) < Ref(finalmov_avg,-1) AND C > finalmov_avg,EncodeColor(colorGreen)+"Possible Change in Trend From Down to Up"+"\n"+" OR Short Term Correction of Previous Trend",WriteIf(Ref(C,-1) > Ref(finalmov_avg,-1) AND C < finalmov_avg,EncodeColor(colorRed)+"Possible Change in Trend From Up to Down "+"\n"+" OR Short Term Correction to Previous Trend",""))+"\n"+WriteIf(C > finalmov_avg,EncodeColor(colorGreen)+"Close has been above Moving Average ( "+WriteVal(BarsSince(C < finalmov_avg),1)+" ) Bars",EncodeColor(colorRed)+"Close has been Below Moving Average ( "+WriteVal(BarsSince(C > finalmov_avg),1)+" ) Bars")+"\n"+EncodeColor(colorBlack)+"The average # of Bars Above ( "+WriteVal(round(Cum(BarsSince(C < finalmov_avg)/Cum(1))),1)+" )"+"\n"+"The average # of Bars Below ( "+WriteVal(round(Cum(BarsSince(C > finalmov_avg)/Cum(1))),1)+" )";
_SECTION_BEGIN("AFL Example");
SetBarsRequired(10000,10000); /* this ensures that the charts include all bars AND NOT just those on screen */
SetFormulaName("Sample System"); /*name it for backtest report identification */
SetTradeDelays( 1, 1, 1, 1 ); /* delay entry/exit by one bar */
SetOption( "initialequity", 100000 ); /* starting capital */
PositionSize = -10; /* trade size will be 10% of available equty */
SetOption( "MaxOpenPositions", 6 ); /* I don't want to comit more than 60% of Equity at any one time */
SetOption( "PriceBoundChecking", 1 ); /* trade only within the chart bar's price range */
SetOption( "CommissionMode", 2 ); /* set commissions AND costs as $ per trade */
SetOption( "CommissionAmount", 32.95 ); /* commissions AND cost */
SetOption( "UsePrevBarEquityForPosSizing", 1 ); /*set the use of last bars equity for trade size*/
PositionScore = 100/C; /*Set the order for which stock trades when get mulitple signals in one bar in backtesting */
LongPer = Param("Long Period", 50, 30, 100, 5 ); /* select periods with parameter window */
ShortPer = Param("Short Period", 5, 3, 10, 1 );
LongMA = EMA( C, LongPer );
ShortMA = EMA( C, ShortPer );
LastHigh = HHV( H, LongPer );
Buy1 = Cross( ShortMA, LongMA ) AND H > Ref( LastHigh, -1 );
Sell1 = Cross( LongMA, ShortMA );
Buy = Ref(buy1,-1);
sell = ref(sell1,-1);
Buy = ExRem(Buy,Sell);
Sell = ExRem(Sell,Buy);
Filter = Buy OR Sell;
AddTextColumn( FullName(), "Company Name" );
AddColumn( Buy, "Buy", 1 );
AddColumn( Sell, "Sell", 1 );
AddColumn( C, "Close", 1.3 );
AddColumn( H, "High", 1.3 );
AddColumn( LastHigh, "HHV", 1.3 );
AddColumn( LongMA, "Long MA", 1,3 );
AddColumn( ShortMA, "Short MA", 1,3 );
GraphXSpace = 10;
//Plot( C, " Close Price", colorGrey50, styleBar );
Plot( LongMA, " EMA(C,"+WriteVal(LongPer,1)+")", colorBrown, styleLine|styleNoRescale );
Plot( ShortMA, " EMA(C,"+WriteVal(ShortPer,1)+")", colorBlue, styleLine|styleNoRescale );
Plot( Ref(Lasthigh,-1), " HHV(H,"+WriteVal(LongPer,1)+")", colorRed, styleNoLine|styleDots|styleNoRescale );
//PlotShapes( shapeUpArrow*Buy, colorGreen, 0, L, -10 );
//PlotShapes( shapeDownArrow*Sell, colorRed, 0, H, -10 );
Title = " {{NAME}} {{DATE}} {{INTERVAL}} "+_DEFAULT_NAME()+" Chart values : {{VALUES}} ";
_SECTION_END();
no=Param( "Swing", 5, 1, 55 );
res=HHV(H,no);
sup=LLV(L,no);
tsl=IIf(ValueWhen(IIf(C>Ref(res,-1),1,IIf(C<Ref(sup,-1),-1,0))!=0,IIf(C>Ref(res,-1),1,IIf(C<Ref(sup,-1),-1,0)),1)==1,sup,res);
Buy = Cross(C,res) ;
Sell = Cross(sup,C) ;
Buy = ref(Buy,-1);
Sell = Ref(Sell,-1);
_SECTION_END();
a=C;
g=(EMA(Close,3) * (2 / 4 - 1)-EMA(Close,5) * (2 / 6 - 1)) / (2 /4- 2 /6);
e=Ref(tsl,-1);
Buy = Cross(C,tsl) ;
Sell = Cross(tsl,C) ;
SellPrice=ValueWhen(Sell,e,1);
BuyPrice=ValueWhen(Buy,e,1);
Long=Flip(Buy,Sell);
Shrt=Flip(Sell,Buy );
Filter=Buy OR Sell;
Buy = Cross(C,tsl) ;
Sell = Cross(tsl,C) ;
shape = Buy * shapeUpArrow + Sell * shapeDownArrow;
PlotShapes( shape, IIf( Buy, colorGreen, colorRed ),0, IIf( Buy, Low, High ) );
a1=Ref(tsl,-1);
dist = 0.8*ATR(1); //0.8
dist1 = 1.8*ATR(1); //1.2
for( i = 0; i < BarCount; i++ )
{
if( Buy[i] )
{
PlotText( "Buy:" + L[ i ] + "\nTgt: " + (a1[i]*1.005) + "\nSL: " + (tsl[i]*0.9975), i, L[ i ]-dist[i], colorLime);
}
if( Sell[i] )
{
PlotText( "Sell:" + H[ i ] + "\nT: " + (a1[i]*0.995) + "\nSL: " + (tsl[i]*1.0025), i, H[ i ]+dist1[i], colorred);
}
}
I found 2 scripts in tradingview and added them to my script, however, it didn't work. I lost a lot of time. Can someone help me convert them to version 4? Thank you. Have a nice day!!!
//#version=2
////////////////////////////////////////////////////////////
// Copyright by HPotter v1.0 09/03/2018
// Linear Regression Intercept is one of the indicators calculated by using the
// Linear Regression technique. Linear regression indicates the value of the Y
// (generally the price) when the value of X (the time series) is 0. Linear
// Regression Intercept is used along with the Linear Regression Slope to create
// the Linear Regression Line. The Linear Regression Intercept along with the Slope
// creates the Regression line.
////////////////////////////////////////////////////////////
study(title="Line Regression Intercept", overlay = true)
Length = input(14, minval=1)
xSeria = input(title="Source", type=source, defval=close)
xX = Length * (Length - 1) * 0.5
xDivisor = xX * xX - Length * Length * (Length - 1) * (2 * Length - 1) / 6
xXY = 0
for i = 0 to Length-1
xXY := xXY + (i * xSeria[i])
xSlope = (Length * xXY - xX * sum(xSeria, Length)) / xDivisor
xLRI = (sum(xSeria, Length) - xSlope * xX) / Length
plot(xLRI, color=blue, title="LRI")
//Author - Rajandran R
//www.marketcalls.in
study("Supertrend V1.0 - Buy or Sell Signal", overlay = true)
Factor=input(3, minval=1,maxval = 100)
Pd=input(7, minval=1,maxval = 100)
Up=hl2-(Factor*atr(Pd))
Dn=hl2+(Factor*atr(Pd))
TrendUp=close[1]>TrendUp[1]? max(Up,TrendUp[1]) : Up
TrendDown=close[1]<TrendDown[1]? min(Dn,TrendDown[1]) : Dn
Trend = close > TrendDown[1] ? 1: close< TrendUp[1]? -1: nz(Trend[1],1)
Tsl = Trend==1? TrendUp: TrendDown
linecolor = Trend == 1 ? green : red
plot(Tsl, color = linecolor , style = line , linewidth = 2,title = "SuperTrend")
plotshape(cross(close,Tsl) and close>Tsl , "Up Arrow", shape.triangleup,location.belowbar,green,0,0)
plotshape(cross(Tsl,close) and close<Tsl , "Down Arrow", shape.triangledown , location.abovebar, red,0,0)
//plot(Trend==1 and Trend[1]==-1,color = linecolor, style = circles, linewidth = 3,title="Trend")
plotarrow(Trend == 1 and Trend[1] == -1 ? Trend : na, title="Up Entry Arrow", colorup=lime, maxheight=60, minheight=50, transp=0)
plotarrow(Trend == -1 and Trend[1] == 1 ? Trend : na, title="Down Entry Arrow", colordown=red, maxheight=60, minheight=50, transp=0)
//#version=4
////////////////////////////////////////////////////////////
// Copyright by HPotter v1.0 09/03/2018
// Linear Regression Intercept is one of the indicators calculated by using the
// Linear Regression technique. Linear regression indicates the value of the Y
// (generally the price) when the value of X (the time series) is 0. Linear
// Regression Intercept is used along with the Linear Regression Slope to create
// the Linear Regression Line. The Linear Regression Intercept along with the Slope
// creates the Regression line.
////////////////////////////////////////////////////////////
study(title="Line Regression Intercept", overlay=true)
Length = input(14, minval=1)
xSeria = input(title="Source", type=input.source, defval=close)
xX = Length * (Length - 1) * 0.5
xDivisor = xX * xX - Length * Length * (Length - 1) * (2 * Length - 1) / 6
xXY = 0.
for i = 0 to Length - 1 by 1
xXY := xXY + i * xSeria[i]
xXY
xSlope = (Length * xXY - xX * sum(xSeria, Length)) / xDivisor
xLRI = (sum(xSeria, Length) - xSlope * xX) / Length
plot(xLRI, color=color.blue, title="LRI")
//#version=4
//Author - Rajandran R
//www.marketcalls.in
study("Supertrend V1.0 - Buy or Sell Signal", overlay=true)
Factor = input(3, minval=1, maxval=100)
Pd = input(7, minval=1, maxval=100)
Up = hl2 - Factor * atr(Pd)
Dn = hl2 + Factor * atr(Pd)
TrendUp = Up
TrendUp := close[1] > TrendUp[1] ? max(Up, TrendUp[1]) : Up
TrendDown = Dn
TrendDown := close[1] < TrendDown[1] ? min(Dn, TrendDown[1]) : Dn
Trend = int(na)
Trend := close > TrendDown[1] ? 1 : close < TrendUp[1] ? -1 : nz(Trend[1], 1)
Tsl = Trend == 1 ? TrendUp : TrendDown
linecolor = Trend == 1 ? color.green : color.red
plot(Tsl, color=linecolor, style=plot.style_line, linewidth=2, title="SuperTrend")
plotshape(cross(close, Tsl) and close > Tsl, "Up Arrow", shape.triangleup, location.belowbar, color.green, 0, 0)
plotshape(cross(Tsl, close) and close < Tsl, "Down Arrow", shape.triangledown, location.abovebar, color.red, 0, 0)
//plot(Trend==1 and Trend[1]==-1,color = linecolor, style = circles, linewidth = 3,title="Trend")
plotarrow(Trend == 1 and Trend[1] == -1 ? Trend : na, title="Up Entry Arrow", colorup=color.lime, maxheight=60, minheight=50, transp=0)
plotarrow(Trend == -1 and Trend[1] == 1 ? Trend : na, title="Down Entry Arrow", colordown=color.red, maxheight=60, minheight=50, transp=0)
i got the same problem( develop with podofo in c++). after Insert multiple(2 times)digital signatures,i found there are 3 info——dictionary in the pdf file:
how to add two digital signature without invalidating the previous one?
thanks!
i open file in notepad++,and i found the different
the first: 97 0 obj<</Title(? G I S e r C l u bThR\n 2 0 1 4 0 7 2 0) /Author(edison qian) /Keywords(GISerClub) /Creator(? M i c r o s o f t ? W o r d 2 0 1 3)
/CreationDate(D:20150601200942+08'00') /ModDate(D:20150601200942+08'00') /Producer(? M i c r o s o f t ? W o r d 2 0 1 3) >>
the second: 97 0 obj<</Author(edison qian)/CreationDate(D:20150601200942+08'00')/Creator(? M i c r o s o f t ? W o r d 2 0 1 3)/Keywords(GISerClub)
/ModDate(D:20190426155330+08'00')/Producer(? M i c r o s o f t ? W o r d 2 0 1 3)/Title(? G I S e r C l u bThR\n 2 0 1 4 0 7 2 0)>>
the third: 97 0 obj<</Author(edison qian)/CreationDate(D:20150601200942+08'00')/Creator(? M i c r o s o f t ? W o r d 2 0 1 3)/Keywords(GISerClub)
/ModDate(D:20190426155428+08'00')/Producer(? M i c r o s o f t ? W o r d 2 0 1 3)/Title(? G I S e r C l u bThR\n 2 0 1 4 0 7 2 0)>>
my code:
bool pdfSign(PdfMemDocument* document,PdfOutputDevice* outputDevice,PKCS12* p12,RSA* rsa,int npage,PdfRect rect,int min_signature_size,const char* ImgFile/*,PdfDate& sigData*/)
{
PdfInfo* pInfo = document->GetInfo();
TKeyMap itm = pInfo->GetObject()->GetDictionary().GetKeys();
PdfObject* pobj = pInfo->GetObject()->GetDictionary().GetKey(PdfName("ModDate"));
PdfString modDate = pobj->GetString();
string sDate = modDate.GetString();
string sutf8Date = modDate.GetStringUtf8();
PdfOutlines* pOutLine = document->GetOutlines();
TKeyMap itm2 = pOutLine->GetObject()->GetDictionary().GetKeys();
const char *field_name = NULL;
bool field_use_existing = false;
int annot_page = npage;
//double annot_left = 80.0, annot_top = 70.0, annot_width = 150.0, annot_height = 150.0;
bool annot_print = true;
const char *reason = "I agree";
int result = 0;
PdfSignatureField *pSignField = NULL;
try
{
PdfSignOutputDevice signer( outputDevice );
PdfAcroForm* pAcroForm = document->GetAcroForm();
if( !pAcroForm )
PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidHandle, "acroForm == NULL" );
if( !pAcroForm->GetObject()->GetDictionary().HasKey( PdfName( "SigFlags" ) ) ||
!pAcroForm->GetObject()->GetDictionary().GetKey( PdfName( "SigFlags" ) )->IsNumber() ||
pAcroForm->GetObject()->GetDictionary().GetKeyAsLong( PdfName( "SigFlags" ) ) != 3 )
{
if( pAcroForm->GetObject()->GetDictionary().HasKey( PdfName( "SigFlags" ) ) )
pAcroForm->GetObject()->GetDictionary().RemoveKey( PdfName( "SigFlags" ) );
pdf_int64 val = 3;
pAcroForm->GetObject()->GetDictionary().AddKey( PdfName( "SigFlags" ), PdfObject( val ) );
}
if( pAcroForm->GetNeedAppearances() )
{
#if 0 /* TODO */
update_default_appearance_streams( pAcroForm );
#endif
pAcroForm->SetNeedAppearances( false );
}
PdfString name;
PdfObject* pExistingSigField = NULL;
PdfImage image( document );
image.LoadFromFile( ImgFile );
double dimgWidth = image.GetWidth();
double dimgHeight = image.GetHeight();
char fldName[96]; // use bigger buffer to make sure sprintf does not overflow
sprintf( fldName, "PodofoSignatureField%" PDF_FORMAT_INT64, static_cast( document->GetObjects().GetObjectCount() ) );
name = PdfString( fldName );
PdfPage* pPage = document->GetPage( annot_page );
if( !pPage )
PODOFO_RAISE_ERROR( ePdfError_PageNotFound );
double dPageHeight = pPage->GetPageSize().GetHeight();
double dPageWidth = pPage->GetPageSize().GetWidth();
PdfRect annot_rect;
annot_rect = PdfRect( rect.GetLeft(),
pPage->GetPageSize().GetHeight() - rect.GetBottom() - rect.GetHeight(),
dimgWidth,
dimgHeight );
PdfAnnotation* pAnnot = pPage->CreateAnnotation( ePdfAnnotation_Widget, annot_rect );
if( !pAnnot )
PODOFO_RAISE_ERROR_INFO( ePdfError_OutOfMemory, "Cannot allocate annotation object" );
if( annot_print )
pAnnot->SetFlags( ePdfAnnotationFlags_Print );
else if( !field_name || !field_use_existing )
pAnnot->SetFlags( ePdfAnnotationFlags_Invisible | ePdfAnnotationFlags_Hidden );
PdfPainter painter;
try
{
painter.SetPage( /*&sigXObject*/pPage );
/* Workaround Adobe's reader error 'Expected a dict object.' when the stream
contains only one object which does Save()/Restore() on its own, like
the image XObject. */
painter.Save();
painter.Restore();
draw_annotation( *document, painter, image, annot_rect );
}
catch( PdfError & e )
{
if( painter.GetPage() )
{
try
{
painter.FinishPage();
}
catch( ... )
{
}
}
}
painter.FinishPage();
//pSignField = new PdfSignatureField( pAnnot, pAcroForm, document );
pSignField = new PdfSignatureField( pPage, annot_rect, document );
if( !pSignField )
PODOFO_RAISE_ERROR_INFO( ePdfError_OutOfMemory, "Cannot allocate signature field object" );
PdfRect annotSize( 0.0, 0.0, dimgWidth, dimgHeight );
PdfXObject sigXObject( annotSize, document );
pSignField->SetAppearanceStream( &sigXObject );
// use large-enough buffer to hold the signature with the certificate
signer.SetSignatureSize( min_signature_size );
pSignField->SetFieldName( name );
pSignField->SetSignatureReason( PdfString( reinterpret_cast( reason ) ) );
pSignField->SetSignatureDate( /*sigData*/PdfDate() );
pSignField->SetSignature( *signer.GetSignatureBeacon() );
pSignField->SetBackgroundColorTransparent();
pSignField->SetBorderColorTransparent();
// The outPdfFile != NULL means that the write happens to a new file,
// which will be truncated first and then the content of the srcPdfFile
// will be copied into the document, follwed by the changes.
//signer.Seek(0);
document->WriteUpdate( &signer, true );
if( !signer.HasSignaturePosition() )
PODOFO_RAISE_ERROR_INFO( ePdfError_SignatureError, "Cannot find signature position in the document data" );
// Adjust ByteRange for signature
signer.AdjustByteRange();
// Read data for signature and count it
// We seek at the beginning of the file
signer.Seek( 0 );
sign_with_signer( signer, g_x509, g_pKey );
signer.Flush();
}
catch( PdfError & e )
{
}
if( pSignField )
delete pSignField;
}
i use the code above two times, and the first signature is invalid.
how to add two digital signature without invalidating the previous one?
Painting on the right PdfCanvas
After analyzing the example pdf the reason why your second signature invalidated your first one became clear: In the course of signing you change the page content of the page with the widget annotation of the signature.
But changing the content of any page invalidates any previous signature! Cf. this answer for details on allowed and disallowed changes of signed documents.
Indeed:
PdfPainter painter;
try
{
painter.SetPage( /*&sigXObject*/pPage );
/* Workaround Adobe's reader error 'Expected a dict object.' when the stream
contains only one object which does Save()/Restore() on its own, like
the image XObject. */
painter.Save();
painter.Restore();
draw_annotation( *document, painter, image, annot_rect );
}
Apparently you here change something in the page content itself. When this code is executed while applying the second signature, the first signature is invalidated.
You confirmed in a comment:
i use '&sigXObject' instead of 'pPage ',All two signatures are working! but the red seal disappeared
Using the right coordinates
Concerning your observation that the red seal disappeared: You use the wrong coordinates for drawing the image on the annotation appearance!
You use coordinates for the page coordinate system, but you have to use the coordinates in the coordinate system given by the appearance's bounding box.
Thus, your
painter.DrawImage( annot_rect.GetLeft(), annot_rect.GetBottom(), &image );
is wrong, instead try something like
painter.DrawImage( 0, 0, &image );
as the bounding box of your appearance is is
[ 0 0 151 151 ]