IEX Works with secret key but not with test key - python

Hi I have a problem with this piece of code that needs to get stock prices based on a defined time period and a ticker code.
The program actually works when I use my IEX API KEY, but not when I use my TEST IEX API KEY, I get the following error message
Unable to read URL: https://cloud.iexapis.com/stable/stock/market/batch?symbols=AAPL&types=chart&range=1y&token=Tpk_157dbb6ac5914bb6b5e309b5eb1484f5
Response Text:
b'Test tokens may only be used in the sandbox environment. Please use https://sandbox.iexapis.com' error
'''
How to download stock data
'''
import pandas as pd
import pandas_datareader.data as web
import datetime as dt
from datetime import datetime
import os
os.environ["IEX_API_KEY"] = "Tpk_157dbb6ac5914bb6b5e309b5eb1484f5"
def get_stock_data():
tickers = ['AAPL'] #capitalize tickers
start = dt.datetime(2019,1,1) # can import 5 years max with iex
end = dt.datetime.today()
if not os.path.exists('stockdata'):
os.makedirs('stockdata')
for ticker in tickers:
print(ticker)
try :
df = web.DataReader(ticker, "iex", start, end)
print(df.head())
df.to_csv('stockdata/{}.to_csv'.format(ticker))
print(ticker, 'downloaded')
except Exception as e:
print(e, 'error')
get_stock_data()
I probably should have told the API that this is the iexcloud-sandbox that I need to access,as described in the Error Message, but the description link dosent say anything about it: https://intercom.help/iexcloud/en/articles/2915433-testing-with-the-iex-cloud-sandbox and I don't know how get it to work, can anybody help?

Set your IEX_API_VERSION environment variable to iexcloud-sandbox:
os.environ['IEX_API_VERSION'] = 'iexcloud-sandbox'
Reference: https://github.com/addisonlynch/iexfinance/blob/7cf902e275f3f84b2892b87ff072fa1808926c15/docs/source/sandbox.rst

The reason why python os.getenv("IEX_SANDBOX")=="enable" works. The following code was retrieved from pdr_DataReader/iex/daily.py/IEXDailyReader itself.
if os.getenv("IEX_SANDBOX") == "enable":
self.sandbox = True
else:
self.sandbox = False
self.api_key = api_key
super(IEXDailyReader, self).__init__(
symbols=symbols,
start=start,
end=end,
retry_count=retry_count,
pause=pause,
session=session,
chunksize=chunksize,
)
#property
def default_start_date(self):
today = datetime.date.today()
return today - datetime.timedelta(days=365 * 15)
#property
def url(self):
"""API URL"""
if self.sandbox is True:
return "https://sandbox.iexapis.com/stable/stock/market/batch"
else:
return "https://cloud.iexapis.com/stable/stock/market/batch"

I was having the same issue as you and this worked for me:
import os
os.environ['IEX_SANDBOX'] = 'enable'
During the DataReader call, there is a check for this environment variable, and if you have set it to 'enable', then it will choose the sandbox URL.

Related

while using openweather.org api using for temperature and weather it shows an keyerror

In my voice assistant project, I want to set a forecast. Hence I am using api key from openweather.org and my code is as below
import requests
from os import *
api_address = "https://api.openweathermap.org/data/2.5/weather?id=bfbe606c8d661478b8132b49eee8051a"
json_data = requests.get(api_address).json()
# json_data = json_data.json()
def temp():
temperature = round(json_data['main']['temp']-273.1)
return temperature
def des():
description = json_data["weather"][0]["description"]
return description
print(temp())
print(des())
But here problem is console shows an error about 'keyerror':
line 9, in temp
temperature = round(json_data['main']['temp']-273.1)
KeyError: 'main'
please suggest me any solution which can took out me from this problem.
creator of Open-Meteo here. You could use the Open-Meteo API which does not require an API key:
import requests
from os import *
api_address = "https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41&current_weather=true"
json_data = requests.get(api_address).json()
def temp():
temperature = json_data['current_weather']['temperature']
return temperature
def des():
description = json_data["current_weather"]["weathercode"]
return description
print(temp())
print(des())
Output:
12.4
2
Please note to put in your correct latitude and longitude to get the forecast for your location

AWS chalice local works but not chalice deploy

I am pretty new to coding and aws chalice. I tried writing a code that gets messages from trading-view and executes orders depending on the signals.
I tested the code locally and everything worked fine, but when I test the Rest API I get the following error:
{"message":"Missing Authentication Token"}
I set up my credentials via "aws configure" as explained here: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html
I also created a config.txt file in my aws folder and checked my settings via "aws configure get" and they were fine.
The index function in the beginning worked too, so there should be a problem within my code?
I changed some values and cut some functions and the strategy part out, but the code looks somewhat like this:
from chalice import Chalice
from datetime import datetime
from binance.client import Client
from binance.enums import *
import ccxt
exchange = ccxt.binance({
'apiKey': 'KEY',
'secret': 'SECRET',
'enableRateLimit': True,
'options': {
'defaultType': 'future',
},
})
def buy_order(quantity, symbol, order_type = ORDER_TYPE_MARKET,side=SIDE_BUY,recvWindow=5000):
try:
print("sending order")
order = client.futures_create_order(symbol = symbol, type = order_type, side = side, quantity = quantity,recvWindow=recvWindow)
print(order)
except Exception as e:
print("an exception occured - {}".format(e))
return False
return True
app = Chalice(app_name='tradingview-webhook-alert')
indicator1 = "x"
indicator2 = "y"
TRADE_SYMBOL = "Test123"
in_position = False
def diff_time(time1, time2):
fmt = '%Y-%m-%dT%H:%M:%SZ'
tstamp1 = datetime.strptime(time1, fmt)
tstamp2 = datetime.strptime(time2, fmt)
if tstamp1 > tstamp2:
td = tstamp1 - tstamp2
else:
td = tstamp2 - tstamp1
td_mins = int(round(td.total_seconds() / 60))
return td_mins
#app.route('/test123', methods=['POST'])
def test123():
global indicator1, indicator2
request = app.current_request
message = request.json_body
indicator = message["indicator"]
price = message["price"]
value = message["value"]
if indicator == "indicator1":
indicator1 = value
if indicator == "indicator2":
indicator2 = value
if in_position == False:
if (indicator1 >123) & (indicator2 < 321):
balance = exchange.fetch_free_balance()
usd = float(balance['USDT'])
TRADE_QUANTITY = (usd / price)*0.1
order_succeeded = buy_order(TRADE_QUANTITY, TRADE_SYMBOL)
if order_succeeded:
in_position = True
return {"test": "123"}
I tested it locally with Insomnia and tried the Rest API link there and in my browser, both with the same error message. Is my testing method wrong or is it the code? But even then, why isn't the Rest API link working, when I include the index function from the beginning again? If I try the index function from the beginning, I get the {"message": "Internal server error"} .
This is probably a very very basic question but I couldn't find an answer online.
Any help would be appreciated!
I am not pretty sure if that helps you because I don't really understand your question but:
You are using a POST-request which will not be executed by opening a URL.
Try something like #app.route('/test123', methods=['POST', 'GET']) so that if you just open the URL, it will execute a GET-request
Some more information:
https://www.w3schools.com/tags/ref_httpmethods.asp

exchangelib bug: Message object has no attribute item_id

Although I've been happily running this script for best part of a year, i recently upgraded to Catalina OSX and reinstalled Exchangelib. Now I get an error with item_id:
'Message' object has no attribute 'item_id'
Here's my code, I would love to know what I'm doing wrong please 🙏 TIA ps-forgive any convoluted coding...
from exchangelib import DELEGATE, Account, Credentials, Message, \
EWSDateTime, EWSTimeZone, Configuration
from exchangelib.util import PrettyXmlHandler
import logging
logging.basicConfig(level=logging.DEBUG, handlers=[PrettyXmlHandler()])
from datetime import datetime, timedelta
import monthdelta as md
import sqlite3
import pandas as pd
import pm_ews_module as pem
__DBPATH__ = "/Users/patrickstacey/CODE/JUMPY_CODE/dev/data/test_data_tbase11_002"
__CONFIGFILE__ = '/Users/patrickstacey/CODE/JUMPY_CODE/dev/config/jumpyConfig.csv'
__OUTLOOK_EMAIL__ = 'bspks#lunet.lboro.ac.uk'
_PRIMARY_SMTP_ADDRESS_ = 'bspks#lunet.lboro.ac.uk'
__OUTLOOK_PASSWORD__ = '****'
def connect_to_EWS(__OUTLOOK_EMAIL__, __OUTLOOK_PASSWORD__, _PRIMARY_SMTP_ADDRESS_):
creds = Credentials(__OUTLOOK_EMAIL__,__OUTLOOK_PASSWORD__)
config = Configuration(server='outlook.office365.com/EWS/Exchange.asmx', \
credentials=creds)
return Account(
primary_smtp_address=_PRIMARY_SMTP_ADDRESS_,
autodiscover=False,
config = config,
access_type=DELEGATE
)
last_analysis = pem.determine_start_date_required(__OUTLOOK_EMAIL__)
if last_analysis == "no records":
df = pd.read_csv(__CONFIGFILE__)
retrodays = df['detail'].where(df['item'] == "demo_user_days_retro").dropna().values
retrodays = int(retrodays)
last_analysis = None
last_analysis = datetime.today() - timedelta(days=retrodays)
(year,month,day,hour,mins,secs) = pem.unpackDateElements(str(last_analysis))
tz = EWSTimeZone.timezone('Europe/London')
last_analysis = tz.localize(EWSDateTime(year, month, day, hour, mins, secs))
account = connect_to_EWS(__OUTLOOK_EMAIL__, __OUTLOOK_PASSWORD__, __OUTLOOK_EMAIL__)
for item in account.inbox.filter(datetime_received__gt=last_analysis):
if type(item) == Message:
try:
db = sqlite3.connect(__DBPATH__)
cursor = db.cursor()
cursor.execute("INSERT INTO escores_log(email, datetime, subject, body, emailtype, pos_threshold, item_id, status, sender) VALUES(?,?,?,?,?,?,?,?,?)", (__OUTLOOK_EMAIL__, str(item.datetime_received), pem.deEmojify(item.subject), item.text_body, "received", 0.5, item.item_id, 0, item.sender.email_address))
print("Inserted an email from ",item.sender.email_address," about ",item.subject," on ",str(item.datetime_received))
db.commit()
db.close()
except Exception as e:
print ("Exception found: "+str(e))
pass
item_id was renamed to id in version 1.12.0, and finally deprecated in 2.0.0. See notes in the CHANGELOG: https://github.com/ecederstrand/exchangelib/blob/master/CHANGELOG.md#200
looks as though item_id is now called id. I took an educated guess. so the script works again. look fwd to hearing any other views on this. with thanks.

How can I limit python script to 1 API trade per day?

I'm putting together a python script to make trades on poloniex with the API, and so far I've got it to make trades when certain conditions are met, but I still need it to NOT place anymore trades for the rest of that day (I have the entire script looping every 60 seconds).
So far I have this script:
import requests
import urllib.request
import urllib.parse
import http.client
import hashlib
import hmac
import time
import json
from urllib.request import urlopen
The_Currency_Pair = input('Which Currency Pair?\nPAIRS TO CHOOSE FROM:\nUSDT_BTC\nUSDT_XRP\nUSDT_ETH\nUSDT_BCH\nUSDT_STR\nUSDT_LTC\nUSDT_ETC\nUSDT_XMR\n')
api = 'https://poloniex.com/tradingApi'
key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
secret = 'XXXXXXXXXXXXXXXXXXXXXXXXX'
def main():
poloniexPrices = urlopen('https://poloniex.com/public?command=returnTicker').read()
poloniexjson = json.loads(poloniexPrices)
poloniexlastP = poloniexjson[The_Currency_Pair]['last']
poloniexOCHL = urlopen('https://poloniex.com/public?command=returnChartData&currencyPair=USDT_BCH&start=1538352000&period=86400').read()
poloniexOCHLjson = json.loads(poloniexOCHL)
poloniexlasthigh = poloniexOCHLjson[-2]['high']
print ('Last Price')
print (poloniexlastP)
print ('----------------------------------------')
print ('Last Day High')
print (poloniexlasthigh)
print ('----------------------------------------')
data = {
'command': 'returnBalances',
'nonce' : int(time.time() * 1000)
}
data = urllib.parse.urlencode(data).encode()
signature = hmac.new(secret.encode(), data, hashlib.sha512)
headers = {
'Key' : key,
'Sign': signature.hexdigest()
}
request = urllib.request.Request(
url=api, data=data, headers=headers, method='POST'
)
text = urllib.request.urlopen(request).read().decode()
print ('MY ACCOUNT BALANCE')
try:
print(json.loads(text)['USDT'])
except:
print(text)
print ('-----------------------------------------')
if float(poloniexlastP) > 0:
print ('PLACING TRADE')
print ('-----------------------------------------------')
parms = {"command":"buy",
"currencyPair":The_Currency_Pair,
"rate":100,
"immediateOrCancel":1,
"amount":0.01,
"nonce":int(time.time() * 1000)}
parms = urllib.parse.urlencode(parms).encode()
signature = hmac.new(secret.encode(), parms, hashlib.sha512)
headers = {'Key' : key,
'Sign': signature.hexdigest()}
request = urllib.request.Request(
url=api, data=parms, headers=headers, method='POST')
text = urllib.request.urlopen(request).read().decode()
ordernumber = (json.loads(text)['orderNumber'])
print ('Order Number:')
print (ordernumber)
while True:
main()
time.sleep(60)
Anyway, after a trade has been placed, I need it to make sure that after the 60 second sleep, it doesn't make a second trade unless it is a new day/the day after the trade was made. (Could I use poloniex server time for this?)
So, if it has got as far as print (ordernumber) that means it has placed a trade. But how do I mark it as placed trade for the day or something and use it in the if float(poloniexlastP) > 0: for the next loop to make sure it doesn't place another one?
Maybe you can use Python to get the date, and create a global variable, and after the print statement, you can set the variable to the current date, and the coffee will check if it has already sent, that way it doesn't execute more than once in a day.
import datetime
# This Gets The Day Of The Month
todaysDateNumber = int(datetime.datetime.now().strftime("%d"))
dateNumberTradeSent = 0
if todaysDateNumber == dateNumberTradeSent:
print("The API has already been used once today, try again tomorrow!")
return
else:
# Call Your Trade Sending Code Here
# After The Print Statement That Shows That The Trade Was Sent:
global dateNumberTradeSent
dateNumberTradeSent = int(datetime.datetime.now().strftime("%d"))

AWS Lambda - How do I convert my code to work in AWS?

I'm struggling to get a Lambda function working. I have a python script to access twitter API, pull information, and export that information into an excel sheet. I'm trying to transfer python script over to AWS/Lambda, and I'm having a lot of trouble.
What I've done so far: Created AWS account, setup S3 to have a bucket, and poked around trying to get things to work.
I think the main area I'm struggling is how to go from a python script that I'm executing via local CLI and transforming that code into lambda-capable code. I'm not sure I understand how the lambda_handler function works, what the event or context arguments actually mean (despite watching a half dozen different tutorial videos), or how to integrate my existing functions into Lambda in the context of the lambda_handler, and I'm just very confused and hoping someone might be able to help me get some clarity!
Code that I'm using to pull twitter data (just a sample):
import time
import datetime
import keys
import pandas as pd
from twython import Twython, TwythonError
import pymysql
def lambda_handler(event, context):
def oauth_authenticate():
twitter_oauth = Twython(keys.APP_KEY, keys.APP_SECRET, oauth_version=2)
ACCESS_TOKEN = twitter_oauth.obtain_access_token()
twitter = Twython(keys.APP_KEY, access_token = ACCESS_TOKEN)
return twitter
def get_username():
"""
Prompts for the screen name of targetted account
"""
username = input("Enter the Twitter screenname you'd like information on. Do not include '#':")
return username
def get_user_followers(username):
"""
Returns data on all accounts following the targetted user.
WARNING: The number of followers can be huge, and the data isn't very valuable
"""
#username = get_username()
#import pdb; pdb.set_trace()
twitter = oauth_authenticate()
datestamp = str(datetime.datetime.now().strftime("%Y-%m-%d"))
target = twitter.lookup_user(screen_name = username)
for y in target:
target_id = y['id_str']
next_cursor = -1
index = 0
followersdata = {}
while next_cursor:
try:
get_followers = twitter.get_followers_list(screen_name = username,
count = 200,
cursor = next_cursor)
for x in get_followers['users']:
followersdata[index] = {}
followersdata[index]['screen_name'] = x['screen_name']
followersdata[index]['id_str'] = x['id_str']
followersdata[index]['name'] = x['name']
followersdata[index]['description'] = x['description']
followersdata[index]['date_checked'] = datestamp
followersdata[index]['targeted_account_id'] = target_id
index = index + 1
next_cursor = get_followers["next_cursor"]
except TwythonError as e:
print(e)
remainder = (float(twitter.get_lastfunction_header(header = 'x-rate-limit-reset')) \
- time.time())+1
print("Rate limit exceeded. Waiting for:", remainder/60, "minutes")
print("Current Time is:", time.strftime("%I:%M:%S"))
del twitter
time.sleep(remainder)
twitter = oauth_authenticate()
continue
followersDF = pd.DataFrame.from_dict(followersdata, orient = "index")
followersDF.to_excel("%s-%s-follower list.xlsx" % (username, datestamp),
index = False, encoding = 'utf-8')

Categories