How do I start my strategy after a corssover/under? - crossover

I am trying to code the following strategy:
Buy:
(1) signal one being the 50 ema crossing over the 200 ema.
(2) signal two, wait for three red candles, with the final candle closing under the 50 ema.
(3) signal three, next candle is immediately engulfing.
Only buy when all three signals are true.
The strategy is the same for short positions expect with reversed logic.
I have managed to input (2) and (3) with the following but I am struggling with the code required for signal 1.
Any help/tips would be appreciated.
//#version=5
//Indicators
strategy("Enculfing Candles Long", overlay=true, initial_capital = 2000, default_qty_value = 100, default_qty_type = strategy.percent_of_equity)
fastma = ta.ema(close, 50)
slowma = ta.ema(close, 200)
atr = ta.atr(14)
plot(fastma, "fastma", color=color.blue)
plot(slowma, "slowma", color= color.yellow)
//Buy Conditions
lowerClose1 = (close[1]<close[2]) and (close[1]<fastma)
lowerClose2 = (close[2]<close[3]) and (close[2]>fastma)
lowerClose3 = (close[3]<close[4]) and close[3]>fastma
higherClose = close>open[1]
buysignal1 = (fastma>slowma)
buysignal2 = close>fastma
longcond1 = buysignal1 and buysignal2 and lowerClose1 and lowerClose2 and lowerClose3 and higherClose
//Strategy Execution
timePeriod = time>= timestamp(syminfo.timezone, 2021, 01, 01, 0, 0)
InTrade = strategy.position_size > 0
notInTrade = strategy.position_size <= 0
strategy.entry("buy", strategy.long, when= notInTrade and longcond1)
strategy.exit(id="buy", loss = (atr*200000), profit = (atr*300000))

Related

Color background within price range of only latest 5 candle ( highest and lowest price level)

I want to color the background of price range within the latest 5 candle.
Get the highest price and lowest price among them and color the background.
Other previous candle ( candle 6 and previous ) I just want to ignore.
I'm newbie and still learning.
I try using :
highest(5)
lowest(5)
and
highest(high, 5)
lowest(low, 5)
But it didn't work for me.
Here's the closet example form Kodify web. But need to enter the price range manually.
//#version=4
study(title="Colour background in price range", overlay=true)
// STEP 1:
// Configure price range with inputs
rangeUp = input(title="Price Range Upper Bound", type=input.float, defval=1, minval=0)
rangeDown = input(title="Price Range Lower Bound", type=input.float, defval=0.95, minval=0)
fullBarInRange = input(title="Full Bar In Range?", type=input.bool, defval=false)
// STEP 2:
// Check if bar falls in range, based on input
insideRange = if fullBarInRange
high < rangeUp and low > rangeDown
else
high > rangeDown and low < rangeUp
// STEP 3:
// Plot range's upper and lower bound
ubPlot = plot(series=insideRange ? rangeUp : na, style=plot.style_linebr, transp=100, title="Upper Bound")
lbPlot = plot(series=insideRange ? rangeDown : na, style=plot.style_linebr, transp=100, title="Lower Bound")
// STEP 4:
// Fill the background for bars inside the price range
fill(plot1=ubPlot, plot2=lbPlot, color=#FF8C00, transp=75)
Version 1
This will fill between the highest/lowest of the last 5 bars:
//#version=4
study("Hi/Lo Range", "", true)
p = input(5)
hi = highest(p)
lo = lowest(p)
p_hi = plot(hi, "Hi")
p_lo = plot(lo, "Lo")
fill(p_hi, p_lo)
Version 2
//#version=4
study("Hi/Lo Range", "", true)
p = input(5)
hi = highest(p)
lo = lowest(p)
p_hi = plot(hi, "Hi", show_last = 5)
p_lo = plot(lo, "Lo", show_last = 5)
fill(p_hi, p_lo, show_last = 5)

How to mark High of today if it has a particular decimal say ".55" at end for a 5m interval chart in Tradingview using Pine script

What I want to do is to mark the candle in 5m chart for the current day if it meets following two condition:
1) The candle should be highest of the day and it's high=1234.75 (at end ".75" decimal)
2) The candle should be lowest of the day and it's low=900.25 (at end "0.25" decimal)
I could mark a candle if it's high value consist of ".75" decimal at end and low value consist of ".25" decimal behind any value using below code but it shows all candles whose high ends with "0.75". I want to mark only Day high candle if it meets 0.75 criteria. Please refer and help me out.. Thank you in advance
// This source code is subject to the terms of the Mozilla Public License 2.0 at
https://mozilla.org/MPL/2.0/
//#version=4
study("(75-25)", overlay=true)
ch = high[0]
cl = low[0]
truncate(number, decimals) =>
factor = pow(10, decimals)
int(number * factor) / factor
chA = truncate(ch,0)
chB = ch - chA
data = chB == 0.75
clA = truncate(cl,0)
clB = cl - clA
data1 = clB == 0.25
plotshape(data, style=shape.triangledown, size=size.small, location=location.abovebar,
color=color.red)
plotshape(data1, style=shape.triangleup, size=size.small, location=location.belowbar,
color=color.green)
You can use the security() function to get the daily high and lows. However, you would miss the intraday actions for backtesting. What you need I believe is, if the price is the daily high/low from the session start until that specific bar.
You can use the following method the keep track of the daily high/low and update the values if a new high/low forms.
var dailyHigh = high
var dailyLow = low
t = time("1440", session.regular) // Get the session open
isSessionFirstBar = na(t[1]) and not na(t) or t[1] < t // True: If first bar in the session
dailyHigh := iff(isSessionFirstBar, high, iff(high > dailyHigh, high, dailyHigh))
dailyLow := iff(isSessionFirstBar, low, iff(low < dailyLow, low, dailyLow))
Then you should combine this with your data and data1 variables.
data = (chB == 0.75) and (close == dailyHigh)
data1 = (clB == 0.25) and (close == dailyLow)

Calculate RSI indicator according to tradingview?

I would like to calculate RSI 14 in line with the tradingview chart.
According to there wiki this should be the solution:
https://www.tradingview.com/wiki/Talk:Relative_Strength_Index_(RSI)
I implemented this is in a object called RSI:
Calling within object RSI:
self.df['rsi1'] = self.calculate_RSI_method_1(self.df, period=self.period)
Implementation of the code the calculation:
def calculate_RSI_method_1(self, ohlc: pd.DataFrame, period: int = 14) -> pd.Series:
delta = ohlc["close"].diff()
ohlc['up'] = delta.copy()
ohlc['down'] = delta.copy()
ohlc['up'] = pd.to_numeric(ohlc['up'])
ohlc['down'] = pd.to_numeric(ohlc['down'])
ohlc['up'][ohlc['up'] < 0] = 0
ohlc['down'][ohlc['down'] > 0] = 0
# This one below is not correct, but why?
ohlc['_gain'] = ohlc['up'].ewm(com=(period - 1), min_periods=period).mean()
ohlc['_loss'] = ohlc['down'].abs().ewm(com=(period - 1), min_periods=period).mean()
ohlc['RS`'] = ohlc['_gain']/ohlc['_loss']
ohlc['rsi'] = pd.Series(100 - (100 / (1 + ohlc['RS`'])))
self.currentvalue = round(self.df['rsi'].iloc[-1], 8)
print (self.currentvalue)
self.exportspreadsheetfordebugging(ohlc, 'calculate_RSI_method_1', self.symbol)
I tested several other solution like e.g but non return a good value:
https://github.com/peerchemist/finta
https://gist.github.com/jmoz/1f93b264650376131ed65875782df386
Therefore I created a unittest based on :
https://school.stockcharts.com/doku.php?id=technical_indicators:relative_strength_index_rsi
I created an input file: (See excel image below)
and a output file: (See excel image below)
Running the unittest (unittest code not included here) should result in but is only checking the last value.
if result == 37.77295211:
log.info("Unit test 001 - PASSED")
return True
else:
log.error("Unit test 001 - NOT PASSED")
return False
But again I cannot pass the test.
I checked all values by help with excel.
So now i'm a little bit lost.
If I'm following this question:
Calculate RSI indicator from pandas DataFrame?
But this will not give any value in the gain.
a) How should the calculation be in order to align the unittest?
b) How should the calculation be in order to align with tradingview?
Here is a Python implementation of the current RSI indicator version in TradingView:
https://github.com/lukaszbinden/rsi_tradingview/blob/main/rsi.py
I had same issue in calculating RSI and the result was different from TradingView,
I have found RSI Step 2 formula described in InvestoPedia and I changed the code as below:
N = 14
close_price0 = float(klines[0][4])
gain_avg0 = loss_avg0 = close_price0
for kline in klines[1:]:
close_price = float(kline[4])
if close_price > close_price0:
gain = close_price - close_price0
loss = 0
else:
gain = 0
loss = close_price0 - close_price
close_price0 = close_price
gain_avg = (gain_avg0 * (N - 1) + gain) / N
loss_avg = (loss_avg0 * (N - 1) + loss) / N
rsi = 100 - 100 / (1 + gain_avg / loss_avg)
gain_avg0 = gain_avg
loss_avg0 = loss_avg
N is the number of period for calculating RSI (by default = 14)
the code is put in a loop to calculate all RSI values for a series.
For those who are experience the same.
My raw data contained ticks where the volume is zero. Filtering this OLHCV rows will directly give the good results.

Repeat function until index value exceeds threshold in R

I need to apply a function until an index limit (distance, in this case) is met. I'm trying to figure out a way to apply the function repeatedly while avoiding recursion issues.
Example:
I want to apply the following code until total_dist = flight_distance (2500 km). The distance traveled in a given flight depends on the energy available. The flight proceeds as a series of jumps and stops--expending and obtaining energy, respectively. If there is enough energy at the start, the flight can be finished in only two jumps (with one stop). Sometimes two or more stops are necessary. I can't know this ahead of time.
So how can I modify jump_metrics to get it to repeat until the total distance covered is 2500?
flight_distance = 2500
flight_markers = c(1:flight_distance)
TD_cost_km = rnorm(2500, 5, 1)
potential_stops = c(1:(flight_distance-1))
cumulative_flight_cost = vector("list", length=length(potential_stops))
for(i in 1:length(potential_stops)) {
cumulative_flight_cost[[i]] = cumsum(TD_cost_km[flight_markers>potential_stops[i]])
}
max_fuel_quantiles = seq(0, 1, length=flight_distance)
jump_metrics = function() {
start_fuel_prob = qbeta(runif(flight_distance, pbeta(max_fuel_quantiles,1,1),
pbeta(max_fuel_quantiles,1,1)), 1.45*2, 1)
start_energy_level_est =
rnorm(1, sample(1544 + (start_fuel_prob * 7569), 1, replace=T),
0.25)
start_max_energy = ifelse(start_energy_level_est < 1544, 1544,
start_energy_level_est)
fuel_level = start_max_energy - cumulative_flight_cost[[1]]
dist_traveled = length(fuel_level[fuel_level>(max(fuel_level)*0.2)])
dist_left = flight_distance - dist_traveled
partial_dist = 1 + dist_traveled
dist_dep_max_energy = c(rep(start_max_energy, length(1:dist_left)),
seq(start_max_energy, 1544,
length.out=length((dist_left+1):flight_distance)))
next_max_energy = dist_dep_max_energy[partial_dist]
next_fuel_level = next_max_energy - cumulative_flight_cost[[partial_dist]]
next_dist_traveled = length(next_fuel_level[next_fuel_level >
(max(next_fuel_level)*0.2)])
total_dist = next_dist_traveled + partial_dist
list(partial_dist, next_dist_traveled, total_dist)
}
jump_metrics()

Axibase Time Series Database - filter out negative values on time chart

I am using Axibase Time Series Database Community Edition, version 10552, to store my photovoltaic and sun altitude data. Sun altitude values are negative during the night time and I don't want to see them on my graphs.
How can I view only the positive values? Anyone know a setting or a trick that can acheive this?
Here is my current Time Chart widget configuration:
[widget]
type = chart
title = PV power
timespan = 3 day
entity = pvout.25630
[series]
label = Sun Altitude at (-35.3089, 149.2004)
metric = sun_altitude
color = orange
[tags]
lat = -35.3089
lon = 149.2004
Here is a screenshot of what I am actually seeing at the moment:
Here is an example in Chart Lab:
https://axibase.com/chartlab/3170e35d/2/
Good question.
There are several ways to hide or filter out the negative values:
replace-value setting uses an expression to modify or filter series values:
[widget]
type = chart
title = PV power
timespan = 3 day
entity = pvout.25630
[series]
label = Sun Altitude at (-35.3089, 149.2004)
metric = sun_altitude
color = orange
replace-value = value < 0 ? null : value
[tags]
lat=-35.3089
lon=149.2004
This expression will filter out all values that are less than 0 from the series.
Results: https://axibase.com/chartlab/3170e35d/3/
min-range-force setting can be used to set the minimum range of the y-axis:
[widget]
type = chart
title = PV power
timespan = 3 day
entity = pvout.25630
min-range-force = 0
[series]
label = Sun Altitude at (-35.3089, 149.2004)
metric = sun_altitude
color = orange
[tags]
lat=-35.3089
lon=149.2004
Results: https://axibase.com/chartlab/3170e35d/4/
If you are using a script to calculate the Sun Altitude, then you can use the Math.max function:
[widget]
type = chart
title = PV power
timespan = 3 day
[series]
label = Altitude
#API: SunCalc.getPosition = function (date, lat, lng)
value = var pos = SunCalc.getPosition(new Date(time), -35.3089, 149.2004);
value = return Math.max(0, pos.altitude)
frequency = 30 minute
color = orange
Results: https://axibase.com/chartlab/3170e35d/5/
value equation can be used to create a computed series, excluding the negative values:
[widget]
type = chart
title = PV power
timespan = 3 day
entity = pvout.25630
[series]
metric = sun_altitude
display = false
alias = sun_alt
[tags]
lat=-35.3089
lon=149.2004
[series]
label = Sun Altitude at (-35.3089, 149.2004)
value = Math.max(0, value('sun_alt'))
color = orange
In this case, we hide the original series and assign an alias, then we use the value = Math.max(0, value('sun_alt')) equation to create a new computed series without the negative values.
Results: https://axibase.com/chartlab/3170e35d/6/

Resources