opentrader
Version:
OpenTrader is a powerful open-source crypto trading bot designated to automate your trading strategies on various cryptocurrency exchanges.
1,096 lines (1,093 loc) • 28.3 kB
TypeScript
import { Exchange, Market } from "ccxt";
import { ZodObject } from 'zod';
export declare const USE_SMART_TRADE = "USE_SMART_TRADE";
export declare const USE_TRADE = "USE_TRADE";
export declare const USE_ARB_TRADE = "USE_ARB_TRADE";
export declare const USE_DCA = "USE_DCA";
export declare const BUY = "BUY";
export declare const SELL = "SELL";
export declare const REPLACE_SMART_TRADE = "REPLACE_SMART_TRADE";
export declare const GET_SMART_TRADE = "GET_SMART_TRADE";
export declare const CREATE_SMART_TRADE = "CREATE_SMART_TRADE";
export declare const CANCEL_SMART_TRADE = "CANCEL_SMART_TRADE";
export declare const USE_EXCHANGE = "USE_EXCHANGE";
export declare const USE_INDICATOR = "USE_INDICATOR";
export declare const USE_INDICATORS = "USE_INDICATORS";
export declare const USE_MARKET = "USE_MARKET";
export declare const USE_CANDLE = "USE_CANDLE";
export declare const USE_RSI_INDICATOR = "USE_RSI_INDICATOR";
export type EffectType = typeof USE_SMART_TRADE | typeof USE_TRADE | typeof USE_ARB_TRADE | typeof USE_DCA | typeof BUY | typeof SELL | typeof REPLACE_SMART_TRADE | typeof GET_SMART_TRADE | typeof CREATE_SMART_TRADE | typeof CANCEL_SMART_TRADE | typeof USE_EXCHANGE | typeof USE_INDICATOR | typeof USE_INDICATORS | typeof USE_MARKET | typeof USE_CANDLE | typeof USE_RSI_INDICATOR;
export type BaseEffect<T extends EffectType, P = undefined, R = undefined> = {
type: T;
ref: R;
payload: P;
};
export declare const makeEffect: <T extends EffectType, P = undefined, R = undefined>(type: T, payload: P, ref: R) => BaseEffect<T, P, R>;
export declare function isEffect<T extends EffectType, P = undefined, R = undefined>(effect: unknown): effect is BaseEffect<T, P, R>;
declare const XOrderSide: {
readonly Buy: "Buy";
readonly Sell: "Sell";
};
export type XOrderSide = (typeof XOrderSide)[keyof typeof XOrderSide];
declare const XOrderStatus: {
readonly Idle: "Idle";
readonly Placed: "Placed";
readonly Filled: "Filled";
readonly Canceled: "Canceled";
readonly Revoked: "Revoked";
readonly Deleted: "Deleted";
};
export type XOrderStatus = (typeof XOrderStatus)[keyof typeof XOrderStatus];
declare const XOrderType: {
readonly Limit: "Limit";
readonly Market: "Market";
};
export type XOrderType = (typeof XOrderType)[keyof typeof XOrderType];
declare const XSmartTradeType: {
readonly Trade: "Trade";
readonly DCA: "DCA";
readonly ARB: "ARB";
};
export type XSmartTradeType = (typeof XSmartTradeType)[keyof typeof XSmartTradeType];
declare const XEntityType: {
readonly EntryOrder: "EntryOrder";
readonly TakeProfitOrder: "TakeProfitOrder";
readonly StopLossOrder: "StopLossOrder";
readonly SafetyOrder: "SafetyOrder";
};
export type XEntityType = (typeof XEntityType)[keyof typeof XEntityType];
declare const BarSize: {
readonly ONE_MINUTE: "1m";
readonly FIVE_MINUTES: "5m";
readonly FIFTEEN_MINUTES: "15m";
readonly ONE_HOUR: "1h";
readonly FOUR_HOURS: "4h";
readonly ONE_DAY: "1d";
readonly ONE_WEEK: "1w";
readonly ONE_MONTH: "1M";
readonly THREE_MONTHS: "3M";
};
export type BarSize = (typeof BarSize)[keyof typeof BarSize];
declare const ExchangeCode: {
readonly OKX: "OKX";
readonly BYBIT: "BYBIT";
readonly BINANCE: "BINANCE";
readonly KRAKEN: "KRAKEN";
readonly COINBASE: "COINBASE";
readonly GATEIO: "GATEIO";
readonly BITGET: "BITGET";
};
export type ExchangeCode = (typeof ExchangeCode)[keyof typeof ExchangeCode];
export interface IAccountAsset {
/**
* e.g. USDT
*/
currency: string;
/**
* Total balance
*/
balance: number;
/**
* Available balance
*/
availableBalance: number;
}
export interface IGetCandlesticksRequest {
/**
* e.g. ADA-USDT
*/
symbol: string;
bar?: BarSize;
/**
* Number of results per request.
*/
limit?: number;
/**
* Return results since specified timestamp.
*/
since?: number;
}
export interface ICandlestick {
/**
* Opening time of the candlestick, Unix timestamp format in milliseconds,
* e.g. `1597026383085`
*/
open: number;
high: number;
low: number;
close: number;
/**
* Data generation time, Unix timestamp format in milliseconds,
* e.g. `1597026383085`
*/
timestamp: number;
}
export type OrderSide = "buy" | "sell";
export type OrderStatus = "canceled" | "open" | "partially_filled" | "filled";
export interface ITrade {
id: string;
amount: number;
price: number;
timestamp: number;
side: OrderSide;
symbol: string;
takerOrMaker?: "taker" | "maker" | string;
}
export type IBid = {
price: number;
quantity: number;
};
export type IAsk = {
price: number;
quantity: number;
};
export type IOrderbook = {
asks: IAsk[];
bids: IBid[];
/**
* Timestamp of the orderbook in milliseconds
*/
timestamp: number;
/**
* Marget symbol as BTC/USDT
*/
symbol: string;
};
export type ITicker = {
symbol: string;
timestamp: number;
bid: number;
ask: number;
last: number;
open?: number;
high?: number;
low?: number;
close?: number;
baseVolume: number;
quoteVolume: number;
};
export interface IGetMarketPriceRequest {
/**
* e.g. ADA/USDT
*/
symbol: string;
}
export interface IGetMarketPriceResponse {
/**
* e.g. ADA-USDT
*/
symbol: string;
/**
* Market price
*/
price: number;
/**
* Timestamp
*/
timestamp: number;
}
export interface IGetSymbolInfoRequest {
/**
* e.g. BTC/USDT
*/
currencyPair: string;
}
export interface ISymbolFilter {
precision: PrecisionFilter;
decimals: PrecisionDecimals;
limits: LimitsFilter;
}
export interface PrecisionFilter {
amount?: number;
price?: number;
}
export interface PrecisionDecimals {
amount?: number;
price?: number;
}
export interface LimitsFilter {
amount?: MinMaxFilter;
cost?: MinMaxFilter;
leverage?: MinMaxFilter;
price?: MinMaxFilter;
}
export interface MinMaxFilter {
min?: number;
max?: number;
}
export interface ISymbolInfo {
/**
* e.g. OKX:BTC/USDT
*/
symbolId: string;
/**
* e.g. BTC/USDT
*/
currencyPair: string;
exchangeCode: ExchangeCode;
/**
* Exchange supplied symbol ID
*
* Named as:
* - `symbol` on Binance
* - `instrumentId` on OKx
* - `productId` on Coinbase
* - May occur as `assetId` on other exchanges
*/
exchangeSymbolId: string;
baseCurrency: string;
quoteCurrency: string;
filters: ISymbolFilter;
}
export type ICancelLimitOrderRequest = {
/**
* e.g. ADA/USDT
*/
symbol: string;
/**
* Order ID provided by the exchange
*/
orderId: string;
};
export interface ICancelLimitOrderResponse {
/**
* Exchange-supplied Order ID
*/
orderId: string;
}
export type IGetLimitOrderRequest = {
/**
* e.g. ADA/USDT
*/
symbol: string;
/**
* Order ID provided by the exchange
*/
orderId: string;
};
export interface IGetLimitOrderResponse {
/**
* Exchange-supplied order ID.
*/
exchangeOrderId: string;
/**
* Client-supplied order ID
*/
clientOrderId?: string;
side: OrderSide;
/**
* Quantity to buy or sell.
*/
quantity: number;
/**
* Order price.
*/
price: number;
/**
* Filled price.
*/
filledPrice: number | null;
/**
* Unix timestamp of the most recent trade on this order.
*/
lastTradeTimestamp: number;
/**
* Order status.
*/
status: OrderStatus;
/**
* Order fee.
*/
fee: number;
/**
* Creation time, Unix timestamp format in milliseconds, e.g. `1597026383085`
*/
createdAt: number;
}
export interface IPlaceOrderRequest {
/**
* Order type: Limit | Market
*/
type: XOrderType;
/**
* Instrument ID, e.g `BTC/USDT`.
*/
symbol: string;
/**
* Client-supplied order ID
*/
clientOrderId?: string;
side: OrderSide;
/**
* Quantity to buy or sell.
*/
quantity: number;
/**
* Some exchanges require price for Market orders to calculate the total cost of the order in the quote currency.
* @see https://docs.ccxt.com/#/?id=market-buys
*/
price?: number;
}
export interface IPlaceOrderResponse {
/**
* Order ID.
*/
orderId: string;
/**
* Client-supplied order ID
*/
clientOrderId?: string;
}
export interface IPlaceLimitOrderRequest {
/**
* Instrument ID, e.g `ADA-USDT`.
*/
symbol: string;
/**
* Client-supplied order ID
*/
clientOrderId?: string;
side: OrderSide;
/**
* Quantity to buy or sell.
*/
quantity: number;
/**
* Order price.
*/
price: number;
}
export interface IPlaceLimitOrderResponse {
/**
* Order ID.
*/
orderId: string;
/**
* Client-supplied order ID
*/
clientOrderId?: string;
}
export interface IPlaceMarketOrderRequest {
/**
* Instrument ID, e.g `BTC/USDT`.
*/
symbol: string;
/**
* Client-supplied order ID
*/
clientOrderId?: string;
side: OrderSide;
/**
* Quantity to buy or sell.
*/
quantity: number;
}
export interface IPlaceMarketOrderResponse {
/**
* Order ID.
*/
orderId: string;
/**
* Client-supplied order ID
*/
clientOrderId?: string;
}
export interface IPlaceStopOrderRequest {
type: "limit" | "market";
/**
* Instrument ID, e.g `ADA/USDT`.
*/
symbol: string;
side: OrderSide;
/**
* Quantity to buy or sell.
* If type == limit, the quantity is base currency
* If type == market, the quantity is quote currency
*/
quantity: number;
/**
* Order price.
*/
price?: number;
stopPrice: number;
}
export interface IPlaceStopOrderResponse {
/**
* Order ID.
*/
orderId: string;
/**
* Client-supplied order ID
*/
clientOrderId?: string;
}
export interface IOpenOrder {
/**
* Exchange-supplied order ID.
*/
exchangeOrderId: string;
/**
* Client-supplied order ID
*/
clientOrderId?: string;
side: OrderSide;
/**
* Quantity to buy or sell.
*/
quantity: number;
/**
* Order price.
*/
price: number;
/**
* Filled price.
*/
filledPrice: null;
/**
* Unix timestamp of the most recent trade on this order.
*/
lastTradeTimestamp: number;
/**
* Order status.
*/
status: Extract<OrderStatus, "open">;
/**
* Order fee.
*/
fee: number;
/**
* Creation time, Unix timestamp format in milliseconds, e.g. `1597026383085`
*/
createdAt: number;
}
export type IGetOpenOrdersRequest = {
/**
* e.g. ADA/USDT
*/
symbol: string;
};
export type IGetOpenOrdersResponse = IOpenOrder[];
export interface IClosedOrder {
/**
* Exchange-supplied order ID.
*/
exchangeOrderId: string;
/**
* Client-supplied order ID
*/
clientOrderId?: string;
side: OrderSide;
/**
* Quantity to buy or sell.
*/
quantity: number;
/**
* Order price.
*/
price: number;
/**
* Filled price.
*/
filledPrice: number | null;
/**
* Unix timestamp of the most recent trade on this order.
*/
lastTradeTimestamp: number;
/**
* Order status.
*/
status: Extract<OrderStatus, "filled" | "canceled">;
/**
* Order fee.
*/
fee: number;
/**
* Creation time, Unix timestamp format in milliseconds, e.g. `1597026383085`
*/
createdAt: number;
}
export type IGetClosedOrdersRequest = {
/**
* e.g. ADA/USDT
*/
symbol: string;
};
export type IGetClosedOrdersResponse = IClosedOrder[];
export interface IWatchOrder {
/**
* Exchange-supplied order ID.
*/
exchangeOrderId: string;
/**
* Client-supplied order ID
*/
clientOrderId?: string;
side: OrderSide;
/**
* Quantity to buy or sell.
*/
quantity: number;
/**
* Order price.
*/
price: number;
/**
* Filled price.
*/
filledPrice: number | null;
/**
* Order status.
*/
status: OrderStatus;
/**
* Order fee.
*/
fee: number;
/**
* Creation time, Unix timestamp format in milliseconds, e.g. `1597026383085`
*/
createdAt: number;
/**
* Unix timestamp of the most recent trade on this order.
*/
lastTradeTimestamp?: number;
}
export type IWatchOrdersRequest = {
/**
* e.g. ADA/USDT
*/
symbol?: string;
};
export type IWatchOrdersResponse = IWatchOrder[];
export type IWatchCandlesRequest = {
/**
* e.g. ADA/USDT
*/
symbol: string;
};
export type IWatchTradesRequest = {
/**
* e.g. ADA/USDT
*/
symbol: string;
};
export type IWatchTradesResponse = ITrade[];
export type MarketId<Base extends string = string, Quote extends string = string> = `${ExchangeCode}:${Base}/${Quote}`;
declare const MarketEventType: {
readonly onOrderFilled: "onOrderFilled";
readonly onTradeCompleted: "onTradeCompleted";
readonly onCandleClosed: "onCandleClosed";
readonly onPublicTrade: "onPublicTrade";
readonly onOrderbookChange: "onOrderbookChange";
readonly onTickerChange: "onTickerChange";
};
export type MarketEventType = (typeof MarketEventType)[keyof typeof MarketEventType];
export interface MarketData {
/**
* Last closed candlestick. May be `undefined` if the bot has just started or if the strategy policy is not subscribed
* to the candlesticks channel.
*/
candle?: ICandlestick;
/**
* Candles history. Last candle can be accessed by `candles[candles.length - 1]`
*/
candles: ICandlestick[];
/**
* Last public trade
*/
trade?: ITrade;
orderbook?: IOrderbook;
ticker?: ITicker;
}
declare const OrderType: {
readonly Limit: "Limit";
readonly Market: "Market";
};
export type OrderType = (typeof OrderType)[keyof typeof OrderType];
export type TIndicatorName = "RSI" | "SMA" | "EMA";
export type TIndicatorOptions<I extends TIndicatorName> = I extends "RSI" | "SMA" | "EMA" ? {
periods: number;
} : never;
export type IBotConfiguration<T = any> = {
id: number;
symbol: string;
exchangeCode?: ExchangeCode;
settings: T;
timeframe?: BarSize | null;
};
export interface IExchange {
isPaper: boolean;
ccxt: Exchange;
exchangeCode: ExchangeCode;
destroy: () => Promise<void>;
loadMarkets: () => Promise<Record<string, Market>>;
accountAssets: () => Promise<IAccountAsset[]>;
getLimitOrder: (body: IGetLimitOrderRequest) => Promise<IGetLimitOrderResponse>;
placeOrder: (body: IPlaceOrderRequest) => Promise<IPlaceOrderResponse>;
placeLimitOrder: (body: IPlaceLimitOrderRequest) => Promise<IPlaceLimitOrderResponse>;
placeMarketOrder: (boyd: IPlaceMarketOrderRequest) => Promise<IPlaceMarketOrderResponse>;
cancelLimitOrder: (body: ICancelLimitOrderRequest) => Promise<ICancelLimitOrderResponse>;
placeStopOrder: (body: IPlaceStopOrderRequest) => Promise<IPlaceStopOrderResponse>;
getOpenOrders: (body: IGetOpenOrdersRequest) => Promise<IGetOpenOrdersResponse>;
getClosedOrders: (body: IGetClosedOrdersRequest) => Promise<IGetClosedOrdersResponse>;
getTicker: (symbol: string) => Promise<ITicker>;
getMarketPrice: (params: IGetMarketPriceRequest) => Promise<IGetMarketPriceResponse>;
getCandlesticks: (params: IGetCandlesticksRequest) => Promise<ICandlestick[]>;
getSymbols: () => Promise<ISymbolInfo[]>;
getSymbol: (params: IGetSymbolInfoRequest) => Promise<ISymbolInfo>;
watchOrders: (params?: IWatchOrdersRequest) => Promise<IWatchOrdersResponse>;
watchCandles: (symbol: IWatchCandlesRequest) => Promise<ICandlestick[]>;
watchTrades: (symbol: IWatchTradesRequest) => Promise<IWatchTradesResponse>;
watchOrderbook: (symbol: string) => Promise<IOrderbook>;
watchTicker: (symbol: string) => Promise<ITicker>;
}
export type Order = {
id: number;
status: XOrderStatus;
type: XOrderType;
entityType: XEntityType;
side: XOrderSide;
price?: number;
stopPrice?: number;
relativePrice?: number;
filledPrice?: number;
fee?: number;
symbol: string;
exchangeAccountId: number;
exchangeOrderId?: string;
quantity: number;
createdAt: Date;
updatedAt: Date;
placedAt?: Date;
syncedAt?: Date;
filledAt?: Date;
};
export interface BaseTrade<T extends XSmartTradeType> {
id: number;
ref: string;
type: T;
symbol: string;
createdAt: Date;
updatedAt: Date;
orders: Order[];
}
export interface SmartTrade extends BaseTrade<typeof XSmartTradeType.Trade> {
entryOrder: Order;
tpOrder?: Order;
slOrder?: Order;
}
export interface DcaTrade extends BaseTrade<typeof XSmartTradeType.DCA> {
entryOrder: Order;
tpOrder: Order;
slOrder?: Order;
safetyOrders: Order[];
}
export interface ArbTrade extends BaseTrade<typeof XSmartTradeType.ARB> {
entryOrder: Order;
tpOrder: Order;
slOrder?: Order;
}
export type Trade = SmartTrade | DcaTrade | ArbTrade;
export type CreateOrder = {
/**
* Exchange account ID where the order will be placed.
*/
exchangeAccountId?: number;
/**
* Symbol to trade. If not provided, then the bot's default symbol will be used.
*/
symbol?: string;
type: XOrderType;
status?: XOrderStatus;
side: XOrderSide;
stopPrice?: number;
price?: number;
quantity: number;
/**
* Price deviation relative to entry price.
* If 0.1, the order will be placed as entryPrice + 10%
* If -0.1, the order will be placed as entryPrice - 10%
*/
relativePrice?: number;
};
export type CreateSmartTrade = {
type: typeof XSmartTradeType.Trade;
entry: CreateOrder;
tp?: CreateOrder;
sl?: CreateOrder;
};
export type CreateDcaTrade = {
type: typeof XSmartTradeType.DCA;
entry: CreateOrder;
tp: CreateOrder;
sl?: CreateOrder;
safetyOrders: CreateOrder[];
};
export type CreateArbTrade = {
type: typeof XSmartTradeType.ARB;
entry: CreateOrder;
tp: CreateOrder;
};
export type CreateTrade = CreateSmartTrade | CreateDcaTrade | CreateArbTrade;
export interface IBotControl {
/**
* Stop bot
*/
stop: () => Promise<void>;
getSmartTrade: (ref: string) => Promise<Trade | null>;
updateSmartTrade: (ref: string, payload: Pick<CreateTrade, "tp">) => Promise<Trade | null>;
createSmartTrade: (ref: string, payload: CreateTrade) => Promise<Trade>;
getOrCreateSmartTrade: (ref: string, payload: CreateTrade) => Promise<Trade>;
replaceSmartTrade: (ref: string, payload: Trade) => Promise<Trade>;
cancelSmartTrade: (ref: string) => Promise<boolean>;
getExchange: (label: string) => Promise<IExchange | null>;
}
export type BotState = Record<string, any>;
export type TBotContext<T extends IBotConfiguration, S extends BotState = BotState> = {
/**
* Default exchange instance.
*/
exchange: IExchange;
additionalExchanges: IExchange[];
/**
* Bot control panel
*/
control: IBotControl;
/**
* Bot configuration
*/
config: T;
/**
* Bot's state
*/
state: S;
/**
* Event
*/
command: "start" | "stop" | "process";
event?: MarketEventType;
onStart: boolean;
onStop: boolean;
onProcess: boolean;
/**
* Default market from `bot.symbol`
*/
market: MarketData;
/**
* Additional markets
*/
markets: Record<MarketId, MarketData>;
};
export type WatchCondition<T extends IBotConfiguration> = string | string[] | ((botConfig: T) => string | string[]);
export declare const Watcher: {
readonly watchTrades: "watchTrades";
readonly watchOrderbook: "watchOrderbook";
readonly watchTicker: "watchTicker";
readonly watchCandles: "watchCandles";
};
export type Watcher = (typeof Watcher)[keyof typeof Watcher];
export interface BotTemplate<T extends IBotConfiguration> {
(ctx: TBotContext<T>): Generator<unknown, unknown>;
/**
* Display name of the bot. Used in the UI.
*/
displayName?: string;
/**
* Strategy description. What does the strategy do?
*/
description?: string;
/**
* Number of candles the strategy requires for warm-up.
* When the bot starts, it will download the required number of candles.
*/
requiredHistory?: number | ((botConfig: T) => number | undefined);
/**
* Used to aggregate 1m candles to a higher timeframe, when using candles watcher.
* If not provided, the timeframe from the bot config will be used.
*/
timeframe?: BarSize | null | ((botConfig: T) => BarSize | null | undefined);
/**
* Strategy params schema.
*/
schema: ZodObject<any, any, any>;
/**
* If true, the bot will not be displayed in the list of available strategies.
* Mainly used for debug strategies.
*/
hidden?: boolean;
/**
* List of pairs to watch for trades.
*
* @example Watch trades on BTC/USDT pair. The default exchange from bot config will be used.
* ```ts
* strategy.watchers = {
* watchTrades: "BTC/USDT",
* }
* ```
*
* @example Watch trades on specific exchange.
* ```ts
* strategy.watchers = {
* watchTrades: "OKX:BTC/USDT"
* }
* ```
*
* @example Watch trades on multiple pairs.
* ```ts
* strategy.watchers = {
* watchTrades: ["BTC/USDT", "ETH/USDT"],
* }
* ```
*
* @example Watch trades on different exchanges.
* ```ts
* strategy.watchers = {
* watchTrades: ["OKX:BTC/USDT", "BINANCE:BTC/USDT"]
* }
* ```
*
* @example Watch trades on a computed pairs list.
* ```ts
* strategy.watchers = {
* watchTrades: (botConfig) => botConfig.symbol
* }
* ```
*/
watchers?: {
[Watcher.watchTrades]?: WatchCondition<T>;
[Watcher.watchOrderbook]?: WatchCondition<T>;
[Watcher.watchTicker]?: WatchCondition<T>;
[Watcher.watchCandles]?: WatchCondition<T>;
};
runPolicy?: {
/**
* The size of the candle is determined by `timeframe` property above.
* If not provided, the channel will listen to 1m candles.
*/
[MarketEventType.onCandleClosed]?: boolean | ((botConfig: T) => boolean);
[MarketEventType.onPublicTrade]?: boolean | ((botConfig: T) => boolean);
[MarketEventType.onOrderbookChange]?: boolean | ((botConfig: T) => boolean);
[MarketEventType.onTickerChange]?: boolean | ((botConfig: T) => boolean);
[MarketEventType.onOrderFilled]?: boolean | ((botConfig: T) => boolean);
[MarketEventType.onTradeCompleted]?: boolean | ((botConfig: T) => boolean);
};
}
export declare class SmartTradeService {
private ref;
private smartTrade;
type: XSmartTradeType;
entry: Trade["entryOrder"];
tp: Trade["tpOrder"];
sl: Trade["slOrder"];
constructor(ref: string, smartTrade: Trade);
/**
* Create a new SmartTrade with same buy/sell orders
*/
replace(): BaseEffect<"REPLACE_SMART_TRADE", Trade, string>;
cancel(): BaseEffect<"CANCEL_SMART_TRADE", undefined, string>;
isCompleted(): boolean;
}
export interface IStore {
stopBot: (botId: number) => Promise<void>;
getSmartTrade: (ref: string, botId: number) => Promise<Trade | null>;
createSmartTrade: (ref: string, payload: CreateTrade, botId: number) => Promise<Trade>;
updateSmartTrade: (ref: string, payload: Pick<CreateTrade, "tp">, botId: number) => Promise<Trade | null>;
/**
* If `true` then SmartTrade was canceled with success.
* @param ref - SmartTrade ref
* @param botId - Bot ID
*/
cancelSmartTrade: (ref: string, botId: number) => Promise<boolean>;
getExchange: (label: string) => Promise<IExchange | null>;
}
export type UseSmartTradePayload = {
entry: {
type: XOrderType;
side: XOrderSide;
price?: number;
status?: XOrderStatus;
};
tp?: {
type: XOrderType;
side: XOrderSide;
price?: number;
status?: XOrderStatus;
};
sl?: {
type: XOrderType;
side: XOrderSide;
price?: number;
stopPrice: number;
};
quantity: number;
};
export declare function useSmartTrade(params: UseSmartTradePayload, ref?: string): BaseEffect<"USE_SMART_TRADE", UseSmartTradePayload, string>;
export declare function getSmartTrade(ref?: string): BaseEffect<"GET_SMART_TRADE", undefined, string>;
export declare function createSmartTrade(payload: UseSmartTradePayload, ref?: string): BaseEffect<"CREATE_SMART_TRADE", UseSmartTradePayload, string>;
export declare function cancelSmartTrade(ref?: string): BaseEffect<"CANCEL_SMART_TRADE", undefined, string>;
export declare function replaceSmartTrade(payload: Trade, ref?: string): BaseEffect<"REPLACE_SMART_TRADE", Trade, string>;
export type BuyPayload = {
exchange?: ExchangeCode;
pair?: string;
quantity: number;
price?: number;
orderType?: "Limit" | "Market";
};
export declare function buy(payload: BuyPayload, ref?: string): BaseEffect<"BUY", BuyPayload, string>;
export type SellPayload = {
exchange?: ExchangeCode;
pair?: string;
quantity: number;
price?: number;
orderType?: "Limit" | "Market";
};
export declare function sell(payload: SellPayload, ref?: string): BaseEffect<"SELL", SellPayload, string>;
/**
* If no label is provided, the default exchange linked to the bot will be used.
* If provided, an external exchange with the given label will be used.
*/
export declare function useExchange(label?: string): BaseEffect<"USE_EXCHANGE", string | undefined, undefined>;
export type IndicatorPayload<I extends TIndicatorName = TIndicatorName> = [
name: I,
barSize: BarSize,
options: TIndicatorOptions<I>
];
export declare function useIndicator<I extends TIndicatorName>(...[name, barSize, options]: IndicatorPayload<I>): BaseEffect<"USE_INDICATOR", {
name: I;
barSize: BarSize;
options: TIndicatorOptions<I>;
}, undefined>;
export declare function useIndicators(payload: IndicatorPayload[]): BaseEffect<"USE_INDICATORS", IndicatorPayload<TIndicatorName>[], undefined>;
export type UseTradePayload = {
quantity: number;
/**
* Order side. Default to "buy"
*/
side?: OrderSide;
/**
* Entry order price.
*/
price?: number;
/**
* Take profit order price.
*/
tp?: number;
/**
* Stop loss order price.
*/
sl?: never;
exchange?: ExchangeCode;
pair?: string;
/**
* Entry order type. Default to "Limit"
*/
entryType?: OrderType;
/**
* Entry order type. Default to "Limit"
*/
takeProfitType?: OrderType;
/**
* Entry order type. Default to "Market". Not implemented.
*/
stopLossType?: OrderType;
};
export declare function useTrade(params: UseTradePayload, ref?: string): BaseEffect<"USE_TRADE", UseTradePayload, string>;
export type UseArbPayload = {
/**
* The quantity of the asset to trade.
*/
quantity: number;
/**
* The exchange to buy from.
*/
exchange1: number;
/**
* The exchange to sell to.
*/
exchange2: number;
/**
* The Limit entry price of the order. If not provided, a market order will be placed.
*/
price?: number;
/**
* The Limit exit price of the order. If not provided, a market order will be placed.
*/
tp?: number;
/**
* The symbol to trade, e.g. BTC/USDT.
*/
symbol?: string;
};
export declare function useArbTrade(params: UseArbPayload, ref?: string): BaseEffect<"USE_ARB_TRADE", UseArbPayload, string>;
export type SafetyOrder = {
quantity: number;
relativePrice: number;
};
export type UseDcaPayload = {
/**
* Entry order quantity
*/
quantity: number;
/**
* The Limit entry price of the order. If not provided, a market order will be placed.
*/
price?: number;
/**
* The Limit exit price of the order (e.g. 0.01 is 10%)
*/
tpPercent: number;
/**
* The price drop to trigger the SL (e.g. 0.01 is 10% drop)
*/
slPercent?: number;
/**
* Safety orders to be placed when price goes down
*/
safetyOrders: SafetyOrder[];
/**
* The symbol to trade, e.g. BTC/USDT.
*/
symbol?: string;
};
export declare function useDca(params: UseDcaPayload, ref?: string): BaseEffect<"USE_DCA", UseDcaPayload, string>;
export declare function useMarket(): BaseEffect<"USE_MARKET", undefined, undefined>;
/**
* Get candle data for the given index.
* If the index is negative, it will return the candle data from the end.
* By default, will return the last candle.
*/
export declare function useCandle(index?: number): BaseEffect<"USE_CANDLE", number, undefined>;
export declare function useRSI(periods?: number): BaseEffect<"USE_RSI_INDICATOR", number, undefined>;
export declare class StrategyRunner<T extends IBotConfiguration> {
private control;
private botConfig;
private exchange;
private additionalExchanges;
private botTemplate;
constructor(control: IBotControl, botConfig: T, exchange: IExchange, additionalExchanges: IExchange[], botTemplate: BotTemplate<T>);
start(state: BotState): Promise<void>;
stop(state: BotState): Promise<void>;
process(state: BotState, event?: MarketEventType, market?: MarketData, markets?: Record<MarketId, MarketData>): Promise<void>;
private runTemplate;
}
export declare function createStrategyRunner<T extends IBotConfiguration>(options: {
store: IStore;
exchange: IExchange;
additionalExchanges: IExchange[];
botConfig: T;
botTemplate: BotTemplate<T>;
}): StrategyRunner<T>;
export declare class BotControl<T extends IBotConfiguration> implements IBotControl {
private store;
private bot;
constructor(store: IStore, bot: T);
stop(): Promise<void>;
getSmartTrade(ref: string): Promise<Trade | null>;
createSmartTrade(ref: string, payload: CreateTrade): Promise<Trade>;
updateSmartTrade(ref: string, payload: Pick<CreateTrade, "tp">): Promise<Trade | null>;
getOrCreateSmartTrade(ref: string, payload: CreateTrade): Promise<Trade>;
replaceSmartTrade(ref: string, smartTrade: Trade): Promise<Trade>;
cancelSmartTrade(ref: string): Promise<boolean>;
getExchange(label: string): Promise<IExchange | null>;
}
export {};