-
Notifications
You must be signed in to change notification settings - Fork 3
/
graph.py
54 lines (40 loc) · 1.69 KB
/
graph.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import math
import networkx as nx
from threading import Lock
from symbol_info_util import get_symbol_info
from config import config
G = nx.MultiDiGraph()
graph_mx = Lock()
def path_product(path):
with graph_mx:
cost = nx.path_weight(G, path, 'weight')
product = math.e ** (-cost)
return product
def get_price(base, target):
weight = G.get_edge_data(base, target, key=0)['weight']
price = (math.e ** (-weight)) / (1 - config['transaction_fee'])
return price
def find_negative_cycle(start):
cycle = []
with graph_mx:
try:
cycle = nx.find_negative_cycle(G, start)
except (nx.exception.NetworkXError, nx.NodeNotFound):
pass # No negative cycle found or start not in graph
return cycle
def update_graph(symbol, price_info):
symbol_info = get_symbol_info(symbol)
if not symbol_info or not symbol_info['trading']: return
with graph_mx:
if not G.has_node(symbol_info['base']):
G.add_node(symbol_info['base'])
if not G.has_node(symbol_info['target']):
G.add_node(symbol_info['target'])
if G.has_edge(symbol_info['base'], symbol_info['target']):
G.remove_edge(symbol_info['base'], symbol_info['target'])
if G.has_edge(symbol_info['target'], symbol_info['base']):
G.remove_edge(symbol_info['target'], symbol_info['base'])
weight = -math.log(float(price_info['b']) * (1 - config['transaction_fee']))
G.add_edge(symbol_info['base'], symbol_info['target'], weight=weight)
weight = -math.log(1 / float(price_info['a']) * (1 - config['transaction_fee']))
G.add_edge(symbol_info['target'], symbol_info['base'], weight=weight)