I have created a very basic script in pinescript.
study(title='Renko Strat w/ Alerts', shorttitle='S_EURUSD_5_[MakisMooz]', overlay=true)
rc = close
buy_entry = rc[0] > rc[2]
sell_entry = rc[0] < rc[2]
alertcondition(buy_entry, title='BUY')
alertcondition(sell_entry, title='SELL')
plot(buy_entry/10)
The problem is that I get a lot of duplicate alerts. I want to edit this script so that I only get a 'Buy' alert when the previous alert was a 'Sell' alert and visa versa. It seems like such a simple problem, but I have a hard time finding good sources to learn pinescript. So, any help would be appreciated. :)
One way to solve duplicate alters within the candle is by using "Once Per Bar Close" alert. But for alternative alerts (Buy - Sell) you have to code it with different logic.
I Suggest to use Version 3 (version shown above the study line) than version 1 and 2 and you can accomplish the result by using this logic:
buy_entry = 0.0
sell_entry = 0.0
buy_entry := rc[0] > rc[2] and sell_entry[1] == 0? 2.0 : sell_entry[1] > 0 ? 0.0 : buy_entry[1]
sell_entry := rc[0] < rc[2] and buy_entry[1] == 0 ? 2.0 : buy_entry[1] > 0 ? 0.0 : sell_entry[1]
alertcondition(crossover(buy_entry ,1) , title='BUY' )
alertcondition(crossover(sell_entry ,1), title='SELL')
You'll have to do it this way
if("Your buy condition here")
strategy.entry("Buy Alert",true,1)
if("Your sell condition here")
strategy.entry("Sell Alert",false,1)
This is a very basic form of it but it works.
You were getting duplicate alerts because the conditions were fulfulling more often. But with strategy.entry(), this won't happen
When the sell is triggered, as per paper trading, the quantity sold will be double (one to cut the long position and one to create a short position)
PS :You will have to add code to create alerts and enter this not in study() but strategy()
The simplest solution to this problem is to use the built-in crossover and crossunder functions.
They consider the entire series of in-this-case close values, only returning true the moment they cross rather than every single time a close is lower than the close two candles ago.
//#version=5
indicator(title='Renko Strat w/ Alerts', shorttitle='S_EURUSD_5_[MakisMooz]', overlay=true)
c = close
bool buy_entry = false
bool sell_entry = false
if ta.crossover(c[1], c[3])
buy_entry := true
alert('BUY')
if ta.crossunder(c[1], c[3])
sell_entry := true
alert('SELL')
plotchar(buy_entry, title='BUY', char='B', location=location.belowbar, color=color.green, offset=-1)
plotchar(sell_entry, title='SELL', char='S', location=location.abovebar, color=color.red, offset=-1)
It's important to note why I have changed to the indices to 1 and 3 with an offset of -1 in the plotchar function. This will give the exact same signals as 0 and 2 with no offset.
The difference is that you will only see the character print on the chart when the candle actually closes rather than watch it flicker on and off the chart as the close price of the incomplete candle moves.
Related
I'm working on a deep learning model and I would like to be able to display images on Tensorboard to have the input, the ground truth and the prediction side by side.
Currently, the display look like this :
current display
But this visualization is not convenient, because it's not easy to compare the ground truth with the prediction if images are not side by side, and we have to scroll to pass from the ground truth to the prediction (because images are too big and we display more than 6 images).
The current code :
for epoch in range(EPOCHS):
for step, (x_train, y_train) in enumerate(train_ds):
y_, gloss, dloss = pix2pix.train_step(x_train, y_train, epoch)
if step%PRINT_STEP == 0:
template = 'Epoch {} {}%, G-Loss: {}, D-Loss: {}'
print (template.format(epoch+1,int(100*step/max_steps),gloss, dloss))
with train_writer.as_default():
tf.summary.image('GT', y_train+0.5, step=epoch*max_steps+step, max_outputs=3, description=None)
tf.summary.image('pred', y_+0.5, step=epoch*max_steps+step, max_outputs=3, description=None)
tf.summary.image('input', x_train+0.5, step=epoch*max_steps+step, max_outputs=3, description=None)
tf.summary.scalar('generator loss', gloss, step = epoch*max_steps+step)
tf.summary.scalar('discriminator loss', dloss, step = epoch*max_steps+step)
tf.summary.flush()
So here is an example that what I would like to have :
desired display
I thought about an other solution : save all triples images(input/truth/pred) in local folders (folders 1 : input 1 /truth 1 /pred 1, folders 2 : input 2 /truth 2 /pred 2 ...) and display them with a python library (cv2, matplotlib ...) but same problem, I don't know how to do that if it's possible.
Thanks for your help
I'm trying to replicate values from pine script cci() function in golang. I've found this lib https://github.com/markcheno/go-talib/blob/master/talib.go#L1821
but it gives totally different values than cci function does
pseudo code how do I use the lib
cci := talib.Cci(latest14CandlesHighArray, latest14CandlesLowArray, latest14CandlesCloseArray, 14)
The lib gives me the following data
Timestamp: 2021-05-22 18:59:27.675, Symbol: BTCUSDT, Interval: 5m, Open: 38193.78000000, Close: 38122.16000000, High: 38283.55000000, Low: 38067.92000000, StartTime: 2021-05-22 18:55:00.000, EndTime: 2021-05-22 18:59:59.999, Sma: 38091.41020000, Cci0: -16.63898084, Cci1: -53.92565811,
While current cci values on TradingView are: cci0 - -136, cci1 - -49
could anyone guide what do I miss?
Thank you
P.S. cci0 - current candle cci, cci1 - previous candle cci
PineScript has really great reference when looking for functions, usually even supplying the pine code to recreate it.
https://www.tradingview.com/pine-script-reference/v4/#fun_cci
The code wasn't provided for cci, but a step-by-step explanation was.
Here is how I managed to recreate the cci function using Pine, following the steps in the reference:
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © bajaco
//#version=4
study("CCI Breakdown", overlay=false, precision=16)
cci_breakdown(src, p) =>
// The CCI (commodity channel index) is calculated as the
// 1. difference between the typical price of a commodity and its simple moving average,
// divided by the
// 2. mean absolute deviation of the typical price.
// 3. The index is scaled by an inverse factor of 0.015
// to provide more readable numbers
// 1. diff
ma = sma(src,p)
diff = src - ma
// 2. mad
s = 0.0
for i = 0 to p - 1
s := s + abs(src[i] - ma)
mad = s / p
// 3. Scaling
mcci = diff/mad / 0.015
mcci
plot(cci(close, 100))
plot(cci_breakdown(close,100))
I didn't know what mean absolute deviation meant, but at least in their implementation it appears to be taking the difference from the mean for each value in the range, but NOT changing the mean value as you go back.
I don't know Go but that's the logic.
I was trying to replace certain selections of sounds with silences, but before I could get into the essential part, the "Get label from interval" command failed before I was able to check whether I'd obtained the correct output.
Error Message I've Got on Praat
I'd thought it was some problems with the toy audio I played with, so I switched to another one but strangely enough, every time I always got stuck with the third interval in the sequence. Screenshot available here:
The Third Interval was Strangely not Available
The code I'm using right now is quite simple as below:
There could be problems with how I process the intervals labelled as "sounding", but it should not be relevant to the error I got here.
----------------------------------------------------------------------------
soundname$ = chooseReadFile$: "Open a sound file"
sound = Read from file: soundname$
gridname$ = chooseReadFile$: "Select the corresponding TextGrid file."
grid = Read from file: gridname$
tier = 1
soundEnd = Get total duration
numOfIntervals = Get number of intervals: tier
writeInfoLine: "Number of Intervals:", numOfIntervals
appendInfoLine: "**** Starting to Replace Selected Sounds... ****"
for interval from 1 to numOfIntervals
appendInfoLine: "Interval#", interval
label$ = Get label of interval: tier, interval
appendInfoLine: "Interval#", interval, ": ", label$
if label$ == "sounding"
startTime = Get starting point: tier, interval
endTime = Get end point: tier, interval
newSilence = Create Sound from formula: "new_silence", 1, startTime, endTime, 44100, ~ 0
before = Extract part: 0, startTime, "rectangular", 1, "no"
after = Extract part: endTime, soundEnd, "rectangular", 1, "no"
selectObject: before, newSilence, after
new = Concatenate
Write to WAV file... "new".wav
removeObject: before, newSilence, after
endif
endfor
appendInfoLine: "Finish!"
----------------------------------------------------------------------------
I'd suspected that it was because of my editing that some shifts occurred in the TextGrid-- however, since I only supplanted the sounds with silences that were of the same length, there should not be impacts on sounds or TextGrids afterwards. However, since I never had the chance to output some playable audio results, all I inferred above could not be corroborated by solid truth.
Thank you all so much for your kind attention and help in advance!
I'm working on a security system with my raspberry pi and node-red. I have an infrared sensor outputting 1 when motion is detected, 0 when no motion is detected. I also have a switch with the pallete node-red-dashboard that outputs 1 when it is "open" and 0 when "closed". I want to make a function that would output 1 when both of the inputs are 1, kind of like an and gate. Any help?
There are a number of ways to achieve what you want. Import the flow below and see if it behaves like you want.
Credits to Cory Guyyn
[{"id":"326ee761.191508","type":"tab","label":"Flow 6","disabled":false,"info":""},{"id":"aa420627.bdb3e8","type":"function","z":"326ee761.191508","name":"Flow On/Off","func":"var state = context.get(\"state\") || \"on\";\n\n// Display initial state status\nif(state ==\"on\"){\n node.status({fill:\"green\",shape:\"dot\",text:state});\n}else{\n node.status({fill:\"red\",shape:\"ring\",text:state});\n}\n\nif(msg.topic == \"state\"){\n context.set(\"state\",msg.payload);\n state = msg.payload;\n // update status\n if(state == \"on\"){\n node.status({fill:\"green\",shape:\"dot\",text:state});\n }else{\n node.status({fill:\"red\",shape:\"ring\",text:state});\n }\n}else{\n if(state == \"on\"){\n return msg;\n }\n}\n","outputs":1,"noerr":0,"x":570,"y":340,"wires":[["6968506.c5da8b"]]},{"id":"d1c0dabc.ff33f8","type":"ui_switch","z":"326ee761.191508","name":"","label":"Dynamic Input","group":"efb0cd04.2f1fe","order":0,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"state","style":"","onvalue":"on","onvalueType":"str","onicon":"","oncolor":"","offvalue":"off","offvalueType":"str","officon":"","offcolor":"","x":500,"y":240,"wires":[["aa420627.bdb3e8"]]},{"id":"fb35a101.734b3","type":"inject","z":"326ee761.191508","name":"","topic":"state","payload":"on","payloadType":"str","repeat":"","crontab":"","once":true,"x":280,"y":220,"wires":[["d1c0dabc.ff33f8"]]},{"id":"7f455eab.e11b4","type":"inject","z":"326ee761.191508","name":"","topic":"state","payload":"off","payloadType":"str","repeat":"","crontab":"","once":false,"x":270,"y":260,"wires":[["d1c0dabc.ff33f8"]]},{"id":"6968506.c5da8b","type":"debug","z":"326ee761.191508","name":"","active":true,"console":"false","complete":"false","x":750,"y":340,"wires":[]},{"id":"38c4ee82.f54e92","type":"comment","z":"326ee761.191508","name":"Sample Flow Toggle with UI and Link input","info":"","x":300,"y":120,"wires":[]},{"id":"5fb3fc9b.523764","type":"inject","z":"326ee761.191508","name":"PIR - 0","topic":"","payload":"0","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":270,"y":340,"wires":[["aa420627.bdb3e8"]]},{"id":"a1e5b421.b65e08","type":"inject","z":"326ee761.191508","name":"PIR - 1","topic":"","payload":"1","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":270,"y":380,"wires":[["aa420627.bdb3e8"]]},{"id":"efb0cd04.2f1fe","type":"ui_group","z":"","name":"Flow Toggle","tab":"6dfbaaa8.8cfbb4","disp":true,"width":"6"},{"id":"6dfbaaa8.8cfbb4","type":"ui_tab","z":"","name":"Sandbox","icon":"dashboard"}]
I will have to admit the title of this question sucks... I couldn't get the best description out. Let me see if I can give an example.
I have about 2700 customers with my software at one time was installed on their server. 1500 or so still do. Basically what I have going on is an Auto Diagnostics to help weed out people who have uninstalled or who have problems with the software for us to assist with. Currently we have a cURL fetching their website for our software and looking for a header return.
We have 8 different statuses that are returned
GREEN - Everything works (usually pretty quick 0.5 - 2 seconds)
RED - Software not found (usually the longest from 5 - 15 seconds)
BLUE - Software found but not activated (usually from 3 - 9 seconds)
YELLOW - Server IP mismatch (usually from 1 - 3 seconds)
ORANGE - Server IP mismatch and wrong software type (usually 5 - 10 seconds)
PURPLE - Activation key incorrect (usually within 2 seconds)
BLACK - Domain returns 404 - No longer exists (usually within a second)
UNK - Connection failed (usually due to our load balancer -- VERY rare) (never countered this yet)
Now basically what happens is a cronJob will start the process by pulling the domain and product type. It will then cURL the domain and start cycling through the status colors above.
While this is happening we have an ajax page that is returning the results so we can keep an eye on the status. The major problem is the Time Remaining is so volatile that it does not do a good estimate. Here is the current math:
# Number of accounts between NOW and when started
$completedAccounts = floor($parseData[2]*($parseData[1]/100));
# Number of seconds between NOW and when started
$completedTime = strtotime("now") - strtotime("$hour:$minute:$second");
# Avg number of seconds per account
$avgPerCompleted = $completedTime / $completedAccounts;
# Total number of remaining accounts to be scanned
$remainingAccounts = $parseData[2] - $completedAccounts;
# The total of seconds remaining for all of the remaining accounts
$remainingSeconds = $remainingAccounts * $avgPerCompleted;
$remainingTime = format_time($remainingSeconds, ":");
I could create a count on all of the green, red, blue, etc... and do an average of how long each color does, then use that for the average time, although I don't believe that would give much better results.
With the difference in times that are so varied, any suggestions would be grateful?
Thanks,
Jeff
OK, I believe I have figured it out. I had to create a class so I could calculate a single regression over a period of time.
function calc() {
$n = count($this->mDatas);
$vSumXX = $vSumXY = $vSumX = $vSumY = 0;
//var_dump($this->mDatas);
$vCnt = 0; // for time-series, start at t=0<br />
foreach ($this->mDatas AS $vOne) {
if (is_array($vOne)) { // x,y pair<br />
list($x,$y) = $vOne;
} else { // time-series<br />
$x = $vCnt; $y = $vOne;
} // fi</p>
$vSumXY += $x*$y;
$vSumXX += $x*$x;
$vSumX += $x;
$vSumY += $y;
$vCnt++;
} // rof
$vTop = ($n*$vSumXY – $vSumX*$vSumY);
$vBottom = ($n*$vSumXX – $vSumX*$vSumX);
$a = $vBottom!=0?$vTop/$vBottom:0;
$b = ($vSumY – $a*$vSumX)/$n;
//var_dump($a,$b);
return array($a,$b);
}
I take each account and start building an array, for the amount of time it takes for each one. The array then runs through this calculation so it will build a x and y time sets. Finally I then run the array through the predict function.
/** given x, return the prediction y */
function calcpredict($x) {
list($a,$b) = $this->calc();
$y = $a*$x+$b;
return $y;
}
I put static values in so you could see the results:
$eachTime = array(7,1,.5,12,11,6,3,.24,.12,.28,2,1,14,8,4,1,.15,1,12,3,8,4,5,8,.3,.2,.4,.6,4,5);
$forecastProcess = new Linear($eachTime);
$forecastTime = $forecastProcess->calcpredict(5);
This overall system gives me about a .003 difference in 10 accounts and about 2.6 difference in 2700 accounts. Next will be to calculate the Accuracy.
Thanks for trying guys and gals