Compare commits
2 Commits
a5f951dea9
...
becffcd1fb
Author | SHA1 | Date | |
---|---|---|---|
becffcd1fb | |||
3d2a454e96 |
@ -1,2 +1,2 @@
|
||||
from algorithm.wma import WMA
|
||||
from algorithm.ma import SMA, WMA, EMA, MA_Cross
|
||||
from algorithm.status import Status
|
||||
|
64
algorithm/ma.py
Normal file
64
algorithm/ma.py
Normal file
@ -0,0 +1,64 @@
|
||||
class SMA:
|
||||
def __init__(self):
|
||||
return
|
||||
|
||||
def calc(self, cands, period):
|
||||
sum = 0
|
||||
n = min(period, len(cands))
|
||||
for i in range(n):
|
||||
sum += cands[i][3]
|
||||
return sum / n
|
||||
|
||||
class EMA:
|
||||
def __init__(self):
|
||||
return
|
||||
|
||||
def calc(self, cands, period):
|
||||
n = min(period, len(cands))
|
||||
ret = 0
|
||||
for i in range(n):
|
||||
ret += cands[i][3]
|
||||
ret /= n
|
||||
for i in range(n):
|
||||
ret = (2/(1+n))*(cands[n-i-1][3] - ret) + ret
|
||||
return ret
|
||||
|
||||
class WMA:
|
||||
def __init__(self):
|
||||
return
|
||||
|
||||
def calc(self, cands, period):
|
||||
sum = 0
|
||||
den = 0
|
||||
for i in range(min(period, len(cands))):
|
||||
sum += cands[i][3] * (i+1)
|
||||
den += i+1
|
||||
return sum / den
|
||||
|
||||
|
||||
class MA_Cross:
|
||||
def __init__(self, ma, unit, width):
|
||||
self._ma = ma
|
||||
self._unit = unit
|
||||
self._width = width
|
||||
|
||||
self._period_short = 5
|
||||
self._period_mid = 21
|
||||
self._period_long = 55
|
||||
|
||||
self._posi_amp = 0.1
|
||||
|
||||
def judge(self, status):
|
||||
cands = status.candles[self._unit]
|
||||
short = self._ma.calc(cands, self._period_short)
|
||||
mid = self._ma.calc(cands, self._period_mid)
|
||||
long = self._ma.calc(cands, self._period_long)
|
||||
|
||||
width = mid * self._width
|
||||
posi = max(-1, min((short-long)/(2.5*width), 1)) * self._posi_amp
|
||||
|
||||
diff = short - mid
|
||||
if diff < 0:
|
||||
return max(-1, diff/width+posi) # sell
|
||||
else:
|
||||
return min(1, diff/width+posi) # buy
|
@ -1,33 +0,0 @@
|
||||
class WMA:
|
||||
def __init__(self, unit, width):
|
||||
self._unit = unit
|
||||
self._width = width
|
||||
|
||||
self._period_short = 7
|
||||
self._period_mid = 15
|
||||
self._period_long = 60
|
||||
|
||||
self._posi_amp = 0.1
|
||||
|
||||
def judge(self, status):
|
||||
cands = status.candles[self._unit]
|
||||
short = self._wma(cands, self._period_short)
|
||||
mid = self._wma(cands, self._period_mid)
|
||||
long = self._wma(cands, self._period_long)
|
||||
|
||||
width = mid * self._width
|
||||
posi = max(-1, min((short-long)/width, 1)) * self._posi_amp
|
||||
|
||||
diff = short - mid
|
||||
if diff < 0:
|
||||
return max(-1, diff/width+posi) # sell
|
||||
else:
|
||||
return min(1, diff/width+posi) # buy
|
||||
|
||||
def _wma(self, cands, period):
|
||||
sum = 0
|
||||
den = 0
|
||||
for i in range(min(period, len(cands))):
|
||||
sum += cands[i][3] * (i+1)
|
||||
den += i+1
|
||||
return sum / den
|
50
bitbank.py
50
bitbank.py
@ -5,7 +5,7 @@ import random
|
||||
import sys
|
||||
import time
|
||||
|
||||
import algorithm
|
||||
import algorithm as algo
|
||||
|
||||
|
||||
FETCH_INTERVAL = 5
|
||||
@ -23,30 +23,39 @@ def init():
|
||||
return []
|
||||
|
||||
procs = []
|
||||
procs.append(Fetcher(pub, "btc_jpy"))
|
||||
procs.append(Fetcher(pub, "eth_jpy"))
|
||||
procs.append(Fetcher(pub, "matic_jpy"))
|
||||
procs.append(Proc(pri, "btc_jpy", 5000, algorithm.WMA("1h", 0.01), 10*60))
|
||||
procs.append(Proc(pri, "eth_jpy", 5000, algorithm.WMA("1h", 0.01), 10*60))
|
||||
procs.append(Proc(pri, "matic_jpy", 5000, algorithm.WMA("1m", 0.01), 5))
|
||||
procs.append(Fetcher(pub, "xlm_jpy", 10*60))
|
||||
procs.append(Proc(pri, "xlm_jpy", 5000, algo.MA_Cross(algo.EMA(), "1h", 0.01), 10*60))
|
||||
|
||||
procs.append(Fetcher(pub, "btc_jpy", 10*60))
|
||||
procs.append(Proc(pri, "btc_jpy", 5000, algo.MA_Cross(algo.EMA(), "1h", 0.01), 10*60))
|
||||
|
||||
procs.append(Fetcher(pub, "eth_jpy", 10*60))
|
||||
procs.append(Proc(pri, "eth_jpy", 5000, algo.MA_Cross(algo.EMA(), "1h", 0.01), 10*60))
|
||||
|
||||
procs.append(Fetcher(pub, "matic_jpy", 5))
|
||||
procs.append(Proc(pri, "matic_jpy", 1000, algo.MA_Cross(algo.EMA(), "1m", 0.01), 5))
|
||||
return procs
|
||||
|
||||
|
||||
class Fetcher:
|
||||
def __init__(self, pub, pair):
|
||||
def __init__(self, pub, pair, interval):
|
||||
self._interval = interval
|
||||
self._last_update = 0
|
||||
|
||||
self._pub = pub
|
||||
self._pair = pair
|
||||
|
||||
self._candle_prev = {}
|
||||
|
||||
def tick(self):
|
||||
if time.time()-self._last_update < FETCH_INTERVAL:
|
||||
now = time.time()
|
||||
if now-self._last_update < self._interval:
|
||||
return
|
||||
try:
|
||||
st = algorithm.Status()
|
||||
st = algo.Status()
|
||||
|
||||
st.candles["1m"] = self._get_candle("1min")
|
||||
st.candles["1h"] = self._get_candle("1hour")
|
||||
st.candles["1m"] = self._get_candle("1min", 60)
|
||||
st.candles["1h"] = self._get_candle("1hour", 60)
|
||||
|
||||
st.price = st.candles["1m"][0][3]
|
||||
|
||||
@ -54,19 +63,24 @@ class Fetcher:
|
||||
status[self._pair] = st
|
||||
except Exception as e:
|
||||
print("fetce error:", e)
|
||||
return
|
||||
self._last_update = now
|
||||
|
||||
def _get_candle(self, unit):
|
||||
def _get_candle(self, unit, n, t = datetime.datetime.now(tz=datetime.timezone.utc)):
|
||||
data = self._pub.get_candlestick(
|
||||
self._pair,
|
||||
unit,
|
||||
datetime.datetime.now(tz=datetime.timezone.utc).strftime("%Y%m%d"))
|
||||
t.strftime("%Y%m%d"))
|
||||
data = data["candlestick"][0]["ohlcv"]
|
||||
|
||||
ret = []
|
||||
for i in range(min(60, len(data))):
|
||||
for i in range(min(n, len(data))):
|
||||
j = len(data)-i-1
|
||||
ret.append([float(data[j][0]), float(data[j][1]), float(data[j][2]), float(data[j][3])])
|
||||
|
||||
if len(ret) < n:
|
||||
t = t - datetime.timedelta(days=1)
|
||||
data = self._get_candle(unit, n-len(ret), t)
|
||||
ret = [*ret, *data]
|
||||
return ret
|
||||
|
||||
|
||||
@ -109,7 +123,7 @@ class Proc:
|
||||
amount = self._asset/st.price
|
||||
self._order_market(amount, "buy")
|
||||
self._buy_price = st.price
|
||||
print(f"[bitbank: {self._pair}] <BUY> amount: {amount}")
|
||||
print(f"[bitbank: {self._pair}] <BUY> +{amount} / -{self._asset}")
|
||||
except Exception as e:
|
||||
print(f"[bitbank: {self._pair}] buy error", e)
|
||||
self._buy_price = 0
|
||||
@ -117,7 +131,7 @@ class Proc:
|
||||
try:
|
||||
amount = self._asset/self._buy_price
|
||||
self._order_market(amount, "sell")
|
||||
print(f"[bitbank: {self._pair}] <SELL> amount: {amount}")
|
||||
print(f"[bitbank: {self._pair}] <SELL> -{amount} / +{amount*st.price}")
|
||||
except Exception as e:
|
||||
print(f"[bitbank: {self._pair}] sell error", e)
|
||||
|
||||
|
10
main.py
10
main.py
@ -6,15 +6,19 @@ import time
|
||||
import bitbank
|
||||
|
||||
|
||||
alive = True
|
||||
|
||||
def main():
|
||||
global alive
|
||||
procs = [*bitbank.init()]
|
||||
while True:
|
||||
while alive:
|
||||
for i in range(len(procs)):
|
||||
procs[i].tick()
|
||||
time.sleep(1)
|
||||
time.sleep(0.5)
|
||||
|
||||
def on_exit(sig, x):
|
||||
print(f"received {sig}")
|
||||
global alive
|
||||
alive = False
|
||||
|
||||
proc = multiprocessing.Process(target = main)
|
||||
proc.start()
|
||||
|
Loading…
Reference in New Issue
Block a user