I am trying to download the data from IB api and upload it onto a google sheet. If the data already exists in the sheet, then I want the new data to be added into the sheet without overwriting the previous data. This is what I have done so far:
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.contract import Contract
from threading import Timer
import pandas as pd
from datetime import datetime
import os
import pygsheets
class TestApp(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
self.df = pd.DataFrame(columns=['accountName', 'contract', 'position','marketPrice', 'marketValue', 'averageCost', 'unrealizedPNL','realizedPNL'])
self.df1 = pd.DataFrame(columns=['key', 'value', 'currency'])
def error(self, reqId, errorCode, errorString):
print("Error: ", reqId, " ", errorCode, " ", errorString)
def nextValidId(self,orderId):
self.start()
def updatePortfolio(self, contract: Contract, position: float, marketPrice: float, marketValue: float,
averageCost: float, unrealizedPNL: float, realizedPNL: float, accountName: str):
self.df.loc[len(self.df)] = [accountName, contract.symbol,position,marketPrice, marketValue,averageCost, unrealizedPNL,realizedPNL]
# See unrealized P&L, which will be the total unrealized P&L since the position was open, the
# realized P&L which would be the realized profit loss for the current day
# If you’ve closed out any positions, as well as the account name, the current market value,
# the average cost used to open the position and of course the position size
print("UpdatePortfolio.", "Symbol:", contract.symbol, "SecType:", contract.secType, "Exchange:",
contract.exchange,
"Position:", position, "MarketPrice:", marketPrice, "MarketValue:", marketValue, "AverageCost:",
averageCost,
"UnrealizedPNL:", unrealizedPNL, "RealizedPNL:", realizedPNL, "AccountName:", accountName)
def updateAccountValue(self, key: str, val: str, currency: str, accountName: str):
# returns the cash balance, the required margin for the account, or the net liquidity
self.df1.loc[len(self.df)] = ['ExchangeRate', val, currency]
print("UpdateAccountValue. Key:", key, "Value:", val, "Currency:", currency, "AccountName:", accountName)
def updateAccountTime(self, timeStamp: str):
print("UpdateAccountTime. Time:", timeStamp)
def accountDownloadEnd(self, accountName: str):
print("AccountDownloadEnd. Account:", accountName)
def start(self):
# ReqAccountUpdates - This function causes both position and account information to be returned for a specified account
# Invoke ReqAccountUpdates with true to start a subscription
self.reqAccountUpdates(True, "U0000000") # <----- Change account number here
def stop(self):
self.reqAccountUpdates(False,"U00000") # <----- Change account number here
self.done = True
self.disconnect()
def main():
app = TestApp()
app.connect("127.0.0.1", 7496, 0)
Timer(5, app.stop).start()
app.run()
# service file is the ib_data json file key
service_file_path = "googlesheet_api_json"
gc = pygsheets.authorize(service_file= service_file_path )
spreadsheet_id = '00000'
sh = gc.open_by_key(spreadsheet_id)
# inserting date and time to the data
now = datetime.now()
dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
app.df['Date_Time'] = dt_string
#check if the google sheet has previous data
wk_sheet_stock = gc.open('workbook').sheet1
cells = wk_sheet_stock.get_all_values(include_tailing_empty_rows=False, include_tailing_empty=False, returnas='matrix')
if len(cells) < 1:
print('no data in the file')
data_write = sh.worksheet_by_title('stocks')
data_write.clear('A1',None,'*')
data_write.set_dataframe(app.df, (1,1), encoding='utf-8', fit=True)
data_write.frozen_rows = 1
data_write = sh.worksheet_by_title('currency')
data_write.clear('A1', None, '*')
data_write.set_dataframe(app.df1, (1, 1), encoding='utf-8', fit=True)
data_write.frozen_rows = 1
else:
print('adding data to the file')
stock_df_values = app.df.values.tolist()
currency_df_values = app.df1.values.tolist()
sh.values_append('stocks', {'valueInputOption': 'RAW'}, {'values': stock_df_values})
sh.values_append('currency', {'valueInputOption': 'RAW'}, {'values': currency_df_values})
if __name__ == "__main__":
main()
I get the error: AttributeError: 'Spreadsheet' object has no attribute 'values_append'
I am confused as to how do I go about this. Thank you for your help!
I believe your goal is as follows.
You want to append the values using values_append.
You want to remove your current issue of I get the error: AttributeError: 'Spreadsheet' object has no attribute 'values_append'.
You want to achieve this using pygsheets for python.
Modification points:
When I saw the document of pygsheets, it seems that the method of values_append is for class pygsheets.sheet.SheetAPIWrapper. In this case, sh of sh = gc.open_by_key(spreadsheet_id) is not it. I think that this might be the reason for your current issue of AttributeError: 'Spreadsheet' object has no attribute 'values_append'.
And, I cannot know your values of stock_df_values and currency_df_values. So, in this answer, I propose a modification point by guessing that those values are the 2-dimensional array. Please be careful about this.
When these points are reflected in your script, how about the following modification?
From:
sh.values_append('stocks', {'valueInputOption': 'RAW'}, {'values': stock_df_values})
sh.values_append('currency', {'valueInputOption': 'RAW'}, {'values': currency_df_values})
To:
gc.sheet.values_append(spreadsheet_id, stock_df_values, "ROWS", "stocks")
gc.sheet.values_append(spreadsheet_id, currency_df_values, "ROWS", "currency")
Note:
I guessed that the values of "stocks" and "currency" are the sheet names in the Spreadsheet of sh = gc.open_by_key(spreadsheet_id). Please be careful about this.
If you cannot know whether the values of stock_df_values and currency_df_values are a 2-dimensional array, please modify them as follows.
gc.sheet.values_append(spreadsheet_id, stock_df_values if isinstance(stock_df_values[0], list) else [stock_df_values], "ROWS", "stocks")
gc.sheet.values_append(spreadsheet_id, currency_df_values if isinstance(currency_df_values[0], list) else [currency_df_values], "ROWS", "currency")
In this answer, I suppose that other parts except for sh.values_append of your script work fine. Please be careful about this.
Reference:
values_append
I am using flask and web3.eth on pythonanywhere and connecting to a contract, but am having issues returning a value for one of the smart contract functions. No errors are being logged. I have placed several print statements to see where the app is stopping and found that it stops when I call a smart contract function.
Also I should mention that I am able to run this exact code locally without issues.
This is the function that is most likely failing:
def getDataFromTokenID(tokenid, contract):
print('getting uri')
uri = contract.functions.tokenURI(tokenid).call() # This is where it stops printing
print('PRINT:',uri)
html = requests.get(uri)
name, img_url = html.json()['name'], html.json()['image']
code = name[-5:]
return name, img_url, code
The function above is called in the following blueprint:
#TokenInfo.route('/rarity/<int:tokenid>', methods=['GET'])
def sendTokenInfo(tokenid):
contract_address = ' ' # left empty for posting purposes
w3 = Web3(Web3.WebsocketProvider(' ')) # left empty purposefully as well
contract = w3.eth.contract(address=contract_address, abi=contract_abi.abi)
model = Shape_classifier()
model.load_state_dict(load(os.getcwd()+'/mysite/app/state_dict.pth'))
uri = current_app.config['MONGO_URI']
mongo.init_app(current_app, uri)
gs = mongo.db.gantomstone_info
try:
id_exists = [{"$match": {'_id': tokenid}}, {"$count": "count"}]
list(gs.aggregate(id_exists))[0]
except:
print('getting data from token id')
name, img_url, serial = getDataFromTokenID(tokenid, contract) ## Stops printing here
print('opening image')
img = Image.open(requests.get(img_url, stream=True).raw)
shape = getImageShape(img, model)
colors = getColors(getCounts(img))
rgb_count = getCounts(img)
serialTF = getCodeInfo(serial)
to_db = {'_id': tokenid, 'name': name, 'img_url': img_url, 'serial': serial,
'shape': shape, 'colors': colors, 'serialTF': serialTF, 'rgb_count': rgb_count}
gs.insert_one(to_db)
rarity = getRarity(gs, tokenid)
gs.update_one({'_id': tokenid}, {
'$set': {'rarity_values': rarity}}, upsert=True)
to_json = list(gs.find({'_id': tokenid}))[0]
return jsonify(to_json)
I have tried moving contract address around (both out of TokenInfo view function and into the functions file) to no avail. I have also tried changing the function inputs to receive the get request args instead of the int in the URL, which made no difference either.
If the code uses websockets it won't currently work in web apps on PythonAnywhere.
Hi I'm pretty new to python. I try to make a chatbot with rasa for personal use. Would like to add weather api now. I use weatherstack.com. If I use their example this works, but if I adjust it to my own liking I always end up with the same error.
condition = api_response['current']['weather_descriptions'] TypeError: list indices must be integers or slices, not str
This is the code I am using.
class Actionweatherapi(Action):
def name(self):
return "actions.weatherapi"
def run(self, dispatcher, tracker, domain):
import requests
location = tracker.get_slot('location')
if location == 'None':
location = 'fetch:ip'
api_result = requests.get('http://api.weatherstack.com/current?access_key=0000000&query={}'.format(location))
api_response = api_result.json()
country = api_response['request']['query']
condition = api_response['current']['weather_descriptions']
temperature_c = api_response['current']['temperature']
humidity = api_response['current']['humidity']
wind_mph = api_response['current']['wind_speed']
response = """It is currently {} in {} at the moment. The temperature is {} degrees, the humidity is {}% and the wind speed is {} mph.""".format(condition, country, temperature_c, humidity, wind_mph)
dispatcher.utter_message(response)
return [AllSlotsReset()]
I have also reviewed the printf-style String Formatting on the python website, but I cannot figure out how to get it working.
The json response is like this example
http://api.weatherstack.com/current?access_key=1c80e8b9fe4fcef4f8d6fd7514a8e9e9&query=New%20York
I am new to python and programming but I am learning. I am trying to send an order through python for options to TWS. I keep getting this error message
"Server Error: Server Response:
error, Traceback (most recent
call last):"
I tried to put an order for stock and it went through but not for options
def create_contract(a,b,c,d):
contract = Contract()
contract.symbol = '%a'
contract.secType = "OPT"
contract.exchange = "SMART"
contract.order_exchange = "SMART"
contract.currency = "USD"
contract.ContractMonth = b
contract.strike = c
contract.right = '%d'
contract.multiplier = "100"
return contract
def create_order(order_type, quantity, action):
order = Order()
order.m_orderType = order_type
order.m_totalQuantity = quantity
order.m_action = action
return order
if __name__ == "__main__":
tws_conn = Connection.create("127.0.0.1", port=7495)
tws_conn.connect()
tws_conn.register(error_handler, 'Error')
tws_conn.registerAll(reply_handler)
order_id = 1
goog_contract = create_contract(tic,hup.cell(2,3).value,hup.cell(2,4).value,hup.cell(2,13).value)
goog_order = create_order('MKT', 1, 'BUY')
tws_conn.placeOrder(order_id, goog_contract, goog_order)
I want to see the option orders goes through TWS. I also would love to see some proper example on how the placeorder parameter should have.
from ib_insync import *
util.startLoop()
ib=IB()
ib.connect("127.0.0.1", 7497, clientId=13)
contract=Option("SPY","20191016", 280,"P","SMART")
ib.qualifyContracts(contract)
order=MarketOrder("Buy",2)
trade=ib.placeOrder(contract,order)
trade
this code will allow. you to buy 2 puts on the "spy" at a 280 strike expiring October 19 2019
It looks like you're using IBPy or a third party wrapper of an IB API? You may want to consider instead using the native Python API from IB, or ib_insync.
If you can place an order for a stock but not an option, the problem is likely in the way the option contract is defined (assuming your paper account has the necessary permissions). There are examples of defining options in the native IB Python API at:
http://interactivebrokers.github.io/tws-api/basic_contracts.html#opt
To say which parameter is incorrect you would have to show the values of a,b,c,d.
You may want to also enable API logging in TWS as described at:
http://interactivebrokers.github.io/tws-api/support.html#tws_logs
for troubleshooting purposes.
I am fairly new to python and need help taking a json file and incorporating
it into the init in a class to be used through out, but I am getting the error below and don't understand why. I have a build a few classes before and this seems to look the same.
AttributeError: 'dict' object has no attribute 'zipcode'
I have a separate json file called config.json that I have changed some information in (i.e. location and api key), but other than that, this is what I am working with.
config.json:
{
"unit_system":"metric",
"location_information":{
"country_code":"US",
"country_name":"United States",
"city":"New York City",
"state":"New York",
"postal":10001
},
"api_keys":{
"weather_api_key":"97a484e1039b7a0779b59f2e57e597a3"
}
}
weather.py
class weather:
"""weather retrieving app"""
def __init__(self, data):
"""initialize attributes for weather app"""
self.unit_system = data['unit_system']
#unit system
self.country_code = data['location_information']['country_code']
self.zipcode = data['location_information']['postal']
#location information
self.api_key = data['api_keys']['weather_api_key']
#api key informaation
def get_update(self):
threading.Timer(5.0, w.get_update).start()
#runs get_update every 5 seconds
#get weather information
weather_url = 'http://api.openweathermap.org/data/2.5/weather?zip=' \
+ str(self.zipcode) + ',' \
+ self.country_code + '&appid=' \
+ self.api_key
weather_request = requests.get(weather_url)
weather_data = weather_request.json()
temp_k = float(weather_data['main']['temp'])
#determine unit system conversions
if self.unit_system == 'english':
temp = (temp_k - 273.15) * 1.8 + 32
elif self.unit_system == 'metric':
temp = temp_k - 273.15
print(temp)
#return(temp)
import threading
import requests
import json
with open('config.json') as config_file:
config = json.load(config_file)
w = weather(config)
w.get_update()
Remove the last line and put these lines at the bottom. The first line creates an instance of class weather named weather_obj. You can then call the get_update using weather_obj
weather_obj = weather(config)
weather_obj.get_update()
The scipt you have provided seems to be working.
a screenshot of my output(s)