pandas time series column conditional on other columns - python

I am trying to re-create the column 'sig', below, but in a faster, more efficient way.
My attempt is 'sig2' but that, too, runs into its own errors.
import numpy as np
import pandas as pd
a = np.random.standard_normal(500)
A = pd.DataFrame(np.cumsum(a))
A['Max'] = pd.rolling_max(A[0],10)
A['Min'] = pd.rolling_min(A[0],10)
A['Mean'] = pd.rolling_mean(A[0],3)
A['sig'] = 0
for t in range(1,A.shape[0]):
if (A['Max'][t] > A['Max'][t-1]) & (A['sig'][t-1]==0):
A['sig'][t] = 1
elif (A['Min'][t] < A['Min'][t-1]) & (A['sig'][t-1]==0):
A['sig'][t] = -1
elif ((A[0][t] > A['Mean'][t]) & (A['sig'][t-1]==-1)) | ((A[0][t] < A['Mean'][t]) & (A['sig'][t-1]==1)):
A['sig'][t] = 0
else:
A['sig'][t] = A['sig'][t-1]
state = 0
B = A.shift()
def get_val(A,B,prev_state):
global state
if (A['Max'] > B['Max']) & (prev_state==0):
state = 1
return state
elif (A['Min'] < B['Min']) & (prev_state==0):
state = -1
return state
elif ((A[0] > A['Mean']) & (prev_state==-1)) | ((A[0] < A['Mean']) & (prev_state==1)):
state = 0
return state
else:
return state
A['sig2'] = A.apply(lambda x: get_val(x,B,state))
Thank you

Related

convert tradingview script into python3

I am looking for a converting from TV to python. Just a little code. This is the code in tradingview :
last_signal = 0
long_final = longCond and (nz(last_signal[1]) == 0 or nz(last_signal[1]) == -1)
short_final = shortCond and (nz(last_signal[1]) == 0 or nz(last_signal[1]) == 1)
last_signal := long_final ? 1 : short_final ? -1 : last_signal[1]
for variable :
-> longCond and shortCond, i have the right value (I compared between plot)
But for others, i have some differences (i think, because of last_signal)
this is my code in python :
for x in range(0,len(mavi),1):
last_signal[i] = 0
if x == 0:
longCond_tmp = 0
shortCond_tmp = 0
last_signal_tmp = 0
short_final_tmp = 0
long_final_tmp = 0
else:
if ((longCond_tmp and ((last_signal[i-1])) == 0) or ((last_signal[i-1]) == -1)):
long_final_tmp = 1
else:
long_final_tmp = 0
if ((shortCond_tmp and ((last_signal[i-1])) == 0) or ((last_signal[i-1]) == 1)):
short_final_tmp = 1
else:
short_final_tmp = 0
if long_final_tmp != 0:
last_signal_tmp = 1
else:
if short_final_tmp != 0:
last_signal_tmp = -1
else:
last_signal_tmp = last_signal[i-1]
last_signal[i] += last_signal_tmp
Are there errors in my script in python ?
Ok i found.
Just the number of "(" in
if ((longCond_tmp and ((last_signal[i-1])) == 0) or ((last_signal[i-1]) == -1)):
long_final_tmp = 1
else:
long_final_tmp = 0
if ((shortCond_tmp and ((last_signal[i-1])) == 0) or ((last_signal[i-1]) == 1)):
short_final_tmp = 1
else:
short_final_tmp = 0

Python Scipy fsolve function returns roots which are equal to starting points

I need to get all roots of a scalar equation. But fsolve can only return 1 root for each call. So I design a self-call function find_root_recursively of fsolve. This function will call itself until the new root is equal the previous root, which means fsovle has found all roots and no more new roots will be added. I use this logic to end self calling. But in some cases fsolve will return a root which is exactly the same as starting point. one_root = start always. Obviously this start is not a root. So the list_root is always adding new roots, it never ends.
min_value = df_group['strike'].min()
start_point = int(float(min_value) * 0.8)
def find_root_by_small_step(function, start_0, increment):
start = start_0
one_root = fsolve(function, start)
def get_transaction_data(self, expiry_date, df_group):
return df_group[df_group['expiration_date'] == expiry_date].loc[(df_group['type'] == 1) & (df_group['position'] == 1)], \
df_group[df_group['expiration_date'] == expiry_date].loc[(df_group['type'] == 1) & (df_group['position'] == 0)], \
df_group[df_group['expiration_date'] == expiry_date].loc[(df_group['type'] == 0) & (df_group['position'] == 1)], \
df_group[df_group['expiration_date'] == expiry_date].loc[(df_group['type'] == 0) & (df_group['position'] == 0)]
def calculate_one_payoff(self, stock_price, df_long_call, df_short_call, df_long_put, df_short_put):
# buy call
df_buy_call_executed = df_long_call[stock_price >= df_long_call['strike']]
if len(df_buy_call_executed) > 0:
buy_call_executed_sum = ((stock_price - df_buy_call_executed['breakeven_price']) * df_buy_call_executed['option_amount']).sum()
else:
buy_call_executed_sum = 0
df_buy_call_noExec = df_long_call[stock_price < df_long_call['strike']]
if len(df_buy_call_noExec) > 0:
buy_call_noExec_sum = (-1 * df_buy_call_noExec['option_price'] * df_buy_call_noExec['option_amount']).sum()
else:
buy_call_noExec_sum = 0
# sell call
df_sell_call_executed = df_short_call[stock_price >= df_short_call['strike']]
if len(df_sell_call_executed) > 0:
sell_call_executed_sum = ((df_sell_call_executed['breakeven_price'] - stock_price) * df_sell_call_executed['option_amount']).sum()
else:
sell_call_executed_sum = 0
df_sell_call_noExec = df_short_call[stock_price < df_short_call['strike']]
if len(df_sell_call_noExec) > 0:
sell_call_noExec_sum = (df_sell_call_noExec['option_price'] * df_sell_call_noExec['option_amount']).sum()
else:
sell_call_noExec_sum = 0
# buy put
df_buy_put_executed = df_long_put[stock_price < df_long_put['strike']]
if len(df_buy_put_executed) > 0:
buy_put_executed_sum = ((df_buy_put_executed['breakeven_price'] - stock_price) * df_buy_put_executed['option_amount']).sum()
else:
buy_put_executed_sum = 0
df_buy_put_noExec = df_long_put[stock_price >= df_long_put['strike']]
if len(df_buy_put_noExec) > 0:
buy_put_noExec_sum = (-1 * df_buy_put_noExec['option_price'] * df_buy_put_noExec['option_amount']).sum()
else:
buy_put_noExec_sum = 0
# sell put
df_sell_put_executed = df_short_put[stock_price < df_short_put['strike']]
if len(df_sell_put_executed) > 0:
sell_put_executed_sum = ((stock_price - df_sell_put_executed['breakeven_price']) * df_sell_put_executed['option_amount']).sum()
else:
sell_put_executed_sum = 0
df_sell_put_noExec = df_short_put[stock_price >= df_short_put['strike']]
if len(df_sell_put_noExec) > 0:
sell_put_noExec_sum = (df_sell_put_noExec['option_price'] * df_sell_put_noExec['option_amount']).sum()
else:
sell_put_noExec_sum = 0
one_stock_price_sum = buy_call_executed_sum + buy_call_noExec_sum + sell_call_executed_sum + sell_call_noExec_sum + \
buy_put_executed_sum + buy_put_noExec_sum + sell_put_executed_sum + sell_put_noExec_sum
one_stock_price_sum = float(one_stock_price_sum)
return one_stock_price_sum
df_long_call, df_short_call, df_long_put, df_short_put = self.get_transaction_data(expiry_date, df_group)
find_root_by_small_step(function=calculate_one_payoff, start=start_point, increment=increment)
ticker type position expiration_date strike option_price option_amount breakeven_price
AAPL 1 0 2021-11-19 145.0000 5.1700 2500.0000 150.1700
AAPL 0 1 2021-11-19 145.0000 2.9700 2500.0000 142.0300
AAPL 0 1 2021-11-19 145.0000 2.7000 5000.0000 142.3000
AAPL 1 1 2021-11-19 145.0000 5.8500 5000.0000 150.8500
AAPL 1 1 2021-11-19 155.0000 1.6000 1050.0000 156.6000
True root = 139.9 and 159.0

Reduce the time my code tooks to calculate a stock indicator in python

I would like to reduce the time my function tooks to calculate my stock indicator. Is there any way to do that?
The function tooks a timeseries of a stock for example and calculate the "zigzag". Also, the funtion need a reversal like 0.03
import pandas as pd
import yfinance as yf
def zigzag(dataframe=None, prices_column=None):
reversal = 0.03
dataframe = dataframe.copy()
empty_dataframe = pd.DataFrame()
start = 0
for i, row in dataframe.iterrows():
if start == i:
endLine = False
lastIndex = None
trend = None
while endLine is False:
start += 1
database = dataframe.loc[i:start]
firstPrice = database.iloc[0][prices_column]
lastPrice = database.iloc[-1][prices_column]
change = lastPrice / firstPrice - 1
if not lastIndex:
if abs(change) >= reversal:
lastIndex = database.iloc[-1].name
trend = 1 if firstPrice < lastPrice else -1
else:
pass
else:
if lastPrice / database.loc[lastIndex][prices_column] - 1 < 0 and trend == -1:
lastIndex = database.iloc[-1].name
elif lastPrice / database.loc[lastIndex][prices_column] - 1 > 0 and trend == 1:
lastIndex = database.iloc[-1].name
elif (
lastPrice / database.loc[lastIndex][prices_column] - 1 > 0 and
abs(lastPrice / database.loc[lastIndex][prices_column] - 1) >= reversal and
trend == -1
):
endLine = True
start = lastIndex
elif (
lastPrice / database.loc[lastIndex][prices_column] - 1 < 0 and
abs(lastPrice / database.loc[lastIndex][prices_column] - 1) >= reversal and
trend == 1
):
endLine = True
start = lastIndex
if dataframe.shape[0] < start:
endLine = True
empty_dataframe = empty_dataframe.append(dataframe.loc[i])
empty_dataframe = empty_dataframe.append(dataframe.loc[lastIndex])
empty_dataframe = empty_dataframe[~empty_dataframe.index.duplicated(keep='first')]
empty_dataframe = empty_dataframe.set_index('Date')
return empty_dataframe
dataframe = yf.download("AAPL", start="2010-01-01", end="2017-04-30")
dataframe.reset_index(drop=False, inplace=True)
result = zigzag(dataframe=dataframe, prices_column='Close')

Solving a maze by eliminating junctions

We are trying to make a program that solves any maze by recognising all junctions and eliminating the ones that do not lead to the entrance. We managed to create such a program but we are struggling to get the dots to connect to create a proper path. Does anybody have an idea how to do this because we are out of clues...Picture of the result, but the dots aren't connect by a line
The maze is basically a (n)x(n) grid in a numpy array with walls (true) and paths (false) see:picture of maze as seen from the variable explorer
import numpy as np
import maze_utils as mu
import matplotlib.pyplot as plt
size = 101
maze, start = mu.make_maze(size)
start = [start[1],start[0]]
#------------------------------------------------------------------------------
def junctions_finder(maze, size, start):
junctions = [start]
end = []
for y, row in enumerate(maze):
for x, column in enumerate(row):
if maze[x,y] == False:
if x == 0 or x == (size-1) or y == 0 or y == (size-1):
junctions.append([y,x])
end.append([y,x])
while True:
if x+1 < size and y+1 < size and\
maze[x+1,y] == False and maze[x,y+1] == False\
or x+1 < size and y-1 > 0 and\
maze[x+1,y] == False and maze[x,y-1] == False\
or x-1 > 0 and y-1 > 0 and\
maze[(x-1),y] == False and maze[x,(y-1)] == False\
or x-1 > 0 and y+1 < size and\
maze[(x-1),y] == False and maze[x,(y+1)] == False:
junctions.append([y,x])
break
else:
break
return junctions, end
#------------------------------------------------------------------------------
def eliminate_coor(junctions, end, start):
eliminated = []
for row in junctions:
a = row[1]
b = row[0]
connections = 0
U = False
D = False
L = False
R = False
UW = False
DW = False
LW = False
RW = False
SE = False
if row == start or row == end[0]:
connections = 2
SE = True
for i in range(1,size):
if SE == False:
if a+i <= size-1 and DW == False and D == False:
if maze[a+i, b] == True:
DW = True
else:
for coor in junctions:
if [coor[1],coor[0]] == [a+i,b]:
connections = connections + 1
D = True
if a-i >= 0 and UW == False and U == False:
if maze[a-i, b] == True:
UW = True
else:
for coor in junctions:
if [coor[1],coor[0]] == [a-i,b]:
connections = connections + 1
U = True
if b+i <= size-1 and RW == False and R == False:
if maze[a, b+i] == True:
RW = True
else:
for coor in junctions:
if [coor[1],coor[0]] == [a,b+i]:
connections = connections + 1
R = True
if b-i >= 0 and LW == False and L == False:
if maze[a, b-i] == True:
LW = True
else:
for coor in junctions:
if [coor[1],coor[0]] == [a,b-i]:
connections = connections + 1
L = True
if connections < 2:
eliminated.append([b,a])
return eliminated
#------------------------------------------------------------------------------
def junction_remover(junctions, eliminated):
counter = 0
for index, row in enumerate(junctions):
for erow in (eliminated):
if erow == row:
junctions[index] = -1
counter = counter + 1
for times in range(counter):
junctions.remove(-1)
return junctions, counter
#------------------------------------------------------------------------------
junctions, end = junctions_finder(maze, size, start)
counter = 1
while counter > 0:
eliminated = eliminate_coor(junctions, end, start)
junctions, counter = junction_remover(junctions, eliminated)
start = [start[1],start[0]]
junctions.pop(0)
pyjunc = np.array(junctions)
mu.plot_maze(maze, start=start)
plt.plot(pyjunc[:,0], pyjunc[:,1], 'o')
plt.plot(pyjunc[:,0], pyjunc[:,1]) would connect the dots... Or did you mean you have a bug you can't trace? In your picture it seems there's a beginning, but no end, so it retraces back to the beginning?
plt.plot(pyjunc[:,0], pyjunc[:,1], 'o')
plots the data points in the list with the circle marker 'o'. But you haven't defined a linestyle.
The quickest way to do this is to add it the format shorthand:
plt.plot(pyjunc[:,0], pyjunc[:,1], 'o-')
Which says to use a circle marker and a solid line '-'.
Expanding that out to how matplotlib interprets it, you could write:
plt.plot(pyjunc[:,0], pyjunc[:,1], marker='o', linestyle='-')
You can see the full documentation for plt.plot more ways to customise your plot

IndentationError in the Following Python Script

My code is not running although everything is properly indented and I have been using Python for a while now, so I am no longer in the world of programming. I couldn't find the solution.
def revisedRussianRoulette(doors):
counter = 0
for i in range(0, len(doors), 2):
i = int(i)
if doors[i] == 1 & counter == 0:
counter += 1
elif doors[i] == 1 & counter == 1:
doors[i] = 0
doors[i-2] = 0
doors[i+2] = 0
elif doors[i] == 0 & counter == 1:
doors[i-2] = 0
return doors
n = int(input().strip())
doors = list(map(int, input().strip().split(' ')))
result = revisedRussianRoulette(doors)
print (" ".join(map(str, result)))
The thing I want to do with this code does not matter. I just want to ask if the syntax is correct because I am getting the following error.
C:\Users\lenovo\Desktop\Practice Files>2nd_answer_week_of_code_36.py
File "C:\Users\lenovo\Desktop\PracticeFiles\2nd_answer_week_of_code_36.py", line 13
return doors
^
IndentationError: unindent does not match any outer indentation level
Please, could anyone tell me the solution fast?
EDIT:
The solution provided by Vikas was accurate, although there were no differences between his and my code.
Do indenation like this :
def revisedRussianRoulette(doors):
counter = 0
for i in range(0, len(doors), 2):
i = int(i)
if doors[i] == 1 & counter == 0:
counter += 1
elif doors[i] == 1 & counter == 1:
doors[i] = 0
doors[i-2] = 0
doors[i+2] = 0
elif doors[i] == 0 & counter == 1:
doors[i-2] = 0
return doors
def revisedRussianRoulette(doors):
counter = 0
for i in range(0, len(doors), 2):
i = int(i)
condition_one = doors[i] == 1 & counter == 0
condition_two = doors[i] == 1 & counter == 1
condition_three = doors[i] == 0 & counter == 1
if condition_one:
counter += 1
elif condition_two:
doors[i] = 0
doors[i-2] = 0
doors[i+2] = 0
elif condition_three:
doors[i-2] = 0
return doors
n = int(input().strip())
doors = list(map(int, input().strip().split()))
result = revisedRussianRoulette(doors)
print (" ".join(map(str, result)))

Categories