Convert Pine Script V5 Strategy to Study/ Indicator - pine-script-v5

I'm a beginner playing around with Pine Script on Trading View and I'm looking to convert the below V5 Pine script strategy into an study/ indicator so I can use alerts to make trades and also show the alerts on the chart. I only want one buy/sell alert at a time
Buy Alert if rsi > 75 and (rsiMA > rsiMA[1]) but I don't want another buy alert while I'm still in a long trade, so the price would need to have increased by 0.8% (TP), dropped by 2% (SL) or the RSI dropped below 55 for a long to close
Similar with Short trade
Sell alert if rsi < 35 and (rsiMA < rsiMA[1]) but I don't want another sell alert while I'm still in a short trade, so the price would need to have decreased by 0.8% (TP), increased by 2% (SL) or the RSI gone above 55 for a short to close
I think I can use alertcondition() for a buy and sell alert but I don't know how to tie in the other conditions so it wont issue another buy/sell alert on the next candle
Any help would be great
if rsi > 75 and (rsiMA > rsiMA[1])
strategy.entry("Long Order", strategy.long, comment="ENTER-LONG")
if rsi < 55
strategy.close("Long Order", alert_message="L-CL")
strategy.exit("L-TP1", from_entry="Long Order", limit=high * 1.004, qty_percent=50, alert_message="L-TP1" + str.tostring(high * 1.004))
strategy.exit("L-TP2", from_entry="Long Order", limit=high * 1.008, qty_percent=100, alert_message="L-TP2" + str.tostring(high * 1.008))
strategy.exit("Exit Long", from_entry="Long Order", stop=low * 0.98, alert_message="L-SL" + str.tostring(low * 0.98))
if rsi < 35 and (rsiMA < rsiMA[1])
strategy.entry("Short Order", strategy.short, comment="ENTER-SHORT")
if rsi > 55
strategy.close("Short Order", alert_message="S-CL")
strategy.exit("S-TP1", from_entry="Short Order", limit=low * 0.996, qty_percent=50, alert_message="S-TP1" + str.tostring(low * 0.996))
strategy.exit("S-TP2", from_entry="Short Order", limit=low * 0.992, qty_percent=100, alert_message="S-TP2" + str.tostring(low * 0.992))
strategy.exit("Exit Short", from_entry="Short Order", stop=high * 1.02, alert_message="S-SL" + str.tostring(high * 1.02))
```

Related

How can I enter and exit a trade at a given time?

I am trying to backtest a strategy in Tradingview on an hourly chart that goes short AUDJPY at 5am Japan time and exits with a market order at 7am on the same day. I am using the hour(time) function and the IANA timezone 'Asia/Tokyo'.
Below is the code. I verified that the variable hr picks up the right hour by plotting it in the chart. But when I run the Strategy Tester the result is "No Data" and no trades appear on the screen after I apply "Add to chart" to the script.
strategy("Foreign JPY", overlay=true, currency = currency.USD)
hr = hour(time, "Asia/Tokyo")
shortCondition = hr == 5
if (shortCondition)
strategy.entry("short", strategy.short, 100000)
exitCondition = hr == 7 and strategy.position_size < 0
if (exitCondition)
strategy.close("exit", 100000)
The exit condition in your example is executed only for entries with an "exit" id=. If you want to point to the existing short order, use its id= in the strategy.close() parameter:
if (exitCondition)
strategy.close("short", 100000)

How to code dynamic stop loss orders under each swing low/high in a pine strategy script?

I am trying to program a strategy with stop loss orders that would automatically be placed under each swing low or high, because I believe that static stop loss orders with percentages or ticks are more likely to fail in the market.
After searching online for a long time I could not find any script that worked with dynamic stop loss, but most of them rather worked with fixed stop loss orders. Then, I came across the
ta.lowest(low,14) / ta.highest(high,14) function
and thought that it could be used to identify the value of the lowest candle in a certain range which could then be used as the initial point on which to add a percentage, and voila, that would be a dynamic stop loss based on swing low/high. Now the problem is it did not work out as I imagined and I have no clue why, which is why I am posting this question and hope that someone can point out my mistake.
Here the proof that it is not working:
The trade should be stopped out after reaching the price of the lowest candle (-0.1%) within the range of the last 5 candles
This is the part of the script that does not work:
// *************Entry orders*************
if longCondition
strategy.entry("Long", strategy.long)
if shortCondition
strategy.entry("Short", strategy.short)
//*************Stop Loss Orders*************
long_pos = strategy.position_size > 0
short_pos = strategy.position_size < 0
sl_perc = input.float(0.1, "Stop Loss Percentage under swing low/high")
sl_long = ta.lowest(low, 5) - ta.lowest(low, 14)/100*sl_perc
sl_short = ta.highest(high,5) + ta.lowest(low, 14)/100*sl_perc
strategy.exit("LongExit", "SL Long", stop = sl_long )
strategy.exit("ShortExit", "SL Short",stop = sl_short )
Thanks for any suggestions and help!
I think I found the answer myself:
I chose the wrong ID for the Exits. Really stupid mistake :(
(Hope that can be useful for anyone looking to try to do the same)
//*************STOP LOSS*************
long_pos = strategy.position_size > 0
short_pos = strategy.position_size < 0
sl_perc = input.float(1, "Stop Loss Percentage under swing low/high")
sl_long = ta.lowest(low, 5) - ta.lowest(low, 14)/100*sl_perc
sl_short = ta.highest(high, 5) + ta.lowest(low, 14)/100*sl_perc
strategy.exit("SL Long", "Long", stop=sl_long)
strategy.exit("SL Short", "Short", stop=sl_short)

How do I calculate the number of ticks per measure from a MIDI file

I am trying to calculate the number of ticks per measure (bar) from a MIDI file, but I am a bit stuck.
I have a MIDI file from which I can extract the following information (provided in meta messages):
#0: Time signature: 4/4, Metronome pulse: 24 MIDI clock ticks per click, Number of 32nd notes per beat: 8
There are two tempo messages, which I'm not sure are relevant:
#0: Microseconds per quarternote: 400000, Beats per minute: 150.0
#1800: Microseconds per quarternote: 441176, Beats per minute: 136.0001450668214
From trial and error, looking at the Note On messages, and looking at the MIDI file in Garageband, I can 'guess' that the number of ticks per measure is 2100, with a quarternote 525 ticks.
My question is: can I arrive at the 2100 number using the tempo information that was provided above, and if so how? Or have I not parsed enough information from the MIDI file and is there some other control message that I need to look at?
Use the following Java 11 code to extract the ticks per measure. This assumes 4 quarter notes per bar.
public MidiFile(String filename) throws Exception {
var file = new File(filename);
var sequence = MidiSystem.getSequence(file);
System.out.println("Tick length: " + sequence.getTickLength());
System.out.println("Division Type: " + sequence.getDivisionType());
System.out.println("Resolution (PPQ if division = " + javax.sound.midi.Sequence.PPQ + "): " + sequence.getResolution());
System.out.println("Ticks per measure: " + (4 * sequence.getResolution()));
}

Perfomance slowdown with growth of operations number

I have next problem. My code performance depends on number of operation! How can it be? (I use gcc v 4.3.2 under openSuse 11.1)
Here is my code:
#define N_MAX 1000000
typedef unsigned int uint;
double a[N_MAX];
double b[N_MAX];
uint n;
int main(){
for (uint i=0; i<N_MAX; i++) {
a[i]=(double)rand()/RAND_MAX;
}
for (uint n=100000; n<500000; n+=5000) {
uint time1 = time(NULL);
for (uint i=0; i<n;++i)
for (uint j=0;j<n;++j)
b[j] = a[j];
uint time2 = time(NULL);
double time = double(time2-time1);
printf("%5d ", n);
printf("%5.2f %.3f\n", time, ((double)n*n/time)/1e9);
}
return 0;
}
And here is the log of results:
n-time-Gflops (=)
200000 23.00 1.739
205000 24.00 1.751
210000 25.00 1.764
215000 26.00 1.778
220000 27.00 1.793
225000 29.00 1.746
230000 30.00 1.763
235000 32.00 1.726
240000 32.00 1.800
245000 34.00 1.765
250000 36.00 1.736
255000 37.00 1.757
260000 38.00 1.779
265000 40.00 1.756
270000 42.00 1.736
275000 44.00 1.719
280000 46.00 1.704
285000 48.00 1.692
290000 49.00 1.716
295000 51.00 1.706
300000 54.00 1.667
305000 54.00 1.723
310000 59.00 1.629
315000 61.00 1.627
320000 66.00 1.552
325000 71.00 1.488
330000 76.00 1.433
335000 79.00 1.421
340000 84.00 1.376
345000 85.00 1.400
350000 89.00 1.376
355000 96.00 1.313
360000 102.00 1.271
365000 110.00 1.211
370000 121.00 1.131
375000 143.00 0.983
380000 156.00 0.926
385000 163.00 0.909
There is also the image but I can't post it cause of new users restrictions. But here is the log plot.
What is the reason of this slowdown?
How to get rid of it? Please Help!
Your inner loops increase number of iterations every time - it is expected to take more time to do their job if there is more calculations to do. First time there are 100k operations to be done, second time 105k operations, and so on. It simply must take more and more time.
EDIT: To be clearer, I tried to say it looks to something that Spolsky called Shlemiel the painter's algorithm
Thank a lot for response!
My expectation bases on idea that operation number per time unit should remains the same. So if I increase number of operations, say twice, then computation time should increase also twice, therefore the ration of operations number and the computation time should be constant. This is something that i didn't meet. :(

Instrument for count the number of method calls on iPhone

The Time Profiler can measure the amount of time spent on certain methods. Is there a similar method that measures the number of times a method is called?
DTrace can do this, but only in the iPhone Simulator (it's supported by Snow Leopard, but not yet by iOS). I have two writeups about this technology on MacResearch here and here where I walk through some case studies of using DTrace to look for specific methods and when they are called.
For example, I created the following DTrace script to measure the number of times methods were called on classes with the CP prefix, as well as total up the time spent in those methods:
#pragma D option quiet
#pragma D option aggsortrev
dtrace:::BEGIN
{
printf("Sampling Core Plot methods ... Hit Ctrl-C to end.\n");
starttime = timestamp;
}
objc$target:CP*::entry
{
starttimeformethod[probemod,probefunc] = timestamp;
methodhasenteredatleastonce[probemod,probefunc] = 1;
}
objc$target:CP*::return
/methodhasenteredatleastonce[probemod,probefunc] == 1/
{
this->executiontime = (timestamp - starttimeformethod[probemod,probefunc]) / 1000;
#overallexecutions[probemod,probefunc] = count();
#overallexecutiontime[probemod,probefunc] = sum(this->executiontime);
#averageexecutiontime[probemod,probefunc] = avg(this->executiontime);
}
dtrace:::END
{
milliseconds = (timestamp - starttime) / 1000000;
normalize(#overallexecutiontime, 1000);
printf("Ran for %u ms\n", milliseconds);
printf("%30s %30s %20s %20s %20s\n", "Class", "Method", "Total CPU time (ms)", "Executions", "Average CPU time (us)");
printa("%30s %30s %20#u %20#u %20#u\n", #overallexecutiontime, #overallexecutions, #averageexecutiontime);
}
This generates the following nicely formatted output:
Class Method Total CPU time (ms) Executions Average CPU time (us)
CPLayer -drawInContext: 6995 352 19874
CPPlot -drawInContext: 5312 88 60374
CPScatterPlot -renderAsVectorInContext: 4332 44 98455
CPXYPlotSpace -viewPointForPlotPoint: 3208 4576 701
CPAxis -layoutSublayers 2050 44 46595
CPXYPlotSpace -viewCoordinateForViewLength:linearPlotRange:plotCoordinateValue: 1870 9152
...
While you can create and run DTrace scripts from the command line, probably your best bet would be to create a custom instrument in Instruments and fill in the appropriate D code within that instrument. You can then easily run that against your application in the Simulator.
Again, this won't work on the device, but if you just want statistics on the number of times something is called, and not the duration it runs for, this might do the job.