Issue
I have a file called, runner.py, which has a lot of functions that make calls to a market DLL.
#Imports para execução da DLL
import time
import gc
from ctypes import *
from ctypes.wintypes import UINT
import struct
from datetime import*
import sys
import functions
from threading import Thread
rotPassword = ''
accountID = ''
corretora = ''
profit_dll = WinDLL('./ProfitDLL64.dll')
profit_dll.argtypes = None
def printPosition():
global profit_dll
global corretora, accountID
asset = 'asset'
bolsa = 'f'
thisCorretora = corretora
acc_id = accountID
priceToReturn = 0
result = profit_dll.GetPosition(c_wchar_p(str(acc_id)), c_wchar_p(str(thisCorretora)), c_wchar_p(asset), c_wchar_p(bolsa))
print(f'here {result}')
return result
n_qtd = result[0]
if (n_qtd == 0):
print('Nao ha posicao para esse ativo')
return priceToReturn
else:
n_tam = result[1]
arr = cast(result, POINTER(c_char))
frame = bytearray()
for i in range(n_tam):
c = arr[i]
frame.append(c[0])
start = 8
for i in range(n_qtd):
corretora_id = struct.unpack('i', frame[start:start+4])[0]
start += 4
acc_id_length = struct.unpack('h', frame[start:start+2])[0]
start += 2
account_id = frame[start:start+acc_id_length]
start += acc_id_length
titular_length = struct.unpack('h', frame[start:start+2])[0]
start += 2
titular = frame[start:start+titular_length]
start += titular_length
ticker_length = struct.unpack('h', frame[start:start+2])[0]
start += 2
ticker = frame[start:start+ticker_length]
start += ticker_length
intraday_pos = struct.unpack('i', frame[start:start+4])[0]
start += 4
price = struct.unpack('d', frame[start:start + 8])[0]
priceToReturn = str(price)
start += 8
avg_sell_price = struct.unpack('d', frame[start:start + 8])[0]
start += 8
sell_qtd = struct.unpack('i', frame[start:start+4])[0]
start += 4
avg_buy_price = struct.unpack('d', frame[start:start + 8])[0]
start += 8
buy_qtd = struct.unpack('i', frame[start:start+4])[0]
start += 4
custody_d1 = struct.unpack('i', frame[start:start+4])[0]
start += 4
custody_d2 = struct.unpack('i', frame[start:start+4])[0]
start += 4
custody_d3 = struct.unpack('i', frame[start:start+4])[0]
start += 4
blocked = struct.unpack('i', frame[start:start+4])[0]
start += 4
pending = struct.unpack('i', frame[start:start+4])[0]
start += 4
allocated = struct.unpack('i', frame[start:start+4])[0]
start += 4
provisioned = struct.unpack('i', frame[start:start+4])[0]
start += 4
qtd_position = struct.unpack('i', frame[start:start+4])[0]
start += 4
available = struct.unpack('i', frame[start:start+4])[0]
start += 4
print(f"Corretora: {corretora_id}, Titular: {str(titular)}, Ticker: {str(ticker)}, Price: {price}, AvgSellPrice: {avg_sell_price}, AvgBuyPrice: {avg_buy_price}, SellQtd: {sell_qtd}, BuyQtd: {buy_qtd}")
return priceToReturn
def dllStart():
try:
global profit_dll
key = input("Chave de acesso: ")
user = input("Usuário: ") # preencher com usuário da conta (email ou documento)
password = input("Senha: ") # preencher com senha da conta
bRoteamento = True
if bRoteamento :
result = profit_dll.DLLInitializeLogin(c_wchar_p(key), c_wchar_p(user), c_wchar_p(password), stateCallback, historyCallBack, orderChangeCallBack, accountCallback,
newTradeCallback, newDailyCallback, priceBookCallback,
offerBookCallback, newHistoryCallback, progressCallBack, newTinyBookCallBack)
else :
result = profit_dll.DLLInitializeMarketLogin(c_wchar_p(key), c_wchar_p(user), c_wchar_p(password), stateCallback, newTradeCallback, newDailyCallback, priceBookCallback,
offerBookCallback, newHistoryCallback, progressCallBack, newTinyBookCallBack)
profit_dll.SendSellOrder.restype = c_longlong
profit_dll.SendBuyOrder.restype = c_longlong
profit_dll.SendStopBuyOrder.restype = c_longlong
profit_dll.SendStopSellOrder.restype = c_longlong
profit_dll.SendZeroPosition.restype = c_longlong
profit_dll.GetAgentNameByID.restype = c_wchar_p
profit_dll.GetAgentShortNameByID.restype = c_wchar_p
profit_dll.GetPosition.restype = POINTER(c_int)
profit_dll.SendMarketSellOrder.restype = c_longlong
profit_dll.SendMarketBuyOrder.restype = c_longlong
print('DLLInitialize: ' + str(result))
wait_login()
except Exception as e:
print(str(e))
if __name__ == '__main__':
try:
dllStart()
strInput = ''
while strInput != "exit":
strInput = input('Insira o comando: ')
if strInput == 'subscribe':
subscribeTicker()
elif strInput == 'unsubscribe':
unsubscribeTicker()
elif strInput == 'offerbook':
subscribeOffer()
elif strInput == 'position':
printPosition()
elif strInput == 'lastAdjusted':
printLastAdjusted()
elif strInput == 'buystop' :
buyStopOrder()
elif strInput == 'sellstop':
sellStopOrder()
elif strInput == 'cancel':
cancelOrder()
elif strInput == 'changeOrder':
changeOrder()
elif strInput == 'cancelAllOrders':
cancelAllOrders()
elif strInput == 'getOrders':
getOrders()
elif strInput == 'getOrder':
getOrder()
elif strInput == 'selectOrder':
selectOrder()
elif strInput == 'cancelOrder':
cancelOrder()
elif strInput == 'getOrderProfitID':
getOrderProfitID()
elif strInput == 'getAllTickersByStock':
getAllTickersByStock()
elif strInput == 'getOld':
getSerieHistory()
elif strInput == 'account':
getAccount()
elif strInput == 'myBuy':
sendBuyOrder()
except KeyboardInterrupt:
pass
The correct log that I get when calling:
<ctypes.wintypes.LP_c_long object at 0x000001714E9CABC0>
When running directly the runner.py
and calling printPosition()
, everything works fine and it returns what I need (the object above).
Although, I need to import this printPosition in a separate file to make a call for it. When performing so, I received a number only and not the object I needed.
import socket, base64
import re
import sys
from operator import neg
from datetime import datetime
import profitrunner
import time
import gc
from ctypes import *
from ctypes.wintypes import UINT
import struct
def calculate_pos():
memory_address = profitrunner.printPosition()
print(heapPosition)
# I though on doing but did not work:
arr = cast(memory_address, POINTER(c_char))
The logs from this:
2015042512
2015042656
2015042800
2015042944
2015043088
2015043232
The documentation from GetPosition
gives is the follwing:
Function that returns the position for a given ticker. Returns a data structure specified below. With full size (90 + N + T + K) bytes:
function GetPosition(
pwcIDAccount : PWideChar;
pwcIDCorretora : PWideChar;
pwcTicker : PWideChar;
pwcBolsa : PWideChar) : Pointer; stdcall;
Solution
You need something like this:
import ctypes as ct
profit_dll = ct.WinDLL('./ProfitDLL64.dll')
profit_dll.GetPosition.argtypes = ct.c_wchar_p, ct.c_wchar_p, ct.c_wchar_p, ct.c_wchar_p
profit_dll.GetPosition.restype = ct.POINTER(ct.c_int)
result = profit_dll.GetPosition(acc_id, thisCorretora, asset, bolsa)
The return type is only Pointer
which isn't descriptive, but in the .zip
provided in comments the return type is POINTER(c_int)
so I used that. No need to wrap every parameter in a C type if .argtypes
is set properly for the function, but profitDLL.py
isn't doing that. Make sure to call dllStart()
to set the return types, but it's better to set .argtypes
and .restype
correctly for every function for better error checking by ctypes
.
Answered By - Mark Tolonen
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.