fix(gate): align fund transfer between gate and gate_bot
- Extract shared gate_transfer_lib and global transfer form on all pages - Block auto-transfer when trend pullback plans have open positions - Redirect manual transfer back to the current page after submit Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+20
-19
@@ -2600,23 +2600,17 @@ def get_exchange_capitals(force=False):
|
|||||||
|
|
||||||
|
|
||||||
def execute_transfer_usdt(amount, from_account, to_account):
|
def execute_transfer_usdt(amount, from_account, to_account):
|
||||||
if amount <= 0:
|
from gate_transfer_lib import execute_transfer_usdt as _gate_execute_transfer_usdt
|
||||||
return False, "划转金额必须大于0", None
|
|
||||||
ok_live, reason = ensure_exchange_live_ready()
|
return _gate_execute_transfer_usdt(
|
||||||
if not ok_live:
|
exchange,
|
||||||
return False, reason, None
|
amount,
|
||||||
try:
|
from_account,
|
||||||
resp = exchange.transfer(TRANSFER_CCY, float(amount), from_account, to_account)
|
to_account,
|
||||||
return True, "划转成功", resp
|
transfer_ccy=TRANSFER_CCY,
|
||||||
except Exception as e:
|
ensure_live_ready=ensure_exchange_live_ready,
|
||||||
msg = str(e)
|
ensure_markets_loaded=ensure_markets_loaded,
|
||||||
if "INVALID_KEY" in msg or "Invalid key" in msg:
|
)
|
||||||
msg += (
|
|
||||||
"。常见原因:① GATE_API_SECRET 错误或 .env 里多了空格/换行;② IP 白名单未包含当前服务器出口 IP;"
|
|
||||||
"③ Gate「交易账户」类 API Key 若不支持钱包接口则无法走账户内划转 POST /wallet/transfers(需在官网确认该 Key 类型是否开放划转);"
|
|
||||||
"④ Key 已重置或权限变更。你已勾选现货/统一账户仍报错时,优先核对 Secret 与白名单。"
|
|
||||||
)
|
|
||||||
return False, msg, None
|
|
||||||
|
|
||||||
|
|
||||||
def get_account_usdt_total(account_type):
|
def get_account_usdt_total(account_type):
|
||||||
@@ -2638,6 +2632,12 @@ def get_account_usdt_total(account_type):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _auto_transfer_active_count(conn):
|
||||||
|
from gate_transfer_lib import count_auto_transfer_blockers
|
||||||
|
|
||||||
|
return count_auto_transfer_blockers(conn, count_order_monitors=get_active_position_count)
|
||||||
|
|
||||||
|
|
||||||
def auto_transfer_once_per_day():
|
def auto_transfer_once_per_day():
|
||||||
run_auto_transfer_once_per_day(
|
run_auto_transfer_once_per_day(
|
||||||
enabled=AUTO_TRANSFER_ENABLED,
|
enabled=AUTO_TRANSFER_ENABLED,
|
||||||
@@ -2647,7 +2647,7 @@ def auto_transfer_once_per_day():
|
|||||||
to_account=AUTO_TRANSFER_TO,
|
to_account=AUTO_TRANSFER_TO,
|
||||||
funds_decimals=2,
|
funds_decimals=2,
|
||||||
get_db=get_db,
|
get_db=get_db,
|
||||||
get_active_position_count=get_active_position_count,
|
get_active_position_count=_auto_transfer_active_count,
|
||||||
get_account_usdt_total=get_account_usdt_total,
|
get_account_usdt_total=get_account_usdt_total,
|
||||||
execute_transfer_usdt=execute_transfer_usdt,
|
execute_transfer_usdt=execute_transfer_usdt,
|
||||||
send_wechat_msg=send_wechat_msg,
|
send_wechat_msg=send_wechat_msg,
|
||||||
@@ -5995,6 +5995,7 @@ def render_main_page(page="trade"):
|
|||||||
auto_transfer_from=AUTO_TRANSFER_FROM,
|
auto_transfer_from=AUTO_TRANSFER_FROM,
|
||||||
auto_transfer_to=AUTO_TRANSFER_TO,
|
auto_transfer_to=AUTO_TRANSFER_TO,
|
||||||
auto_transfer_bj_hour=AUTO_TRANSFER_BJ_HOUR,
|
auto_transfer_bj_hour=AUTO_TRANSFER_BJ_HOUR,
|
||||||
|
transfer_amount_fmt=format_usdt(AUTO_TRANSFER_AMOUNT),
|
||||||
full_margin_buffer_ratio=FULL_MARGIN_BUFFER_RATIO,
|
full_margin_buffer_ratio=FULL_MARGIN_BUFFER_RATIO,
|
||||||
price_refresh_seconds=PRICE_REFRESH_SECONDS,
|
price_refresh_seconds=PRICE_REFRESH_SECONDS,
|
||||||
active_count=active_count,
|
active_count=active_count,
|
||||||
@@ -8104,7 +8105,7 @@ def manual_transfer():
|
|||||||
flash(f"手动划转成功:{amount}U {from_account}->{to_account}")
|
flash(f"手动划转成功:{amount}U {from_account}->{to_account}")
|
||||||
else:
|
else:
|
||||||
flash(f"手动划转失败:{msg}")
|
flash(f"手动划转失败:{msg}")
|
||||||
return redirect("/")
|
return redirect(request.referrer or "/trade")
|
||||||
|
|
||||||
|
|
||||||
def _journal_ai_chart_builder(row):
|
def _journal_ai_chart_builder(row):
|
||||||
|
|||||||
@@ -318,6 +318,7 @@
|
|||||||
<div class="stat-item"><div class="label">当日资金(交易账户)</div><div class="value" id="current-capital">{{ funds_fmt(current_capital) }}U</div></div>
|
<div class="stat-item"><div class="label">当日资金(交易账户)</div><div class="value" id="current-capital">{{ funds_fmt(current_capital) }}U</div></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="rule-tip">实时价格更新时间:<span id="price-last-updated">--</span>(北京时间 UTC+8)</div>
|
<div class="rule-tip">实时价格更新时间:<span id="price-last-updated">--</span>(北京时间 UTC+8)</div>
|
||||||
|
{% include 'gate_transfer_block.html' %}
|
||||||
|
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
{% if page == 'key_monitor' %}
|
{% if page == 'key_monitor' %}
|
||||||
@@ -451,23 +452,6 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|移动保本:下单可勾选关闭;开启时 {{ breakeven_rr_trigger }}R 触发(每 1R 阶梯上移),偏移 {{ breakeven_offset_pct }}%
|
|移动保本:下单可勾选关闭;开启时 {{ breakeven_rr_trigger }}R 触发(每 1R 阶梯上移),偏移 {{ breakeven_offset_pct }}%
|
||||||
</div>
|
</div>
|
||||||
<div class="rule-tip">
|
|
||||||
划转:自动划转 {{ '开启' if auto_transfer_enabled else '关闭' }}(每天<strong>北京时间 {{ auto_transfer_bj_hour }}:00</strong>起该整点小时内尝试;账簿按 <strong>UTC 自然日</strong>去重;将 {{ auto_transfer_to }} 调整至 {{ auto_transfer_amount }}U:不足从 {{ auto_transfer_from }} 划入、超出划回 {{ auto_transfer_from }};<strong>持仓中不划转</strong>并微信通知)
|
|
||||||
</div>
|
|
||||||
<form action="/manual_transfer" method="post" class="form-row">
|
|
||||||
<input name="amount" type="number" min="0.01" step="0.01" placeholder="手动划转金额U" required>
|
|
||||||
<select name="from_account">
|
|
||||||
<option value="funding" {% if auto_transfer_from == 'funding' %}selected{% endif %}>from: funding</option>
|
|
||||||
<option value="swap" {% if auto_transfer_from == 'swap' %}selected{% endif %}>from: swap</option>
|
|
||||||
<option value="spot" {% if auto_transfer_from == 'spot' %}selected{% endif %}>from: spot</option>
|
|
||||||
</select>
|
|
||||||
<select name="to_account">
|
|
||||||
<option value="swap" {% if auto_transfer_to == 'swap' %}selected{% endif %}>to: swap</option>
|
|
||||||
<option value="funding" {% if auto_transfer_to == 'funding' %}selected{% endif %}>to: funding</option>
|
|
||||||
<option value="spot" {% if auto_transfer_to == 'spot' %}selected{% endif %}>to: spot</option>
|
|
||||||
</select>
|
|
||||||
<button type="submit">手动划转</button>
|
|
||||||
</form>
|
|
||||||
<form id="add-order-form" action="/add_order" method="post" class="form-row">
|
<form id="add-order-form" action="/add_order" method="post" class="form-row">
|
||||||
<input id="order-symbol" name="symbol" placeholder="BTC 或 BTC/USDT" required>
|
<input id="order-symbol" name="symbol" placeholder="BTC 或 BTC/USDT" required>
|
||||||
<select id="order-direction" name="direction" required>
|
<select id="order-direction" name="direction" required>
|
||||||
|
|||||||
@@ -2610,23 +2610,17 @@ def get_exchange_capitals(force=False):
|
|||||||
|
|
||||||
|
|
||||||
def execute_transfer_usdt(amount, from_account, to_account):
|
def execute_transfer_usdt(amount, from_account, to_account):
|
||||||
if amount <= 0:
|
from gate_transfer_lib import execute_transfer_usdt as _gate_execute_transfer_usdt
|
||||||
return False, "划转金额必须大于0", None
|
|
||||||
ok_live, reason = ensure_exchange_live_ready()
|
return _gate_execute_transfer_usdt(
|
||||||
if not ok_live:
|
exchange,
|
||||||
return False, reason, None
|
amount,
|
||||||
try:
|
from_account,
|
||||||
resp = exchange.transfer(TRANSFER_CCY, float(amount), from_account, to_account)
|
to_account,
|
||||||
return True, "划转成功", resp
|
transfer_ccy=TRANSFER_CCY,
|
||||||
except Exception as e:
|
ensure_live_ready=ensure_exchange_live_ready,
|
||||||
msg = str(e)
|
ensure_markets_loaded=ensure_markets_loaded,
|
||||||
if "INVALID_KEY" in msg or "Invalid key" in msg:
|
)
|
||||||
msg += (
|
|
||||||
"。常见原因:① GATE_API_SECRET 错误或 .env 里多了空格/换行;② IP 白名单未包含当前服务器出口 IP;"
|
|
||||||
"③ Gate「交易账户」类 API Key 若不支持钱包接口则无法走账户内划转 POST /wallet/transfers(需在官网确认该 Key 类型是否开放划转);"
|
|
||||||
"④ Key 已重置或权限变更。你已勾选现货/统一账户仍报错时,优先核对 Secret 与白名单。"
|
|
||||||
)
|
|
||||||
return False, msg, None
|
|
||||||
|
|
||||||
|
|
||||||
def get_account_usdt_total(account_type):
|
def get_account_usdt_total(account_type):
|
||||||
@@ -2648,6 +2642,12 @@ def get_account_usdt_total(account_type):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _auto_transfer_active_count(conn):
|
||||||
|
from gate_transfer_lib import count_auto_transfer_blockers
|
||||||
|
|
||||||
|
return count_auto_transfer_blockers(conn, count_order_monitors=get_active_position_count)
|
||||||
|
|
||||||
|
|
||||||
def auto_transfer_once_per_day():
|
def auto_transfer_once_per_day():
|
||||||
run_auto_transfer_once_per_day(
|
run_auto_transfer_once_per_day(
|
||||||
enabled=AUTO_TRANSFER_ENABLED,
|
enabled=AUTO_TRANSFER_ENABLED,
|
||||||
@@ -2657,7 +2657,7 @@ def auto_transfer_once_per_day():
|
|||||||
to_account=AUTO_TRANSFER_TO,
|
to_account=AUTO_TRANSFER_TO,
|
||||||
funds_decimals=2,
|
funds_decimals=2,
|
||||||
get_db=get_db,
|
get_db=get_db,
|
||||||
get_active_position_count=get_active_position_count,
|
get_active_position_count=_auto_transfer_active_count,
|
||||||
get_account_usdt_total=get_account_usdt_total,
|
get_account_usdt_total=get_account_usdt_total,
|
||||||
execute_transfer_usdt=execute_transfer_usdt,
|
execute_transfer_usdt=execute_transfer_usdt,
|
||||||
send_wechat_msg=send_wechat_msg,
|
send_wechat_msg=send_wechat_msg,
|
||||||
@@ -5697,6 +5697,7 @@ def render_main_page(page="trade"):
|
|||||||
auto_transfer_from=AUTO_TRANSFER_FROM,
|
auto_transfer_from=AUTO_TRANSFER_FROM,
|
||||||
auto_transfer_to=AUTO_TRANSFER_TO,
|
auto_transfer_to=AUTO_TRANSFER_TO,
|
||||||
auto_transfer_bj_hour=AUTO_TRANSFER_BJ_HOUR,
|
auto_transfer_bj_hour=AUTO_TRANSFER_BJ_HOUR,
|
||||||
|
transfer_amount_fmt=format_money_usdt(AUTO_TRANSFER_AMOUNT),
|
||||||
full_margin_buffer_ratio=FULL_MARGIN_BUFFER_RATIO,
|
full_margin_buffer_ratio=FULL_MARGIN_BUFFER_RATIO,
|
||||||
price_refresh_seconds=PRICE_REFRESH_SECONDS,
|
price_refresh_seconds=PRICE_REFRESH_SECONDS,
|
||||||
active_count=active_count,
|
active_count=active_count,
|
||||||
@@ -8020,7 +8021,7 @@ def manual_transfer():
|
|||||||
flash(f"手动划转成功:{amount}U {from_account}->{to_account}")
|
flash(f"手动划转成功:{amount}U {from_account}->{to_account}")
|
||||||
else:
|
else:
|
||||||
flash(f"手动划转失败:{msg}")
|
flash(f"手动划转失败:{msg}")
|
||||||
return redirect("/")
|
return redirect(request.referrer or "/trade")
|
||||||
|
|
||||||
|
|
||||||
def _journal_ai_chart_builder(row):
|
def _journal_ai_chart_builder(row):
|
||||||
|
|||||||
@@ -365,6 +365,7 @@
|
|||||||
<div class="stat-item"><div class="label">当日资金(交易账户)</div><div class="value" id="current-capital">{{ money_fmt(current_capital) }}U</div></div>
|
<div class="stat-item"><div class="label">当日资金(交易账户)</div><div class="value" id="current-capital">{{ money_fmt(current_capital) }}U</div></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="rule-tip">实时价格更新时间:<span id="price-last-updated">--</span>(北京时间 UTC+8)</div>
|
<div class="rule-tip">实时价格更新时间:<span id="price-last-updated">--</span>(北京时间 UTC+8)</div>
|
||||||
|
{% include 'gate_transfer_block.html' %}
|
||||||
|
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
{% if page == 'trade' %}
|
{% if page == 'trade' %}
|
||||||
@@ -392,23 +393,6 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|移动保本:下单可勾选关闭;开启时 {{ breakeven_rr_trigger }}R 触发(每 1R 阶梯上移),偏移 {{ breakeven_offset_pct }}%
|
|移动保本:下单可勾选关闭;开启时 {{ breakeven_rr_trigger }}R 触发(每 1R 阶梯上移),偏移 {{ breakeven_offset_pct }}%
|
||||||
</div>
|
</div>
|
||||||
<div class="rule-tip">
|
|
||||||
划转:自动划转 {{ '开启' if auto_transfer_enabled else '关闭' }}(每天<strong>北京时间 {{ auto_transfer_bj_hour }}:00</strong>起该整点小时内尝试;账簿按 <strong>UTC 自然日</strong>去重;将 {{ auto_transfer_to }} 调整至 {{ money_fmt(auto_transfer_amount) }}U:不足从 {{ auto_transfer_from }} 划入、超出划回 {{ auto_transfer_from }};<strong>持仓中不划转</strong>并微信通知)
|
|
||||||
</div>
|
|
||||||
<form action="/manual_transfer" method="post" class="form-row">
|
|
||||||
<input name="amount" type="number" min="0.01" step="0.01" placeholder="手动划转金额U" required>
|
|
||||||
<select name="from_account">
|
|
||||||
<option value="funding" {% if auto_transfer_from == 'funding' %}selected{% endif %}>from: funding</option>
|
|
||||||
<option value="swap" {% if auto_transfer_from == 'swap' %}selected{% endif %}>from: swap</option>
|
|
||||||
<option value="spot" {% if auto_transfer_from == 'spot' %}selected{% endif %}>from: spot</option>
|
|
||||||
</select>
|
|
||||||
<select name="to_account">
|
|
||||||
<option value="swap" {% if auto_transfer_to == 'swap' %}selected{% endif %}>to: swap</option>
|
|
||||||
<option value="funding" {% if auto_transfer_to == 'funding' %}selected{% endif %}>to: funding</option>
|
|
||||||
<option value="spot" {% if auto_transfer_to == 'spot' %}selected{% endif %}>to: spot</option>
|
|
||||||
</select>
|
|
||||||
<button type="submit">手动划转</button>
|
|
||||||
</form>
|
|
||||||
<form id="add-order-form" action="/add_order" method="post" class="form-row">
|
<form id="add-order-form" action="/add_order" method="post" class="form-row">
|
||||||
<input id="order-symbol" name="symbol" placeholder="BTC 或 BTC/USDT" required>
|
<input id="order-symbol" name="symbol" placeholder="BTC 或 BTC/USDT" required>
|
||||||
<select id="order-direction" name="direction" required>
|
<select id="order-direction" name="direction" required>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
| 余额 **低于** `AUTO_TRANSFER_AMOUNT` | 从 `AUTO_TRANSFER_FROM`(默认 funding)划入差额 |
|
| 余额 **低于** `AUTO_TRANSFER_AMOUNT` | 从 `AUTO_TRANSFER_FROM`(默认 funding)划入差额 |
|
||||||
| 余额 **高于** `AUTO_TRANSFER_AMOUNT` | 将多余划回 `AUTO_TRANSFER_FROM` |
|
| 余额 **高于** `AUTO_TRANSFER_AMOUNT` | 将多余划回 `AUTO_TRANSFER_FROM` |
|
||||||
| 与目标相差 < 0.01U | 跳过,不写划转 |
|
| 与目标相差 < 0.01U | 跳过,不写划转 |
|
||||||
| 存在 **active** 持仓(`order_monitors`) | **不划转**,写账簿 `skipped`,并**企业微信**说明「持仓中,本次资金无划转」 |
|
| 存在 **active** 持仓(`order_monitors`,或 Gate 趋势回调已开仓计划) | **不划转**,写账簿 `skipped`,并**企业微信**说明「持仓中,本次资金无划转」 |
|
||||||
|
|
||||||
## 配置示例(目标 50U)
|
## 配置示例(目标 50U)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
"""Gate.io 资金划转(crypto_monitor_gate / crypto_monitor_gate_bot 共用)。"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any, Callable, Optional
|
||||||
|
|
||||||
|
INVALID_KEY_HINT = (
|
||||||
|
"。常见原因:① GATE_API_SECRET 错误或 .env 里多了空格/换行;② IP 白名单未包含当前服务器出口 IP;"
|
||||||
|
"③ Gate「交易账户」类 API Key 若不支持钱包接口则无法走账户内划转 POST /wallet/transfers(需在官网确认该 Key 类型是否开放划转);"
|
||||||
|
"④ Key 已重置或权限变更。你已勾选现货/统一账户仍报错时,优先核对 Secret 与白名单。"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def execute_transfer_usdt(
|
||||||
|
exchange,
|
||||||
|
amount: float,
|
||||||
|
from_account: str,
|
||||||
|
to_account: str,
|
||||||
|
*,
|
||||||
|
transfer_ccy: str = "USDT",
|
||||||
|
ensure_live_ready: Callable[[], tuple[bool, str]],
|
||||||
|
ensure_markets_loaded: Optional[Callable[[], None]] = None,
|
||||||
|
) -> tuple[bool, str, Any]:
|
||||||
|
if amount <= 0:
|
||||||
|
return False, "划转金额必须大于0", None
|
||||||
|
ok_live, reason = ensure_live_ready()
|
||||||
|
if not ok_live:
|
||||||
|
return False, reason, None
|
||||||
|
if ensure_markets_loaded:
|
||||||
|
try:
|
||||||
|
ensure_markets_loaded()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
resp = exchange.transfer(transfer_ccy, float(amount), from_account, to_account)
|
||||||
|
return True, "划转成功", resp
|
||||||
|
except Exception as e:
|
||||||
|
msg = str(e)
|
||||||
|
if "INVALID_KEY" in msg or "Invalid key" in msg:
|
||||||
|
msg += INVALID_KEY_HINT
|
||||||
|
return False, msg, None
|
||||||
|
|
||||||
|
|
||||||
|
def count_auto_transfer_blockers(conn, *, count_order_monitors: Callable[[Any], int]) -> int:
|
||||||
|
"""自动划转持仓守卫:order_monitors active + 趋势回调已开仓计划。"""
|
||||||
|
n = int(count_order_monitors(conn) or 0)
|
||||||
|
if n > 0:
|
||||||
|
return n
|
||||||
|
try:
|
||||||
|
row = conn.execute(
|
||||||
|
"SELECT COUNT(*) FROM trend_pullback_plans "
|
||||||
|
"WHERE status='active' AND COALESCE(first_order_done, 0) != 0"
|
||||||
|
).fetchone()
|
||||||
|
return int(row[0] or 0) if row else 0
|
||||||
|
except Exception:
|
||||||
|
return n
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<div class="rule-tip gate-transfer-tip">
|
||||||
|
划转:自动划转 {{ '开启' if auto_transfer_enabled else '关闭' }}(每天<strong>北京时间 {{ auto_transfer_bj_hour }}:00</strong>起该整点小时内尝试;账簿按 <strong>UTC 自然日</strong>去重;将 {{ auto_transfer_to }} 调整至 {{ transfer_amount_fmt }}U:不足从 {{ auto_transfer_from }} 划入、超出划回 {{ auto_transfer_from }};<strong>持仓中不划转</strong>并微信通知)
|
||||||
|
</div>
|
||||||
|
<form action="/manual_transfer" method="post" class="form-row gate-transfer-form">
|
||||||
|
<input name="amount" type="number" min="0.01" step="0.01" placeholder="手动划转金额U" required>
|
||||||
|
<select name="from_account">
|
||||||
|
<option value="funding" {% if auto_transfer_from == 'funding' %}selected{% endif %}>from: funding</option>
|
||||||
|
<option value="swap" {% if auto_transfer_from == 'swap' %}selected{% endif %}>from: swap</option>
|
||||||
|
<option value="spot" {% if auto_transfer_from == 'spot' %}selected{% endif %}>from: spot</option>
|
||||||
|
</select>
|
||||||
|
<select name="to_account">
|
||||||
|
<option value="swap" {% if auto_transfer_to == 'swap' %}selected{% endif %}>to: swap</option>
|
||||||
|
<option value="funding" {% if auto_transfer_to == 'funding' %}selected{% endif %}>to: funding</option>
|
||||||
|
<option value="spot" {% if auto_transfer_to == 'spot' %}selected{% endif %}>to: spot</option>
|
||||||
|
</select>
|
||||||
|
<button type="submit">手动划转</button>
|
||||||
|
</form>
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
"""gate_transfer_lib 单元测试。"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import sqlite3
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from gate_transfer_lib import count_auto_transfer_blockers
|
||||||
|
|
||||||
|
|
||||||
|
class GateTransferLibTest(unittest.TestCase):
|
||||||
|
def test_counts_order_monitors_first(self):
|
||||||
|
conn = sqlite3.connect(":memory:")
|
||||||
|
conn.execute("CREATE TABLE order_monitors (status TEXT)")
|
||||||
|
conn.execute("CREATE TABLE trend_pullback_plans (status TEXT, first_order_done INTEGER)")
|
||||||
|
conn.execute("INSERT INTO order_monitors VALUES ('active')")
|
||||||
|
conn.execute("INSERT INTO trend_pullback_plans VALUES ('active', 1)")
|
||||||
|
conn.commit()
|
||||||
|
n = count_auto_transfer_blockers(conn, count_order_monitors=lambda c: 1)
|
||||||
|
self.assertEqual(n, 1)
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
def test_counts_trend_plan_when_no_order_monitors(self):
|
||||||
|
conn = sqlite3.connect(":memory:")
|
||||||
|
conn.execute("CREATE TABLE order_monitors (status TEXT)")
|
||||||
|
conn.execute("CREATE TABLE trend_pullback_plans (status TEXT, first_order_done INTEGER)")
|
||||||
|
conn.execute("INSERT INTO trend_pullback_plans VALUES ('active', 1)")
|
||||||
|
conn.commit()
|
||||||
|
n = count_auto_transfer_blockers(conn, count_order_monitors=lambda c: 0)
|
||||||
|
self.assertEqual(n, 1)
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
def test_ignores_trend_plan_without_first_order(self):
|
||||||
|
conn = sqlite3.connect(":memory:")
|
||||||
|
conn.execute("CREATE TABLE order_monitors (status TEXT)")
|
||||||
|
conn.execute("CREATE TABLE trend_pullback_plans (status TEXT, first_order_done INTEGER)")
|
||||||
|
conn.execute("INSERT INTO trend_pullback_plans VALUES ('active', 0)")
|
||||||
|
conn.commit()
|
||||||
|
n = count_auto_transfer_blockers(conn, count_order_monitors=lambda c: 0)
|
||||||
|
self.assertEqual(n, 0)
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
Reference in New Issue
Block a user