#![allow(non_camel_case_types)]
use std::fmt;
use std::str::FromStr;
macro_rules! wire_enum {
(
$(#[$meta:meta])*
$name:ident,
display_name = $display:expr,
{ $( $variant:ident = $wire:literal [ $( $alias:literal ),* ] ),* $(,)? }
) => {
$(#[$meta])*
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum $name {
$( #[cfg_attr(feature = "serde", serde(rename = $wire))] $variant ),*
}
impl $name {
pub const ALL: &'static [Self] = &[ $( Self::$variant ),* ];
pub fn as_str(&self) -> &'static str {
match self { $( Self::$variant => $wire ),* }
}
pub fn chinese_alias(&self) -> &'static [&'static str] {
match self { $( Self::$variant => &[ $( $alias ),* ] ),* }
}
pub const DISPLAY: &'static str = $display;
}
impl fmt::Display for $name {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
impl FromStr for $name {
type Err = EnumParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
$( if s == $wire { return Ok(Self::$variant); } )*
$(
$( if s == $alias { return Ok(Self::$variant); } )*
)*
Err(EnumParseError { input: s.to_string(), type_name: $display })
}
}
};
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct EnumParseError {
pub input: String,
pub type_name: &'static str,
}
impl fmt::Display for EnumParseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "unknown {} value: {:?}", self.type_name, self.input)
}
}
impl std::error::Error for EnumParseError {}
wire_enum!(
Direction, display_name = "Direction",
{
LONG = "LONG" ["多"],
SHORT = "SHORT" ["空"],
NET = "NET" ["净"]
}
);
wire_enum!(
Offset, display_name = "Offset",
{
NONE = "NONE" [""],
OPEN = "OPEN" ["开"],
CLOSE = "CLOSE" ["平"],
CLOSETODAY = "CLOSETODAY" ["平今"],
CLOSEYESTERDAY = "CLOSEYESTERDAY" ["平昨"]
}
);
wire_enum!(
Status, display_name = "Status",
{
SUBMITTING = "SUBMITTING" ["提交中"],
NOTTRADED = "NOTTRADED" ["未成交"],
PARTTRADED = "PARTTRADED" ["部分成交"],
ALLTRADED = "ALLTRADED" ["全部成交"],
CANCELLED = "CANCELLED" ["已撤销"],
REJECTED = "REJECTED" ["拒单"],
UNKNOWN = "UNKNOWN" ["未知"]
}
);
wire_enum!(
Asset, display_name = "Asset",
{
EQUITY = "EQUITY" ["股票"],
BOND = "BOND" ["债券"],
FUTURES = "FUTURES" ["期货"],
OPTION = "OPTION" ["期权"],
FOREX = "FOREX" ["外汇"],
UNKNOWN = "UNKNOWN" ["未知"]
}
);
wire_enum!(
InstrumentType, display_name = "InstrumentType",
{
STOCK = "STOCK" ["股票"],
ETF = "ETF" [],
INDEX = "INDEX" ["指数"],
FUTURES_CONTRACT = "FUTURES_CONTRACT" ["期货合约"],
MAIN_CONTRACT = "MAIN_CONTRACT" ["主力合约"],
CONTINUOUS_CONTRACT = "CONTINUOUS_CONTRACT" ["连续合约"],
OPTION_CONTRACT = "OPTION_CONTRACT" ["期权合约"],
BOND = "BOND" ["债券"],
CONVERTIBLE_BOND = "CONVERTIBLE_BOND" ["可转债"],
SPREAD = "SPREAD" ["价差组合"],
HEDGE = "HEDGE" ["对冲组合"]
}
);
wire_enum!(
OrderType, display_name = "OrderType",
{
LIMIT = "LIMIT" ["限价"],
MARKET = "MARKET" ["市价"],
STOP = "STOP" [],
FAK = "FAK" [],
FOK = "FOK" [],
RFQ = "RFQ" ["询价"],
UNKNOWN = "UNKNOWN" ["未知"]
}
);
wire_enum!(
OptionType, display_name = "OptionType",
{
CALL = "CALL" ["看涨期权"],
PUT = "PUT" ["看跌期权"]
}
);
wire_enum!(
Currency, display_name = "Currency",
{
USD = "USD" [],
HKD = "HKD" [],
CNY = "CNY" [],
CAD = "CAD" []
}
);
wire_enum!(
Exchange, display_name = "Exchange",
{
CFFEX = "CFFEX" [],
SHFE = "SHFE" [],
CZCE = "CZCE" [],
DCE = "DCE" [],
INE = "INE" [],
GFEX = "GFEX" [],
SSE = "SSE" [],
SZSE = "SZSE" [],
BSE = "BSE" [],
SHHK = "SHHK" [],
SZHK = "SZHK" [],
SGE = "SGE" [],
WXE = "WXE" [],
CFETS = "CFETS" [],
XBOND = "XBOND" [],
SMART = "SMART" [],
NYSE = "NYSE" [],
NASDAQ = "NASDAQ" [],
ARCA = "ARCA" [],
EDGEA = "EDGEA" [],
ISLAND = "ISLAND" [],
BATS = "BATS" [],
IEX = "IEX" [],
AMEX = "AMEX" [],
TSE = "TSE" [],
NYMEX = "NYMEX" [],
COMEX = "COMEX" [],
GLOBEX = "GLOBEX" [],
IDEALPRO = "IDEALPRO" [],
CME = "CME" [],
ICE = "ICE" [],
SEHK = "SEHK" [],
HKFE = "HKFE" [],
SGX = "SGX" [],
CBOT = "CBT" [],
CBOE = "CBOE" [],
CFE = "CFE" [],
DME = "DME" [],
EUREX = "EUX" [],
APEX = "APEX" [],
LME = "LME" [],
BMD = "BMD" [],
TOCOM = "TOCOM" [],
EUNX = "EUNX" [],
KRX = "KRX" [],
OTC = "OTC" [],
IBKRATS = "IBKRATS" [],
LOCAL = "LOCAL" [],
ETF_INDEX = "ETF_index" [],
SW = "SW" [],
UNKNOWN = "UNKNOWN" ["未知"]
}
);
wire_enum!(
Interval, display_name = "Interval",
{
TICK = "TICK" [],
MINUTE = "MINUTE" [],
MINUTE_5 = "MINUTE_5" [],
MINUTE_15 = "MINUTE_15" [],
MINUTE_30 = "MINUTE_30" [],
HOUR = "HOUR" [],
DAILY = "DAILY" [],
WEEKLY = "WEEKLY" []
}
);
impl Interval {
pub fn seconds(&self) -> i64 {
match self {
Self::TICK => 0,
Self::MINUTE => 60,
Self::MINUTE_5 => 300,
Self::MINUTE_15 => 900,
Self::MINUTE_30 => 1800,
Self::HOUR => 3600,
Self::DAILY => 86400,
Self::WEEKLY => 604800,
}
}
}
pub const ACTIVE_STATUSES: [Status; 3] =
[Status::SUBMITTING, Status::NOTTRADED, Status::PARTTRADED];
impl Status {
pub fn is_active(&self) -> bool {
ACTIVE_STATUSES.contains(self)
}
}
impl Default for Exchange {
fn default() -> Self {
Self::LOCAL
}
}
impl Default for OrderType {
fn default() -> Self {
Self::LIMIT
}
}
impl Default for Offset {
fn default() -> Self {
Self::NONE
}
}
impl Default for Status {
fn default() -> Self {
Self::SUBMITTING
}
}
impl Default for Direction {
fn default() -> Self {
Self::NET
}
}
impl Default for Asset {
fn default() -> Self {
Self::EQUITY
}
}