feat: Describe all tags explicitly
This commit is contained in:
@@ -125,7 +125,7 @@ def __run_backtest_bg(btconfig: Config):
|
|||||||
ApiBG.bgtask_running = False
|
ApiBG.bgtask_running = False
|
||||||
|
|
||||||
|
|
||||||
@router.post("/backtest", response_model=BacktestResponse, tags=["backtest"])
|
@router.post("/backtest", response_model=BacktestResponse)
|
||||||
async def api_start_backtest(
|
async def api_start_backtest(
|
||||||
bt_settings: BacktestRequest, background_tasks: BackgroundTasks, config=Depends(get_config)
|
bt_settings: BacktestRequest, background_tasks: BackgroundTasks, config=Depends(get_config)
|
||||||
):
|
):
|
||||||
@@ -168,7 +168,7 @@ async def api_start_backtest(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@router.get("/backtest", response_model=BacktestResponse, tags=["backtest"])
|
@router.get("/backtest", response_model=BacktestResponse)
|
||||||
def api_get_backtest():
|
def api_get_backtest():
|
||||||
"""
|
"""
|
||||||
Get backtesting result.
|
Get backtesting result.
|
||||||
@@ -215,7 +215,7 @@ def api_get_backtest():
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/backtest", response_model=BacktestResponse, tags=["backtest"])
|
@router.delete("/backtest", response_model=BacktestResponse)
|
||||||
def api_delete_backtest():
|
def api_delete_backtest():
|
||||||
"""Reset backtesting"""
|
"""Reset backtesting"""
|
||||||
if ApiBG.bgtask_running:
|
if ApiBG.bgtask_running:
|
||||||
@@ -242,7 +242,7 @@ def api_delete_backtest():
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@router.get("/backtest/abort", response_model=BacktestResponse, tags=["backtest"])
|
@router.get("/backtest/abort", response_model=BacktestResponse)
|
||||||
def api_backtest_abort():
|
def api_backtest_abort():
|
||||||
if not ApiBG.bgtask_running:
|
if not ApiBG.bgtask_running:
|
||||||
return {
|
return {
|
||||||
@@ -262,13 +262,13 @@ def api_backtest_abort():
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@router.get("/backtest/history", response_model=list[BacktestHistoryEntry], tags=["backtest"])
|
@router.get("/backtest/history", response_model=list[BacktestHistoryEntry])
|
||||||
def api_backtest_history(config=Depends(get_config)):
|
def api_backtest_history(config=Depends(get_config)):
|
||||||
# Get backtest result history, read from metadata files
|
# Get backtest result history, read from metadata files
|
||||||
return get_backtest_resultlist(config["user_data_dir"] / "backtest_results")
|
return get_backtest_resultlist(config["user_data_dir"] / "backtest_results")
|
||||||
|
|
||||||
|
|
||||||
@router.get("/backtest/history/result", response_model=BacktestResponse, tags=["backtest"])
|
@router.get("/backtest/history/result", response_model=BacktestResponse)
|
||||||
def api_backtest_history_result(filename: str, strategy: str, config=Depends(get_config)):
|
def api_backtest_history_result(filename: str, strategy: str, config=Depends(get_config)):
|
||||||
# Get backtest result history, read from metadata files
|
# Get backtest result history, read from metadata files
|
||||||
bt_results_base: Path = config["user_data_dir"] / "backtest_results"
|
bt_results_base: Path = config["user_data_dir"] / "backtest_results"
|
||||||
@@ -295,9 +295,7 @@ def api_backtest_history_result(filename: str, strategy: str, config=Depends(get
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@router.delete(
|
@router.delete("/backtest/history/{file}", response_model=list[BacktestHistoryEntry])
|
||||||
"/backtest/history/{file}", response_model=list[BacktestHistoryEntry], tags=["backtest"]
|
|
||||||
)
|
|
||||||
def api_delete_backtest_history_entry(file: str, config=Depends(get_config)):
|
def api_delete_backtest_history_entry(file: str, config=Depends(get_config)):
|
||||||
# Get backtest result history, read from metadata files
|
# Get backtest result history, read from metadata files
|
||||||
bt_results_base: Path = config["user_data_dir"] / "backtest_results"
|
bt_results_base: Path = config["user_data_dir"] / "backtest_results"
|
||||||
@@ -313,9 +311,7 @@ def api_delete_backtest_history_entry(file: str, config=Depends(get_config)):
|
|||||||
return get_backtest_resultlist(config["user_data_dir"] / "backtest_results")
|
return get_backtest_resultlist(config["user_data_dir"] / "backtest_results")
|
||||||
|
|
||||||
|
|
||||||
@router.patch(
|
@router.patch("/backtest/history/{file}", response_model=list[BacktestHistoryEntry])
|
||||||
"/backtest/history/{file}", response_model=list[BacktestHistoryEntry], tags=["backtest"]
|
|
||||||
)
|
|
||||||
def api_update_backtest_history_entry(
|
def api_update_backtest_history_entry(
|
||||||
file: str, body: BacktestMetadataUpdate, config=Depends(get_config)
|
file: str, body: BacktestMetadataUpdate, config=Depends(get_config)
|
||||||
):
|
):
|
||||||
@@ -338,9 +334,7 @@ def api_update_backtest_history_entry(
|
|||||||
return get_backtest_result(file_abs)
|
return get_backtest_result(file_abs)
|
||||||
|
|
||||||
|
|
||||||
@router.get(
|
@router.get("/backtest/history/{file}/market_change", response_model=BacktestMarketChange)
|
||||||
"/backtest/history/{file}/market_change", response_model=BacktestMarketChange, tags=["backtest"]
|
|
||||||
)
|
|
||||||
def api_get_backtest_market_change(file: str, config=Depends(get_config)):
|
def api_get_backtest_market_change(file: str, config=Depends(get_config)):
|
||||||
bt_results_base: Path = config["user_data_dir"] / "backtest_results"
|
bt_results_base: Path = config["user_data_dir"] / "backtest_results"
|
||||||
for fn in (
|
for fn in (
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ logger = logging.getLogger(__name__)
|
|||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
@router.get("/pair_history", response_model=PairHistory, tags=["candle data"])
|
@router.get("/pair_history", response_model=PairHistory, tags=["Candle data"])
|
||||||
def pair_history(
|
def pair_history(
|
||||||
pair: str,
|
pair: str,
|
||||||
timeframe: str,
|
timeframe: str,
|
||||||
@@ -43,7 +43,7 @@ def pair_history(
|
|||||||
raise HTTPException(status_code=502, detail=str(e))
|
raise HTTPException(status_code=502, detail=str(e))
|
||||||
|
|
||||||
|
|
||||||
@router.post("/pair_history", response_model=PairHistory, tags=["candle data"])
|
@router.post("/pair_history", response_model=PairHistory, tags=["Candle data"])
|
||||||
def pair_history_filtered(payload: PairHistoryRequest, config=Depends(get_config)):
|
def pair_history_filtered(payload: PairHistoryRequest, config=Depends(get_config)):
|
||||||
# The initial call to this endpoint can be slow, as it may need to initialize
|
# The initial call to this endpoint can be slow, as it may need to initialize
|
||||||
# the exchange class.
|
# the exchange class.
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ logger = logging.getLogger(__name__)
|
|||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
@router.get("/pairlists/available", response_model=PairListsResponse, tags=["pairlists"])
|
@router.get("/pairlists/available", response_model=PairListsResponse)
|
||||||
def list_pairlists(config=Depends(get_config)):
|
def list_pairlists(config=Depends(get_config)):
|
||||||
from freqtrade.resolvers import PairListResolver
|
from freqtrade.resolvers import PairListResolver
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ def __run_pairlist(job_id: str, config_loc: Config):
|
|||||||
ApiBG.pairlist_running = False
|
ApiBG.pairlist_running = False
|
||||||
|
|
||||||
|
|
||||||
@router.post("/pairlists/evaluate", response_model=BgJobStarted, tags=["pairlists"])
|
@router.post("/pairlists/evaluate", response_model=BgJobStarted)
|
||||||
def pairlists_evaluate(
|
def pairlists_evaluate(
|
||||||
payload: PairListsPayload, background_tasks: BackgroundTasks, config=Depends(get_config)
|
payload: PairListsPayload, background_tasks: BackgroundTasks, config=Depends(get_config)
|
||||||
):
|
):
|
||||||
@@ -124,11 +124,7 @@ def handleExchangePayload(payload: ExchangeModePayloadMixin, config_loc: Config)
|
|||||||
config_loc["margin_mode"] = payload.margin_mode
|
config_loc["margin_mode"] = payload.margin_mode
|
||||||
|
|
||||||
|
|
||||||
@router.get(
|
@router.get("/pairlists/evaluate/{jobid}", response_model=WhitelistEvaluateResponse)
|
||||||
"/pairlists/evaluate/{jobid}",
|
|
||||||
response_model=WhitelistEvaluateResponse,
|
|
||||||
tags=["pairlists"],
|
|
||||||
)
|
|
||||||
def pairlists_evaluate_get(jobid: str):
|
def pairlists_evaluate_get(jobid: str):
|
||||||
if not (job := ApiBG.jobs.get(jobid)):
|
if not (job := ApiBG.jobs.get(jobid)):
|
||||||
raise HTTPException(status_code=404, detail="Job not found.")
|
raise HTTPException(status_code=404, detail="Job not found.")
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ logger = logging.getLogger(__name__)
|
|||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
@router.get("/balance", response_model=Balances, tags=["trading-info"])
|
@router.get("/balance", response_model=Balances, tags=["Trading-info"])
|
||||||
def balance(rpc: RPC = Depends(get_rpc), config=Depends(get_config)):
|
def balance(rpc: RPC = Depends(get_rpc), config=Depends(get_config)):
|
||||||
"""Account Balances"""
|
"""Account Balances"""
|
||||||
return rpc._rpc_balance(
|
return rpc._rpc_balance(
|
||||||
@@ -51,37 +51,37 @@ def balance(rpc: RPC = Depends(get_rpc), config=Depends(get_config)):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/count", response_model=Count, tags=["trading-info"])
|
@router.get("/count", response_model=Count, tags=["Trading-info"])
|
||||||
def count(rpc: RPC = Depends(get_rpc)):
|
def count(rpc: RPC = Depends(get_rpc)):
|
||||||
return rpc._rpc_count()
|
return rpc._rpc_count()
|
||||||
|
|
||||||
|
|
||||||
@router.get("/entries", response_model=list[Entry], tags=["trading-info"])
|
@router.get("/entries", response_model=list[Entry], tags=["Trading-info"])
|
||||||
def entries(pair: str | None = None, rpc: RPC = Depends(get_rpc)):
|
def entries(pair: str | None = None, rpc: RPC = Depends(get_rpc)):
|
||||||
return rpc._rpc_enter_tag_performance(pair)
|
return rpc._rpc_enter_tag_performance(pair)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/exits", response_model=list[Exit], tags=["trading-info"])
|
@router.get("/exits", response_model=list[Exit], tags=["Trading-info"])
|
||||||
def exits(pair: str | None = None, rpc: RPC = Depends(get_rpc)):
|
def exits(pair: str | None = None, rpc: RPC = Depends(get_rpc)):
|
||||||
return rpc._rpc_exit_reason_performance(pair)
|
return rpc._rpc_exit_reason_performance(pair)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/mix_tags", response_model=list[MixTag], tags=["trading-info"])
|
@router.get("/mix_tags", response_model=list[MixTag], tags=["Trading-info"])
|
||||||
def mix_tags(pair: str | None = None, rpc: RPC = Depends(get_rpc)):
|
def mix_tags(pair: str | None = None, rpc: RPC = Depends(get_rpc)):
|
||||||
return rpc._rpc_mix_tag_performance(pair)
|
return rpc._rpc_mix_tag_performance(pair)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/performance", response_model=list[PerformanceEntry], tags=["trading-info"])
|
@router.get("/performance", response_model=list[PerformanceEntry], tags=["Trading-info"])
|
||||||
def performance(rpc: RPC = Depends(get_rpc)):
|
def performance(rpc: RPC = Depends(get_rpc)):
|
||||||
return rpc._rpc_performance()
|
return rpc._rpc_performance()
|
||||||
|
|
||||||
|
|
||||||
@router.get("/profit", response_model=Profit, tags=["trading-info"])
|
@router.get("/profit", response_model=Profit, tags=["Trading-info"])
|
||||||
def profit(rpc: RPC = Depends(get_rpc), config=Depends(get_config)):
|
def profit(rpc: RPC = Depends(get_rpc), config=Depends(get_config)):
|
||||||
return rpc._rpc_trade_statistics(config["stake_currency"], config.get("fiat_display_currency"))
|
return rpc._rpc_trade_statistics(config["stake_currency"], config.get("fiat_display_currency"))
|
||||||
|
|
||||||
|
|
||||||
@router.get("/profit_all", response_model=ProfitAll, tags=["trading-info"])
|
@router.get("/profit_all", response_model=ProfitAll, tags=["Trading-info"])
|
||||||
def profit_all(rpc: RPC = Depends(get_rpc), config=Depends(get_config)):
|
def profit_all(rpc: RPC = Depends(get_rpc), config=Depends(get_config)):
|
||||||
response = {
|
response = {
|
||||||
"all": rpc._rpc_trade_statistics(
|
"all": rpc._rpc_trade_statistics(
|
||||||
@@ -99,12 +99,12 @@ def profit_all(rpc: RPC = Depends(get_rpc), config=Depends(get_config)):
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
@router.get("/stats", response_model=Stats, tags=["trading-info"])
|
@router.get("/stats", response_model=Stats, tags=["Trading-info"])
|
||||||
def stats(rpc: RPC = Depends(get_rpc)):
|
def stats(rpc: RPC = Depends(get_rpc)):
|
||||||
return rpc._rpc_stats()
|
return rpc._rpc_stats()
|
||||||
|
|
||||||
|
|
||||||
@router.get("/daily", response_model=DailyWeeklyMonthly, tags=["trading-info"])
|
@router.get("/daily", response_model=DailyWeeklyMonthly, tags=["Trading-info"])
|
||||||
def daily(
|
def daily(
|
||||||
timescale: int = Query(7, ge=1, description="Number of days to fetch data for"),
|
timescale: int = Query(7, ge=1, description="Number of days to fetch data for"),
|
||||||
rpc: RPC = Depends(get_rpc),
|
rpc: RPC = Depends(get_rpc),
|
||||||
@@ -115,7 +115,7 @@ def daily(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/weekly", response_model=DailyWeeklyMonthly, tags=["trading-info"])
|
@router.get("/weekly", response_model=DailyWeeklyMonthly, tags=["Trading-info"])
|
||||||
def weekly(
|
def weekly(
|
||||||
timescale: int = Query(4, ge=1, description="Number of weeks to fetch data for"),
|
timescale: int = Query(4, ge=1, description="Number of weeks to fetch data for"),
|
||||||
rpc: RPC = Depends(get_rpc),
|
rpc: RPC = Depends(get_rpc),
|
||||||
@@ -126,7 +126,7 @@ def weekly(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/monthly", response_model=DailyWeeklyMonthly, tags=["trading-info"])
|
@router.get("/monthly", response_model=DailyWeeklyMonthly, tags=["Trading-info"])
|
||||||
def monthly(
|
def monthly(
|
||||||
timescale: int = Query(3, ge=1, description="Number of months to fetch data for"),
|
timescale: int = Query(3, ge=1, description="Number of months to fetch data for"),
|
||||||
rpc: RPC = Depends(get_rpc),
|
rpc: RPC = Depends(get_rpc),
|
||||||
@@ -137,7 +137,7 @@ def monthly(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/status", response_model=list[OpenTradeSchema], tags=["trading-info"])
|
@router.get("/status", response_model=list[OpenTradeSchema], tags=["Trading-info"])
|
||||||
def status(rpc: RPC = Depends(get_rpc)):
|
def status(rpc: RPC = Depends(get_rpc)):
|
||||||
try:
|
try:
|
||||||
return rpc._rpc_trade_status()
|
return rpc._rpc_trade_status()
|
||||||
@@ -147,7 +147,7 @@ def status(rpc: RPC = Depends(get_rpc)):
|
|||||||
|
|
||||||
# Using the responsemodel here will cause a ~100% increase in response time (from 1s to 2s)
|
# Using the responsemodel here will cause a ~100% increase in response time (from 1s to 2s)
|
||||||
# on big databases. Correct response model: response_model=TradeResponse,
|
# on big databases. Correct response model: response_model=TradeResponse,
|
||||||
@router.get("/trades", tags=["trading-info", "trades"])
|
@router.get("/trades", tags=["Trading-info", "Trades"])
|
||||||
def trades(
|
def trades(
|
||||||
limit: int = Query(500, ge=1, description="Maximum number of different trades to return data"),
|
limit: int = Query(500, ge=1, description="Maximum number of different trades to return data"),
|
||||||
offset: int = Query(0, ge=0, description="Number of trades to skip for pagination"),
|
offset: int = Query(0, ge=0, description="Number of trades to skip for pagination"),
|
||||||
@@ -159,7 +159,7 @@ def trades(
|
|||||||
return rpc._rpc_trade_history(limit, offset=offset, order_by_id=order_by_id)
|
return rpc._rpc_trade_history(limit, offset=offset, order_by_id=order_by_id)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/trade/{tradeid}", response_model=OpenTradeSchema, tags=["trades"])
|
@router.get("/trade/{tradeid}", response_model=OpenTradeSchema, tags=["Trades"])
|
||||||
def trade(tradeid: int = 0, rpc: RPC = Depends(get_rpc)):
|
def trade(tradeid: int = 0, rpc: RPC = Depends(get_rpc)):
|
||||||
try:
|
try:
|
||||||
return rpc._rpc_trade_status([tradeid])[0]
|
return rpc._rpc_trade_status([tradeid])[0]
|
||||||
@@ -167,24 +167,24 @@ def trade(tradeid: int = 0, rpc: RPC = Depends(get_rpc)):
|
|||||||
raise HTTPException(status_code=404, detail="Trade not found.")
|
raise HTTPException(status_code=404, detail="Trade not found.")
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/trades/{tradeid}", response_model=DeleteTrade, tags=["trades"])
|
@router.delete("/trades/{tradeid}", response_model=DeleteTrade, tags=["Trades"])
|
||||||
def trades_delete(tradeid: int, rpc: RPC = Depends(get_rpc)):
|
def trades_delete(tradeid: int, rpc: RPC = Depends(get_rpc)):
|
||||||
return rpc._rpc_delete(tradeid)
|
return rpc._rpc_delete(tradeid)
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/trades/{tradeid}/open-order", response_model=OpenTradeSchema, tags=["trades"])
|
@router.delete("/trades/{tradeid}/open-order", response_model=OpenTradeSchema, tags=["Trades"])
|
||||||
def trade_cancel_open_order(tradeid: int, rpc: RPC = Depends(get_rpc)):
|
def trade_cancel_open_order(tradeid: int, rpc: RPC = Depends(get_rpc)):
|
||||||
rpc._rpc_cancel_open_order(tradeid)
|
rpc._rpc_cancel_open_order(tradeid)
|
||||||
return rpc._rpc_trade_status([tradeid])[0]
|
return rpc._rpc_trade_status([tradeid])[0]
|
||||||
|
|
||||||
|
|
||||||
@router.post("/trades/{tradeid}/reload", response_model=OpenTradeSchema, tags=["trades"])
|
@router.post("/trades/{tradeid}/reload", response_model=OpenTradeSchema, tags=["Trades"])
|
||||||
def trade_reload(tradeid: int, rpc: RPC = Depends(get_rpc)):
|
def trade_reload(tradeid: int, rpc: RPC = Depends(get_rpc)):
|
||||||
rpc._rpc_reload_trade_from_exchange(tradeid)
|
rpc._rpc_reload_trade_from_exchange(tradeid)
|
||||||
return rpc._rpc_trade_status([tradeid])[0]
|
return rpc._rpc_trade_status([tradeid])[0]
|
||||||
|
|
||||||
|
|
||||||
@router.get("/trades/open/custom-data", response_model=list[ListCustomData], tags=["trades"])
|
@router.get("/trades/open/custom-data", response_model=list[ListCustomData], tags=["Trades"])
|
||||||
def list_open_trades_custom_data(
|
def list_open_trades_custom_data(
|
||||||
key: str | None = Query(None, description="Optional key to filter data"),
|
key: str | None = Query(None, description="Optional key to filter data"),
|
||||||
limit: int = Query(100, ge=1, description="Maximum number of different trades to return data"),
|
limit: int = Query(100, ge=1, description="Maximum number of different trades to return data"),
|
||||||
@@ -202,7 +202,7 @@ def list_open_trades_custom_data(
|
|||||||
raise HTTPException(status_code=404, detail=str(e))
|
raise HTTPException(status_code=404, detail=str(e))
|
||||||
|
|
||||||
|
|
||||||
@router.get("/trades/{trade_id}/custom-data", response_model=list[ListCustomData], tags=["trades"])
|
@router.get("/trades/{trade_id}/custom-data", response_model=list[ListCustomData], tags=["Trades"])
|
||||||
def list_custom_data(trade_id: int, key: str | None = Query(None), rpc: RPC = Depends(get_rpc)):
|
def list_custom_data(trade_id: int, key: str | None = Query(None), rpc: RPC = Depends(get_rpc)):
|
||||||
"""
|
"""
|
||||||
Fetch custom data for a specific trade.
|
Fetch custom data for a specific trade.
|
||||||
@@ -215,11 +215,11 @@ def list_custom_data(trade_id: int, key: str | None = Query(None), rpc: RPC = De
|
|||||||
|
|
||||||
|
|
||||||
# /forcebuy is deprecated with short addition. use /forceentry instead
|
# /forcebuy is deprecated with short addition. use /forceentry instead
|
||||||
@router.post("/forceenter", response_model=ForceEnterResponse, tags=["trades"])
|
@router.post("/forceenter", response_model=ForceEnterResponse, tags=["Trades"])
|
||||||
@router.post(
|
@router.post(
|
||||||
"/forcebuy",
|
"/forcebuy",
|
||||||
response_model=ForceEnterResponse,
|
response_model=ForceEnterResponse,
|
||||||
tags=["trades"],
|
tags=["Trades"],
|
||||||
summary="(deprecated) Please use /forceenter instead",
|
summary="(deprecated) Please use /forceenter instead",
|
||||||
)
|
)
|
||||||
def force_entry(payload: ForceEnterPayload, rpc: RPC = Depends(get_rpc)):
|
def force_entry(payload: ForceEnterPayload, rpc: RPC = Depends(get_rpc)):
|
||||||
@@ -244,11 +244,11 @@ def force_entry(payload: ForceEnterPayload, rpc: RPC = Depends(get_rpc)):
|
|||||||
|
|
||||||
|
|
||||||
# /forcesell is deprecated with short addition. use /forceexit instead
|
# /forcesell is deprecated with short addition. use /forceexit instead
|
||||||
@router.post("/forceexit", response_model=ResultMsg, tags=["trades"])
|
@router.post("/forceexit", response_model=ResultMsg, tags=["Trades"])
|
||||||
@router.post(
|
@router.post(
|
||||||
"/forcesell",
|
"/forcesell",
|
||||||
response_model=ResultMsg,
|
response_model=ResultMsg,
|
||||||
tags=["trades"],
|
tags=["Trades"],
|
||||||
summary="(deprecated) Please use /forceexit instead",
|
summary="(deprecated) Please use /forceexit instead",
|
||||||
)
|
)
|
||||||
def forceexit(payload: ForceExitPayload, rpc: RPC = Depends(get_rpc)):
|
def forceexit(payload: ForceExitPayload, rpc: RPC = Depends(get_rpc)):
|
||||||
@@ -258,78 +258,78 @@ def forceexit(payload: ForceExitPayload, rpc: RPC = Depends(get_rpc)):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/blacklist", response_model=BlacklistResponse, tags=["trading-info", "pairlist"])
|
@router.get("/blacklist", response_model=BlacklistResponse, tags=["Trading-info", "Pairlist"])
|
||||||
def blacklist(rpc: RPC = Depends(get_rpc)):
|
def blacklist(rpc: RPC = Depends(get_rpc)):
|
||||||
return rpc._rpc_blacklist()
|
return rpc._rpc_blacklist()
|
||||||
|
|
||||||
|
|
||||||
@router.post("/blacklist", response_model=BlacklistResponse, tags=["pairlist"])
|
@router.post("/blacklist", response_model=BlacklistResponse, tags=["Pairlist"])
|
||||||
def blacklist_post(payload: BlacklistPayload, rpc: RPC = Depends(get_rpc)):
|
def blacklist_post(payload: BlacklistPayload, rpc: RPC = Depends(get_rpc)):
|
||||||
return rpc._rpc_blacklist(payload.blacklist)
|
return rpc._rpc_blacklist(payload.blacklist)
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/blacklist", response_model=BlacklistResponse, tags=["pairlist"])
|
@router.delete("/blacklist", response_model=BlacklistResponse, tags=["Pairlist"])
|
||||||
def blacklist_delete(pairs_to_delete: list[str] = Query([]), rpc: RPC = Depends(get_rpc)):
|
def blacklist_delete(pairs_to_delete: list[str] = Query([]), rpc: RPC = Depends(get_rpc)):
|
||||||
"""Provide a list of pairs to delete from the blacklist"""
|
"""Provide a list of pairs to delete from the blacklist"""
|
||||||
|
|
||||||
return rpc._rpc_blacklist_delete(pairs_to_delete)
|
return rpc._rpc_blacklist_delete(pairs_to_delete)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/whitelist", response_model=WhitelistResponse, tags=["trading-info", "pairlist"])
|
@router.get("/whitelist", response_model=WhitelistResponse, tags=["Trading-info", "Pairlist"])
|
||||||
def whitelist(rpc: RPC = Depends(get_rpc)):
|
def whitelist(rpc: RPC = Depends(get_rpc)):
|
||||||
return rpc._rpc_whitelist()
|
return rpc._rpc_whitelist()
|
||||||
|
|
||||||
|
|
||||||
@router.get("/locks", response_model=Locks, tags=["trading-info", "locks"])
|
@router.get("/locks", response_model=Locks, tags=["Trading-info", "Locks"])
|
||||||
def locks(rpc: RPC = Depends(get_rpc)):
|
def locks(rpc: RPC = Depends(get_rpc)):
|
||||||
return rpc._rpc_locks()
|
return rpc._rpc_locks()
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/locks/{lockid}", response_model=Locks, tags=["locks"])
|
@router.delete("/locks/{lockid}", response_model=Locks, tags=["Locks"])
|
||||||
def delete_lock(lockid: int, rpc: RPC = Depends(get_rpc)):
|
def delete_lock(lockid: int, rpc: RPC = Depends(get_rpc)):
|
||||||
return rpc._rpc_delete_lock(lockid=lockid)
|
return rpc._rpc_delete_lock(lockid=lockid)
|
||||||
|
|
||||||
|
|
||||||
@router.post("/locks/delete", response_model=Locks, tags=["locks"])
|
@router.post("/locks/delete", response_model=Locks, tags=["Locks"])
|
||||||
def delete_lock_pair(payload: DeleteLockRequest, rpc: RPC = Depends(get_rpc)):
|
def delete_lock_pair(payload: DeleteLockRequest, rpc: RPC = Depends(get_rpc)):
|
||||||
return rpc._rpc_delete_lock(lockid=payload.lockid, pair=payload.pair)
|
return rpc._rpc_delete_lock(lockid=payload.lockid, pair=payload.pair)
|
||||||
|
|
||||||
|
|
||||||
@router.post("/locks", response_model=Locks, tags=["locks"])
|
@router.post("/locks", response_model=Locks, tags=["Locks"])
|
||||||
def add_locks(payload: list[LocksPayload], rpc: RPC = Depends(get_rpc)):
|
def add_locks(payload: list[LocksPayload], rpc: RPC = Depends(get_rpc)):
|
||||||
for lock in payload:
|
for lock in payload:
|
||||||
rpc._rpc_add_lock(lock.pair, lock.until, lock.reason, lock.side)
|
rpc._rpc_add_lock(lock.pair, lock.until, lock.reason, lock.side)
|
||||||
return rpc._rpc_locks()
|
return rpc._rpc_locks()
|
||||||
|
|
||||||
|
|
||||||
@router.post("/start", response_model=StatusMsg, tags=["botcontrol"])
|
@router.post("/start", response_model=StatusMsg, tags=["Bot-control"])
|
||||||
def start(rpc: RPC = Depends(get_rpc)):
|
def start(rpc: RPC = Depends(get_rpc)):
|
||||||
return rpc._rpc_start()
|
return rpc._rpc_start()
|
||||||
|
|
||||||
|
|
||||||
@router.post("/stop", response_model=StatusMsg, tags=["botcontrol"])
|
@router.post("/stop", response_model=StatusMsg, tags=["Bot-control"])
|
||||||
def stop(rpc: RPC = Depends(get_rpc)):
|
def stop(rpc: RPC = Depends(get_rpc)):
|
||||||
return rpc._rpc_stop()
|
return rpc._rpc_stop()
|
||||||
|
|
||||||
|
|
||||||
@router.post("/pause", response_model=StatusMsg, tags=["botcontrol"])
|
@router.post("/pause", response_model=StatusMsg, tags=["Bot-control"])
|
||||||
@router.post("/stopentry", response_model=StatusMsg, tags=["botcontrol"])
|
@router.post("/stopentry", response_model=StatusMsg, tags=["Bot-control"])
|
||||||
@router.post("/stopbuy", response_model=StatusMsg, tags=["botcontrol"])
|
@router.post("/stopbuy", response_model=StatusMsg, tags=["Bot-control"])
|
||||||
def pause(rpc: RPC = Depends(get_rpc)):
|
def pause(rpc: RPC = Depends(get_rpc)):
|
||||||
return rpc._rpc_pause()
|
return rpc._rpc_pause()
|
||||||
|
|
||||||
|
|
||||||
@router.post("/reload_config", response_model=StatusMsg, tags=["botcontrol"])
|
@router.post("/reload_config", response_model=StatusMsg, tags=["Bot-control"])
|
||||||
def reload_config(rpc: RPC = Depends(get_rpc)):
|
def reload_config(rpc: RPC = Depends(get_rpc)):
|
||||||
return rpc._rpc_reload_config()
|
return rpc._rpc_reload_config()
|
||||||
|
|
||||||
|
|
||||||
@router.get("/pair_candles", response_model=PairHistory, tags=["candle data"])
|
@router.get("/pair_candles", response_model=PairHistory, tags=["Candle data"])
|
||||||
def pair_candles(pair: str, timeframe: str, limit: int | None = None, rpc: RPC = Depends(get_rpc)):
|
def pair_candles(pair: str, timeframe: str, limit: int | None = None, rpc: RPC = Depends(get_rpc)):
|
||||||
return rpc._rpc_analysed_dataframe(pair, timeframe, limit, None)
|
return rpc._rpc_analysed_dataframe(pair, timeframe, limit, None)
|
||||||
|
|
||||||
|
|
||||||
@router.post("/pair_candles", response_model=PairHistory, tags=["candle data"])
|
@router.post("/pair_candles", response_model=PairHistory, tags=["Candle data"])
|
||||||
def pair_candles_filtered(payload: PairCandlesRequest, rpc: RPC = Depends(get_rpc)):
|
def pair_candles_filtered(payload: PairCandlesRequest, rpc: RPC = Depends(get_rpc)):
|
||||||
# Advanced pair_candles endpoint with column filtering
|
# Advanced pair_candles endpoint with column filtering
|
||||||
return rpc._rpc_analysed_dataframe(
|
return rpc._rpc_analysed_dataframe(
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ def logs(limit: int | None = None):
|
|||||||
return RPC._rpc_get_logs(limit)
|
return RPC._rpc_get_logs(limit)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/plot_config", response_model=PlotConfig, tags=["candle data"])
|
@router.get("/plot_config", response_model=PlotConfig, tags=["Candle data"])
|
||||||
def plot_config(
|
def plot_config(
|
||||||
strategy: str | None = None,
|
strategy: str | None = None,
|
||||||
config=Depends(get_config),
|
config=Depends(get_config),
|
||||||
@@ -115,7 +115,7 @@ def plot_config(
|
|||||||
raise HTTPException(status_code=502, detail=str(e))
|
raise HTTPException(status_code=502, detail=str(e))
|
||||||
|
|
||||||
|
|
||||||
@router.get("/markets", response_model=MarketResponse, tags=["candle data", "webserver"])
|
@router.get("/markets", response_model=MarketResponse, tags=["Candle data"])
|
||||||
def markets(
|
def markets(
|
||||||
query: Annotated[MarketRequest, Query()],
|
query: Annotated[MarketRequest, Query()],
|
||||||
config=Depends(get_config),
|
config=Depends(get_config),
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ logger = logging.getLogger(__name__)
|
|||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
@router.get("/strategies", response_model=StrategyListResponse, tags=["strategy"])
|
@router.get("/strategies", response_model=StrategyListResponse, tags=["Strategy"])
|
||||||
def list_strategies(config=Depends(get_config)):
|
def list_strategies(config=Depends(get_config)):
|
||||||
from freqtrade.resolvers.strategy_resolver import StrategyResolver
|
from freqtrade.resolvers.strategy_resolver import StrategyResolver
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ def list_strategies(config=Depends(get_config)):
|
|||||||
return {"strategies": [x["name"] for x in strategies]}
|
return {"strategies": [x["name"] for x in strategies]}
|
||||||
|
|
||||||
|
|
||||||
@router.get("/strategy/{strategy}", response_model=StrategyResponse, tags=["strategy"])
|
@router.get("/strategy/{strategy}", response_model=StrategyResponse, tags=["Strategy"])
|
||||||
def get_strategy(strategy: str, config=Depends(get_config)):
|
def get_strategy(strategy: str, config=Depends(get_config)):
|
||||||
if ":" in strategy:
|
if ":" in strategy:
|
||||||
raise HTTPException(status_code=500, detail="base64 encoded strategies are not allowed.")
|
raise HTTPException(status_code=500, detail="base64 encoded strategies are not allowed.")
|
||||||
@@ -69,9 +69,7 @@ def list_exchanges(config=Depends(get_config)):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@router.get(
|
@router.get("/hyperoptloss", response_model=HyperoptLossListResponse, tags=["Hyperopt"])
|
||||||
"/hyperoptloss", response_model=HyperoptLossListResponse, tags=["hyperopt", "webserver"]
|
|
||||||
)
|
|
||||||
def list_hyperoptloss(
|
def list_hyperoptloss(
|
||||||
config=Depends(get_config),
|
config=Depends(get_config),
|
||||||
):
|
):
|
||||||
@@ -93,7 +91,7 @@ def list_hyperoptloss(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@router.get("/freqaimodels", response_model=FreqAIModelListResponse, tags=["freqai"])
|
@router.get("/freqaimodels", response_model=FreqAIModelListResponse, tags=["FreqAI"])
|
||||||
def list_freqaimodels(config=Depends(get_config)):
|
def list_freqaimodels(config=Depends(get_config)):
|
||||||
from freqtrade.resolvers.freqaimodel_resolver import FreqaiModelResolver
|
from freqtrade.resolvers.freqaimodel_resolver import FreqaiModelResolver
|
||||||
|
|
||||||
@@ -104,7 +102,7 @@ def list_freqaimodels(config=Depends(get_config)):
|
|||||||
|
|
||||||
|
|
||||||
@router.get(
|
@router.get(
|
||||||
"/available_pairs", response_model=AvailablePairs, tags=["candle data", "download-data"]
|
"/available_pairs", response_model=AvailablePairs, tags=["Candle data", "Download-data"]
|
||||||
)
|
)
|
||||||
def list_available_pairs(
|
def list_available_pairs(
|
||||||
timeframe: str | None = None,
|
timeframe: str | None = None,
|
||||||
|
|||||||
@@ -5,8 +5,7 @@ from uuid import uuid4
|
|||||||
from fastapi import Depends, HTTPException
|
from fastapi import Depends, HTTPException
|
||||||
|
|
||||||
from freqtrade.constants import Config
|
from freqtrade.constants import Config
|
||||||
from freqtrade.enums import RunMode
|
from freqtrade.enums import TRADE_MODES, RunMode
|
||||||
from freqtrade.enums.runmode import TRADE_MODES
|
|
||||||
from freqtrade.persistence import Trade
|
from freqtrade.persistence import Trade
|
||||||
from freqtrade.persistence.models import _request_id_ctx_var
|
from freqtrade.persistence.models import _request_id_ctx_var
|
||||||
from freqtrade.rpc.api_server.webserver_bgwork import ApiBG
|
from freqtrade.rpc.api_server.webserver_bgwork import ApiBG
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
_TRADE_MODE_ONLY = "*only available in trading mode*"
|
_TRADE_MODE_ONLY = "*only available in trading mode*"
|
||||||
|
_WEBSERVER_MODE_ONLY = "*only available in webserver mode*"
|
||||||
|
|
||||||
_OPENAPI_TAGS = (
|
_OPENAPI_TAGS = (
|
||||||
{"name": "Auth", "description": "Authentication endpoints."},
|
{"name": "Auth", "description": "Authentication endpoints."},
|
||||||
@@ -29,29 +30,61 @@ _OPENAPI_TAGS = (
|
|||||||
"name": "Info",
|
"name": "Info",
|
||||||
"description": ("Information endpoints providing general information about the bot."),
|
"description": ("Information endpoints providing general information about the bot."),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Bot-control",
|
||||||
|
"description": (f"Bot control endpoints to start/stop trading - {_TRADE_MODE_ONLY}."),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Pairlist",
|
||||||
|
"description": f"Pairlist management - {_TRADE_MODE_ONLY}.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Locks",
|
||||||
|
"description": f"Pair lock management - {_TRADE_MODE_ONLY}.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Candle data",
|
||||||
|
"description": "Candle / OHLCV data.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Trading-info",
|
||||||
|
"description": f"Trading related information - {_TRADE_MODE_ONLY}.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Trades",
|
||||||
|
"description": f"Trade management - {_TRADE_MODE_ONLY}.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Strategy",
|
||||||
|
"description": f"List and retrieve strategies - {_WEBSERVER_MODE_ONLY}.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Hyperopt",
|
||||||
|
"description": f"Retrieve hyperopt loss functions - {_WEBSERVER_MODE_ONLY}.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "FreqAI",
|
||||||
|
"description": f"FreqAI related endpoints - {_WEBSERVER_MODE_ONLY}.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Download-data",
|
||||||
|
"description": f"Download data endpoints - {_WEBSERVER_MODE_ONLY}.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Backtest",
|
||||||
|
"description": f"Backtest endpoints - {_WEBSERVER_MODE_ONLY}.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Pairlists",
|
||||||
|
"description": f"Pairlist endpoints - {_WEBSERVER_MODE_ONLY}.",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Trading",
|
"name": "Trading",
|
||||||
"description": f"Trading related endpoints - {_TRADE_MODE_ONLY}.",
|
"description": f"Trading related endpoints - {_TRADE_MODE_ONLY}.",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Webserver",
|
"name": "Webserver",
|
||||||
"description": ("Webserver related endpoints - *only available in webserver mode*."),
|
"description": (f"Webserver related endpoints - {_WEBSERVER_MODE_ONLY}."),
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Bot-control",
|
|
||||||
"description": (f"Bot control endpoints to start/stop trading - {_TRADE_MODE_ONLY}."),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "pairlist",
|
|
||||||
"description": f"Pairlist management - {_TRADE_MODE_ONLY}.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "locks",
|
|
||||||
"description": f"Pair lock management - {_TRADE_MODE_ONLY}.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "candle data",
|
|
||||||
"description": "Candle / OHLCV data.",
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -189,6 +222,7 @@ class ApiServer(RPCHandler):
|
|||||||
app.include_router(
|
app.include_router(
|
||||||
api_backtest,
|
api_backtest,
|
||||||
prefix="/api/v1",
|
prefix="/api/v1",
|
||||||
|
tags=["Backtest"],
|
||||||
dependencies=[Depends(http_basic_or_jwt_token), Depends(is_webserver_mode)],
|
dependencies=[Depends(http_basic_or_jwt_token), Depends(is_webserver_mode)],
|
||||||
)
|
)
|
||||||
app.include_router(
|
app.include_router(
|
||||||
@@ -205,13 +239,13 @@ class ApiServer(RPCHandler):
|
|||||||
app.include_router(
|
app.include_router(
|
||||||
api_pairlists,
|
api_pairlists,
|
||||||
prefix="/api/v1",
|
prefix="/api/v1",
|
||||||
tags=["Webserver"],
|
tags=["Webserver", "Pairlists"],
|
||||||
dependencies=[Depends(http_basic_or_jwt_token), Depends(is_webserver_mode)],
|
dependencies=[Depends(http_basic_or_jwt_token), Depends(is_webserver_mode)],
|
||||||
)
|
)
|
||||||
app.include_router(
|
app.include_router(
|
||||||
api_download_data,
|
api_download_data,
|
||||||
prefix="/api/v1",
|
prefix="/api/v1",
|
||||||
tags=["download-data", "Webserver"],
|
tags=["Download-data", "Webserver"],
|
||||||
dependencies=[Depends(http_basic_or_jwt_token), Depends(is_webserver_mode)],
|
dependencies=[Depends(http_basic_or_jwt_token), Depends(is_webserver_mode)],
|
||||||
)
|
)
|
||||||
app.include_router(ws_router, prefix="/api/v1")
|
app.include_router(ws_router, prefix="/api/v1")
|
||||||
|
|||||||
Reference in New Issue
Block a user