update 03-29 01:36

This commit is contained in:
2026-03-29 01:36:30 +09:00
parent 710949f034
commit dbf2c2bb1f
12 changed files with 399 additions and 44 deletions

View File

@@ -0,0 +1,15 @@
{"t":0,"agent":"system","event":"keyword_detected","keyword":"autopilot"}
{"t":0,"agent":"system","event":"mode_change","mode_from":"none","mode_to":"autopilot"}
{"t":0,"agent":"system","event":"skill_invoked","skill_name":"oh-my-claudecode:autopilot"}
{"t":0,"agent":"a2823c2","agent_type":"Explore","event":"agent_start","parent_mode":"none"}
{"t":0,"agent":"a5a8656","agent_type":"general-purpose","event":"agent_start","parent_mode":"none"}
{"t":0,"agent":"a562974","agent_type":"general-purpose","event":"agent_start","parent_mode":"none"}
{"t":0,"agent":"a2823c2","agent_type":"Explore","event":"agent_stop","success":true,"duration_ms":87491}
{"t":0,"agent":"a5a8656","agent_type":"general-purpose","event":"agent_stop","success":true,"duration_ms":68289}
{"t":0,"agent":"a562974","agent_type":"general-purpose","event":"agent_stop","success":true,"duration_ms":217576}
{"t":0,"agent":"a4c4346","agent_type":"executor","event":"agent_start","parent_mode":"none"}
{"t":0,"agent":"a67d07c","agent_type":"executor","event":"agent_start","parent_mode":"none"}
{"t":0,"agent":"ac65b63","agent_type":"executor","event":"agent_start","parent_mode":"none"}
{"t":0,"agent":"a4c4346","agent_type":"executor","event":"agent_stop","success":true,"duration_ms":46095}
{"t":0,"agent":"ac65b63","agent_type":"executor","event":"agent_stop","success":true,"duration_ms":38984}
{"t":0,"agent":"a67d07c","agent_type":"executor","event":"agent_stop","success":true,"duration_ms":83609}

View File

@@ -1 +1 @@
{"session_id":"a9e3d3e8-6b91-4c7a-9c52-a928a3b1fb98","transcript_path":"C:\\Users\\User\\.claude\\projects\\D--PRJ-poly-company-dtr2-poly\\a9e3d3e8-6b91-4c7a-9c52-a928a3b1fb98.jsonl","cwd":"D:\\PRJ\\poly_company\\dtr2_poly\\polymarket-arb-bot","model":{"id":"claude-opus-4-6[1m]","display_name":"Opus 4.6 (1M context)"},"workspace":{"current_dir":"D:\\PRJ\\poly_company\\dtr2_poly\\polymarket-arb-bot","project_dir":"D:\\PRJ\\poly_company\\dtr2_poly","added_dirs":["D:/PRJ/poly_company/dtr2_poly"]},"version":"2.1.78","output_style":{"name":"default"},"cost":{"total_cost_usd":7.426863299999999,"total_duration_ms":1802055,"total_api_duration_ms":717171,"total_lines_added":126,"total_lines_removed":36},"context_window":{"total_input_tokens":166,"total_output_tokens":44526,"context_window_size":1000000,"current_usage":{"input_tokens":3,"output_tokens":125,"cache_creation_input_tokens":104255,"cache_read_input_tokens":24263},"used_percentage":13,"remaining_percentage":87},"exceeds_200k_tokens":false}
{"session_id":"a9e3d3e8-6b91-4c7a-9c52-a928a3b1fb98","transcript_path":"C:\\Users\\User\\.claude\\projects\\D--PRJ-poly-company-dtr2-poly\\a9e3d3e8-6b91-4c7a-9c52-a928a3b1fb98.jsonl","cwd":"D:\\PRJ\\poly_company\\dtr2_poly\\polymarket-arb-bot","model":{"id":"claude-opus-4-6[1m]","display_name":"Opus 4.6 (1M context)"},"workspace":{"current_dir":"D:\\PRJ\\poly_company\\dtr2_poly\\polymarket-arb-bot","project_dir":"D:\\PRJ\\poly_company\\dtr2_poly","added_dirs":["D:/PRJ/poly_company/dtr2_poly"]},"version":"2.1.78","output_style":{"name":"default"},"cost":{"total_cost_usd":17.360554950000008,"total_duration_ms":52058270,"total_api_duration_ms":1692584,"total_lines_added":178,"total_lines_removed":76},"context_window":{"total_input_tokens":26490,"total_output_tokens":97675,"context_window_size":1000000,"current_usage":{"input_tokens":3,"output_tokens":522,"cache_creation_input_tokens":886,"cache_read_input_tokens":200200},"used_percentage":20,"remaining_percentage":80},"exceeds_200k_tokens":true}

View File

@@ -1,3 +1,3 @@
{
"lastSentAt": "2026-03-28T02:24:21.283Z"
"lastSentAt": "2026-03-28T16:00:45.742Z"
}

View File

@@ -1,7 +1,7 @@
{
"tool_name": "Bash",
"tool_input_preview": "{\"command\":\".venv/Scripts/python.exe -c \\\"\\nimport sqlite3, tempfile, os\\nfrom pathlib import Path\\nimport pandas as pd\\nprint('=== Test 5: Dashboard query_db ===')\\n\\ndef query_db(db_path, sql):\\n ...",
"error": "Exit code 1\nTraceback (most recent call last):\r\n File \u001b[35m\"<string>\"\u001b[0m, line \u001b[35m29\u001b[0m, in \u001b[35m<module>\u001b[0m\r\n \u001b[31mos.unlink\u001b[0m\u001b[1;31m(tmp_path)\u001b[0m\r\n \u001b[31m~~~~~~~~~\u001b[0m\u001b[1;31m^^^^^^^^^^\u001b[0m\r\n\u001b[1;35mPermissionError\u001b[0m: \u001b[35m[WinError 32] <20>ٸ<EFBFBD> <20><><EFBFBD>μ<EFBFBD><CEBC><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD>̱<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>μ<EFBFBD><CEBC><EFBFBD><EFBFBD><EFBFBD> <20>׼<EFBFBD><D7BC><EFBFBD> <20><> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>: 'C:\\\\Users\\\\User\\\\AppData\\\\Local\\\\Temp\\\\tmpe_93w69z.db'\u001b[0m\r\n=== Test 5: Dashboard query_db ===\r\n Normal query OK\r\n Exception handling OK\r\n Nonexistent DB OK",
"timestamp": "2026-03-28T02:23:24.339Z",
"retry_count": 1
"tool_input_preview": "{\"command\":\"ssh kakao@100.125.85.86 \\\"ps aux | grep streamlit | grep -v grep; echo '---'; ss -tlnp | grep 8503 2>/dev/null\\\"\",\"timeout\":10000,\"description\":\"Check current dashboard status\"}",
"error": "Exit code 1\n---",
"timestamp": "2026-03-28T16:00:08.546Z",
"retry_count": 2
}

View File

@@ -0,0 +1,135 @@
{
"updatedAt": "2026-03-28T16:32:51.357Z",
"missions": [
{
"id": "session:a9e3d3e8-6b91-4c7a-9c52-a928a3b1fb98:none",
"source": "session",
"name": "none",
"objective": "Session mission",
"createdAt": "2026-03-28T16:26:16.914Z",
"updatedAt": "2026-03-28T16:32:51.357Z",
"status": "done",
"workerCount": 6,
"taskCounts": {
"total": 6,
"pending": 0,
"blocked": 0,
"inProgress": 0,
"completed": 6,
"failed": 0
},
"agents": [
{
"name": "Explore:a2823c2",
"role": "Explore",
"ownership": "a2823c25be1f8b5ce",
"status": "done",
"currentStep": null,
"latestUpdate": "completed",
"completedSummary": null,
"updatedAt": "2026-03-28T16:27:44.405Z"
},
{
"name": "general-purpose:a5a8656",
"role": "general-purpose",
"ownership": "a5a8656ed974efc3b",
"status": "done",
"currentStep": null,
"latestUpdate": "completed",
"completedSummary": null,
"updatedAt": "2026-03-28T16:27:44.789Z"
},
{
"name": "general-purpose:a562974",
"role": "general-purpose",
"ownership": "a562974c694d29e8f",
"status": "done",
"currentStep": null,
"latestUpdate": "completed",
"completedSummary": null,
"updatedAt": "2026-03-28T16:30:22.237Z"
},
{
"name": "executor:a4c4346",
"role": "executor",
"ownership": "a4c4346f86c16a176",
"status": "done",
"currentStep": null,
"latestUpdate": "completed",
"completedSummary": null,
"updatedAt": "2026-03-28T16:31:57.664Z"
},
{
"name": "executor:a67d07c",
"role": "executor",
"ownership": "a67d07c795eb3ca16",
"status": "done",
"currentStep": null,
"latestUpdate": "completed",
"completedSummary": null,
"updatedAt": "2026-03-28T16:32:51.357Z"
},
{
"name": "executor:ac65b63",
"role": "executor",
"ownership": "ac65b630adcae3e6c",
"status": "done",
"currentStep": null,
"latestUpdate": "completed",
"completedSummary": null,
"updatedAt": "2026-03-28T16:32:15.560Z"
}
],
"timeline": [
{
"id": "session-start:a4c4346f86c16a176:2026-03-28T16:31:11.569Z",
"at": "2026-03-28T16:31:11.569Z",
"kind": "update",
"agent": "executor:a4c4346",
"detail": "started executor:a4c4346",
"sourceKey": "session-start:a4c4346f86c16a176"
},
{
"id": "session-start:a67d07c795eb3ca16:2026-03-28T16:31:27.748Z",
"at": "2026-03-28T16:31:27.748Z",
"kind": "update",
"agent": "executor:a67d07c",
"detail": "started executor:a67d07c",
"sourceKey": "session-start:a67d07c795eb3ca16"
},
{
"id": "session-start:ac65b630adcae3e6c:2026-03-28T16:31:36.576Z",
"at": "2026-03-28T16:31:36.576Z",
"kind": "update",
"agent": "executor:ac65b63",
"detail": "started executor:ac65b63",
"sourceKey": "session-start:ac65b630adcae3e6c"
},
{
"id": "session-stop:a4c4346f86c16a176:2026-03-28T16:31:57.664Z",
"at": "2026-03-28T16:31:57.664Z",
"kind": "completion",
"agent": "executor:a4c4346",
"detail": "completed",
"sourceKey": "session-stop:a4c4346f86c16a176"
},
{
"id": "session-stop:ac65b630adcae3e6c:2026-03-28T16:32:15.560Z",
"at": "2026-03-28T16:32:15.560Z",
"kind": "completion",
"agent": "executor:ac65b63",
"detail": "completed",
"sourceKey": "session-stop:ac65b630adcae3e6c"
},
{
"id": "session-stop:a67d07c795eb3ca16:2026-03-28T16:32:51.357Z",
"at": "2026-03-28T16:32:51.357Z",
"kind": "completion",
"agent": "executor:a67d07c",
"detail": "completed",
"sourceKey": "session-stop:a67d07c795eb3ca16"
}
]
}
]
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,62 @@
{
"agents": [
{
"agent_id": "a2823c25be1f8b5ce",
"agent_type": "Explore",
"started_at": "2026-03-28T16:26:16.914Z",
"parent_mode": "none",
"status": "completed",
"completed_at": "2026-03-28T16:27:44.405Z",
"duration_ms": 87491
},
{
"agent_id": "a5a8656ed974efc3b",
"agent_type": "general-purpose",
"started_at": "2026-03-28T16:26:36.500Z",
"parent_mode": "none",
"status": "completed",
"completed_at": "2026-03-28T16:27:44.789Z",
"duration_ms": 68289
},
{
"agent_id": "a562974c694d29e8f",
"agent_type": "general-purpose",
"started_at": "2026-03-28T16:26:44.661Z",
"parent_mode": "none",
"status": "completed",
"completed_at": "2026-03-28T16:30:22.237Z",
"duration_ms": 217576
},
{
"agent_id": "a4c4346f86c16a176",
"agent_type": "oh-my-claudecode:executor",
"started_at": "2026-03-28T16:31:11.569Z",
"parent_mode": "none",
"status": "completed",
"completed_at": "2026-03-28T16:31:57.664Z",
"duration_ms": 46095
},
{
"agent_id": "a67d07c795eb3ca16",
"agent_type": "oh-my-claudecode:executor",
"started_at": "2026-03-28T16:31:27.748Z",
"parent_mode": "none",
"status": "completed",
"completed_at": "2026-03-28T16:32:51.357Z",
"duration_ms": 83609
},
{
"agent_id": "ac65b630adcae3e6c",
"agent_type": "oh-my-claudecode:executor",
"started_at": "2026-03-28T16:31:36.576Z",
"parent_mode": "none",
"status": "completed",
"completed_at": "2026-03-28T16:32:15.560Z",
"duration_ms": 38984
}
],
"total_spawned": 6,
"total_completed": 6,
"total_failed": 0,
"last_updated": "2026-03-28T16:32:51.471Z"
}

View File

@@ -194,15 +194,15 @@ class Backtester:
# Simulate Polymarket price (lagging behind reality)
if abs(change_pct) > 0.05:
lag_factor = 0.3 # Polymarket adjusts at 30% of actual
lag_factor = 0.8 # Polymarket adjusts slowly behind CEX
if change_pct > 0:
sim_poly_up = 0.50 + abs(change_pct) * lag_factor * 10
sim_poly_up = min(sim_poly_up, 0.75)
sim_poly_down = max(0.25, 1.0 - sim_poly_up - rng.uniform(0, 0.04))
sim_poly_up = 0.50 + abs(change_pct) * lag_factor
sim_poly_up = min(sim_poly_up, 0.70)
sim_poly_down = max(0.30, 1.0 - sim_poly_up - rng.uniform(0, 0.04))
else:
sim_poly_down = 0.50 + abs(change_pct) * lag_factor * 10
sim_poly_down = min(sim_poly_down, 0.75)
sim_poly_up = max(0.25, 1.0 - sim_poly_down - rng.uniform(0, 0.04))
sim_poly_down = 0.50 + abs(change_pct) * lag_factor
sim_poly_down = min(sim_poly_down, 0.70)
sim_poly_up = max(0.30, 1.0 - sim_poly_down - rng.uniform(0, 0.04))
else:
sim_poly_up = 0.50 + rng.uniform(-0.02, 0.02)
sim_poly_down = 0.50 + rng.uniform(-0.02, 0.02)
@@ -370,17 +370,17 @@ class Backtester:
change_pct = (mid_price - start_price) / start_price * 100
# Simulate Polymarket prices based on actual market behavior
# More conservative lag simulation for historical
# Conservative lag simulation for historical data
if abs(change_pct) > 0.05:
lag = 0.25 # Market adjusts at ~25% speed
lag = 0.6 # Market adjusts at ~60% speed
if change_pct > 0:
poly_up = 0.50 + abs(change_pct) * lag * 8
poly_up = min(poly_up, 0.72)
poly_down = max(0.28, 1.0 - poly_up - 0.02)
poly_up = 0.50 + abs(change_pct) * lag
poly_up = min(poly_up, 0.68)
poly_down = max(0.32, 1.0 - poly_up - 0.02)
else:
poly_down = 0.50 + abs(change_pct) * lag * 8
poly_down = min(poly_down, 0.72)
poly_up = max(0.28, 1.0 - poly_down - 0.02)
poly_down = 0.50 + abs(change_pct) * lag
poly_down = min(poly_down, 0.68)
poly_up = max(0.32, 1.0 - poly_down - 0.02)
else:
poly_up = 0.50
poly_down = 0.50

122
backtest_results.json Normal file
View File

@@ -0,0 +1,122 @@
[
{
"mode": "synthetic",
"asset": "BTC",
"timeframe": "5M",
"total_windows": 1000,
"total_trades": 204,
"wins": 145,
"losses": 59,
"win_rate": 71.08,
"total_pnl": 4756.79,
"avg_pnl": 23.32,
"total_fees": 168.6,
"total_volume": 20340.62,
"profit_factor": 1.81,
"sharpe_ratio": 4.24,
"max_drawdown": 715.02,
"best_trade": 75.92,
"worst_trade": -99.99,
"max_consecutive_losses": 4
},
{
"mode": "synthetic",
"asset": "BTC",
"timeframe": "15M",
"total_windows": 1000,
"total_trades": 204,
"wins": 145,
"losses": 59,
"win_rate": 71.08,
"total_pnl": 4601.16,
"avg_pnl": 22.55,
"total_fees": 324.22,
"total_volume": 20340.62,
"profit_factor": 1.78,
"sharpe_ratio": 4.13,
"max_drawdown": 727.9,
"best_trade": 74.81,
"worst_trade": -99.99,
"max_consecutive_losses": 4
},
{
"mode": "synthetic",
"asset": "ETH",
"timeframe": "5M",
"total_windows": 1000,
"total_trades": 157,
"wins": 100,
"losses": 57,
"win_rate": 63.69,
"total_pnl": 1671.74,
"avg_pnl": 10.65,
"total_fees": 116.56,
"total_volume": 15652.7,
"profit_factor": 1.29,
"sharpe_ratio": 1.6,
"max_drawdown": 532.2,
"best_trade": 75.94,
"worst_trade": -99.99,
"max_consecutive_losses": 4
},
{
"mode": "synthetic",
"asset": "ETH",
"timeframe": "15M",
"total_windows": 1000,
"total_trades": 157,
"wins": 100,
"losses": 57,
"win_rate": 63.69,
"total_pnl": 1564.15,
"avg_pnl": 9.96,
"total_fees": 224.15,
"total_volume": 15652.7,
"profit_factor": 1.28,
"sharpe_ratio": 1.51,
"max_drawdown": 537.54,
"best_trade": 74.83,
"worst_trade": -99.99,
"max_consecutive_losses": 4
},
{
"mode": "synthetic",
"asset": "SOL",
"timeframe": "5M",
"total_windows": 1000,
"total_trades": 115,
"wins": 70,
"losses": 45,
"win_rate": 60.87,
"total_pnl": 653.02,
"avg_pnl": 5.68,
"total_fees": 81.47,
"total_volume": 11464.51,
"profit_factor": 1.15,
"sharpe_ratio": 0.72,
"max_drawdown": 581.01,
"best_trade": 75.94,
"worst_trade": -100.0,
"max_consecutive_losses": 4
},
{
"mode": "synthetic",
"asset": "SOL",
"timeframe": "15M",
"total_windows": 1000,
"total_trades": 115,
"wins": 70,
"losses": 45,
"win_rate": 60.87,
"total_pnl": 577.82,
"avg_pnl": 5.02,
"total_fees": 156.67,
"total_volume": 11464.51,
"profit_factor": 1.13,
"sharpe_ratio": 0.64,
"max_drawdown": 595.86,
"best_trade": 74.83,
"worst_trade": -100.0,
"max_consecutive_losses": 4
}
]

View File

@@ -7,10 +7,10 @@ starting_balance = 500.0
[strategy.temporal_arb]
enabled = true
min_price_move_pct = 0.03 # 낮춤: 0.03%만 움직여도 평가 (원래 0.15%)
max_poly_entry_price = 0.65
min_edge = 0.05 # 낮춤: 5% 엣지에서 진입 (원래 20%)
exit_before_resolution_sec = 5
min_price_move_pct = 0.08 # raised from 0.03 — filters low-quality signals
max_poly_entry_price = 0.58 # lowered from 0.65 — lower entry = lower dynamic fees, higher edge
min_edge = 0.03 # lowered from 0.05 — accurate dynamic fee model allows tighter threshold
exit_before_resolution_sec = 8 # raised from 5 — more buffer for execution near resolution
[strategy.sum_to_one]
enabled = true
@@ -21,15 +21,17 @@ enabled = false
spread_target = 0.04
[risk]
max_position_per_market_usd = 5000
max_total_exposure_usd = 20000
max_daily_loss_usd = 2000
kelly_fraction_cap = 0.25
max_concurrent_positions = 6
max_position_per_market_usd = 100 # lowered from 5000 — realistic for $500 account
max_total_exposure_usd = 300 # lowered from 20000 — ~60% of starting balance
max_daily_loss_usd = 50 # lowered from 2000 — 10% of starting balance
kelly_fraction_cap = 0.20 # lowered from 0.25 — conservative for estimation uncertainty
max_concurrent_positions = 4 # lowered from 6 — more focused capital allocation
[fees]
taker_fee_5m = 0.0156
taker_fee_15m = 0.03
fee_rate = 0.045 # dynamic fee base rate
fee_exponent = 1 # linear fee scaling
[exchange.binance]
ws_url = "wss://stream.binance.com:9443/stream"

View File

@@ -65,6 +65,8 @@ class RiskConfig:
class FeesConfig:
taker_fee_5m: float = 0.0156
taker_fee_15m: float = 0.03
fee_rate: float = 0.045
fee_exponent: int = 1
def fee_for_timeframe(self, timeframe: str) -> float:
"""Return the taker fee for a given timeframe string (e.g. '5M')."""
@@ -76,6 +78,13 @@ class FeesConfig:
raise ValueError(f"Unknown timeframe '{timeframe}'; expected one of {list(mapping)}")
return mapping[timeframe]
def dynamic_fee(self, price: float, shares: int = 1) -> float:
"""Compute Polymarket's dynamic taker fee for a given price and share count.
Formula: shares * price * fee_rate * (price * (1 - price)) ** fee_exponent
"""
return shares * price * self.fee_rate * (price * (1.0 - price)) ** self.fee_exponent
@dataclass(frozen=True)
class BinanceConfig:

View File

@@ -109,7 +109,8 @@ class TemporalArbStrategy:
)
# 6. Edge calculation (after fees)
taker_fee = self.fees.fee_for_timeframe(timeframe)
# Use dynamic fee formula: fee per share / price = effective fee rate
taker_fee = self.fees.dynamic_fee(poly_price, 1) / poly_price
edge = estimated_prob - poly_price - taker_fee
if edge < self.arb.min_edge:
@@ -118,7 +119,7 @@ class TemporalArbStrategy:
# 7. Position sizing
asset = Asset(symbol)
size = self.calculate_kelly_size(
edge=edge,
estimated_prob=estimated_prob,
price=poly_price,
balance=self.balance,
max_size=self.risk.max_position_per_market_usd,
@@ -181,25 +182,25 @@ class TemporalArbStrategy:
"""
abs_change = abs(price_change_pct)
# Factor 1: Base probability from price magnitude
# 0.15% → ~70%, 0.3% → ~82%, 0.5% → ~90%, 1.0%+ → ~95%
base_prob = 0.55 + abs_change * 1.0 # 1.0 scaling factor
base_prob = min(base_prob, 0.95)
# Factor 1: Sigmoid base probability from price magnitude
# k=18.0 steepness, inflection at 0.10% change
# 0.03% → ~0.53, 0.10% → ~0.65, 0.20% → ~0.80, 0.50% → ~0.93
k = 18.0
threshold = 0.10
sigmoid_val = 1.0 / (1.0 + math.exp(-k * (abs_change - threshold)))
base_prob = 0.52 + sigmoid_val * 0.43 # maps [0,1] → [0.52, 0.95]
# Factor 2: Time decay — more time elapsed = more confirmation
# If 80% of window has passed and price is still in this direction,
# the probability of reversal is lower
elapsed_fraction = max(0, 1.0 - (time_remaining / total_window_sec))
# Sigmoid-like boost: ramps up in the last 40% of the window
elapsed_fraction = 1.0 - (time_remaining / total_window_sec) if total_window_sec > 0 else 0.5
# Ramps up in the last 40% of the window
time_factor = 1.0 + 0.08 * max(0, elapsed_fraction - 0.6) / 0.4
time_factor = min(time_factor, 1.08)
# Factor 3: Volatility / momentum strength
# Very large moves (>0.5%) get extra confidence
if abs_change > 0.5:
vol_boost = min(0.05, (abs_change - 0.5) * 0.1)
else:
vol_boost = 0.0
vol_boost = min(0.05, (abs_change - 0.5) * 0.1) if abs_change > 0.5 else 0.0
final_prob = base_prob * time_factor + vol_boost
return min(0.95, max(0.50, final_prob))
@@ -210,7 +211,7 @@ class TemporalArbStrategy:
def calculate_kelly_size(
self,
edge: float,
estimated_prob: float,
price: float,
balance: float,
max_size: float,
@@ -224,7 +225,7 @@ class TemporalArbStrategy:
return 0
b = (1.0 / price) - 1.0 # Payout odds
p = edge + price # estimated_prob (edge = prob - price - fee)
p = estimated_prob
q = 1.0 - p
if b <= 0: