580 lines
21 KiB
Python
580 lines
21 KiB
Python
# pragma pylint: disable=too-few-public-methods
|
|
|
|
"""
|
|
bot constants
|
|
"""
|
|
from typing import List, Literal, Tuple
|
|
|
|
from freqtrade.enums import CandleType
|
|
|
|
|
|
DEFAULT_CONFIG = "config.json"
|
|
DEFAULT_EXCHANGE = "bittrex"
|
|
PROCESS_THROTTLE_SECS = 5 # sec
|
|
HYPEROPT_EPOCH = 100 # epochs
|
|
RETRY_TIMEOUT = 30 # sec
|
|
TIMEOUT_UNITS = ["minutes", "seconds"]
|
|
EXPORT_OPTIONS = ["none", "trades", "signals"]
|
|
DEFAULT_DB_PROD_URL = "sqlite:///tradesv3.sqlite"
|
|
DEFAULT_DB_DRYRUN_URL = "sqlite:///tradesv3.dryrun.sqlite"
|
|
UNLIMITED_STAKE_AMOUNT = "unlimited"
|
|
DEFAULT_AMOUNT_RESERVE_PERCENT = 0.05
|
|
REQUIRED_ORDERTIF = ["entry", "exit"]
|
|
REQUIRED_ORDERTYPES = ["entry", "exit", "stoploss", "stoploss_on_exchange"]
|
|
PRICING_SIDES = ["ask", "bid", "same", "other"]
|
|
ORDERTYPE_POSSIBILITIES = ["limit", "market"]
|
|
ORDERTIF_POSSIBILITIES = ["gtc", "fok", "ioc"]
|
|
HYPEROPT_LOSS_BUILTIN = [
|
|
"ShortTradeDurHyperOptLoss",
|
|
"OnlyProfitHyperOptLoss",
|
|
"SharpeHyperOptLoss",
|
|
"SharpeHyperOptLossDaily",
|
|
"SortinoHyperOptLoss",
|
|
"SortinoHyperOptLossDaily",
|
|
"CalmarHyperOptLoss",
|
|
"MaxDrawDownHyperOptLoss",
|
|
"MaxDrawDownRelativeHyperOptLoss",
|
|
"ProfitDrawDownHyperOptLoss",
|
|
]
|
|
AVAILABLE_PAIRLISTS = [
|
|
"StaticPairList",
|
|
"VolumePairList",
|
|
"AgeFilter",
|
|
"OffsetFilter",
|
|
"PerformanceFilter",
|
|
"PrecisionFilter",
|
|
"PriceFilter",
|
|
"RangeStabilityFilter",
|
|
"ShuffleFilter",
|
|
"SpreadFilter",
|
|
"VolatilityFilter",
|
|
]
|
|
AVAILABLE_PROTECTIONS = ["CooldownPeriod", "LowProfitPairs", "MaxDrawdown", "StoplossGuard"]
|
|
AVAILABLE_DATAHANDLERS = ["json", "jsongz", "hdf5"]
|
|
BACKTEST_BREAKDOWNS = ["day", "week", "month"]
|
|
BACKTEST_CACHE_AGE = ["none", "day", "week", "month"]
|
|
BACKTEST_CACHE_DEFAULT = "day"
|
|
DRY_RUN_WALLET = 1000
|
|
DATETIME_PRINT_FORMAT = "%Y-%m-%d %H:%M:%S"
|
|
MATH_CLOSE_PREC = 1e-14 # Precision used for float comparisons
|
|
DEFAULT_DATAFRAME_COLUMNS = ["date", "open", "high", "low", "close", "volume"]
|
|
# Don't modify sequence of DEFAULT_TRADES_COLUMNS
|
|
# it has wide consequences for stored trades files
|
|
DEFAULT_TRADES_COLUMNS = ["timestamp", "id", "type", "side", "price", "amount", "cost"]
|
|
TRADING_MODES = ["spot", "margin", "futures"]
|
|
MARGIN_MODES = ["cross", "isolated", ""]
|
|
|
|
LAST_BT_RESULT_FN = ".last_result.json"
|
|
FTHYPT_FILEVERSION = "fthypt_fileversion"
|
|
|
|
USERPATH_HYPEROPTS = "hyperopts"
|
|
USERPATH_STRATEGIES = "strategies"
|
|
USERPATH_NOTEBOOKS = "notebooks"
|
|
USERPATH_FREQAIMODELS = "freqaimodels"
|
|
|
|
TELEGRAM_SETTING_OPTIONS = ["on", "off", "silent"]
|
|
WEBHOOK_FORMAT_OPTIONS = ["form", "json", "raw"]
|
|
|
|
ENV_VAR_PREFIX = "FREQTRADE__"
|
|
|
|
NON_OPEN_EXCHANGE_STATES = ("cancelled", "canceled", "closed", "expired")
|
|
|
|
# Define decimals per coin for outputs
|
|
# Only used for outputs.
|
|
DECIMAL_PER_COIN_FALLBACK = 3 # Should be low to avoid listing all possible FIAT's
|
|
DECIMALS_PER_COIN = {
|
|
"BTC": 8,
|
|
"ETH": 5,
|
|
}
|
|
|
|
DUST_PER_COIN = {"BTC": 0.0001, "ETH": 0.01}
|
|
|
|
# Source files with destination directories within user-directory
|
|
USER_DATA_FILES = {
|
|
"sample_strategy.py": USERPATH_STRATEGIES,
|
|
"sample_hyperopt_loss.py": USERPATH_HYPEROPTS,
|
|
"strategy_analysis_example.ipynb": USERPATH_NOTEBOOKS,
|
|
}
|
|
|
|
SUPPORTED_FIAT = [
|
|
"AUD",
|
|
"BRL",
|
|
"CAD",
|
|
"CHF",
|
|
"CLP",
|
|
"CNY",
|
|
"CZK",
|
|
"DKK",
|
|
"EUR",
|
|
"GBP",
|
|
"HKD",
|
|
"HUF",
|
|
"IDR",
|
|
"ILS",
|
|
"INR",
|
|
"JPY",
|
|
"KRW",
|
|
"MXN",
|
|
"MYR",
|
|
"NOK",
|
|
"NZD",
|
|
"PHP",
|
|
"PKR",
|
|
"PLN",
|
|
"RUB",
|
|
"UAH",
|
|
"SEK",
|
|
"SGD",
|
|
"THB",
|
|
"TRY",
|
|
"TWD",
|
|
"ZAR",
|
|
"USD",
|
|
"BTC",
|
|
"ETH",
|
|
"XRP",
|
|
"LTC",
|
|
"BCH",
|
|
]
|
|
|
|
MINIMAL_CONFIG = {
|
|
"stake_currency": "",
|
|
"dry_run": True,
|
|
"exchange": {
|
|
"name": "",
|
|
"key": "",
|
|
"secret": "",
|
|
"pair_whitelist": [],
|
|
"ccxt_async_config": {},
|
|
},
|
|
}
|
|
|
|
# Required json-schema for user specified config
|
|
CONF_SCHEMA = {
|
|
"type": "object",
|
|
"properties": {
|
|
"max_open_trades": {"type": ["integer", "number"], "minimum": -1},
|
|
"new_pairs_days": {"type": "integer", "default": 30},
|
|
"timeframe": {"type": "string"},
|
|
"stake_currency": {"type": "string"},
|
|
"stake_amount": {
|
|
"type": ["number", "string"],
|
|
"minimum": 0.0001,
|
|
"pattern": UNLIMITED_STAKE_AMOUNT,
|
|
},
|
|
"tradable_balance_ratio": {"type": "number", "minimum": 0.0, "maximum": 1, "default": 0.99},
|
|
"available_capital": {
|
|
"type": "number",
|
|
"minimum": 0,
|
|
},
|
|
"amend_last_stake_amount": {"type": "boolean", "default": False},
|
|
"last_stake_amount_min_ratio": {
|
|
"type": "number",
|
|
"minimum": 0.0,
|
|
"maximum": 1.0,
|
|
"default": 0.5,
|
|
},
|
|
"fiat_display_currency": {"type": "string", "enum": SUPPORTED_FIAT},
|
|
"dry_run": {"type": "boolean"},
|
|
"dry_run_wallet": {"type": "number", "default": DRY_RUN_WALLET},
|
|
"cancel_open_orders_on_exit": {"type": "boolean", "default": False},
|
|
"process_only_new_candles": {"type": "boolean"},
|
|
"minimal_roi": {
|
|
"type": "object",
|
|
"patternProperties": {"^[0-9.]+$": {"type": "number"}},
|
|
"minProperties": 1,
|
|
},
|
|
"amount_reserve_percent": {"type": "number", "minimum": 0.0, "maximum": 0.5},
|
|
"stoploss": {"type": "number", "maximum": 0, "exclusiveMaximum": True, "minimum": -1},
|
|
"trailing_stop": {"type": "boolean"},
|
|
"trailing_stop_positive": {"type": "number", "minimum": 0, "maximum": 1},
|
|
"trailing_stop_positive_offset": {"type": "number", "minimum": 0, "maximum": 1},
|
|
"trailing_only_offset_is_reached": {"type": "boolean"},
|
|
"use_exit_signal": {"type": "boolean"},
|
|
"exit_profit_only": {"type": "boolean"},
|
|
"exit_profit_offset": {"type": "number"},
|
|
"ignore_roi_if_entry_signal": {"type": "boolean"},
|
|
"ignore_buying_expired_candle_after": {"type": "number"},
|
|
"trading_mode": {"type": "string", "enum": TRADING_MODES},
|
|
"margin_mode": {"type": "string", "enum": MARGIN_MODES},
|
|
"liquidation_buffer": {"type": "number", "minimum": 0.0, "maximum": 0.99},
|
|
"backtest_breakdown": {
|
|
"type": "array",
|
|
"items": {"type": "string", "enum": BACKTEST_BREAKDOWNS},
|
|
},
|
|
"bot_name": {"type": "string"},
|
|
"unfilledtimeout": {
|
|
"type": "object",
|
|
"properties": {
|
|
"entry": {"type": "number", "minimum": 1},
|
|
"exit": {"type": "number", "minimum": 1},
|
|
"exit_timeout_count": {"type": "number", "minimum": 0, "default": 0},
|
|
"unit": {"type": "string", "enum": TIMEOUT_UNITS, "default": "minutes"},
|
|
},
|
|
},
|
|
"entry_pricing": {
|
|
"type": "object",
|
|
"properties": {
|
|
"price_last_balance": {
|
|
"type": "number",
|
|
"minimum": 0,
|
|
"maximum": 1,
|
|
"exclusiveMaximum": False,
|
|
},
|
|
"price_side": {"type": "string", "enum": PRICING_SIDES, "default": "same"},
|
|
"use_order_book": {"type": "boolean"},
|
|
"order_book_top": {
|
|
"type": "integer",
|
|
"minimum": 1,
|
|
"maximum": 50,
|
|
},
|
|
"check_depth_of_market": {
|
|
"type": "object",
|
|
"properties": {
|
|
"enabled": {"type": "boolean"},
|
|
"bids_to_ask_delta": {"type": "number", "minimum": 0},
|
|
},
|
|
},
|
|
},
|
|
"required": ["price_side"],
|
|
},
|
|
"exit_pricing": {
|
|
"type": "object",
|
|
"properties": {
|
|
"price_side": {"type": "string", "enum": PRICING_SIDES, "default": "same"},
|
|
"price_last_balance": {
|
|
"type": "number",
|
|
"minimum": 0,
|
|
"maximum": 1,
|
|
"exclusiveMaximum": False,
|
|
},
|
|
"use_order_book": {"type": "boolean"},
|
|
"order_book_top": {
|
|
"type": "integer",
|
|
"minimum": 1,
|
|
"maximum": 50,
|
|
},
|
|
},
|
|
"required": ["price_side"],
|
|
},
|
|
"custom_price_max_distance_ratio": {"type": "number", "minimum": 0.0},
|
|
"order_types": {
|
|
"type": "object",
|
|
"properties": {
|
|
"entry": {"type": "string", "enum": ORDERTYPE_POSSIBILITIES},
|
|
"exit": {"type": "string", "enum": ORDERTYPE_POSSIBILITIES},
|
|
"force_exit": {"type": "string", "enum": ORDERTYPE_POSSIBILITIES},
|
|
"force_entry": {"type": "string", "enum": ORDERTYPE_POSSIBILITIES},
|
|
"emergency_exit": {
|
|
"type": "string",
|
|
"enum": ORDERTYPE_POSSIBILITIES,
|
|
"default": "market",
|
|
},
|
|
"stoploss": {"type": "string", "enum": ORDERTYPE_POSSIBILITIES},
|
|
"stoploss_on_exchange": {"type": "boolean"},
|
|
"stoploss_on_exchange_interval": {"type": "number"},
|
|
"stoploss_on_exchange_limit_ratio": {
|
|
"type": "number",
|
|
"minimum": 0.0,
|
|
"maximum": 1.0,
|
|
},
|
|
},
|
|
"required": ["entry", "exit", "stoploss", "stoploss_on_exchange"],
|
|
},
|
|
"order_time_in_force": {
|
|
"type": "object",
|
|
"properties": {
|
|
"entry": {"type": "string", "enum": ORDERTIF_POSSIBILITIES},
|
|
"exit": {"type": "string", "enum": ORDERTIF_POSSIBILITIES},
|
|
},
|
|
"required": REQUIRED_ORDERTIF,
|
|
},
|
|
"exchange": {"$ref": "#/definitions/exchange"},
|
|
"edge": {"$ref": "#/definitions/edge"},
|
|
"experimental": {
|
|
"type": "object",
|
|
"properties": {"block_bad_exchanges": {"type": "boolean"}},
|
|
},
|
|
"pairlists": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"method": {"type": "string", "enum": AVAILABLE_PAIRLISTS},
|
|
},
|
|
"required": ["method"],
|
|
},
|
|
},
|
|
"protections": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"method": {"type": "string", "enum": AVAILABLE_PROTECTIONS},
|
|
"stop_duration": {"type": "number", "minimum": 0.0},
|
|
"stop_duration_candles": {"type": "number", "minimum": 0},
|
|
"trade_limit": {"type": "number", "minimum": 1},
|
|
"lookback_period": {"type": "number", "minimum": 1},
|
|
"lookback_period_candles": {"type": "number", "minimum": 1},
|
|
},
|
|
"required": ["method"],
|
|
},
|
|
},
|
|
"telegram": {
|
|
"type": "object",
|
|
"properties": {
|
|
"enabled": {"type": "boolean"},
|
|
"token": {"type": "string"},
|
|
"chat_id": {"type": "string"},
|
|
"balance_dust_level": {"type": "number", "minimum": 0.0},
|
|
"notification_settings": {
|
|
"type": "object",
|
|
"default": {},
|
|
"properties": {
|
|
"status": {"type": "string", "enum": TELEGRAM_SETTING_OPTIONS},
|
|
"warning": {"type": "string", "enum": TELEGRAM_SETTING_OPTIONS},
|
|
"startup": {"type": "string", "enum": TELEGRAM_SETTING_OPTIONS},
|
|
"entry": {"type": "string", "enum": TELEGRAM_SETTING_OPTIONS},
|
|
"entry_cancel": {"type": "string", "enum": TELEGRAM_SETTING_OPTIONS},
|
|
"entry_fill": {
|
|
"type": "string",
|
|
"enum": TELEGRAM_SETTING_OPTIONS,
|
|
"default": "off",
|
|
},
|
|
"exit": {
|
|
"type": ["string", "object"],
|
|
"additionalProperties": {
|
|
"type": "string",
|
|
"enum": TELEGRAM_SETTING_OPTIONS,
|
|
},
|
|
},
|
|
"exit_cancel": {"type": "string", "enum": TELEGRAM_SETTING_OPTIONS},
|
|
"exit_fill": {
|
|
"type": "string",
|
|
"enum": TELEGRAM_SETTING_OPTIONS,
|
|
"default": "off",
|
|
},
|
|
"protection_trigger": {
|
|
"type": "string",
|
|
"enum": TELEGRAM_SETTING_OPTIONS,
|
|
"default": "off",
|
|
},
|
|
"protection_trigger_global": {
|
|
"type": "string",
|
|
"enum": TELEGRAM_SETTING_OPTIONS,
|
|
},
|
|
},
|
|
},
|
|
"reload": {"type": "boolean"},
|
|
},
|
|
"required": ["enabled", "token", "chat_id"],
|
|
},
|
|
"webhook": {
|
|
"type": "object",
|
|
"properties": {
|
|
"enabled": {"type": "boolean"},
|
|
"url": {"type": "string"},
|
|
"format": {"type": "string", "enum": WEBHOOK_FORMAT_OPTIONS, "default": "form"},
|
|
"retries": {"type": "integer", "minimum": 0},
|
|
"retry_delay": {"type": "number", "minimum": 0},
|
|
"webhookentry": {"type": "object"},
|
|
"webhookentrycancel": {"type": "object"},
|
|
"webhookentryfill": {"type": "object"},
|
|
"webhookexit": {"type": "object"},
|
|
"webhookexitcancel": {"type": "object"},
|
|
"webhookexitfill": {"type": "object"},
|
|
"webhookstatus": {"type": "object"},
|
|
},
|
|
},
|
|
"api_server": {
|
|
"type": "object",
|
|
"properties": {
|
|
"enabled": {"type": "boolean"},
|
|
"listen_ip_address": {"format": "ipv4"},
|
|
"listen_port": {"type": "integer", "minimum": 1024, "maximum": 65535},
|
|
"username": {"type": "string"},
|
|
"password": {"type": "string"},
|
|
"jwt_secret_key": {"type": "string"},
|
|
"CORS_origins": {"type": "array", "items": {"type": "string"}},
|
|
"verbosity": {"type": "string", "enum": ["error", "info"]},
|
|
},
|
|
"required": ["enabled", "listen_ip_address", "listen_port", "username", "password"],
|
|
},
|
|
"db_url": {"type": "string"},
|
|
"export": {"type": "string", "enum": EXPORT_OPTIONS, "default": "trades"},
|
|
"disableparamexport": {"type": "boolean"},
|
|
"initial_state": {"type": "string", "enum": ["running", "stopped"]},
|
|
"force_entry_enable": {"type": "boolean"},
|
|
"disable_dataframe_checks": {"type": "boolean"},
|
|
"internals": {
|
|
"type": "object",
|
|
"default": {},
|
|
"properties": {
|
|
"process_throttle_secs": {"type": "integer"},
|
|
"interval": {"type": "integer"},
|
|
"sd_notify": {"type": "boolean"},
|
|
},
|
|
},
|
|
"dataformat_ohlcv": {"type": "string", "enum": AVAILABLE_DATAHANDLERS, "default": "json"},
|
|
"dataformat_trades": {
|
|
"type": "string",
|
|
"enum": AVAILABLE_DATAHANDLERS,
|
|
"default": "jsongz",
|
|
},
|
|
"position_adjustment_enable": {"type": "boolean"},
|
|
"max_entry_position_adjustment": {"type": ["integer", "number"], "minimum": -1},
|
|
},
|
|
"definitions": {
|
|
"exchange": {
|
|
"type": "object",
|
|
"properties": {
|
|
"name": {"type": "string"},
|
|
"sandbox": {"type": "boolean", "default": False},
|
|
"key": {"type": "string", "default": ""},
|
|
"secret": {"type": "string", "default": ""},
|
|
"password": {"type": "string", "default": ""},
|
|
"uid": {"type": "string"},
|
|
"pair_whitelist": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string",
|
|
},
|
|
"uniqueItems": True,
|
|
},
|
|
"pair_blacklist": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string",
|
|
},
|
|
"uniqueItems": True,
|
|
},
|
|
"unknown_fee_rate": {"type": "number"},
|
|
"outdated_offset": {"type": "integer", "minimum": 1},
|
|
"markets_refresh_interval": {"type": "integer"},
|
|
"ccxt_config": {"type": "object"},
|
|
"ccxt_async_config": {"type": "object"},
|
|
},
|
|
"required": ["name"],
|
|
},
|
|
"edge": {
|
|
"type": "object",
|
|
"properties": {
|
|
"enabled": {"type": "boolean"},
|
|
"process_throttle_secs": {"type": "integer", "minimum": 600},
|
|
"calculate_since_number_of_days": {"type": "integer"},
|
|
"allowed_risk": {"type": "number"},
|
|
"stoploss_range_min": {"type": "number"},
|
|
"stoploss_range_max": {"type": "number"},
|
|
"stoploss_range_step": {"type": "number"},
|
|
"minimum_winrate": {"type": "number"},
|
|
"minimum_expectancy": {"type": "number"},
|
|
"min_trade_number": {"type": "number"},
|
|
"max_trade_duration_minute": {"type": "integer"},
|
|
"remove_pumps": {"type": "boolean"},
|
|
},
|
|
"required": ["process_throttle_secs", "allowed_risk"],
|
|
},
|
|
"freqai": {
|
|
"type": "object",
|
|
"properties": {
|
|
"timeframes": {"type": "list"},
|
|
"train_period": {"type": "integer", "default": 0},
|
|
"backtest_period": {"type": "integer", "default": 7},
|
|
"identifier": {"type": "str", "default": "example"},
|
|
"base_features": {"type": "list"},
|
|
"corr_pairlist": {"type": "list"},
|
|
"feature_parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"period": {"type": "integer"},
|
|
"shift": {"type": "integer", "default": 0},
|
|
"DI_threshold": {"type": "integer", "default": 0},
|
|
"weight_factor": {"type": "number", "default": 0},
|
|
"principal_component_analysis": {"type": "boolean", "default": False},
|
|
"remove_outliers": {"type": "boolean", "default": False},
|
|
},
|
|
},
|
|
"data_split_parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"test_size": {"type": "number"},
|
|
"random_state": {"type": "integer"},
|
|
},
|
|
},
|
|
"model_training_parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"n_estimators": {"type": "integer", "default": 2000},
|
|
"random_state": {"type": "integer", "default": 1},
|
|
"learning_rate": {"type": "number", "default": 0.02},
|
|
"task_type": {"type": "string", "default": "CPU"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
SCHEMA_TRADE_REQUIRED = [
|
|
"exchange",
|
|
"timeframe",
|
|
"max_open_trades",
|
|
"stake_currency",
|
|
"stake_amount",
|
|
"tradable_balance_ratio",
|
|
"last_stake_amount_min_ratio",
|
|
"dry_run",
|
|
"dry_run_wallet",
|
|
"exit_pricing",
|
|
"entry_pricing",
|
|
"stoploss",
|
|
"minimal_roi",
|
|
"internals",
|
|
"dataformat_ohlcv",
|
|
"dataformat_trades",
|
|
]
|
|
|
|
SCHEMA_BACKTEST_REQUIRED = [
|
|
"exchange",
|
|
"max_open_trades",
|
|
"stake_currency",
|
|
"stake_amount",
|
|
"dry_run_wallet",
|
|
"dataformat_ohlcv",
|
|
"dataformat_trades",
|
|
]
|
|
SCHEMA_BACKTEST_REQUIRED_FINAL = SCHEMA_BACKTEST_REQUIRED + [
|
|
"stoploss",
|
|
"minimal_roi",
|
|
]
|
|
|
|
SCHEMA_MINIMAL_REQUIRED = [
|
|
"exchange",
|
|
"dry_run",
|
|
"dataformat_ohlcv",
|
|
"dataformat_trades",
|
|
]
|
|
|
|
CANCEL_REASON = {
|
|
"TIMEOUT": "cancelled due to timeout",
|
|
"PARTIALLY_FILLED_KEEP_OPEN": "partially filled - keeping order open",
|
|
"PARTIALLY_FILLED": "partially filled",
|
|
"FULLY_CANCELLED": "fully cancelled",
|
|
"ALL_CANCELLED": "cancelled (all unfilled and partially filled open orders cancelled)",
|
|
"CANCELLED_ON_EXCHANGE": "cancelled on exchange",
|
|
"FORCE_EXIT": "forcesold",
|
|
"REPLACE": "cancelled to be replaced by new limit order",
|
|
"USER_CANCEL": "user requested order cancel"
|
|
}
|
|
|
|
# List of pairs with their timeframes
|
|
PairWithTimeframe = Tuple[str, str, CandleType]
|
|
ListPairsWithTimeframes = List[PairWithTimeframe]
|
|
|
|
# Type for trades list
|
|
TradeList = List[List]
|
|
|
|
LongShort = Literal['long', 'short']
|
|
EntryExit = Literal['entry', 'exit']
|
|
BuySell = Literal['buy', 'sell']
|