openpine_vm/
currency.rs

1use openpine_macros::Enum;
2use serde::{Deserialize, Serialize};
3
4/// Currency codes as per ISO 4217 standard.
5#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Enum, Serialize, Deserialize)]
6#[openpine(rename_all = "uppercase")]
7pub enum Currency {
8    /// Arab Emirates Dirham.
9    AED,
10    /// Argentine Peso.
11    ARS,
12    /// Australian Dollar.
13    AUD,
14    /// Bangladeshi Taka.
15    BDT,
16    /// Bahraini Dinar.
17    BHD,
18    /// Brazilian Real.
19    BRL,
20    /// Bitcoin.
21    BTC,
22    /// Canadian Dollar.
23    CAD,
24    /// Swiss Franc.
25    CHF,
26    /// Chilean Peso.
27    CLP,
28    /// Chinese Yuan.
29    CNY,
30    /// Colombian Peso.
31    COP,
32    /// Czech Koruna.
33    CZK,
34    /// Danish Krone.
35    DKK,
36    /// Egyptian Pound.
37    EGP,
38    /// Ether (Ethereum).
39    ETH,
40    /// Euro.
41    EUR,
42    /// British Pound Sterling.
43    GBP,
44    /// Hong Kong Dollar.
45    HKD,
46    /// Hungarian Forint.
47    HUF,
48    /// Indonesian Rupiah.
49    IDR,
50    /// Israeli New Shekel.
51    ILS,
52    /// Indian Rupee.
53    INR,
54    /// Icelandic Krona.
55    ISK,
56    /// Japanese Yen.
57    JPY,
58    /// Kenyan Shilling.
59    KES,
60    /// South Korean Won.
61    KRW,
62    /// Kuwaiti Dinar.
63    KWD,
64    /// Sri Lankan Rupee.
65    LKR,
66    /// Moroccan Dirham.
67    MAD,
68    /// Mexican Peso.
69    MXN,
70    /// Malaysian Ringgit.
71    MYR,
72    /// Nigerian Naira.
73    NGN,
74    /// Norwegian Krone.
75    NOK,
76    /// Unspecified currency.
77    NONE,
78    /// New Zealand Dollar.
79    NZD,
80    /// Peruvian Sol.
81    PEN,
82    /// Philippine Peso.
83    PHP,
84    /// Pakistani Rupee.
85    PKR,
86    /// Polish Zloty.
87    PLN,
88    /// Qatari Riyal.
89    QAR,
90    /// Romanian Leu.
91    RON,
92    /// Serbian Dinar.
93    RSD,
94    /// Russian Ruble.
95    RUB,
96    /// Saudi Riyal.
97    SAR,
98    /// Swedish Krona.
99    SEK,
100    /// Singapore Dollar.
101    SGD,
102    /// Thai Baht.
103    THB,
104    /// Tunisian Dinar.
105    TND,
106    /// Turkish Lira.
107    TRY,
108    /// New Taiwan Dollar.
109    TWD,
110    /// United States Dollar.
111    USD,
112    /// Tether.
113    USDT,
114    /// Venezuelan Bolívar.
115    VES,
116    /// Vietnamese Dong.
117    VND,
118    /// South African Rand.
119    ZAR,
120}
121
122/// Converts monetary values between currencies.
123///
124/// Used by `strategy.convert_to_account()` and
125/// `strategy.convert_to_symbol()`. The default implementation
126/// ([`IdentityCurrencyConverter`]) returns the input value unchanged, which
127/// is correct when the symbol currency equals the account currency.
128///
129/// Supply a custom implementation via
130/// [`InstanceBuilder::with_currency_converter()`](crate::InstanceBuilder::with_currency_converter) to enable cross-currency
131/// backtesting.
132#[async_trait::async_trait(?Send)]
133pub trait CurrencyConverter {
134    /// Converts `value` expressed in `from` currency to `to` currency.
135    ///
136    /// Returns `None` if the conversion is not possible (e.g. missing rate).
137    async fn convert(&self, value: f64, from: Currency, to: Currency) -> Option<f64>;
138}
139
140/// A no-op converter that returns the input value unchanged.
141///
142/// This is the default used when no custom converter is provided.  It is
143/// correct as long as the symbol and account currencies are the same.
144#[derive(Debug, Clone, Copy)]
145pub struct IdentityCurrencyConverter;
146
147#[async_trait::async_trait(?Send)]
148impl CurrencyConverter for IdentityCurrencyConverter {
149    #[inline]
150    async fn convert(&self, value: f64, _from: Currency, _to: Currency) -> Option<f64> {
151        Some(value)
152    }
153}
154
155/// Returns the default (identity) currency converter.
156pub(crate) fn default_currency_converter() -> Box<dyn CurrencyConverter> {
157    Box::new(IdentityCurrencyConverter)
158}
159
160impl Currency {
161    /// Returns the currency sign/symbol.
162    pub fn sign(&self) -> &'static str {
163        match self {
164            Currency::AED => "د.إ",
165            Currency::ARS => "$",
166            Currency::AUD => "$",
167            Currency::BDT => "৳",
168            Currency::BHD => ".د.ب",
169            Currency::BRL => "R$",
170            Currency::BTC => "₿",
171            Currency::CAD => "$",
172            Currency::CHF => "Fr.",
173            Currency::CLP => "$",
174            Currency::CNY => "¥",
175            Currency::COP => "$",
176            Currency::CZK => "Kč",
177            Currency::DKK => "kr",
178            Currency::EGP => "£",
179            Currency::ETH => "Ξ",
180            Currency::EUR => "€",
181            Currency::GBP => "£",
182            Currency::HKD => "$",
183            Currency::HUF => "Ft",
184            Currency::IDR => "Rp",
185            Currency::ILS => "₪",
186            Currency::INR => "₹",
187            Currency::ISK => "kr",
188            Currency::JPY => "¥",
189            Currency::KES => "KSh",
190            Currency::KRW => "₩",
191            Currency::KWD => "د.ك",
192            Currency::LKR => "රු",
193            Currency::MAD => "د.م.",
194            Currency::MXN => "$",
195            Currency::MYR => "RM",
196            Currency::NGN => "₦",
197            Currency::NOK => "kr",
198            Currency::NONE => "",
199            Currency::NZD => "$",
200            Currency::PEN => "S/",
201            Currency::PHP => "₱",
202            Currency::PKR => "₨",
203            Currency::PLN => "zł",
204            Currency::QAR => "ر.ق",
205            Currency::RON => "lei",
206            Currency::RSD => "дин.",
207            Currency::RUB => "₽",
208            Currency::SAR => "ر.س",
209            Currency::SEK => "kr",
210            Currency::SGD => "$",
211            Currency::THB => "฿",
212            Currency::TND => "د.ت",
213            Currency::TRY => "₺",
214            Currency::TWD => "NT$",
215            Currency::USD => "$",
216            Currency::USDT => "$",
217            Currency::VES => "Bs.S.",
218            Currency::VND => "₫",
219            Currency::ZAR => "R",
220        }
221    }
222}