← ブック一覧 / ダッシュボード — タップで資産曲線とソースを展開。取引ありをequity順、無取引・引退は下。
# 外来シード: passivbot流 —— EMA帯の下に指値買い、マークアップで指値売り
# 原型(v8/Rust)はグリッドDCAで平均取得を下げるが、当エンジンは単一建玉のため
# 「初回エントリー+マークアップ利確」の周期のみを移植。損切りは置かず(sl=999ATR)
# 含み損は保有で耐える(原型と同じ思想。実現損失ゼロの代わりに含みDDを負う)
def signal(window, state):
_exec = 'maker'
closes = [b["c"] for b in window]
def ema(vals, n):
k = 2 / (n + 1)
e = vals[0]
for v in vals[1:]:
e = v * k + e * (1 - k)
return e
e_fast = ema(closes[-120:], 30)
e_slow = ema(closes[-120:], 90)
band_lo = min(e_fast, e_slow) * 0.997
if closes[-1] < band_lo:
return 1
return 0
# 狙い: else分岐を追加
def signal(window, state):
_exec = 'maker'
closes = [b['c'] for b in window]
def ema(vals, n):
k = 2 / (n + 1)
e = vals[0]
for v in vals[1:]:
e = v * k + e * (1 - k)
return e
e_fast = ema(closes[-120:], 30)
e_slow = ema(closes[-120:], 90)
if closes[-1] < min(e_fast, e_slow) * 0.993:
return 1
elif sum((_x['l'] for _x in window[-5:])) / 5 >= window[-1]['l'] * 0.9904:
return -1
need = 0.001404
return 0
# 狙い: 執行スタイル切替(taker成行 ⇔ maker指値)
def signal(window, state):
_exec = 'taker'
closes = [b['c'] for b in window]
def ema(vals, n):
k = 2 / (n + 1)
e = vals[0]
for v in vals[1:]:
e = v * k + e * (1 - k)
return e
e_fast = ema(closes[-120:], 30)
e_slow = ema(closes[-120:], 90)
if closes[-1] < min(e_fast, e_slow) * 0.993:
return 1
elif sum((_x['l'] for _x in window[-5:])) / 5 >= window[-1]['l'] * 0.9904:
return -1
need = 0.001404
return 0
# 狙い: 外来シード素通し(passivbot深押し(帯-0.7%))
# 外来シード: passivbot族の変種(実証済み勝ち筋の周辺探索 2026-08-25)
def signal(window, state):
_exec = 'maker'
closes = [b["c"] for b in window]
def ema(vals, n):
k = 2 / (n + 1)
e = vals[0]
for v in vals[1:]:
e = v * k + e * (1 - k)
return e
e_fast = ema(closes[-120:], 30)
e_slow = ema(closes[-120:], 90)
if closes[-1] < min(e_fast, e_slow) * 0.993:
return 1
return 0
# 狙い: 分岐を削除
def signal(window, state):
_exec = 'maker'
closes = [b['c'] for b in window]
def ema(vals, n):
k = 2 / (n + 1)
e = vals[0]
for v in vals[1:]:
e = v * k + e * (1 - k)
return e
e_fast = ema(closes[-120:], 30)
e_slow = ema(closes[-120:], 90)
state['peak'] = max(state.get('peak', 0.0), window[-1]['c'])
if closes[-1] < min(e_fast, e_slow) * 0.993:
return 1
return 0
# 外来シード: 継続確認maker(系統マーカー qk_)
# 根拠(2026-08-14実測・live 40日・5市場):
# bitbank 1分リターンの符号相関は全時間帯で +0.22〜+0.40(通常分)。
# フォロワー市場がリーダー(Bybit)の動きを遅れて織り込む構造で、
# Kim&Hansen(2026)のQH境界リバーサルはbitbankでは成立しない(逆に継続)。
# 3分連続陽線+30分上昇整合のロングは5市場8セル中7セルで正、XRPが最良。
# 設計: 保有は約15分(スプレッド0.1bp級・maker往復リベートで回収)、
# 長期下落圏では要求リターンを段階的に引き上げる(二値ゲート禁止の原則)
def signal(window, state):
_exec = 'maker'
qk_hold = state.get('qk_hold', 0)
if qk_hold > 0:
state['qk_hold'] = qk_hold - 1
if qk_hold == 1:
return -1 # 保有満了 -> 指値売りを置く
return 0
if not all(window[i]['c'] > window[i]['o'] for i in (-1, -2, -3)):
return 0
qk_need = 0.0
if window[-1].get('t1', 0.0) < -0.04:
qk_need = 0.0010
base = window[-30]['c']
if base <= 0:
return 0
if window[-1]['c'] / base - 1 <= qk_need:
return 0
state['qk_hold'] = 15 # 約15分保有
return 1
# 狙い: 状態(state)を導入
def signal(window, state):
_exec = 'maker'
closes = [b['c'] for b in window]
def ema(vals, n):
k = 2 / (n + 1)
e = vals[0]
for v in vals[1:]:
e = v * k + e * (1 - k)
return e
e_fast = ema(closes[-120:], 30)
e_slow = ema(closes[-120:], 90)
state['peak'] = max(state.get('peak', 0.0), window[-1]['c'])
if window[-1]['c'] < state.get('peak', 0.0) * 0.9625:
state['peak'] = 0.0
return -1
if closes[-1] < min(e_fast, e_slow) * 0.993:
return 1
return 0
# 複合シード: 逆張りmakerに長期トレンドガード(下向きなら逆張り禁止)
def signal(window, state):
_exec = 'maker'
c = [b["c"] for b in window]
sma20 = sum(c[-20:]) / 20
sma60 = sum(c[-60:]) / 60
# 下落トレンドガード: 長期が下向きの逆張りは「落ちる板に指値」になる
if sma20 < sma60 * 0.9985:
return -1
if c[-1] < sma20 * 0.999:
return 1
if c[-1] > sma20 * 1.001:
return -1
return 0
# 狙い: 条件を厳しく/緩く
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
if prev_fast <= prev_slow and fast > slow and (sum((_x['v'] for _x in window[-45:])) / 45 / max(sum((_x['v'] for _x in window[-60:])) / 60, 1e-09) >= prev_slow * 0.9513):
return 1
if prev_fast >= prev_slow and fast > slow and (window[-1]['dw'] > window[-1].get('u', 1.0) / max(window[-10].get('u', 1.0), 1e-09) * 0.915):
if window[-1]['h'] <= window[-1]['o'] and prev_slow >= prev_fast * 1.0572:
return -2.2451624208057193
else:
return 0
if prev_fast >= prev_slow and fast > slow and (sum((_x['l'] for _x in window[-8:])) / 8 > sum((_x['c'] * _x['v'] for _x in window[-120:])) / max(sum((_x['v'] for _x in window[-120:])), 1e-09) and sum((_x['c'] * _x['v'] for _x in window[-20:])) / max(sum((_x['v'] for _x in window[-20:])), 1e-09) < window[-1]['l']) and (window[-1]['dw'] <= window[-1].get('fr', 0.0)):
return 1
if not prev_fast > slow * 0.9297:
return -1
return 0.0
# 狙い: 条件を厳しく/緩く
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
if prev_fast <= prev_slow and fast > slow and (sum((_x['v'] for _x in window[-45:])) / 45 / max(sum((_x['v'] for _x in window[-60:])) / 60, 1e-09) >= prev_slow * 0.9513):
return 1
if prev_fast >= prev_slow and fast > slow and (window[-1]['dw'] > window[-1].get('u', 1.0) / max(window[-10].get('u', 1.0), 1e-09) * 0.915):
return -2.2451624208057193
if prev_fast >= prev_slow and fast > slow and (sum((_x['l'] for _x in window[-8:])) / 8 > sum((_x['c'] * _x['v'] for _x in window[-120:])) / max(sum((_x['v'] for _x in window[-120:])), 1e-09) and sum((_x['c'] * _x['v'] for _x in window[-20:])) / max(sum((_x['v'] for _x in window[-20:])), 1e-09) < window[-1]['l']) and (window[-1]['dw'] <= window[-1].get('fr', 0.0)):
return 1
if not prev_fast > slow * 0.9297:
return -1
return 0.0
# 狙い: 入れ子を深く(returnを条件で分ける)
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
if prev_fast <= prev_slow and fast > slow and (sum((_x['v'] for _x in window[-45:])) / 45 / max(sum((_x['v'] for _x in window[-60:])) / 60, 1e-09) >= prev_slow * 0.9513):
return 1
if prev_fast >= prev_slow and fast > slow and (window[-1]['dw'] > window[-1].get('u', 1.0) / max(window[-10].get('u', 1.0), 1e-09) * 0.915):
if window[-1]['h'] <= window[-1]['o']:
return -2.2451624208057193
else:
return 0
if prev_fast >= prev_slow and fast > slow and (sum((_x['l'] for _x in window[-8:])) / 8 > sum((_x['c'] * _x['v'] for _x in window[-120:])) / max(sum((_x['v'] for _x in window[-120:])), 1e-09) and sum((_x['c'] * _x['v'] for _x in window[-20:])) / max(sum((_x['v'] for _x in window[-20:])), 1e-09) < window[-1]['l']) and (window[-1]['dw'] <= window[-1].get('fr', 0.0)):
return 1
if not prev_fast > slow * 0.9297:
return -1
return 0.0
# 狙い: else分岐を追加
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
if prev_fast <= prev_slow and fast > slow and (sum((_x['v'] for _x in window[-45:])) / 45 / max(sum((_x['v'] for _x in window[-60:])) / 60, 1e-09) >= prev_slow * 0.9513):
return 1
if prev_fast >= prev_slow and fast > slow and (window[-1]['dw'] > window[-1].get('u', 1.0) / max(window[-10].get('u', 1.0), 1e-09) * 0.915):
if window[-1]['h'] <= window[-1]['o']:
return -2.2451624208057193
else:
return 0
elif sum((_x['c'] * _x['v'] for _x in window[-10:])) / max(sum((_x['v'] for _x in window[-10:])), 1e-09) < window[-1]['c'] * 0.9361:
return -1
if prev_fast >= prev_slow and fast > slow and (sum((_x['l'] for _x in window[-8:])) / 8 > sum((_x['c'] * _x['v'] for _x in window[-120:])) / max(sum((_x['v'] for _x in window[-120:])), 1e-09) and sum((_x['c'] * _x['v'] for _x in window[-20:])) / max(sum((_x['v'] for _x in window[-20:])), 1e-09) < window[-1]['l']) and (window[-1]['dw'] <= window[-1].get('fr', 0.0)):
return 1
if not prev_fast > slow * 0.9297:
return -1
return 0.0
# 狙い: else分岐を追加
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
if prev_fast <= prev_slow and fast > slow and (sum((_x['v'] for _x in window[-45:])) / 45 / max(sum((_x['v'] for _x in window[-60:])) / 60, 1e-09) >= prev_slow * 0.9513):
return 1
if prev_fast >= prev_slow and fast > slow and (window[-1]['dw'] > window[-1].get('u', 1.0) / max(window[-10].get('u', 1.0), 1e-09) * 0.915):
if window[-1]['h'] <= window[-1]['o']:
return -2.2451624208057193
else:
return 0
elif sum((_x['c'] * _x['v'] for _x in window[-10:])) / max(sum((_x['v'] for _x in window[-10:])), 1e-09) < window[-1]['c'] * 0.9361:
return -1
if prev_fast >= prev_slow and fast > slow and (sum((_x['l'] for _x in window[-8:])) / 8 > sum((_x['c'] * _x['v'] for _x in window[-120:])) / max(sum((_x['v'] for _x in window[-120:])), 1e-09) and sum((_x['c'] * _x['v'] for _x in window[-20:])) / max(sum((_x['v'] for _x in window[-20:])), 1e-09) < window[-1]['l']) and (window[-1]['dw'] <= window[-1].get('fr', 0.0)):
return 1
elif not sum((_x['c'] * _x['v'] for _x in window[-60:])) / max(sum((_x['v'] for _x in window[-60:])), 1e-09) < sum((_x['c'] for _x in window[-20:])) / 20:
return -1
if not prev_fast > slow * 0.9297:
return -1
return 0.0
# 狙い: else分岐を追加
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
if prev_fast <= prev_slow and fast > slow and (sum((_x['v'] for _x in window[-45:])) / 45 / max(sum((_x['v'] for _x in window[-60:])) / 60, 1e-09) >= prev_slow * 0.9513):
return 1
if prev_fast >= prev_slow and fast > slow and (window[-1]['dw'] > window[-1].get('u', 1.0) / max(window[-10].get('u', 1.0), 1e-09) * 0.915):
return -2.2451624208057193
if prev_fast >= prev_slow and fast > slow and (sum((_x['l'] for _x in window[-8:])) / 8 > sum((_x['c'] * _x['v'] for _x in window[-120:])) / max(sum((_x['v'] for _x in window[-120:])), 1e-09) and sum((_x['c'] * _x['v'] for _x in window[-20:])) / max(sum((_x['v'] for _x in window[-20:])), 1e-09) < window[-1]['l']) and (window[-1]['dw'] <= window[-1].get('fr', 0.0)):
return 1
elif not sum((_x['h'] for _x in window[-60:])) / 60 >= window[-1]['c'] * 1.002:
return -1
if not prev_fast > slow * 0.9297:
return -1
return 0.0
# 狙い: 分岐を削除
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
if prev_fast <= prev_slow and fast > slow:
if sum((_x['h'] - _x['l'] for _x in window[-3:])) / max(sum((_x['v'] for _x in window[-3:])), 1e-09) / max(sum((_x['h'] - _x['l'] for _x in window[-60:])) / max(sum((_x['v'] for _x in window[-60:])), 1e-09), 1e-09) > window[-1]['c'] / max(window[-60]['c'], 1e-09):
return 1
else:
return 0
if prev_fast >= prev_slow and fast > slow and (window[-1]['dw'] > window[-1].get('u', 1.0) / max(window[-10].get('u', 1.0), 1e-09) * 0.915):
return -2.2451624208057193
return 0.0
# 狙い: 分岐を追加
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
v1 = window[-1]['dw']
if prev_fast <= prev_slow and fast > slow:
if sum((_x['h'] - _x['l'] for _x in window[-3:])) / max(sum((_x['v'] for _x in window[-3:])), 1e-09) / max(sum((_x['h'] - _x['l'] for _x in window[-60:])) / max(sum((_x['v'] for _x in window[-60:])), 1e-09), 1e-09) > window[-1]['c'] / max(window[-60]['c'], 1e-09):
return 1
else:
return 0
if prev_fast >= prev_slow and fast > slow and (window[-1]['dw'] > window[-1].get('u', 1.0) / max(window[-10].get('u', 1.0), 1e-09) * 0.915):
return -2.2451624208057193
elif not sum((_x['h'] for _x in window[-14:])) / 14 <= window[-1]['h']:
return 0
prev_slow = sum(closes[-31:-2]) / 28
closes = [b['c'] for b in window]
fast = sum(closes[-8:]) / 4
slow = sum(closes[-60:]) / 28
prev_slow = sum(closes[-31:-1]) / 28
if prev_fast <= prev_slow and fast > slow:
return 2.600389113507903
if prev_fast <= prev_slow and fast < slow:
return -1.2690816214440739
if min((_x['l'] for _x in window[-60:])) < sum((_x['h'] for _x in window[-20:])) / 20 * 0.921 or slow < window[-1].get('ta', 0.0) / max(sum((_x.get('ta', 0.0) for _x in window[-20:])) / 20, 1e-09):
return 1
return 0.0
# 狙い: 文レベル交叉(過去の最良個体と組み替え・データフロー解析つき)
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
v1 = window[-1]['dw']
if prev_fast <= prev_slow and fast > slow:
if sum((_x['h'] - _x['l'] for _x in window[-3:])) / max(sum((_x['v'] for _x in window[-3:])), 1e-09) / max(sum((_x['h'] - _x['l'] for _x in window[-60:])) / max(sum((_x['v'] for _x in window[-60:])), 1e-09), 1e-09) > window[-1]['c'] / max(window[-60]['c'], 1e-09):
return 1
else:
return 0
if prev_fast >= prev_slow and fast > slow and (window[-1]['dw'] > window[-1].get('u', 1.0) / max(window[-10].get('u', 1.0), 1e-09) * 0.915):
return -2.2451624208057193
prev_slow = sum(closes[-31:-2]) / 28
closes = [b['c'] for b in window]
fast = sum(closes[-8:]) / 4
slow = sum(closes[-60:]) / 28
if prev_fast >= prev_slow or fast > slow:
return 1
if prev_fast >= prev_slow or fast < slow:
return -1
return 0
# 狙い: 指標を追加
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
v1 = window[-1]['dw']
if prev_fast <= prev_slow and fast > slow:
if sum((_x['h'] - _x['l'] for _x in window[-3:])) / max(sum((_x['v'] for _x in window[-3:])), 1e-09) / max(sum((_x['h'] - _x['l'] for _x in window[-60:])) / max(sum((_x['v'] for _x in window[-60:])), 1e-09), 1e-09) > window[-1]['c'] / max(window[-60]['c'], 1e-09):
return 1
else:
return 0
if prev_fast >= prev_slow and fast > slow and (window[-1]['dw'] > window[-1].get('u', 1.0) / max(window[-10].get('u', 1.0), 1e-09) * 0.915):
return -2.2451624208057193
prev_slow = sum(closes[-31:-2]) / 28
closes = [b['c'] for b in window]
fast = sum(closes[-8:]) / 4
slow = sum(closes[-60:]) / 28
prev_slow = sum(closes[-31:-1]) / 28
if prev_fast <= prev_slow and fast > slow:
return 2.600389113507903
if prev_fast <= prev_slow and fast < slow:
return -1.2690816214440739
return 0.0
# 狙い: 分岐を追加
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
v1 = window[-1]['dw']
if prev_fast <= prev_slow and fast > slow:
if sum((_x['h'] - _x['l'] for _x in window[-3:])) / max(sum((_x['v'] for _x in window[-3:])), 1e-09) / max(sum((_x['h'] - _x['l'] for _x in window[-60:])) / max(sum((_x['v'] for _x in window[-60:])), 1e-09), 1e-09) > window[-1]['c'] / max(window[-60]['c'], 1e-09):
return 1
else:
return 0
if prev_fast >= prev_slow and fast > slow and (window[-1]['dw'] > window[-1].get('u', 1.0) / max(window[-10].get('u', 1.0), 1e-09) * 0.915):
return -2.2451624208057193
prev_slow = sum(closes[-31:-2]) / 28
closes = [b['c'] for b in window]
fast = sum(closes[-8:]) / 4
slow = sum(closes[-60:]) / 28
prev_slow = sum(closes[-31:-1]) / 28
if prev_fast <= prev_slow and fast > slow:
return 2.600389113507903
if prev_fast <= prev_slow and fast < slow:
return -1.2690816214440739
if slow > prev_slow * 0.9322:
return 1
return 0.0
# 狙い: 文レベル交叉(過去の最良個体と組み替え・データフロー解析つき)
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
v1 = window[-1]['dw']
if prev_fast <= prev_slow and fast > slow:
if sum((_x['h'] - _x['l'] for _x in window[-3:])) / max(sum((_x['v'] for _x in window[-3:])), 1e-09) / max(sum((_x['h'] - _x['l'] for _x in window[-60:])) / max(sum((_x['v'] for _x in window[-60:])), 1e-09), 1e-09) > window[-1]['c'] / max(window[-60]['c'], 1e-09):
return 1
else:
return 0
if prev_fast >= prev_slow and fast > slow and (window[-1]['dw'] > window[-1].get('u', 1.0) / max(window[-10].get('u', 1.0), 1e-09) * 0.915):
return -2.2451624208057193
elif not sum((_x['h'] for _x in window[-14:])) / 14 <= window[-1]['h']:
return 0
prev_slow = sum(closes[-31:-2]) / 28
closes = [b['c'] for b in window]
fast = sum(closes[-8:]) / 4
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
if prev_fast <= prev_slow and fast > slow:
return 1
if prev_fast >= prev_slow and fast > slow and (window[-1]['dw'] > window[-1].get('u', 1.0) / max(window[-10].get('u', 1.0), 1e-09) * 0.915):
return -2.2451624208057193
if prev_fast >= prev_slow and fast > slow and (sum((_x['l'] for _x in window[-8:])) / 8 > sum((_x['c'] * _x['v'] for _x in window[-120:])) / max(sum((_x['v'] for _x in window[-120:])), 1e-09) and sum((_x['c'] * _x['v'] for _x in window[-20:])) / max(sum((_x['v'] for _x in window[-20:])), 1e-09) < window[-1]['l']):
ret# 狙い: else分岐を追加
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
if prev_fast <= prev_slow and fast > slow:
return 1
elif window[-1]['l'] <= sum((_x['c'] for _x in window[-10:])) / 10:
return 0
if prev_fast >= prev_slow and fast > slow and (window[-1]['dw'] > window[-1].get('u', 1.0) / max(window[-10].get('u', 1.0), 1e-09) * 0.915) and (sum((_x['l'] for _x in window[-10:])) / 10 <= window[-1]['c']):
return -2.2451624208057193
return 0.0
# 狙い: AST変異(定数摂動・比較演算子の反転・論理演算子の入替)
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-29:]) / 30
prev_fast = sum(closes[-11:-1]) / 10
slow = sum(closes[-31:]) / 30
prev_fast = sum(closes[-12:-1]) / 11
prev_slow = sum(closes[-31:-2]) / 30
state['ref'] = state.get('ref') or window[-1]['c']
if window[-1]['c'] < state['ref'] * 0.9519:
state['ref'] = window[-1]['c']
return -1.0608878213656312
if prev_fast >= prev_slow and fast > slow:
return 1.0365158657883864
if prev_fast >= prev_slow or fast < slow:
return -0.983889696930278
return 0.0
# 狙い: 分岐を削除
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-29:]) / 30
prev_fast = sum(closes[-11:-1]) / 10
slow = sum(closes[-31:]) / 30
prev_fast = sum(closes[-12:-1]) / 11
prev_slow = sum(closes[-31:-2]) / 30
state['ref'] = state.get('ref') or window[-1]['c']
if prev_fast >= prev_slow and fast > slow:
return 1.0365158657883864
if prev_fast >= prev_slow or fast < slow:
return -0.983889696930278
return 0.0
# 逆張りOFIシード: taker売りの投げ(ofi<閾値)+SMA下方乖離で指値買い
# ラボ実測(2026-08-14): eth TUNE+2.96%(32取引・勝率65%・DD4.3%) VALID+1.94%
# (VALID期間の市場は-1.34% → βでなくタイミング)。順張りOFIは全滅(-46〜-60%)
def signal(window, state):
_exec = 'maker'
b = window[-1]
c = [x["c"] for x in window]
tb = sum(x.get("tb", 0.0) for x in window[-10:])
ts = sum(x.get("ts", 0.0) for x in window[-10:])
tot = tb + ts
if tot <= 0:
return 0
ofi = (tb - ts) / tot
if b["t1"] < -0.05:
return -1
sma = sum(c[-30:]) / 30
th = -0.5
if b["t1"] < 0:
th = th - 0.1
if ofi < th and c[-1] < sma * 0.997:
return 1
if c[-1] > sma * 1.004:
return -1
return 0
# 帯域×投げ売り合議シード: EMA帯の下×taker売り集中の時だけ拾う
def signal(window, state):
_exec = 'maker'
b = window[-1]
closes = [x["c"] for x in window]
def ema(vals, n):
k = 2 / (n + 1)
e = vals[0]
for v in vals[1:]:
e = v * k + e * (1 - k)
return e
e_fast = ema(closes[-120:], 30)
e_slow = ema(closes[-120:], 90)
tb = sum(x.get("tb", 0.0) for x in window[-10:])
ts = sum(x.get("ts", 0.0) for x in window[-10:])
ofi = (tb - ts) / max(tb + ts, 1e-9)
if b["t1"] < -0.05:
return -1
dip = 0.997
if b["t1"] < 0:
dip = dip - 0.002
if closes[-1] < min(e_fast, e_slow) * dip and ofi < -0.3:
return 1
if closes[-1] > max(e_fast, e_slow) * 1.004:
return -1
return 0
# 外来シード: 基準回帰maker(系統マーカー bz_)
# 理論: 価格発見はリーダー(Bybit perps)で起き、フォロワー現物は水準へ収斂する
# (cross-venue lead-lag/pairs回帰。2025-26の実証研究でも一貫)。
# bitbankがリーダー換算の適正値より安い時に指値買い=約定選択と意図が整合し、
# maker逆選択(モメンタム追い)の構造欠陥を回避する。
# 実測(2026-08-16, live40日): 前半4市場すべて正(+20〜+47bps/取引 t=1.2〜1.9)、
# 後半(下落レジーム)は負。段階ゲートを備えるが、レジーム適応は進化の仕事。
# 手仕舞いは収斂(価格状態)ベースでカウンタ不使用 → index_probe安全。
def signal(window, state):
_exec = 'maker'
b = window[-1]
u = b.get('u', 0.0)
if u <= 0:
return 0
# 適正比率: 過去120本の c/u 平均
bz_s = 0.0
bz_n = 0
for i in range(-120, 0):
w = window[i]
uu = w.get('u', 0.0)
if uu > 0:
bz_s += w['c'] / uu
bz_n += 1
if bz_n < 60:
return 0
bz_fair = bz_s / bz_n
bz_basis = b['c'] / (u * bz_fair) - 1
# 収斂したら手仕舞い(指値売り)
if bz_basis >= 0.0:
return -1
# 段階ゲート: 自板の中期(120分)下落中は要求を2倍
bz_k = 0.0015
if window[-120]['c'] > 0 and b['c'] / window[-120]['c'] - 1 < -0.003:
bz_k = 0.0030
# リーダー急落ガード: Bybitの10分リターンが-0.3%未満なら拾わない
u10 = window[-10].get('u', 0.0)
if u10 <= 0 or u / u10 - 1 < -0.003:
return 0
if bz_basis < -bz_k:
return 1
return 0
# 外来シード: 基準回帰maker 深押し版(系統マーカー bz_)
# k15版と同構造で、乖離要求を-0.30%に上げた低頻度・高単価型。
# 適応度のedge項(1取引純益の統計的下限/往復コスト)は取引を重ねるほど
# 下限が締まるため、「深い乖離だけを待つ」ことで1取引の期待値を太らせる。
def signal(window, state):
_exec = 'maker'
b = window[-1]
u = b.get('u', 0.0)
if u <= 0:
return 0
bz_s = 0.0
bz_n = 0
for i in range(-120, 0):
w = window[i]
uu = w.get('u', 0.0)
if uu > 0:
bz_s += w['c'] / uu
bz_n += 1
if bz_n < 60:
return 0
bz_basis = b['c'] / (u * (bz_s / bz_n)) - 1
if bz_basis >= 0.0:
return -1
bz_k = 0.0030
if window[-120]['c'] > 0 and b['c'] / window[-120]['c'] - 1 < -0.003:
bz_k = 0.0045
u10 = window[-10].get('u', 0.0)
if u10 <= 0 or u / u10 - 1 < -0.003:
return 0
if bz_basis < -bz_k:
return 1
return 0
# 複合シード: lead-lag追随に、実測で判明した弱点への防御を内蔵
def signal(window, state):
_exec = 'maker'
c = [b["c"] for b in window]
u = [b["u"] for b in window]
if u[-1] <= 0 or u[-6] <= 0:
return 0
# 下落トレンドガード: 直近30分で-0.4%超の下げ = 逆選択地帯。買わず逃げる
if c[-1] / c[-31] - 1 < -0.004:
return -1
# ボラフィルタ: 動きが死んでいるときはエッジがコストを跨げない
rng = sum(abs(c[i] - c[i - 1]) for i in range(-30, 0)) / 30 / c[-1]
if rng < 0.0002:
return 0
lead = u[-1] / u[-6] - 1
lag = c[-1] / c[-6] - 1
gap = lead - lag
if gap > 0.0008:
return 1
if gap < -0.0002:
return -1
return 0
# 複合シードv2: 旗艦に長期トレンド(t1)と資金調達率(fr)の文脈を追加
def signal(window, state):
_exec = 'maker'
b = window[-1]
c = [x["c"] for x in window]
u = [x["u"] for x in window]
if u[-1] <= 0 or u[-6] <= 0:
return 0
# 深い長期下落圏(50日SMA比-8%以下)だけ買いの土俵から降りる。
# 浅い下落圏では全面禁止ではなく「より強い乖離を要求」する段階ゲート
# (二値ブロックだと局面次第で取引ゼロになり進化の素材にならない)
if b["t1"] < -0.08:
return -1
if c[-1] / c[-31] - 1 < -0.004:
return -1
rng = sum(abs(c[i] - c[i - 1]) for i in range(-30, 0)) / 30 / c[-1]
if rng < 0.0002:
return 0
need = 0.0008
if b["t1"] < 0:
need = 0.0012 # 長期下落圏では要求乖離を1.5倍に
if b["fr"] > 0.0003:
need = need * 1.5 # ロング過密でも同様に慎重化
gap = (u[-1] / u[-6] - 1) - (c[-1] / c[-6] - 1)
if gap > need:
return 1
if gap < -0.0002:
return -1
return 0
# 文脈シード: 資金調達率マイナス=ショート過密。反発の初動で踏み上げに乗る
def signal(window, state):
_exec = 'maker'
b = window[-1]
c = [x["c"] for x in window]
if b["fr"] >= 0:
# 偏りが解消したら降りる
if c[-1] > sum(c[-10:]) / 10:
return -1
return 0
sma10 = sum(c[-10:]) / 10
sma30 = sum(c[-30:]) / 30
if b["fr"] < -0.0001 and sma10 > sma30 and c[-1] > sma10:
return 1
if c[-1] < sma30 * 0.997:
return -1
return 0
# ☆基準回帰×funding合議: 割安(basis)とショート混雑(fr<=0)の合議
# 理論: 価格発見収斂(bz_)に、funding負=ショート過密(踏み上げ余地)を重ねる。
# fr正(ロング過密)のときは要求乖離を2倍に(段階ゲート)。
def signal(window, state):
_exec = 'maker'
b = window[-1]
u = b.get('u', 0.0)
if u <= 0:
return 0
s = 0.0; n = 0
for i in range(-120, 0):
w = window[i]; uu = w.get('u', 0.0)
if uu > 0:
s += w['c'] / uu; n += 1
if n < 60:
return 0
basis = b['c'] / (u * (s / n)) - 1
if basis >= 0.0:
return -1
k = 0.0015 if b.get('fr', 0.0) <= 0 else 0.0030
u10 = window[-10].get('u', 0.0)
if u10 <= 0 or u / u10 - 1 < -0.003:
return 0
if basis < -k:
return 1
return 0
# ☆リーダー安定押し目: 自板が投げ売りで急落・リーダーはほぼ無傷の瞬間だけ拾う
# 理論: フォロワー市場のローカルな投げ(需給イベント)はリーダー水準へ回帰する。
# 「押し目の質」をリーダーで判定する — lead-lag makerの核を最も直接に実装。
def signal(window, state):
_exec = 'maker'
b = window[-1]
u = b.get('u', 0.0)
if u <= 0 or window[-15]['c'] <= 0:
return 0
u15 = window[-15].get('u', 0.0)
if u15 <= 0:
return 0
s = 0.0; n = 0
for i in range(-120, 0):
w = window[i]; uu = w.get('u', 0.0)
if uu > 0:
s += w['c'] / uu; n += 1
if n < 60:
return 0
basis = b['c'] / (u * (s / n)) - 1
if basis >= -0.0002:
return -1 # リーダー水準へ回帰したら手仕舞い
local15 = b['c'] / window[-15]['c'] - 1
leader15 = u / u15 - 1
if local15 < -0.004 and leader15 > -0.001:
return 1
return 0
# ☆三者合議: 基準回帰 / lead-lag gap / EMA帯逆張り の2/3投票
# 理論: 独立性のある3つの正当なシグナル源の合議は単独より誤検出に強い。
def signal(window, state):
_exec = 'maker'
b = window[-1]
c = [w['c'] for w in window]
u = b.get('u', 0.0)
vin = 0; vout = 0
# 1) 基準回帰
if u > 0:
s = 0.0; n = 0
for i in range(-120, 0):
w = window[i]; uu = w.get('u', 0.0)
if uu > 0:
s += w['c'] / uu; n += 1
if n >= 60:
basis = b['c'] / (u * (s / n)) - 1
if basis < -0.0015:
vin += 1
if basis >= 0.0:
vout += 1
# 2) lead-lag gap(6分)
u6 = window[-6].get('u', 0.0)
if u > 0 and u6 > 0 and c[-6] > 0:
gap = (u / u6 - 1) - (c[-1] / c[-6] - 1)
if gap > 0.0008:
vin += 1
if gap < -0.0002:
vout += 1
# 3) EMA帯逆張り(長期下向きは棄権)
sma20 = sum(c[-20:]) / 20
sma60 = sum(c[-60:]) / 60
if sma20 >= sma60 * 0.9985:
if c[-1] < sma20 * 0.999:
vin += 1
if c[-1] > sma20 * 1.001:
vout += 1
if vout >= 2:
return -1
if vin >= 2:
return 1
return 0
# ☆リーダー安定押し目: 自板が投げ売りで急落・リーダーはほぼ無傷の瞬間だけ拾う
# 理論: フォロワー市場のローカルな投げ(需給イベント)はリーダー水準へ回帰する。
# 「押し目の質」をリーダーで判定する — lead-lag makerの核を最も直接に実装。
def signal(window, state):
_exec = 'maker'
b = window[-1]
u = b.get('u', 0.0)
if u <= 0 or window[-15]['c'] <= 0:
return 0
u15 = window[-15].get('u', 0.0)
if u15 <= 0:
return 0
s = 0.0; n = 0
for i in range(-120, 0):
w = window[i]; uu = w.get('u', 0.0)
if uu > 0:
s += w['c'] / uu; n += 1
if n < 60:
return 0
basis = b['c'] / (u * (s / n)) - 1
if basis >= -0.0002:
return -1 # リーダー水準へ回帰したら手仕舞い
local15 = b['c'] / window[-15]['c'] - 1
leader15 = u / u15 - 1
# 較正 2026-08-17: -0.4%/15分のローカル投げは実測で月数回しか起きず
# 6日間0取引。-0.25%へ緩和(リーダー静穏条件は-0.15%へ)
if local15 < -0.0025 and leader15 > -0.0015:
return 1
return 0
# 狙い: 分岐を削除
def signal(window, state):
_exec = 'maker'
b = window[-1]
c = [x['c'] for x in window]
u = [x['u'] for x in window]
if u[-1] <= 0 or u[-6] <= 0:
return 0
need = 0.001404
gap = u[-1] / u[-6] - 1 - (c[-1] / c[-6] - 1)
if gap > need and window[-1]['h'] >= max((_x['h'] for _x in window[-8:])):
return 1
if gap < -need * 0.25:
return -1
return 0
# 狙い: 分岐を削除
def signal(window, state):
_exec = 'maker'
b = window[-1]
c = [x['c'] for x in window]
u = [x['u'] for x in window]
if u[-1] <= 0 or u[-6] <= 0:
return 0
need = 0.001404
if b['fr'] > 0.0003:
need = need * 1.5
gap = u[-1] / u[-6] - 1 - (c[-1] / c[-6] - 1)
if gap > need and window[-1]['h'] >= max((_x['h'] for _x in window[-8:])):
return 1
return 0
# 狙い: 条件を厳しく/緩く
def signal(window, state):
_exec = 'maker'
b = window[-1]
c = [x['c'] for x in window]
if c[-1] / c[-31] - 1 < -0.00232 or sum((_x['l'] for _x in window[-14:])) / 14 > window[-1]['c']:
return -1
rng_ = sum((abs(c[i] - c[i - 1]) for i in range(-30, 0))) / 30 / c[-1]
if rng_ < 0.0002:
return 0
u = [x['u'] for x in window]
if u[-1] <= 0 or u[-6] <= 0:
return 0
need = 0.001379
gap = u[-1] / u[-6] - 1 - (c[-1] / c[-6] - 1)
if gap > need:
return 1
if gap < -need * 0.25:
return -1
return 0
# 狙い: 執行スタイル切替(taker成行 ⇔ maker指値)
def signal(window, state):
_exec = 'taker'
b = window[-1]
c = [x['c'] for x in window]
if c[-1] / c[-31] - 1 < -0.00232 or sum((_x['l'] for _x in window[-14:])) / 14 > window[-1]['c']:
return -1
rng_ = sum((abs(c[i] - c[i - 1]) for i in range(-30, 0))) / 30 / c[-1]
if rng_ < 0.0002:
return 0
u = [x['u'] for x in window]
if u[-1] <= 0 or u[-6] <= 0:
return 0
need = 0.001379
gap = u[-1] / u[-6] - 1 - (c[-1] / c[-6] - 1)
if gap > need:
return 1
if gap < -need * 0.25:
return -1
return 0
# 狙い: 分岐を削除
def signal(window, state):
_exec = 'maker'
b = window[-1]
c = [x['c'] for x in window]
u = [x['u'] for x in window]
if u[-1] <= 0 or u[-6] <= 0:
return 0
need = 0.001404
if b['fr'] > 0.0003:
need = need * 1.5
gap = u[-1] / u[-6] - 1 - (c[-1] / c[-6] - 1)
if gap > need and window[-1]['h'] >= max((_x['h'] for _x in window[-8:])):
return 1
if gap < -need * 0.25:
return -1
return 0
# 狙い: 生成(気質DNA→部品合成。dna_gen.py)
# 生成(気質DNA): 気質から部品合成
# _tg: {"exec": "maker", "alpha": "leadlag", "agg": 0.4, "sl": 15, "tp": 9.8, "atr_n": 30, "g_down": true, "g_vol": false, "g_t1": false, "g_fr": false}
def signal(window, state):
_exec = 'maker'
b = window[-1]
c = [x["c"] for x in window]
if c[-1] / c[-31] - 1 < -0.0016:
return -1
u = [x["u"] for x in window]
if u[-1] <= 0 or u[-6] <= 0:
return 0
need = 0.002
gap = (u[-1] / u[-6] - 1) - (c[-1] / c[-6] - 1)
if gap > need:
return 1
if gap < -need * 0.25:
return -1
return 0
# 狙い: 生成(気質DNA→部品合成。dna_gen.py)
# 生成(気質DNA): 気質から部品合成
# _tg: {"exec": "maker", "alpha": "leadlag", "agg": 0.4, "sl": 3.1, "tp": 6.8, "atr_n": 20, "g_down": true, "g_vol": false, "g_t1": false, "g_fr": false}
def signal(window, state):
_exec = 'maker'
b = window[-1]
c = [x["c"] for x in window]
if c[-1] / c[-31] - 1 < -0.0016:
return -1
u = [x["u"] for x in window]
if u[-1] <= 0 or u[-6] <= 0:
return 0
need = 0.002
gap = (u[-1] / u[-6] - 1) - (c[-1] / c[-6] - 1)
if gap > need:
return 1
if gap < -need * 0.25:
return -1
return 0
# 狙い: 生成(気質DNA→部品合成。dna_gen.py)
# 生成(気質DNA): 気質から部品合成
# _tg: {"exec": "maker", "alpha": "leadlag", "agg": 0.4, "sl": 9.1, "tp": 7.5, "atr_n": 30, "g_down": true, "g_vol": false, "g_t1": false, "g_fr": false}
def signal(window, state):
_exec = 'maker'
b = window[-1]
c = [x["c"] for x in window]
if c[-1] / c[-31] - 1 < -0.0016:
return -1
u = [x["u"] for x in window]
if u[-1] <= 0 or u[-6] <= 0:
return 0
need = 0.002
gap = (u[-1] / u[-6] - 1) - (c[-1] / c[-6] - 1)
if gap > need:
return 1
if gap < -need * 0.25:
return -1
return 0
# 狙い: 分岐を追加
def signal(window, state):
_exec = 'maker'
b = window[-1]
c = [x['c'] for x in window]
if c[-1] / c[-31] - 1 < -0.0016:
return -1
u = [x['u'] for x in window]
if u[-1] <= 0 or u[-6] <= 0:
return 0
need = 0.002
gap = u[-1] / u[-6] - 1 - (c[-1] / c[-6] - 1)
if gap > need:
return 1
if window[-1]['c'] >= window[-1]['o']:
return -1
return 0
# 狙い: 執行スタイル切替(taker成行 ⇔ maker指値)
def signal(window, state):
_exec = 'taker'
b = window[-1]
c = [x['c'] for x in window]
if c[-1] / c[-31] - 1 < -0.0016:
return -1
u = [x['u'] for x in window]
if u[-1] <= 0 or u[-6] <= 0:
return 0
need = 0.002
gap = u[-1] / u[-6] - 1 - (c[-1] / c[-6] - 1)
if gap > need:
return 1
if window[-1]['c'] >= window[-1]['o']:
return -1
return 0
# 狙い: 分岐を追加
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
if prev_fast <= prev_slow and fast > slow and (sum((_x['v'] for _x in window[-45:])) / 45 / max(sum((_x['v'] for _x in window[-60:])) / 60, 1e-09) >= prev_slow * 0.9513):
return 1
if prev_fast >= prev_slow and fast > slow and (window[-1]['dw'] > window[-1].get('u', 1.0) / max(window[-10].get('u', 1.0), 1e-09) * 0.915):
if window[-1]['h'] <= window[-1]['o'] and prev_slow >= prev_fast * 1.0572:
return -2.2451624208057193
else:
return 0
elif (window[-1]['c'] - min((_x['l'] for _x in window[-10:]))) / max(max((_x['h'] for _x in window[-10:])) - min((_x['l'] for _x in window[-10:])), 1e-09) > sum((1 for i in range(1, 60) if (window[-i]['c'] - window[-i - 1]['c']) * (window[-i - 1]['c'] - window[-i - 2]['c']) > 0)) / 60 * 0.9116:
return -1
if prev_fast >= prev_slow and fast > slow and (sum((_x['l'] for _x in window[-8:])) / 8 > sum((_x['c'] * _x['v'] for _x in window[-120:])) / max(sum((_x['v'] for _x in window[-120:])), 1e-09) and sum((_x['c'] * _x['v'] for _x in window[-20:])) / max(sum((_x['v'] for _x in window[-20:])), 1e-09) < window[-1]['l']) and (window[-1]['dw'] <= window[-1].get('fr', 0.0)):
return 1
elif not window[-1]['c'] >= sum((_x['c'] * _x['v'] for _x in window[-10:])) / max(sum((_x['v'] for _x in window[-10:])), 1e-09):
return -1
if not prev_fast > slow * 0.9297:
return -1
if (window[-1]['c'] - min((_x['l'] for _x in window[-3:]))) / max(max((_x['h'] for _x in window[-3:])) - min((_x['l'] for _x in window[-3:])), 1e-09) < window[-1]# 狙い: else分岐を追加
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
if prev_fast <= prev_slow and fast > slow and (sum((_x['v'] for _x in window[-45:])) / 45 / max(sum((_x['v'] for _x in window[-60:])) / 60, 1e-09) >= prev_slow * 0.9513):
return 1
if prev_fast >= prev_slow and fast > slow and (window[-1]['dw'] > window[-1].get('u', 1.0) / max(window[-10].get('u', 1.0), 1e-09) * 0.915):
if window[-1]['h'] <= window[-1]['o'] and prev_slow >= prev_fast * 1.0572:
return -2.2451624208057193
else:
return 0
elif (window[-1]['c'] - min((_x['l'] for _x in window[-10:]))) / max(max((_x['h'] for _x in window[-10:])) - min((_x['l'] for _x in window[-10:])), 1e-09) > sum((1 for i in range(1, 60) if (window[-i]['c'] - window[-i - 1]['c']) * (window[-i - 1]['c'] - window[-i - 2]['c']) > 0)) / 60 * 0.9116:
return -1
if prev_fast >= prev_slow and fast > slow and (sum((_x['l'] for _x in window[-8:])) / 8 > sum((_x['c'] * _x['v'] for _x in window[-120:])) / max(sum((_x['v'] for _x in window[-120:])), 1e-09) and sum((_x['c'] * _x['v'] for _x in window[-20:])) / max(sum((_x['v'] for _x in window[-20:])), 1e-09) < window[-1]['l']) and (window[-1]['dw'] <= window[-1].get('fr', 0.0)):
return 1
elif not window[-1]['c'] >= sum((_x['c'] * _x['v'] for _x in window[-10:])) / max(sum((_x['v'] for _x in window[-10:])), 1e-09):
return -1
if not prev_fast > slow * 0.9297:
return -1
return 0.0
# 狙い: 指標を追加
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
v1 = abs(window[-1]['c'] - window[-1]['o']) / max(window[-1]['h'] - window[-1]['l'], 1e-09)
if prev_fast <= prev_slow and fast > slow:
return 1
if prev_fast >= prev_slow and fast > slow and (window[-1]['dw'] > window[-1].get('u', 1.0) / max(window[-10].get('u', 1.0), 1e-09) * 0.915):
return -2.2451624208057193
if prev_fast >= prev_slow and fast > slow and (sum((_x['l'] for _x in window[-8:])) / 8 > sum((_x['c'] * _x['v'] for _x in window[-120:])) / max(sum((_x['v'] for _x in window[-120:])), 1e-09) and sum((_x['c'] * _x['v'] for _x in window[-20:])) / max(sum((_x['v'] for _x in window[-20:])), 1e-09) < window[-1]['l']):
return 1
return 0
# 狙い: 条件を厳しく/緩く
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
if prev_fast <= prev_slow and fast > slow:
return 1
if prev_fast >= prev_slow and fast > slow and (window[-1]['dw'] > window[-1].get('u', 1.0) / max(window[-10].get('u', 1.0), 1e-09) * 0.915):
return -2.2451624208057193
if prev_fast >= prev_slow and fast > slow and (sum((_x['l'] for _x in window[-8:])) / 8 > sum((_x['c'] * _x['v'] for _x in window[-120:])) / max(sum((_x['v'] for _x in window[-120:])), 1e-09) and sum((_x['c'] * _x['v'] for _x in window[-20:])) / max(sum((_x['v'] for _x in window[-20:])), 1e-09) < window[-1]['l']) and (window[-1]['dw'] <= window[-1].get('fr', 0.0)):
return 1
if not prev_fast > slow * 0.9297:
return -1
return 0.0
# 狙い: 分岐を削除
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
if prev_fast <= prev_slow and fast > slow:
return 1
if prev_fast >= prev_slow and fast > slow and (window[-1]['dw'] > window[-1].get('u', 1.0) / max(window[-10].get('u', 1.0), 1e-09) * 0.915):
return -2.2451624208057193
if prev_fast >= prev_slow and fast > slow and (sum((_x['l'] for _x in window[-8:])) / 8 > sum((_x['c'] * _x['v'] for _x in window[-120:])) / max(sum((_x['v'] for _x in window[-120:])), 1e-09) and sum((_x['c'] * _x['v'] for _x in window[-20:])) / max(sum((_x['v'] for _x in window[-20:])), 1e-09) < window[-1]['l']):
return 1
if not prev_fast > slow * 0.9297:
return -1
if prev_fast <= prev_slow and fast > slow:
return 1
if sum((_x.get('fr', 0.0) for _x in window[-14:])) / 14 < window[-1].get('fr', 0.0):
return -1
return 0.0
# 狙い: 状態(state)を導入
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
state['peak'] = max(state.get('peak', 0.0), window[-1]['c'])
if window[-1]['c'] < state.get('peak', 0.0) * 0.9015:
state['peak'] = 0.0
return -1
if prev_fast <= prev_slow and fast > slow:
return 1
if prev_fast >= prev_slow and fast > slow and (window[-1]['dw'] > window[-1].get('u', 1.0) / max(window[-10].get('u', 1.0), 1e-09) * 0.915):
return -2.2451624208057193
if sum((_x['l'] for _x in window[-60:])) / 60 > window[-1]['c'] * 1.0312 and (sum((_x['c'] for _x in window[-120:])) / 120 <= window[-1]['h'] and sum((_x['c'] for _x in window[-90:])) / 90 < max((_x['h'] for _x in window[-8:]))):
return 1
return 0.0
# 狙い: 分岐を追加
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
if prev_fast <= prev_slow and fast > slow:
return 1
if prev_fast >= prev_slow and fast > slow and (window[-1]['dw'] > window[-1].get('u', 1.0) / max(window[-10].get('u', 1.0), 1e-09) * 0.915):
return -2.2451624208057193
if sum((_x['l'] for _x in window[-60:])) / 60 > window[-1]['c'] * 1.0312 and (sum((_x['c'] for _x in window[-120:])) / 120 <= window[-1]['h'] and sum((_x['c'] for _x in window[-90:])) / 90 < max((_x['h'] for _x in window[-8:]))):
return 1
return 0.0
# 狙い: 文レベル交叉(過去の最良個体と組み替え・データフロー解析つき)
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
if prev_fast <= prev_slow and fast > slow:
return 1
if prev_fast >= prev_slow and fast > slow and (window[-1]['dw'] > window[-1].get('u', 1.0) / max(window[-10].get('u', 1.0), 1e-09) * 0.915):
return -2.2451624208057193
return 0.0
# 狙い: 条件を厳しく/緩く
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
if prev_fast <= prev_slow and fast > slow:
return 1
if prev_fast >= prev_slow and fast > slow and (window[-1]['dw'] > window[-1].get('u', 1.0) / max(window[-10].get('u', 1.0), 1e-09) * 0.915) and (sum((_x['l'] for _x in window[-10:])) / 10 <= window[-1]['c']):
return -2.2451624208057193
return 0.0
# 狙い: 条件を厳しく/緩く
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
if prev_fast <= prev_slow and fast > slow:
return 1
if prev_fast >= prev_slow and fast > slow and (window[-1]['dw'] > window[-1].get('u', 1.0) / max(window[-10].get('u', 1.0), 1e-09) * 0.915) and (min((_x['l'] for _x in window[-3:])) > min((_x['l'] for _x in window[-8:]))):
return -2.2451624208057193
if prev_fast <= prev_slow and fast > slow:
return 2.7098316227688017
return 0.0
# 狙い: 条件を厳しく/緩く
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
state['ref'] = state.get('ref') or window[-1]['c']
v1 = closes
if window[-1]['c'] < state['ref'] * 0.9235:
state['ref'] = window[-1]['c']
return -1
if prev_fast >= prev_slow and fast > slow and (not window[-1]['c'] / max(min((_x['l'] for _x in window[-60:])), 1e-09) < window[-1]['v'] / max(sum((_x['v'] for _x in window[-30:])) / 30, 1e-09) * 1.0153):
return 1
if prev_fast <= prev_slow and fast > slow:
return 1
if prev_fast >= prev_slow and fast < slow and (min((_x['l'] for _x in window[-45:])) <= sum((_x['c'] for _x in window[-90:])) / 90):
return -1
return 0
# 狙い: 条件を厳しく/緩く
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
prev_fast = sum(closes[-8:-4]) / 7
prev_slow = sum(closes[-20:-4]) / 19
if prev_fast <= prev_slow and fast > slow and (not sum((_x.get('tb', 0.0) for _x in window[-90:])) / max(sum((_x.get('ts', 0.0) for _x in window[-90:])), 1e-09) < window[-1].get('u', 1.0) / max(window[-20].get('u', 1.0), 1e-09) * 0.916):
return 2.260817479653254
if prev_fast >= prev_slow or fast < slow:
return -1
return 0
# 狙い: 文レベル交叉(過去の最良個体と組み替え・データフロー解析つき)
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-1]) / 10
prev_fast = sum(closes[-7:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 28
if prev_fast <= prev_slow and fast > slow:
return 2.600389113507903
if prev_fast <= prev_slow and fast < slow:
return -1.2690816214440739
return 0.0
# 狙い: 条件を厳しく/緩く
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
state['ref'] = state.get('ref') or window[-1]['c']
v1 = closes
if window[-1]['c'] < state['ref'] * 0.9235:
state['ref'] = window[-1]['c']
return -1
if prev_fast >= prev_slow and fast > slow:
return 1
if prev_fast <= prev_slow and fast > slow:
return 1
if prev_fast >= prev_slow and fast < slow and (min((_x['l'] for _x in window[-45:])) <= sum((_x['c'] for _x in window[-90:])) / 90):
return -1
return 0
# 狙い: 分岐を追加
def signal(window, state):
closes = [b['c'] for b in window]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-30:]) / 30
prev_fast = sum(closes[-11:-2]) / 9
prev_slow = sum(closes[-31:-1]) / 30
state['ref'] = state.get('ref') or window[-1]['c']
v1 = closes
if window[-1]['c'] < state['ref'] * 0.9235:
state['ref'] = window[-1]['c']
return -1
if prev_fast >= prev_slow and fast > slow:
return 1
if prev_fast <= prev_slow and fast > slow:
return 1
if prev_fast >= prev_slow and fast < slow and (min((_x['l'] for _x in window[-45:])) <= sum((_x['c'] for _x in window[-90:])) / 90):
return -1
if window[-1].get('u', 1.0) / max(window[-60].get('u', 1.0), 1e-09) < (window[-1]['c'] - min((_x['l'] for _x in window[-5:]))) / max(max((_x['h'] for _x in window[-5:])) - min((_x['l'] for _x in window[-5:])), 1e-09):
return 1
return 0
更新: 2026-10-03 16:05 JST