I'm building a tool with web3 and python that needs to quickly and accurately get prices of tokens on Binance Smart Chain via PancakeSwap.
The tool gathers information about BSC tokens, price, liquidity etc so I can further analyse rugpulls.
In the following code it is supplied with a contract address and it needs to supply the current price per token in BNB. It however glitches alot and does not give me the correct price and I cannot figure out whats wrong. Code is below.
from web3 import Web3
web3 = Web3(Web3.WebsocketProvider('wss://speedy-nodes-nyc.moralis.io/b51e035eb24e1e81cc144788/bsc/mainnet/ws'))
tokenPriceABI = 'Token Price ABI'
def getTokenPrice(tokenAddress):
BNBTokenAddress = Web3.toChecksumAddress("0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c") # BNB
amountOut = None#
#tokenAddress = Web3.toChecksumAddress(tokenAddress)
tokenRouter = web3_sell.eth.contract(address=tokenAddress, abi=tokenPriceABI)
router = web3_sell.eth.contract(address=Web3.toChecksumAddress("0x10ed43c718714eb63d5aa57b78b54704e256024e"), abi=pancakeABI)
amountIn = web3_sell.toWei(1, 'ether')
amountOut = router.functions.getAmountsOut(amountIn, [tokenAddress, BNBTokenAddress]).call()
amountOut = web3_sell.fromWei(amountOut[1], 'ether')
return amountOut
tokenAddress = input("Enter token address: ")
tokenAddress = Web3.toChecksumAddress(tokenAddress)
priceInBnb = getTokenPrice(tokenAddress)
print(priceInBnb)
Is anyone able to help?
Thanks.
so what you are doing is you are trying to get the wrong value.
the getamountsout doesn't give you you the price. you need to call the getpair from the pancakeswap factory address with your two tokens as parameters.(0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73) docs for the getpair function
then you get a contract address back from which you can call the getreserves function (docs for this contract) from which you get 3 values (_reserve0, _reserve1, _blockTimestampLast) where you divide the first by the second or the second by the first depending on which way you want the price
Related
I have written a trading bot working on futures account for margin trading. The piece of code that I shared below worked fine for just one time. Then it started to give the following error:
APIError(code=-2021): Order would immediately trigger
The problem is when I copy and paste this piece of code(part related to open position and give take profit and stop loss orders) to a new file and run it, it works fine but gives an error in the bot. I couldn't find the cause of the problem.
if currentdiffer > 0:
buy_order = client.futures_create_order(symbol='SOLBUSD',
side='BUY',
type ='MARKET',
quantity = qty,
positionSide='LONG')
poisiton = "LONG"
stopprice = currentprice - (value*1.2)
takeprofit = currentprice + (value*1.2)
stopprice = round(stopprice,2)
takeprofit = round(takeprofit,2)
print("Take profit : ", takeprofit)
print("Stop price : ", stopprice)
tp_order = client.futures_create_order(symbol='SOLBUSD',
side='SELL',
positionSide='LONG',
type ='TAKE_PROFIT_MARKET',
timeInForce='GTE_GTC',
quantity = qty,
stopPrice=stopprice,
workingType='MARK_PRICE'
)
sl_order = client.futures_create_order(symbol='SOLBUSD',
side='SELL',
positionSide='LONG',
type ='STOP_MARKET',
timeInForce='GTE_GTC',
quantity = qty,
stopPrice=takeprofit,
workingType='MARK_PRICE'
)
Seems like you messed up with the parameter that you send
Check the API Docs. It's all there
For TRAILING_STOP_MARKET, if you got such error code.
{"code": -2021, "msg": "Order would immediately trigger."}
means that the parameters you send do not meet the following requirements:
BUY: activationPrice should be smaller than latest price.
SELL: activationPrice should be larger than latest price.
https://binance-docs.github.io/apidocs/futures/en/#new-order-trade
TLDR; I am running an Algorand PrivateNet in a sandbox. I would like to know how I can use the Python SDK for Algorand to return the address and balance of the accounts on this network.
Longer version;
Until now I have been using "./sandbox goal account list" to find the account addresses and account balances in Bash, this returns:
[offline]
I3CMDHG236HVBDMCKEM22DLY5L2OJ3CBRUDHG4PVVFGEZ4QQR3X3KNHRMU
I3CMDHG236HVBDMCKEM22DLY5L2OJ3CBRUDHG4PVVFGEZ4QQR3X3KNHRMU
8012889074131520 microAlgos
[offline]
3NSWKJTYMW3PSZZDIE6NCHMRTOZ24VY5G3OJNDSTYRVRXMZBZVPCGQHJJI
3NSWKJTYMW3PSZZDIE6NCHMRTOZ24VY5G3OJNDSTYRVRXMZBZVPCGQHJJI
1001611000000000 microAlgos
[online]
5KLSI3AHMBBDALXBEO2HEA3PBBCBAYT4PIHCD3B25557WGWUZGRTQETPHQ
5KLSI3AHMBBDALXBEO2HEA3PBBCBAYT4PIHCD3B25557WGWUZGRTQETPHQ
100000 microAlgos
I have tried to utilise the algod and v2client.indexer modules as outlined below but instead of the 3 accounts listed above 4 are being listed by my code (the original 3 +1). The code:
#imports
from algosdk import algod, v2client
# instatiate AlgodClient
def connect_to_network():
algod_address = "http://localhost:4001"
algod_token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
algod_client = algod.AlgodClient(algod_token, algod_address)
return algod_client
# instantiate IndexClient
def indexer():
indexer_token = ""
indexer_address = "http://localhost:8980"
indexer_client = v2client.indexer.IndexerClient(indexer_token, indexer_address)
return indexer_client
# returns all account details from indexer
def account_details():
raw_details = indexer().accounts() # <-- I think the error is here because this returns 4 addresses.
account_details = []
for details in raw_details["accounts"]:
account_details.append({"address":details["address"], "amount": details["amount"]})
return account_details
# returns the amount in each account
def account_amounts(account_address):
return connect_to_network().account_info(account_address)
# returns account address and amount for each account
for detail in account_details():
print(account_amounts(detail["address"])["address"])
print(account_amounts(detail["address"])["amount"])
This returns:
I3CMDHG236HVBDMCKEM22DLY5L2OJ3CBRUDHG4PVVFGEZ4QQR3X3KNHRMU
8013089091731545
NTMTJYBQHWUXEGVG3XRRX5CH6FCYJ3HKCSIOYW4DLAOF6V2WHSIIFMWMPY
1001636000000000
3NSWKJTYMW3PSZZDIE6NCHMRTOZ24VY5G3OJNDSTYRVRXMZBZVPCGQHJJI
1001636000000000
5KLSI3AHMBBDALXBEO2HEA3PBBCBAYT4PIHCD3B25557WGWUZGRTQETPHQ
100000
How can I replicate "./sandbox goal account list" with py-algorand-sdk?
(Bonus question) what is this extra mystery "account" that appears when I use the SDK compared to Bash?
The issue above arose because like with ./sandbox goal accounts listI was trying to return the accounts I had keys for locally in the KMD but my call to the indexer raw_details = indexer().accounts() was returning all accounts on the network.
To remedy this, instead of importing and using the v2client.indexer module import the wallet module from the algosdk library. These are the necessary imports:
from algosdk import algod, kmd, wallet
Then set up the connections to algod, kmd, and your wallet:
# instatiate AlgodClient
def connect_to_network():
algod_address = "http://localhost:4001"
algod_token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
algod_client = algod.AlgodClient(algod_token, algod_address)
return algod_client
# instantiate KMDClient <--- this is used as a parameter when instantiating the Wallet Class.
def key_management():
kmd_address = "http://localhost:4002"
kmd_token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
kmd_client = kmd.KMDClient(kmd_token, kmd_address)
return kmd_client
#get wallet details
def wallet_details():
wallet_name = 'unencrypted-default-wallet'
password = ""
kmd_client = key_management()
return wallet.Wallet(wallet_name, password, kmd_client)
You can now return the account addresses held locally in the KMD:
keys = wallet_details().list_keys()
Now that you have the addresses you can query use the algod client to return the amount of (Micro) Algo held at each of these addresses.
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 getting started with web.py. I have a requirement where I need to get the available token balance at a given ETH address(this address is not the contract owner), going through the docs I stumble upon the following functiion :
https://web3py.readthedocs.io/en/stable/contracts.html#web3.contract.ContractFunction.call
token_contract.functions.myBalance().call({'from': web3.eth.accounts[1]})
so on the above lines, I wrote this :
from web3 import HTTPProvider, Web3
import requests
w3 = Web3(HTTPProvider('https://ropsten.infura.io/RPw9nHRS7Ue47RaKVvHM'))
url_eth = "https://api.etherscan.io/api"
contract_address = '0x0CdCdA4E7FCDD461Ba82B61cBc4163E1022f22e4'
API_ENDPOINT = url_eth+"?module=contract&action=getabi&address="+str(contract_address)
r = requests.get(url = API_ENDPOINT)
response = r.json()
instance = w3.eth.contract(
address=Web3.toChecksumAddress(contract_address),
abi = response["result"]
)
send_address = "0xF35A192475527f80EfcfeE5040C8B5BBB596F69A"
balance = instance.functions.balance_of.call({'from':send_address})
#balnce = instance.functions.myBalance.call({'from':send_address})
print("----------------------",balance)
I get the following error :
"Are you sure you provided the correct contract abi?"
web3.exceptions.MismatchedABI: ("The function 'balance_of' was not foundin this contract's abi. ", 'Are you sure you provided the correct contract abi?')
**Update ** I got rid of the above exception, now I'm getting the following exception :
send_address = "0xF35A192475527f80EfcfeE5040C8B5BBB596F69A"
balance = instance.functions.balanceOf.call(send_address)
#Error :
call_transaction = dict(**transaction)
TypeError: type object argument after ** must be a mapping, not str
If I try this :
send_address = "0xF35A192475527f80EfcfeE5040C8B5BBB596F69A"
balance = instance.functions.balanceOf.call({'from':send_address})
#Error:
AttributeError: 'balanceOf' object has no attribute 'args'
In the last code sample try to modify the second line to look like this: balance = instance.functions.balanceOf().call({'from':send_address}). The parenthesis after balance of are the arguments you are passing to the solidity function.
you have to see if the contract has the function "balance_of". At the time of executing
balance = instance.functions.balanceOf.call(send_address)
You are executing the balance_of function of the contract, if the contract does not have that function it gives the error
This works for sure as of today:
send_address = "0xF35A192475527f80EfcfeE5040C8B5BBB596F69A"
balance = instance.functions.balanceOf(send_address).call()
The following link provides data in JSON regarding a BTC adress -> https://blockchain.info/address/1GA9RVZHuEE8zm4ooMTiqLicfnvymhzRVm?format=json.
The bitcoin adress can be viewed here --> https://blockchain.info/address/1GA9RVZHuEE8zm4ooMTiqLicfnvymhzRVm
As you can see in the first transaction on 2014-10-20 19:14:22, the TX had 10 inputs from 10 adresses. I want to retreive these adresses using the API, but been struggling to get this to work. The following code only retrieves the first adress instead of all 10, see code. I know it has to do with the JSON structure, but I cant figure it out.
import json
import urllib2
import sys
#Random BTC adress (user input)
btc_adress = ("1GA9RVZHuEE8zm4ooMTiqLicfnvymhzRVm")
#API call to blockchain
url = "https://blockchain.info/address/"+(btc_adress)+"?format=json"
json_obj = urllib2.urlopen(url)
data = json.load(json_obj)
#Put tx's into a list
txs_list = []
for txs in data["txs"]:
txs_list.append(txs)
#Cut the list down to 5 recent transactions
listcutter = len(txs_list)
if listcutter >= 5:
del txs_list[5:listcutter]
# Get number of inputs for tx
recent_tx_1 = txs_list[1]
total_inputs_tx_1 = len(recent_tx_1["inputs"])
The block below needs to put all 10 input adresses in the list 'Output_adress'. It only does so for the first one;
output_adress = []
output_adress.append(recent_tx_1["inputs"][0]["prev_out"]["addr"])
print output_adress
Your help is always appreciated, thanks in advance.
Because you only add one address to it. Change it to this:
output_adress = []
for i in xrange(len(recent_tx_1["inputs"])):
output_adress.append(recent_tx_1["inputs"][i]["prev_out"]["addr"])
print output_adress