Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - litepresence

Pages: [1] 2
1
General Discussion / API Node Latency Map
« on: December 07, 2018, 10:30:21 pm »
for data you go here:

https://api.jsonbin.io/b/5c06e4f71deea01014bd4261/latest#Bitshares_Latency

This jsonbin api is at a stationary location.

I update the latency info hourly via python script; I'm on east coast US.

at the link you will find json dictionary with keys:

['GEO', 'COUNT', 'PING', 'URLS', 'LIVE', 'SOURCE_CODE', 'MAP_URL', 'MISSION', 'UTC', 'UNIX', 'OWNER', 'LOCATION', 'UNIVERSE']

UNIVERSE is all known bitshares public api nodes mentioned in various github projects; I suspect I have the largest known list of bitshares public api domains

URLS are github urls where node lists can be found; this tool does not contain a list of nodes.  Instead it goes to many different repos on github (such as bitshares, cryptobridge, rudex) etc.  where people have configuration files with lists of nodes; if they update their repo with new nodes, the script finds them with web scraping methods

LIVE is a list of tested nodes that respond within 10 seconds and have a head block number that is not stale. 

PING is list of tuples of ping time for each LIVE node

GEO is geo location data (country, city, longitude, latitude) for each LIVE node as provided by ip-api.com or ipinfo.io

COUNT is number of live nodes vs number of nodes in universe

SOURCE_CODE is my github were you can get this tool and run it yourself to produce your own web hosted latency map in distributed fashion.  The latency script will also give you information as to why each down node failed to connect.  A full report looks like this:

https://pastebin.com/JL4DZzwY

You can also pick up copy of metaNODE and ExtinctionEvent while you're there :D

UNIX and UTC are time stamp when this jsonbin was last updated

MAP_URL is a link to a visual image of the data on the jsonbin;
the map url will change every hour!


it will be something like:
https://vgy.me/dgCE1C.png


and look like one frame of this gif





source code is here, WTFPL:

https://github.com/litepresence/extinction-event/blob/master/EV/bitshares-latency.py

todo list... upload 24hr animations instead of still images


thanks to free and easy to use api services that make this project is possible:

ip-api.com
jsonbin.io
vgy.me



2
General Discussion / [ANN] metaNODE = Bitshares_Trustless_Client()
« on: June 06, 2018, 01:52:45 pm »
metaNODE = Bitshares_Trustless_Client()

There were two ways to get data from Bitshares blockchain:

- a private node that uses lots of RAM, prefers its own machine, and is technical to tend
- a public node that is difficult to stay connected to and may provide rogue data

I've created a 3rd path; connect to several random nodes in the public network... ask them each for latest market data; then move on to other nodes in the network continually. Finally, perform statistical analysis on the combined feeds and maintain a streaming curated output file; the metaNODE.

python script and whitepaper, including usage:

https://github.com/litepresence/extinction-event/tree/master/metaNODE

Code: [Select]
LICENSE:

'litepresence 2018'

def WTFPL_v0_March_1765():
    if any([stamps, licenses, taxation, regulation, fiat, etat]):
        try:
            print('no thank you')
        except:
            return [tar, feathers]

Mission:

1/10 the RAM usage of a personal node
99.9999 six sigma uptime
99.9999 six sigma accurate data feed
less than 5000ms latency


metaNODE is a streaming text file that contains statistically curated dex data from all public nodes for a single market on a single account.  metaNODE currently curates the following feeds:

- last
- market history
- open orders
- orderbook
- market-account balance


Run time has been demonstrated in excess of 2 weeks. 
metaNODE.txt is updated about once per second with live data.

metaNODE
is entirely independent of pybitshares.
Public database calls are made with websocket-client.


This project has received funding through the DEXbot worker.  Additional funding has been earmarked for incorporation of metaNODE into future release of the DEXbot platform.

metaNODE10 has already been incorporated into the Extinction Event dex algo trading framework EV.py; learn more at

www.litepresence.com





3
General Discussion / Bitshares Database Pocket Reference - Python
« on: April 27, 2018, 08:43:56 pm »
Code: [Select]
#Python3

' Bitshares Database Api Websocket Calls Pocket Reference'

# https://github.com/bitshares/bitshares-core/blob/master/libraries/app/database_api.cpp#L77

'litepresence 2018'

import websocket  #pip install websocket-client
websocket.enableTrace(False)

# EXAMPLE DATABASE REQUEST PARAMETERS
node = 'wss://api.bts.mobi/wss'#'wss://bts-seoul.clockwork.gr' # websocket address
asset = 'BTS' # symbol
currency = 'OPEN.BTC' #symbol
start = '2017-01-01T11:22:33' # iso date
stop = '2018-01-01T11:22:33' # iso date
account_name = 'litepresence1' # string
account_names = '["xeroc", "litepresence1"]' # list of string names
account_id = '1.2.743179' # a.b.c vector
block_num = 26444444 # int block number
block_nums = [26444444, 26444445, 26444446] # list of block numbers
trx_in_block = 4 # int index of item
transaction_id = '1.7.66209049'
transaction_id_type = 'cancel'
skip_order_book = 'false' # bool - non pythonic 'true' or 'false'
limit = 5 # int depth of data called
object_id_type = '' # a.b.c vector
object_ids = []
asset_id = '1.3.0'
asset_id2 = '1.3.861'
subscribe = 'false' # bool - non pythonic 'true' or 'false'
public_key = "BTS7d4MpYzecprWMfso8f6o1Ln8fQyxuQGD5LM83PRTfQBkodk4Ck"
witness_id = '1.6.65'
trx = '{"expiration":"2018-04-27T14:16:35","extensions":[],"operation_results":[[1,"1.7.66407704"]],"operations":[[1,{"amount_to_sell":{"amount":71055254,"asset_id":"1.3.0"},"expiration":"2018-05-04T14:16:04","extensions":[],"fee":{"amount":578,"asset_id":"1.3.0"},"fill_or_kill":false,"min_to_receive":{"amount":1922091,"asset_id":"1.3.121"},"seller":"1.2.879926"}]],"ref_block_num":8413,"ref_block_prefix":4199813419}'

# '{"id":1,"method":"call","params":["database","get_ticker",["OPEN.BTC","BTS"]]}'
Z = '{"id":1,"method":"call","params":["database",'

'Objects'
get_objects                     = Z + ''

'Subscriptions'
set_subscribe_callback          = Z + ''
set_pending_transaction_callback = Z + ''
set_block_applied_callback      = Z + ''
cancel_all_subscriptions        = Z + ''

'Blocks and transactions'
get_block_header                = Z + '"get_block_header",["%s"]]}' % block_num
get_block_header_batch          = Z + '"get_block_header_batch",["%s"]]}' % (block_nums)
get_block                       = Z + '"get_block",["%s"]]}' % block_num
get_transaction                 = Z + '"get_transaction",["%s", "%s"]]}' % (block_num, trx_in_block)
get_recent_transaction_by_id    = Z + ''

'Globals' # DONE
get_chain_properties            = Z + '"get_chain_properties",[]]}'
get_global_properties           = Z + '"get_global_properties",[]]}'
get_config                      = Z + '"get_config",[]]}'
get_chain_id                    = Z + '"get_chain_id",[]]}'
get_dynamic_global_properties   = Z + '"dynamic_global_properties",[]]}'

'Keys'
get_key_references              = Z + '"get_key_references",[["%s",]]]}' % public_key
is_public_key_registered        = Z + '"is_public_key_registered",["%s"]]}' % public_key

'Accounts'
get_accounts                    = Z + '"get_accounts",[["%s",]]]}' % account_id
get_full_accounts               = Z + '"get_full_accounts",[["%s",],%s]]}' % (account_name, subscribe)
get_account_by_name             = Z + '"get_account_by_name",["%s"]]}' % account_name
get_account_references          = Z + '"get_account_references",["%s",]]}' % account_id
lookup_account_names            = Z + '"lookup_account_names",[%s]]}' % account_names
lookup_accounts                 = Z + '"lookup_accounts",["%s", "%s"]]}' % (account_name, limit)
get_account_count               = Z + '"get_account_count",[]]}'

'Balances'
get_account_balances            = Z + '"get_account_balances",["%s", [] ]]}' % (account_id)
get_named_account_balances      = Z + '"get_named_account_balances",["%s", [] ]]}' % (account_name)
get_balance_objects             = Z + ''
get_vested_balances             = Z + ''
get_vesting_balances            = Z + '"get_vesting_balances",["%s"]]}' % account_id

'Assets'
get_assets                      = Z + '"get_assets",[["%s",]]]}' % asset_id
list_assets                     = Z + '"list_assets",["%s","%s"]]}' % (asset, limit)
lookup_asset_symbols            = Z + '"lookup_asset_symbols",[["%s",]]]}' % asset

'Markets / feeds'
get_order_book                  = Z + '"get_order_book",["%s","%s","%s"]]}' % (currency, asset, limit)
get_limit_orders                = Z + '"get_limit_orders",["%s","%s","%s"]]}' % (asset_id, asset_id2, limit)
get_call_orders                 = Z + '"get_call_orders",["%s","%s"]]}' % (asset_id, limit)
get_settle_orders               = Z + '"get_settle_orders",["%s","%s"]]}' % (asset_id, limit)
get_margin_positions            = Z + '"get_margin_positions",["%s"]]}' % account_id
get_collateral_bids             = Z + ''
subscribe_to_market             = Z + ''
unsubscribe_from_market         = Z + ''
get_ticker                      = Z + '"get_ticker",["%s","%s","%s"]]}' % (currency, asset, skip_order_book)
get_24_volume                   = Z + '"get_24_volume",["%s","%s"]]}' % (currency, asset)
get_top_markets                 = Z + '"get_top_markets",["%s"]]}' % limit
get_trade_history               = Z + '"get_trade_history",["%s","%s","%s","%s","%s"]]}' % (currency, asset, start, stop, limit)
get_trade_history_by_sequence   = Z + ''

'Witnesses'
get_witnesses                   = Z + ''
get_witness_by_account          = Z + '"get_witness_by_account",["%s"]]}' % witness_id
lookup_witness_accounts         = Z + '"lookup_witness_accounts",["%s","%s"]]}' % (witness_id, limit)
get_witness_count               = Z + '"get_witness_count",[]]}'

'Committee members'
get_committee_members           = Z + ''
get_committee_member_by_account = Z + ''
lookup_committee_member_accounts = Z + ''
get_committee_count             = Z + '"get_committee_count",[]]}'

'Workers'
get_all_workers                 = Z + ''
get_workers_by_account          = Z + ''
get_worker_count                = Z + '"get_worker_count",[]]}'

'Votes'
lookup_vote_ids = Z + ''

'Authority / validation'
get_transaction_hex             = Z + '"get_transaction_hex",[%s]]}' % trx
get_required_signatures         = Z + ''
get_potential_signatures        = Z + '"get_potential_signatures",[%s]]}' % trx
get_potential_address_signatures  = Z + '"get_potential_address_signatures",[%s]]}' % trx
verify_authority                = Z + '"verify_authority",[%s]]}' % trx
verify_account_authority        = Z + ''
validate_transaction            = Z + '"validate_transaction",[%s]]}' % trx
get_required_fees               = Z + ''

'Proposed transactions'
get_proposed_transactions = Z + '"get_proposed_transactions",["%s"]]}' % account_id

'Blinded balances'
get_blinded_balances = Z + ''

'Withdrawals'
get_withdraw_permissions_by_giver = Z + ''
get_withdraw_permissions_by_recipient = Z + ''


all_calls = [get_objects,set_subscribe_callback,set_pending_transaction_callback,set_block_applied_callback,cancel_all_subscriptions,get_block_header,get_block_header_batch,get_block,get_transaction,get_recent_transaction_by_id,get_chain_properties,get_global_properties,get_config,get_chain_id,get_dynamic_global_properties,get_key_references,is_public_key_registered,get_accounts,get_full_accounts,get_account_by_name,get_account_references,lookup_account_names,lookup_accounts,get_account_count,get_account_balances,get_named_account_balances,get_balance_objects,get_vested_balances,get_vesting_balances,get_assets,list_assets,lookup_asset_symbols,get_order_book,get_limit_orders,get_call_orders,get_settle_orders,get_margin_positions,get_collateral_bids,subscribe_to_market,unsubscribe_from_market,get_ticker,get_24_volume,get_top_markets,get_trade_history,get_trade_history_by_sequence,get_witnesses,get_witness_by_account,lookup_witness_accounts,get_witness_count,get_committee_members,get_committee_member_by_account,lookup_committee_member_accounts,get_committee_count,get_all_workers,get_workers_by_account,get_worker_count,lookup_vote_ids,get_transaction_hex,get_required_signatures,get_potential_signatures,get_potential_address_signatures,verify_authority,verify_account_authority,validate_transaction,get_required_fees,get_proposed_transactions,get_blinded_balances,get_withdraw_permissions_by_giver,get_withdraw_permissions_by_recipient,]


object_calls = []

subscription_calls = []

block_calls =      [get_block,
                    get_block_header,
                    get_block_header_batch,
                    get_transaction]

global_calls =     [get_chain_properties,
                    get_global_properties,
                    get_config,
                    get_chain_id,
                    get_dynamic_global_properties]

key_calls =        [get_key_references,
                    is_public_key_registered]

account_calls =    [get_accounts,
                    get_full_accounts,
                    get_account_by_name,
                    get_account_references,
                    lookup_account_names,
                    lookup_accounts,
                    get_account_count]

asset_calls =      [get_assets,
                    list_assets,
                    lookup_asset_symbols]

balance_calls =    [get_account_balances,
                    get_named_account_balances,
                    get_vesting_balances]

market_calls =     [get_order_book,
                    get_ticker,
                    get_trade_history,
                    get_limit_orders,
                    get_call_orders,
                    get_settle_orders,
                    get_margin_positions,
                    get_24_volume,
                    get_top_markets, ]

witness_calls =    [get_witness_by_account,
                    lookup_witness_accounts,
                    get_witness_count]

committe_calls =   [get_committee_count]

worker_calls =     [get_worker_count]

vote_calls = []

authority_calls =  [get_transaction_hex,
                    get_potential_signatures,
                    get_potential_address_signatures,
                    verify_authority,
                    validate_transaction]

proposed_calls = []
blindied_calls = []
withdrawal_calls = []


for call in asset_calls:

    try:
        ws = websocket.create_connection(node)
        print('')
        print((call.split(',"params":')[1]).rstrip('}'))
        print('-----------------------------------------------------------')
        ws.send(call)
        ret = ws.recv()
        print (ret)
        ws.close()
    except Exception as e:
        print (e.args)
        pass

# you can also make https requests in this manner
'''
import requests
data = '{"id":1,"method":"call","params":["database","get_ticker",["CNY","USD"]]}'
response = requests.post('https://api.bts.mobi/wss;echo', data=data)
'''


also here:

https://github.com/litepresence/extinction-event
https://github.com/litepresence/extinction-event/blob/master/tools/bitshares-database-reference.py

4
get named balances returns an asset id without its human readable name....
and an amount - without the location of its decimal point!

this is kind of thing makes neckbeard itchy

Code: [Select]
["database","get_named_account_balances",["abc123", [] ]]
-----------------------------------------------------------
[{'asset_id': '1.3.0', 'amount': 12019967}, {'asset_id': '1.3.1382', 'amount': 100}, {'asset_id': '1.3.1578', 'amount': 100000000}, {'asset_id': '1.3.2419', 'amount': 500000}, {'asset_id': '1.3.2841', 'amount': 12000}, {'asset_id': '1.3.2931', 'amount': 10000}, {'asset_id': '1.3.3248', 'amount': 2580000}, {'asset_id': '1.3.3261', 'amount': 1000}, {'asset_id': '1.3.3279', 'amount': 10000}, {'asset_id': '1.3.3389', 'amount': 1000000000}, {'asset_id': '1.3.3431', 'amount': 1000}, {'asset_id': '1.3.3530', 'amount': 100000000}, {'asset_id': '1.3.3540', 'amount': 100000000}, {'asset_id': '1.3.3830', 'amount': '25000000000'}]

we can fix this... so get asset details

which is another api call and gives us "precision"; location of decimal, and the asset "symbol"; ie OPEN.BTC or BTS


but then we have to merge those dictionaries and they do not contain a common key; one has "asset_id" the other "id"

grrr

every call for what the asset is called and where its decimal point goes also contains bit of spam for every shitcoin donated to your account, on every bot tick, which brings in a huge page of asset banner ads like this silliness:


Code: [Select]
'{"main":"WARNING, DANGER, RED-ALERT, PANIC! PANIC! PANIC!\\n\\nYOU HAVE BEEN INFECTED,\\n\\nZOMBIES HAVE BEEN RELEASED! \\n\\nZombies are going to appear from nowhere & infest your portfolio,\\nSome zombies will come from your friends and family,\\nAND YES there are even some sickos out there that will want to buy Zombies too :s\\n\\n\\nThese VILE undead human corpses have risen, The Mission, BURN Zombies :)\\nHelp FILL THE POOL, Zombies are BURNED when there sent to the pool.\\n\\n\\nDisclaimer: NO REAL ZOMBIES WILL BE HURT IN THE CREATION OF THIS TOKEN ;)","short_name":"Zombies",

be thankful you're not on data plan!

nonetheless, hocus pocus account balances:

Code: [Select]
>>>
balances
{'TURION': 0.1, 'FREECOIN': 10000.0, 'SOLOMON': 0.1, 'BIRMINGHAMGOLD': 100.0, 'ZOMBIES': 12.0, 'DECENTRALIZED': 10.0, 'ANONYMOUS': 1.0, 'BTS': 120.19967, 'BTSJON': 1000.0, 'BADCOIN': 10000.0, 'HERTZ': 0.01, 'URTHONA': 50.0, 'SEED': 258.0, 'UNIVERSAL': 25000.0}


Code: [Select]
'litepresence 2018'

import websocket  #pip install websocket-client
websocket.enableTrace(False)
from ast import literal_eval as literal

def database_call(node, call):

    while 1:
        try:
            call = call.replace("'",'"') # never use single quotes
            ws = websocket.create_connection(node)
            print('')
            print((call.split(',"params":')[1]).rstrip('}'))
            print('-----------------------------------------------------------')
            ws.send(call)
            # 'result' key of literally evaluated
            # string representation of dictionary from websocket
            ret = literal(ws.recv())['result']
            print (ret)
            ws.close()
            return ret
        except Exception as e:
            print (e.args)
            pass

def account_balances(node, account_name):

    Z = '{"id":1,"method":"call","params":["database",'
    # make call for raw account balances as returned by api
    get_named_account_balances = Z + '"get_named_account_balances",["%s", [] ]]}' % (account_name)
    raw_balances = database_call(node, get_named_account_balances)
    # make list of asset_id's in raw account balances
    asset_ids = []
    for i in range(len(raw_balances)):
        asset_ids.append(raw_balances[i]['asset_id'])
    # make a second api request for additional data about each asset
    get_assets = Z + '"get_assets",[%s]]}' % asset_ids
    raw_assets = database_call(node, get_assets)
    # create a common key "asset_id" for both list of dicts
    # also extract the symbol and precision
    id_sym_prec = []
    for i in range(len(raw_assets)):
        id_sym_prec.append({'asset_id':raw_assets[i]['id'],
                            'symbol':raw_assets[i]['symbol'],
                            'precision':raw_assets[i]['precision'], })
    # merge the two list of dicts with common key "asset_id"
    data = {}
    lists = [raw_balances, id_sym_prec]
    for each_list in lists:
       for each_dict in each_list:
           data.setdefault(each_dict['asset_id'], {}).update(each_dict)
    # convert back to list
    data = list(data.values())
    # create a new dictionary containing only the symbol and quantity
    ret = {}
    for i in range(len(data)):
        qty = float(data[i]['amount'])/10**float(data[i]['precision'])
        ret[data[i]['symbol']] = qty
    return raw_balances, ret

#node = 'wss://bts-seoul.clockwork.gr' # websocket address
node = 'wss://api.bts.mobi/wss'
account_name = 'abc123' # string
raw_balances, balances = account_balances(node, account_name)


print('')
print('balances')
print(balances)

I'll also host this on my github

https://github.com/litepresence/extinction-event
https://github.com/litepresence/extinction-event/blob/master/tools/bitshares-account_balances.py

5
General Discussion / [ANN] microDEX - low latency minimalist UI
« on: March 27, 2018, 12:14:18 am »

What if the UI maintained DEX connection for months at a time?
What if the orderbook was updated several times per second?
What if the data feed was not dependent on a single whitelisted node?
What if historical CEX data and latest DEX data were on the same chart?

What if you could read and trust all the code that makes it happen
over a single cup of coffee?



[ANN] microDEX

Code: [Select]
                                     ______   ________  ____  ____ 
                                    (_   _ `.(_   __  |(_  _)(_  _)
     __  __  ____  ___  ____   ___    | | `. \ | |_ \_|  \ \__/ /   
    (  \/  )(_  _)/ __)(  _ \ / _ \   | |  | | |  _) _    ) __ (   
     )    (  _||_( (__  )   /( (_) ) _| |_.' /_| |__/ | _/ /  \ \_ 
    (_/\/\_)(____)\___)(_)\_) \___/ (______.'(________|(____)(____)
   =================================================================
           microDEX v0.00000009 - low latency minimalist UI
   =================================================================


BUY/SELL/CANCEL
LIVE LOW LATENCY MULTI NODE BOOKS
NEVER OUT OF SYNC
ALWAYS BLOCKCHAIN CONNECTED


minimal dependencies:

python3
pybitshares
tkinter
matplotlib


Code:

https://github.com/litepresence/extinction-event/blob/master/microDEX/microDEX.py

Installation:

https://github.com/litepresence/extinction-event/blob/master/Installation




more coming soon!


'till then, need botscript?  check me out at


litepresence.com



ETA:



how's this for soon?  v0.00000009 is live:





The Fastest DEX Orderbooks in the Business!



All that and just 1300 fluffy lines of script :D



6
General Discussion / 5 Node Verified Price Feed - Python
« on: March 18, 2018, 01:39:28 am »
developing here:

https://github.com/litepresence/extinction-event/tree/master/EV


working under the assumption that any node can provide rogue price feeds at any given time,
I sort all nodes by latency every two minutes
then check last price on 5 low latency nodes to verify authenticity of the data every 30 seconds


5 NODE VERIFIED LAST PRICE

nodes.py and last.py should be run in seperate terminals

nodes.py creates file nodes.txt
last.py creates file last.txt and appends to file blacklist.txt

nodes.txt is the top 10 latency sorted nodes of about 50 known nodes; updated approx every 2 minutes

last.py uses nodes.txt to get price from 5 nodes, then makes a list "prices", updated approx ever 30 seconds

then process that list of prices from 5 different nodes pseudocode:


if the spread of the prices is too wide:

    append to file blacklist.txt the list of prices and the list of nodes used to gather them


if all prices are same:
   
    last = latest price

elif latest price less than 2% different than mean(prices):
   
    last = latest price
 
else:
    try: last = mode(prices)
    except: last = median(prices)

write last to last.txt



the good news:

I ran this all day on BTS/BTC and no set of 5 prices were more than 2% different... meaning I never encountered a rogue node.

the better news:

this price feed can be used with confidence to feed bots with latest price data without risk of node going stale or going rogue

the best news:

I work on bid/ask tomorrow

:D

7
I am not an expert here, I'm simply an algo trader looking to integrate to the Bishares DEX environment by connecting to existing node architecture - without running my own node.  I have asked a lot of questions lately to Node Admins and have concluded there is a good deal of terminology involved that needs clarification.   There are also risks when dealing with existing nodes, that need to be mitigated.  So, please if you are an expert, chime in and I'll update this OP to summarize key points.   

This OP was initial populated with cut/paste commentary via Node Admin channel on Telegram.


NODES


some universal truisms:

- nodes are in no way uniform
- however, all nodes store all blocks
- any node can go rogue at any time
- every node is a man-in-the-middle between you and the blockchain


A node can be:

P2P

RPC

API - exposed to a network, either LAN or WAN

FULL -  nodes which provide full histories;  nodes which provide full histories; needs several tens of gigs of RAM; x5670 with 100G ram should be good for full history node

SEED - full nodes with publicly reachable p2p port

WITNESS - is a matter of votes, but you can run a witness node wich locally validates the blocks

PRODUCTION

LOAD BALANCED

PUBLIC

DOCKER

PAID

DELAY NODE

OWN USE

BLOCK PRODUCING

WHITE LISTED

BLACK LISTED

ACTIVE

STANDBY

LOW LATENCY

UNRESPONSIVE

TESTNET - testnet is actually used to determine if it's mainnet or testnet

SYNCHRONIZED

DATACENTER

HARDENED

SSL

VPS

DELAYED

INITIAL

FAKE - fake.automatic-selection is a hard-coded psuedo server

BITSHARES OFFICIAL - deployed with bitshares UI

CRYPTOBRIDGE OFFICIAL - deployed with cryptobridge UI

UP TO DATE - has a head block that is less than 3 seconds old

STALE - has a head block that is greater than 3 seconds old

PROPERLY DEPLOYED

LATEST VERSION

VERSION 171105a - if there are many wicks in price chart, it's on this version

pre-VERSION 1802xx - if owner key signature is not able to change active permissions, it's before 1802xx

ROGUE - a node can delay, refuse, or reorder your buy/sell/cancel or other requests.   A rogue node can also return inaccurate information to all or any one individual.  A rogue node can NOT modify or create a buy/sell/cancel operation on your behalf.  A rogue node can provide false account ID in an attempt to get you to send funds to bad address.


WORKING

VERIFIED



WALLETS


CLI - command line interface
PYBITSHARES
LIGHT
WEB WALLET
FAUCET - a pool of funds used to pay the registration fee for the new accounts, there are currently several public faucets up



PASSWORDS and KEYS


BRAIN

PASSPHRASE


8
When I get this error and it attempts a retry, it never actually does connect because the node itself is down or having issues.

Code: [Select]
Retrying in 2 seconds
Retrying in 4 seconds
Retrying in 6 seconds
etc.

How can I "catch" this retry-attempt like an error? 
How can I provide an argument to prevent any retry at all?

currently the only way I have found, is to use a `multiprocess.Process` approach to enforce a timeout that overrides the retry attempt by starting a side process to contain the node connect attempt, then breaking that process if it takes too long.   

I would rather it just break as soon as it says
Code: [Select]
Retrying in 2 seconds
as I've yet to see a retry actually accomplish anything.

Using a timeout approach has limitations; the timeout must be long enough to account for latency fluctuation, while being short enough to not eat up too much script time.

From my perspective, it would be advantageous if the pybitshares module, rather than attempting a retry on a down node, throws an exception that I can handle with try/except.  Upon exception, I can then specify a new node to attempt... rather than waiting for a timeout to expire.



related pybitshares code:

https://github.com/xeroc/python-bitshares/blob/9250544ca8eadf66de31c7f38fc37294c11f9548/bitsharesapi/websocket.py

beginning line 291

Code: [Select]
    def run_forever(self):
        """ This method is used to run the websocket app continuously.
            It will execute callbacks as defined and try to stay
            connected with the provided APIs
        """
        cnt = 0
        while not self.run_event.is_set():
            cnt += 1
            self.url = next(self.urls)
            log.debug("Trying to connect to node %s" % self.url)
            try:
                # websocket.enableTrace(True)
                self.ws = websocket.WebSocketApp(
                    self.url,
                    on_message=self.on_message,
                    on_error=self.on_error,
                    on_close=self.on_close,
                    on_open=self.on_open
                )
                self.ws.run_forever()
            except websocket.WebSocketException as exc:
                if (self.num_retries >= 0 and cnt > self.num_retries):
                    raise NumRetriesReached()

                sleeptime = (cnt - 1) * 2 if cnt < 10 else 10
                if sleeptime:
                    log.warning(
                        "Lost connection to node during wsconnect(): %s (%d/%d) "
                        % (self.url, cnt, self.num_retries) +
                        "Retrying in %d seconds" % sleeptime
                    )
                    time.sleep(sleeptime)

            except KeyboardInterrupt:
                self.ws.keep_running = False
                raise

            except Exception as e:
                log.critical("{}\n\n{}".format(str(e), traceback.format_exc()))


this snippet here is a major source of brittleness:

Code: [Select]
"Lost connection to node during wsconnect(): %s (%d/%d) "
                        % (self.url, cnt, self.num_retries) +
                        "Retrying in %d seconds" % sleeptime

A better behavior than just waiting and retrying on the same failed node is to switch nodes, THEN retry.


or simply raise the exception and let the user handle the failure: switching nodes; perhaps also blacklisting the old, or ringing a bell:

Code: [Select]
except websocket.WebSocketException:
    self.ws.keep_running = False
    raise

where the user could command:

Code: [Select]

attempt = 1
while attempt:

     try:

      # make api call
     attempt = 0

    except websocket.WebSocketException:

      # blacklist this node
      # run routine to find another white-listed node with low latency and non-stale blocktime
      attempt +=1
      if attempt > n:
          # run failsafe routine to generate new node list
      else:
          # switch node to known good node and loop
 


would it be possible to import the websocket.WebsocketException from the bitshares module?

something like

Code: [Select]
from bitshares import websocket.WebsocketException
but that doesn't work

I've also tried

Code: [Select]
from bitshares.websocket import WebsocketException
from bitshares import websocket
from bitshares import WebsocketException
and attempted to import the class function:

Quote
from bitshares import BitSharesWebsocket

but none of them work either, don't mind my ignorance here... just throwing things at the wall to see what sticks

I've also tried importing the websocket module and preempting the exception

Code: [Select]
import websocket

try:
    # connect to api
except websocket.WebsocketException:
    # print ('hello world')

does not catch

9
General Discussion / (Python) latency sorted Bitshares nodes
« on: March 11, 2018, 05:53:11 pm »
Update:  Developing here:
https://github.com/litepresence/extinction-event/blob/master/bitshares-node-latency.py







An "official" list of public nodes is here:

https://github.com/bitshares/bitshares-ui/blob/master/app/api/apiConfig.js

you can fetch it like this:
Code: [Select]
def nodes():  # Public Nodes List

    uri = 'https://raw.githubusercontent.com'
    url = uri+'/bitshares/bitshares-ui/master/app/api/apiConfig.js'
    raw = requests.get(url).text
    clean = ((raw.replace('"',"")).replace("'","")).replace(',','')
    parsed = [ t for t in clean.split() if t.startswith('wss') ]
    validated = [i for i in parsed if (('test' not in i) and ('fake' not in i))]

    return validated


result:
Code: [Select]
print (nodes())

>>>
['wss://bitshares.openledger.info/ws', 'wss://eu.openledger.info/ws', 'wss://bit.btsabc.org/ws', 'wss://bts.ai.la/ws', 'wss://bitshares.apasia.tech/ws', 'wss://japan.bitshares.apasia.tech/ws', 'wss://bitshares.dacplay.org/ws', 'wss://bitshares-api.wancloud.io/ws', 'wss://openledger.hk/ws', 'wss://bitshares.crypto.fans/ws', 'wss://ws.gdex.top', 'wss://dex.rnglab.org', 'wss://dexnode.net/ws', 'wss://kc-us-dex.xeldal.com/ws', 'wss://btsza.co.za:8091/ws', 'wss://api.bts.blckchnd.com', 'wss://eu.nodes.bitshares.ws', 'wss://us.nodes.bitshares.ws', 'wss://sg.nodes.bitshares.ws', 'wss://ws.winex.pro']



usage:
Code: [Select]
from bitshares.market import Market
from bitshares import BitShares

BitCURRENCY = 'OPEN.BTC'
BitASSET = 'BTS'
BitPAIR = BitASSET + ":" + BitCURRENCY
MARKET = Market(BitPAIR, bitshares_instance=BitShares(nodes()))

MARKET.buy()

10
Stakeholder Proposals / [Worker] - Ledger Nano S
« on: March 11, 2018, 02:06:37 pm »
I was wondering if adding BTS support to Ledger Nano would be within the realm of what a worker could be used for.

Thoughts?   I don't have any experience opening a worker... so if this is possible please help.




ledgerwallet >>> cryptocurrencies >>> what's next >>> altcoin support info

https://www.ledgerwallet.com/cryptocurrencies
https://trello.com/b/5nQ1mdzt/ledger-roadmap
https://trello.com/c/4Aa7Ug5a/20-altcoin-support-information

Quote
There are a lot of cryptocurrenies and as Ledger has limited ressources it cannot integrate them all. The conditions to integrate another crypto are one of the following:

massive general support and high market cap (ex: Ethereum)
development sponsored by the coin's community (ex: Litecoin)
direct developer integration using Ledger's SDK
For information, the "altcoin package" costs 149,000 EUR and includes:

  • development of altcoin's Nano S / Blue app
  • altcoin support added to the Ledger Wallet Chrome app
  • altcoin explorer API development for the backend
  • 1,000 Ledger Nano S unit with altcoin's logo laser marking
  • maintenance and support
This pricing is available only for project inheriting from Bitcoin. If the blockchain technology is original (ex: Ripple, IOTA...) then the pricing could be much higher.

If you are part of the project's team and have a deep technical understanding of the coin, we also invite you to fill-in our integration form.

Please also refer to our list of already supported coins and tokens if you are unsure if your favorite coin is supported or not.

Integration only (without custom Nano S units) for Bitcoin clones is available at the separate price of 50,000 EUR.

11
Need a low latency UI for DEX?

[ANN] microDEX
https://bitsharestalk.org/index.php?topic=26201.0


Need a bot?
Runs on local machine?
No subscription fees to pay?
No black box to blindly trust?
 100% open source code?
Backtest and Live session all in one python script?
Trades on Bitshares DEX?
Is aware of outside CEX market prices?
So easy grandma could run it?


[ANN] EXTINCTION EVENT















The Original Code:

https://www.pastebin.com/hzUTtapz

latest version at github here:

https://github.com/litepresence/extinction-event/tree/master/EV

Installation here:

https://github.com/litepresence/extinction-event/blob/master/Installation

Python3 - WTFPLv2*


*Includes Free 30X BTC 5X BTS 1 YEAR BACKTEST


Code: [Select]
EXTINCTION EVENT v0.00000001 alpha release
~=== BEGIN BACKTEST ==================~
API call for chartdata BTC_BTS 1390000000s 1520469392e CANDLE 86400 DAYS 1510
Dataset.....: 420 DAYS
Backtesting.: 365 DAYS
PAIR......: BTC_BTS
BitPAIR...: BTS:OPEN.BTC

CANDLE....: 86400
BEGIN.....: 1488933403 Tue Mar  7 19:36:43 2017

Bitshares
[Tue Mar  7 19:36:43 2017] 1 BUY BEAR DESPAIR 334448.16 BTS at 299 sat value 1.00 BTC
[Tue Mar  7 19:36:43 2017] 2 SELL BEAR RESISTANCE 334448.16 BTS at 307 sat value 1.03 BTC
[Fri Apr  7 20:36:43 2017] 3 BUY BULL SUPPORT 153620.86 BTS at 668 sat value 1.03 BTC
[Sat May  6 20:36:43 2017] 4 SELL BULL OVERBOUGHT 153620.86 BTS at 3013 sat value 4.63 BTC
[Tue May 23 20:36:43 2017] 5 BUY BULL SUPPORT 154826.76 BTS at 2989 sat value 4.63 BTC
[Wed Jun  7 20:36:43 2017] 6 SELL BULL OVERBOUGHT 154826.76 BTS at 8499 sat value 13.16 BTC
[Mon Jun 19 20:36:43 2017] 7 BUY BULL SUPPORT 128380.37 BTS at 10250 sat value 13.16 BTC
[Thu Jul 20 20:36:43 2017] 8 SELL BEAR RESISTANCE 128380.37 BTS at 5825 sat value 7.48 BTC
[Sat Oct  7 20:36:43 2017] 9 BUY BEAR DESPAIR 839235.27 BTS at 891 sat value 7.48 BTC
[Sat Oct 14 20:36:43 2017] 10 SELL BEAR RESISTANCE 839235.27 BTS at 1246 sat value 10.46 BTC
[Sun Nov 19 19:36:43 2017] 11 BUY BULL SUPPORT 919439.38 BTS at 1137 sat value 10.46 BTC
[Mon Dec 18 19:36:43 2017] 12 SELL BULL OVERBOUGHT 919439.38 BTS at 3873 sat value 35.62 BTC
[Wed Jan  3 19:36:43 2018] 13 BUY BULL SUPPORT 825211.57 BTS at 4315 sat value 35.62 BTC
[Sat Jan 27 19:36:43 2018] 14 SELL BEAR RESISTANCE 825211.57 BTS at 4050 sat value 33.42 BTC
===============================================================
START DATE........: Tue Mar  7 19:36:43 2017
END DATE..........: Wed Mar  7 19:36:43 2018
DAYS..............: 365.0
TRADES............: 14
DAYS PER TRADE....: 26.1
START PRICE.......: 0.00000299
END PRICE.........: 0.00001768
START PORTFOLIO...: 1.0 BTC 0.0 BTS
START MAX ASSETS..: 334448.160535 BTS
END MAX ASSETS....: 1890331.92993 BTS
ROI ASSETS........: 5.65X
START MAX CURRENCY: 1.0 BTC
END MAX CURRENCY..: 33.4210685212 BTC
ROI CURRENCY......: 33.42
APY CURRENCY......: 32.42
===============================================================
EXTINCTION EVENT v0.00000001 alpha release
~===END BACKTEST=========================~
#######################################
CURRENCY        = "BTC"
ASSET           = "BTS"
MA1             = 17.00
MA2             = 50.00
SELLOFF         = 2.250
SUPPORT         = 1.000
RESISTANCE      = 1.000
DESPAIR         = 0.525
MIN_CROSS       = 1.000
MAX_CROSS       = 1.000
BULL_STOP       = 1.000
BEAR_STOP       = 1.000
#######################################
# RESOLUTION    : 20
# DAYS          : 365
DPT             = 26.1 # Days Per Trade
# MARKET CAP....: 464.5M
# DOMINANCE.....: 0.1137 - RANK 38
ROI             = 33.42
#######################################


The Tunes:


BTS/BTC 500X https://www.pastecoin.com/6O3QlzeKRNg7
DASH/BTC 25X https://www.pastecoin.com/79j1XgOdQJv6






more alt/btc tunes coming soon








special thanks to:

https://www.youtube.com/watch?v=jJxKXOTNXjc
https://www.youtube.com/watch?v=xV1yUVeA_Fw
https://twitter.com/SEC_News/status/971494501343748097
https://twitter.com/lopp/status/971520121704538112
https://twitter.com/oraclepresence/status/971178302089187328
https://www.reddit.com/r/BinanceExchange/comments/82ou1d/binance_sold_all_my_alt_coins_at_market_rate/
docs.pybitshares.com
coinmarketcap.com/api
cryptocompare.com/api
stackoverflow.com
pastebin.com
pastecoin.com
codeshare.io
chatcrypt.com

12
would be super nice if you could sort by volume standardized to BTS in "Starred Markets" and "Featured Markets";
perhaps even as a replacement of the current "VOLUME" column as it really is pretty meaningless as an effective comparison between markets as they're all in different terms.

also, along w/ "Starred Markets" and "Featured Markets":
would be nice if there was a tab for "Active Markets" which included ANY market with > 0 volume in the past 24 hours

 ;D

13
Code: [Select]
from bitshares.blockchain import Blockchain
import time


def dex(command):

    if command == 'blocktime':

        now = int(time.time())
        chain = Blockchain(mode='head')
        current_block = chain.get_current_block_num()
        blocktime = chain.block_time(current_block)
        blocktimestamp = chain.block_timestamp(current_block)
        drift = now - blocktimestamp
        drifthours = drift/3600
        print ('block           :', current_block)
        print ('blocktime       :', blocktime)
        print ('stamp           :', blocktimestamp)
        print ('ctime(stamp)    :', time.ctime(blocktimestamp))
        print ('now             :', now)
        print ('ctime(now)      :', time.ctime(now))
        print ('drift seconds   :', ('%s' % drift))
        print ('drift hours     :', ('%.2f' % drifthours))
        return current_block, blocktimestamp, drift   

dex('blocktime')


returns

Code: [Select]
block           : 24764676
blocktime       : 2018-02-26 15:03:48
stamp           : 1519675428
ctime(stamp)    : Mon Feb 26 15:03:48 2018
now             : 1519657430
ctime(now)      : Mon Feb 26 10:03:50 2018
drift seconds   : -17998
drift hours     : -5.00



はるか, [26.02.18 09:58]
It's a core bug?

Abit More, [26.02.18 09:58]
Timestamp Without tz

Abit More, [26.02.18 09:58]
But too late to fix

はるか, [26.02.18 09:58]
Timestamp should always be epoch I think

BTS litepresence1, [26.02.18 09:59]
from user perspective I agree

Abit More, [26.02.18 09:59]
When converted to or from String,lack of a z at the end

はるか, [26.02.18 10:00]
ah yes it's missing a Z

はるか, [26.02.18 10:00]
so it needs all clients to manually handle that...

Abit More, [26.02.18 10:00]
Py lib can add it

Abit More, [26.02.18 10:00]
Yes

14
v1 : https://pastebin.com/9zAbqx2A

updated Mar6/2018

v2 https://pastebin.com/pBzi8a4N

 - improved cancel all
 - block number / latency
 - account value in BTS, BTC, USD terms



license: WFTPLv2 http://www.wtfpl.net/about/
Code: [Select]
# python3.4
 
' Wrapper for Common PyBitshares DEX Algo Trading API Calls '
 
# data is in easy to quant float / list of floats / dict of floats format
 
    # buy / sell / cancel
    # outstanding orders
    # account balance for pair
    # complete account balance
    # orderbook
    # last_price
    # account value
    # latency
 
# if no price / amount specified executes market order buy/sell
# if no expiration specified default is 3.2 years
# cancels all outstanding orders in market
 
' BTS: litepresence1 '
 
# http://docs.pybitshares.com
from bitshares.market import Market
from bitshares.account import Account
from bitshares import BitShares
from bitshares.blockchain import Blockchain
import time
 
 
ACCOUNT = Account("")
PASS_PHRASE = ""
 
BitCURRENCY = 'OPEN.BTC'
BitASSET = 'BTS'
BitPAIR = BitASSET + ":" + BitCURRENCY
MARKET = Market(BitPAIR, bitshares_instance=BitShares(nodes()))
CHAIN = Blockchain(bitshares_instance=BitShares(
    nodes()), mode='head')
 
SATOSHI = 0.00000001
ANTISAT = 1 / SATOSHI
 
def nodes():  # Public Nodes List
 
    nodes = [
        'wss://b.mrx.im/ws',
        'wss://bitshares.openledger.info/ws',
        'wss://bitshares.dacplay.org:8089/ws',
        'wss://dele-puppy.com/ws',
        'wss://eu.openledger.info/ws',
        'wss://bit.btsabc.org/ws',
        'wss://eu.openledger.info/ws',
        'wss://dexnode.net/ws',
        'wss://ws.gdex.top',
        'wss://kc-us-dex.xeldal.com/ws',
        'wss://bts.ai.la/ws',
        'wss://btsza.co.za:8091/ws',
        'wss://japan.bitshares.apasia.tech/ws',
        'wss://api.bts.blckchnd.com',
        'wss://bitshares-api.wancloud.io/ws',
        'wss://eu.nodes.bitshares.ws',
        'wss://bitshares.crypto.fans/ws',
        'wss://dex.rnglab.org',
        'wss://bitshares.openledger.info/ws',
        'wss://ws.winex.pro',
        'wss://sg.nodes.bitshares.ws',
        'wss://us.nodes.bitshares.ws',
        'wss://bitshares.apasia.tech/ws',
        'wss://openledger.hk/ws',
        'wss://bitshares.dacplay.org/ws',
    ]
    return nodes
 
def dex(  # Public AND Private API Bitshares
        command, amount=ANTISAT, price=None,
        depth=1, expiration=ANTISAT):
 
    MARKET.bitshares.wallet.unlock(PASS_PHRASE)
    ACCOUNT.refresh()
 
    if command == 'buy':
 
        # buy relentlessly until satisfied or currency exhausted
        print(('Bitshares API', command))
        if price is None:
            price = ANTISAT
        print(('buying', amount, 'at', price))
        attempt = 1
        currency = float(ACCOUNT.balance(BitCURRENCY))
        if amount > 0.998 * currency * price:
            amount = 0.998 * currency * price
        if amount > 0:
            while attempt:
                try:
                    details = (MARKET.buy(price, amount, expiration))
                    print (details)
                    attempt = 0
                except:
                    print(("buy attempt %s failed" % attempt))
                    attempt += 1
                    if attempt > 10:
                        print ('buy aborted')
                        return
                    pass
        else:
            print('no currency to buy')
 
    if command == 'sell':
 
        # sell relentlessly until satisfied or assets exhausted
        expiration = 86400 * 7
        print(('Bitshares API', command))
        if price is None:
            price = SATOSHI
        print(('selling', amount, 'at', price))
        attempt = 1
        assets = float(ACCOUNT.balance(BitASSET))
        if amount > 0.998 * assets:
            amount = 0.998 * assets
        if amount > 0:
            while attempt:
                try:
                    details = (MARKET.sell(price, amount, expiration))
                    print (details)
                    attempt = 0
                except:
                    print(("sell attempt %s failed" % attempt))
                    attempt += 1
                    if attempt > 10:
                        print ('sell aborted')
                        return
                    pass
        else:
            print('no assets to sell')
 
    if command == 'cancel':
 
        # cancel all orders in this MARKET relentlessly until satisfied
        print(('Bitshares API', command)) 
        orders = MARKET.accountopenorders()
        print((len(orders), 'open orders to cancel'))
        if len(orders):
            attempt = 1 
            order_list = []     
            for order in orders:
                order_list.append(order['id'])
            while attempt:
                try:
                    details = MARKET.cancel(order_list)
                    print (details)
                    attempt = 0
                except:
                    print((attempt, 'cancel failed', order_list))
                    attempt += 1
                    if attempt > 10:
                        print ('cancel aborted')
                        return
                    pass   
 
    if command == 'orders':
 
        # dictionary of open orders in traditional format:
        # orderNumber, orderType, market, amount, price
        print(('Bitshares API', command))
        orders = []
        for order in MARKET.accountopenorders():
            orderNumber = order['id']
            asset = order['base']['symbol']
            currency = order['quote']['symbol']
            amount = float(order['base'])
            price = float(order['price'])
            orderType = 'buy'
            if asset == BitASSET:
                orderType = 'sell'
                price = 1 / price
            orders.append({'orderNumber': orderNumber,
                           'orderType': orderType,
                           'market': BitPAIR, 'amount': amount,
                           'price': price})
        for o in orders:
            print (o)
        if len(orders) == 0:
            print ('no open orders')
        return orders
 
    if command == 'market_balances':
 
        # dictionary of currency and assets in this MARKET
        print(('Bitshares API', command))
        currency = float(ACCOUNT.balance(BitCURRENCY))
        assets = float(ACCOUNT.balance(BitASSET))
        balances = {'currency': currency, 'assets': assets}
        print (balances)
        return balances
 
    if command == 'complete_balances':
 
        # dictionary of ALL account balances
        print(('Bitshares API', command))
        raw = list(ACCOUNT.balances)
        balances = {}
        for i in range(len(raw)):
            balances[raw[i]['symbol']] = float(raw[i]['amount'])
        print (balances)
        return balances
 
    if command == 'book':
 
        # dictionary of 4 lists containing bid/ask volume/price
        print(('Bitshares API', command))
        raw = MARKET.orderbook(limit=depth)
        bids = raw['bids']
        asks = raw['asks']
        bidp = [float(bids[i]['price']) for i in range(len(bids))]
        bidv = [float(bids[i]['quote']) for i in range(len(bids))]
        askp = [float(asks[i]['price']) for i in range(len(asks))]
        askv = [float(asks[i]['quote']) for i in range(len(asks))]
        book = {'bidp': bidp, 'bidv': bidv, 'askp': askp, 'askv': askv}
        # print(book)
        print(('ask', ('%.8f' % book['askp'][0])))  # lowest ask price
        print(('bid', ('%.8f' % book['bidp'][0])))  # highest bid price
        # print(book['bidv'][0]) #highest bid volume
        # print(book['askv'][0]) #lowest ask volume
        return book
 
    if command == 'last':
 
        # the most recent transation in this MARKET
        print(('Bitshares API', command))
        raw = MARKET.ticker()['latest']
        price = float(raw)
        # print (price)
        return price
 
    if command == 'account_value':
 
        # dictionary account value in BTS BTC and USD
        print(('Bitshares API', command))
        raw = list(ACCOUNT.balances)
        balances = {}
        for i in range(len(raw)):
            balances[raw[i]['symbol']] = float(raw[i]['amount'])
        btc_value = 0
        for asset, amount in list(balances.items()):
            market_pair = 'OPEN.BTC:' + asset
            market = Market(market_pair)
            price = float(market.ticker()['latest'])
            try:
                value = amount / price
            except:
                value = 0
            if value < 0.0001:
                value = 0
            else:
                if asset != 'USD':
                    price = 1 / (price + SATOSHI)
                print((('%.4f' % value), 'OPEN.BTC', ('%.2f' % amount),
                       asset, '@', ('%.8f' % price)))
                btc_value += value
 
        market_pair = 'OPEN.BTC:USD'
        market = Market(market_pair)
        price = float(market.ticker()['latest'])
        usd_value = btc_value * price
        market_pair = 'OPEN.BTC:BTS'
        market = Market(market_pair)
        price = float(market.ticker()['latest'])
        bts_value = btc_value * price
        print((('%.2f' % bts_value), 'BTS',
             ('%.4f' % btc_value), 'OPEN.BTC',
             ('%.2f' % usd_value), 'bitUSD'))
        return bts_value, btc_value, usd_value
 
    if command == 'blocktime':
 
        current_block = CHAIN.get_current_block_num()
        blocktime = CHAIN.block_time(current_block)
        blocktimestamp = CHAIN.block_timestamp(current_block) - 18000
        now = time.time()
        latency = now - blocktimestamp
        print(('block               :', current_block))
        # print(('blocktime           :', blocktime))
        # print(('stamp               :', blocktimestamp))
        # print(('ctime(stamp)        :', time.ctime(blocktimestamp)))
        # print(('now                 :', now))
        print(('dex_rate latency    :', ('%.2f' % latency)))
        return current_block, blocktimestamp, latency
 
 
 
'''
dex('buy')
dex('sell')
dex('orders')
dex('cancel')
dex('market_balances')
dex('complete_balances')
dex('last')
dex('book')
dex('account_value')
dex('blocktime')
'''

15
from docs:

http://docs.pybitshares.com/en/latest/market.html?highlight=cancel#bitshares.market.Market.cancel
Code: [Select]
cancel(orderNumber, account=None)¶
Cancels an order you have placed in a given market.
Requires only the “orderNumber”. An order number takes the form 1.7.xxx.

Parameters: orderNumber (str) – The Order Object ide of the form 1.7.xxxx

how can I get orderNumber actively while placing an order?

how can I get orderNumber after the fact for all outstanding orders?

I attempted

Code: [Select]
print(ACCOUNT.openorders)
and

Code: [Select]
for order in MARKET.accountopenorders():
    print (order)

and this gives the order amount and price... but not orderNumber


thanks


Pages: [1] 2