diff --git a/src/validate/formatter/Currency.js b/src/validate/formatter/Currency.js
new file mode 100644
index 0000000..5ecf339
--- /dev/null
+++ b/src/validate/formatter/Currency.js
@@ -0,0 +1,75 @@
+/**
+ * Currency formatter
+ *
+ * Copyright (C) 2016 LoVullo Associates, Inc.
+ *
+ * This file is part of liza.
+ *
+ * liza is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+var Trait = require( 'easejs' ).Trait,
+ ValidatorFormatter = require( '../ValidatorFormatter' );
+
+
+/**
+ * Formats amount as currency
+ *
+ * This does not guarantee that the value is a number; this should be
+ * mixed in atop of a formatter that does guarantee such.
+ */
+module.exports = Trait( 'Currency' )
+ .implement( ValidatorFormatter )
+ .extend(
+{
+ /**
+ * Parse item as currency
+ *
+ * @param {string} data data to parse
+ *
+ * @return {string} data formatted for storage
+ */
+ 'virtual abstract override public parse': function( data )
+ {
+ return this.__super( data ).replace( /^\$*/g, '' );
+ },
+
+
+ /**
+ * Format amount as a currency
+ *
+ * @param {string} data data to format for display
+ *
+ * @return {string} data formatted for display
+ */
+ 'virtual abstract override public retrieve': function( data )
+ {
+ return this.styleCurrency( this.__super( data ) );
+ },
+
+
+ /**
+ * Style amount with currency symbol
+ *
+ * @param {string} amount amount to style
+ *
+ * @return {string} formatted number
+ */
+ 'virtual protected styleCurrency': function( amount )
+ {
+ return ( ''+amount === '' )
+ ? amount
+ : '$' + amount;
+ },
+} );
diff --git a/test/validate/formatter/CurrencyTest.js b/test/validate/formatter/CurrencyTest.js
new file mode 100644
index 0000000..968e2e3
--- /dev/null
+++ b/test/validate/formatter/CurrencyTest.js
@@ -0,0 +1,60 @@
+/**
+ * Currency formatter test
+ *
+ * Copyright (C) 2016 LoVullo Associates, Inc.
+ *
+ * This file is part of liza.
+ *
+ * liza is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+var liza = require( '../../../' ),
+ Sut = liza.validate.formatter.Currency,
+ EchoFormatter = liza.validate.formatter.EchoFormatter,
+ common = require( './common' );
+
+
+describe( 'validate.formatter.Currency', function()
+{
+ common.testValidate( EchoFormatter.use( Sut )(), {
+ // should format anything given to it, with or without prefix
+ "1": [ "1", "$1" ],
+ "foo": [ "foo", "$foo" ],
+ "+": [ "+", "$+" ],
+ "$foo": [ "foo", "$foo" ],
+
+ // empty shouldn't format as anything
+ "": [ "", "" ],
+ "$": [ "", "" ],
+ "$$": [ "", "" ],
+
+ // make sure these aren't considered to be empty
+ "0": [ "0", "$0" ],
+ "$0": [ "0", "$0" ],
+
+ // be lax on input
+ "$$foo": [ "foo", "$foo" ],
+ "$$$$$$$12.34": [ "12.34", "$12.34" ],
+ } );
+
+
+ common.testMixin(
+ EchoFormatter,
+ Sut,
+ 'foo',
+ '123',
+ 'foo123',
+ '$foo123'
+ );
+} );