as for my question. I just moved to PyTorch but I have not yet done much with it yet. But it works.
@Kuba Kuba,
Can I please check something with you?
I'm calculating an array of int's (only 1's and 0's) in Python (1d numpy), then I use "PyLoadFromFile" and "PyEvalFunction" to pass that array back to AB.
The array has the same length as the current's symbol in AB, but I still get this error:
(comment: variable sym just holds the string of current AB symbol using Name(), then passes an array back to AB )
Error log just shows this:
If I check the array length in AB, barcount returns 3545 (for the length)
If I check the array length in Python:
Funny enough, using plot in AB to display my Python calculated array: it is displayed correctly, even though the error 99 shows up.
Plot(result1,"roll",colorRed,styleHistogram| styleOwnScale);
Any ideas what I'm doing wrong, or how to get rid of the error 99?
Thank you
maybe I can help. Can you show the Python code? Clearly the array that you return has the wrong size or the wrong type maybe.
Hi Ed, thank you so much.
Here is the relevant portion:
name =[]
outdict={}
def calcOutDict():
for quoteCsv in quoteFile:
with open(dataDirectory+"\\"+quoteCsv, mode="r") as file: ## quoteCsv "A500@IAB.csv"
csvFile=csv.reader(file)#, delimiter=",")
values =[]
TrueFalseArray =[]
for line in csvFile:
#name.append(symbol[0])
#print(line[9])
item = line[9]
values.append(item)
name = line[0]
for i in range(len(values)):
if i == 0:
TrueFalseArray.append(0)
elif values[i] != values[i-1]:
TrueFalseArray.append(1)
else:
TrueFalseArray.append(0)
outdict [name] = TrueFalseArray
return outdict
outdict = calcOutDict()
#print(outdict)
def rollDay(sym):
out = outdict[sym]
#print(type(out))
array = np.array((out))
return array
a=rollDay("A50")
print(type(a))
calcOutDict function just opens all csv files in the directory, does some crunching, then throws the crunched values in a dictionary:
example row 'A50' : [1,0,0,0,0,0,1, etc.]
Then rollDay uses "sym" as input to retrieve the corresponding array.
Variable explorer say this:
thank you!
bit hard for me to test but how do you know that your return array has the right size?
what you could do is pass the Close array to Python. Then you can use that array to create an array that has the correct size in which you put your return array.
So instead of just passing the symbol to the function rollDay also pass an array from Amibroker like the Close array. That one has the right size and type. Then make sure your return array has the same size and type as that array.
Thanks for the comment.
technically this works or not?
Using "PyLoadFromFile" and "PyEvalFunction"
def dummy():
array = np.arange(0,XXX,1)
return array
...just change XXX to whatever BarCount says depending on which chart is open. So that ensures that the output array is the same as the AB array, right? I'm still getting the error though.
not sure. I would do it like this:
import numpy as np
import pandas as pd
import AmiPy
def getDataFromAmibroker(close_arr, sym):
global df
df = pd.DataFrame()
df['Close'] = close_arr
df['ReturnArray'] = close_arr # this ensures the correct size of the return array
'''
now do you calculations
and put you return array inside df['ReturnArray']
use: AmiPy.Print(str(yourArray))
to get information about your return array. It will be printed in the interpretation window
'''
# if you finished calculating your return array put it in the data frame
df['ReturnArray'] = yourRetunrArray
# call the retunr array inside Amibroker using this function
def getReturnArrayFromPython():
return df['ReturnArray'].to_numpy()
For what it is worth - the BarCount in AFL is DYNAMIC depending on factors like zoom / the formula itself / QuickAFL etc / mode of operation. You just can't assume that it will always be fixed number of bars. As @empottasch wrote you - either pass array from AFL to your python code or pass BarCount so you know how many elements are expected to be in returned array.
I have this set in AFL,
SetBarsRequired(sbrAll,sbrAll);
That's why I know the array length in AFL. Can I not just use the same length in my Python created array?
How are you using pandas in AmiPy?
Whenever I tried to imprt pandas in my script, I get a failure
ERROR: Error occured during Python execution:
- ModuleNotFoundError: No module named '_ctypes'
- callstack:
- File: 'C:\Users........\AppData\Local\Programs\Python\Python311\Lib\ctypes_init_.py', >line 8 (in )
- from _ctypes import Union, Structure, Array
so I have not really used AmiPy. If I could, this would change my approach a lot.
hi, I just use
import pandas as pd
at the head of the Python file
No, you don't. SetBarsRequired is only a hint and might be ignored in certain situations. Besides number of bars is different from symbol to symbol. Please do really read the article: AmiBroker Knowledge Base ยป Do NOT make assumptions on number of bars
You should pass current BarCount to your python code.
The error is despite import pandas as pd at the head of the python file.
I was hoping there was something really straightforward that I had overlooked.
I've tried all sorts, such as amending environment variables, creating virtual environments etc and I just can't get it to work. I've tried about 4 times over the last 2 or 3 years now and followed the instructions to the letter. Just now working for me.
i will make an example that works for me, will post later
here is some code that works for me. Python code is not nicely formatted. Couldn't get the black formatter to work. Worked couple of months ago. I have not used it in awhile
AFL code (i put this in a file called example1.afl:
//SetBarsRequired( sbrAll, sbrAll );
pythonpath = "C:\\Users\\win 10\\AppData\\Local\\Programs\\Python\\Python38\\mypython\\neural\\relataly\\";
pythonfile = "example1.py";
PyLoadFromFile( "ex1", pythonpath + pythonfile );
resultArray = Null;
docalculation = ParamTrigger("Do the Calculation", "Click here");
yearArray = Year();
monthArray = Month();
dayArray = Day();
hourArray = Hour();
minuteArray = Minute();
secondArray = Second();
openArray = O;
highArray = H;
lowArray = L;
closeArray = C;
volumeArray = V;
if( docalculation )
{
Say( "Do Calculation" );
PyEvalFunction( "ex1", "getDataFromAmibroker",
yearArray, monthArray, dayArray, hourArray, minuteArray, secondArray,
openArray, highArray, lowArray, closeArray, volumeArray );
resultArray = PyEvalFunction( "ex1", "getResultFromPython" );
StaticVarSet( "resultArray", resultArray );
Say( "finished" );
}
SetChartOptions( 1, chartShowDates );
Plot( C, "Data", ColorRGB( 3, 157, 252 ), styleCandle, Null, Null, 0, 0, 1 );
Plot( Nz( StaticVarGet( "resultArray" ) ), "Result Array", ColorGold, styleLine, Null, Null, 0, 0, 2 );
Python code (filename: example1.py)
import numpy as np
import pandas as pd
import datetime
import AmiPy
def getDataFromAmibroker(year_arr, month_arr, day_arr, hour_arr, minute_arr, second_arr,
open_arr, high_arr, low_arr, close_arr, volume_arr ):
global df
df = pd.DataFrame()
df['Year'] = year_arr.astype(int)
df['Month'] = month_arr.astype(int)
df['Day'] = day_arr.astype(int)
df['Hour'] = hour_arr.astype(int)
df['Minute'] = minute_arr.astype(int)
df['Second'] = second_arr.astype(int)
df['Datetime'] = pd.to_datetime(df[['Year', 'Month', 'Day', 'Hour', 'Minute','Second']])
df = df.set_index('Datetime')
df = df.drop(columns=['Year', 'Month', 'Day', 'Hour', 'Minute','Second'])
df['Open'] = open_arr
df['High'] = high_arr
df['Low'] = low_arr
df['Close'] = close_arr
df['Volume'] = volume_arr
df['Result'] = close_arr # fill with data array to overwrite later
# do some calculation and store it in Result
df['Result'] = close_arr + 2
# show dataframe in the interpretation window on Amibroker
AmiPy.Print(str(df))
def getResultFromPython():
return df['Result'].to_numpy()
Did you search the web? There are dozens of pointers about that error. Typically pointing to incorrect Python installation / missing paths.
https://www.google.com/search?q=ModuleNotFoundError%3A+No+module+named+'_ctypes'+windows
Ok, awesome. I didn't quite get it to work initially, but your post, particularly the first line, led me down a path of putting in a load more paths in the environment variables and I just kept pasting in the paths every time an error was thrown, including libraries and eventually it worked.
i have my Python files in the Python file link. Actually at the moment I am not using Python 3.8 but 3.12 with the latest AmiPy plugin. But my old links still exist (meaning 3.8). Does not really matter where you store the files. But indeed in the Windows Environment Variables you have to set the Path for Python. So what I have is probably over the top but you have to also consider the Path