diff --git a/iota/commands/extended/get_inputs.py b/iota/commands/extended/get_inputs.py
index f131f9a..aaeb5d5 100644
--- a/iota/commands/extended/get_inputs.py
+++ b/iota/commands/extended/get_inputs.py
@@ -5,6 +5,7 @@
 from typing import Optional
 
 import filters as f
+
 from iota import BadApiResponse
 from iota.commands import FilterCommand, RequestFilter
 from iota.commands.core.get_balances import GetBalancesCommand
@@ -12,7 +13,7 @@
 from iota.crypto.addresses import AddressGenerator
 from iota.crypto.types import Seed
 from iota.exceptions import with_context
-from iota.filters import Trytes
+from iota.filters import SecurityLevel, Trytes
 
 __all__ = [
   'GetInputsCommand',
@@ -112,7 +113,8 @@ def __init__(self):
         'stop':       f.Type(int) | f.Min(0),
         'start':      f.Type(int) | f.Min(0) | f.Optional(0),
         'threshold':  f.Type(int) | f.Min(0),
-        'securityLevel': f.Type(int) | f.Min(1) | f.Max(3) | f.Optional(default=AddressGenerator.DEFAULT_SECURITY_LEVEL),
+
+        'securityLevel': SecurityLevel,
 
         # These arguments are required.
         'seed': f.Required | Trytes(result_type=Seed),
diff --git a/iota/commands/extended/get_new_addresses.py b/iota/commands/extended/get_new_addresses.py
index 7acf1a8..552561d 100644
--- a/iota/commands/extended/get_new_addresses.py
+++ b/iota/commands/extended/get_new_addresses.py
@@ -6,12 +6,12 @@
 
 import filters as f
 
-from iota import Address, AddressChecksum
+from iota import Address
 from iota.commands import FilterCommand, RequestFilter
 from iota.commands.core.find_transactions import FindTransactionsCommand
 from iota.crypto.addresses import AddressGenerator
 from iota.crypto.types import Seed
-from iota.filters import Trytes
+from iota.filters import SecurityLevel, Trytes
 
 __all__ = [
   'GetNewAddressesCommand',
@@ -40,7 +40,7 @@ def _execute(self, request):
     seed            = request['seed'] # type: Seed
 
     return {
-      'addresses': 
+      'addresses':
          self._find_addresses(seed, index, count, security_level, checksum),
     }
 
@@ -85,11 +85,7 @@ def __init__(self):
         'count':     f.Type(int) | f.Min(1),
         'index':     f.Type(int) | f.Min(0) | f.Optional(default=0),
 
-        'securityLevel':
-              f.Type(int)
-            | f.Min(1)
-            | f.Max(self.MAX_SECURITY_LEVEL)
-            | f.Optional(default=AddressGenerator.DEFAULT_SECURITY_LEVEL),
+        'securityLevel': SecurityLevel,
 
         'seed': f.Required | Trytes(result_type=Seed),
       },
diff --git a/iota/commands/extended/prepare_transfer.py b/iota/commands/extended/prepare_transfer.py
index bac5017..390e218 100644
--- a/iota/commands/extended/prepare_transfer.py
+++ b/iota/commands/extended/prepare_transfer.py
@@ -5,17 +5,17 @@
 from typing import List, Optional
 
 import filters as f
+
 from iota import Address, BadApiResponse, ProposedBundle, \
   ProposedTransaction
 from iota.commands import FilterCommand, RequestFilter
 from iota.commands.core.get_balances import GetBalancesCommand
 from iota.commands.extended.get_inputs import GetInputsCommand
 from iota.commands.extended.get_new_addresses import GetNewAddressesCommand
-from iota.crypto.addresses import AddressGenerator
 from iota.crypto.signing import KeyGenerator
 from iota.crypto.types import Seed
 from iota.exceptions import with_context
-from iota.filters import GeneratedAddress, Trytes
+from iota.filters import GeneratedAddress, SecurityLevel, Trytes
 
 __all__ = [
   'PrepareTransferCommand',
@@ -133,7 +133,7 @@ def __init__(self):
 
         # Optional parameters.
         'changeAddress': Trytes(result_type=Address),
-        'securityLevel': f.Type(int) | f.Min(1) | f.Max(3) | f.Optional(default=AddressGenerator.DEFAULT_SECURITY_LEVEL),
+        'securityLevel': SecurityLevel,
 
         # Note that ``inputs`` is allowed to be an empty array.
         'inputs':
diff --git a/iota/commands/extended/send_transfer.py b/iota/commands/extended/send_transfer.py
index 666cecd..b456c8a 100644
--- a/iota/commands/extended/send_transfer.py
+++ b/iota/commands/extended/send_transfer.py
@@ -5,13 +5,13 @@
 from typing import List, Optional
 
 import filters as f
+
 from iota import Address, Bundle, ProposedTransaction, TransactionHash
 from iota.commands import FilterCommand, RequestFilter
 from iota.commands.extended.prepare_transfer import PrepareTransferCommand
 from iota.commands.extended.send_trytes import SendTrytesCommand
 from iota.crypto.types import Seed
-from iota.crypto.addresses import AddressGenerator
-from iota.filters import Trytes
+from iota.filters import SecurityLevel, Trytes
 
 __all__ = [
   'SendTransferCommand',
@@ -82,7 +82,7 @@ def __init__(self):
 
         # Optional parameters.
         'changeAddress': Trytes(result_type=Address),
-        'securityLevel': f.Choice([1, 2, 3]) | f.Optional(default=AddressGenerator.DEFAULT_SECURITY_LEVEL),
+        'securityLevel': SecurityLevel,
 
         # Note that ``inputs`` is allowed to be an empty array.
         'inputs':
diff --git a/iota/filters.py b/iota/filters.py
index e5bae6a..1c1ffdb 100644
--- a/iota/filters.py
+++ b/iota/filters.py
@@ -5,9 +5,11 @@
 from typing import Text
 
 import filters as f
+from filters.macros import filter_macro
 from six import binary_type, moves as compat, text_type
 
 from iota import Address, TryteString, TrytesCompatible
+from iota.crypto.addresses import AddressGenerator
 
 
 class GeneratedAddress(f.BaseFilter):
@@ -70,6 +72,19 @@ def _apply(self, value):
     return value
 
 
+@filter_macro
+def SecurityLevel():
+  """
+  Generates a filter chain for validating a security level.
+  """
+  return (
+      f.Type(int) |
+      f.Min(1) |
+      f.Max(3) |
+      f.Optional(default=AddressGenerator.DEFAULT_SECURITY_LEVEL)
+  )
+
+
 class Trytes(f.BaseFilter):
   """
   Validates a sequence as a sequence of trytes.
diff --git a/test/commands/extended/send_transfer_test.py b/test/commands/extended/send_transfer_test.py
index 970110f..aaedac8 100644
--- a/test/commands/extended/send_transfer_test.py
+++ b/test/commands/extended/send_transfer_test.py
@@ -6,10 +6,10 @@
 
 import filters as f
 from filters.test import BaseFilterTestCase
-from six import binary_type, text_type
+from six import binary_type
 
-from iota import Address, Bundle, Iota, ProposedTransaction, \
-  TransactionTrytes, TryteString, TransactionHash
+from iota import Address, Bundle, Iota, ProposedTransaction, TransactionHash, \
+  TransactionTrytes, TryteString
 from iota.adapter import MockAdapter
 from iota.commands.extended.send_transfer import SendTransferCommand
 from iota.crypto.addresses import AddressGenerator
@@ -175,13 +175,13 @@ def test_pass_optional_parameters_omitted(self):
 
         'depth':              100,
         'minWeightMagnitude': 13,
+        'securityLevel':      AddressGenerator.DEFAULT_SECURITY_LEVEL,
         'seed':               Seed(self.trytes2),
 
         'transfers': [
           self.transfer1,
           self.transfer2
         ],
-        'securityLevel': AddressGenerator.DEFAULT_SECURITY_LEVEL,
       }
     )
 
@@ -635,7 +635,7 @@ def test_fail_wrong_security_level(self):
       },
 
       {
-        'securityLevel': [f.Choice.CODE_INVALID],
+        'securityLevel': [f.Min.CODE_TOO_SMALL],
       },
     )
 
@@ -656,7 +656,7 @@ def test_fail_wrong_security_level_type(self):
       },
 
       {
-        'securityLevel': [f.Choice.CODE_INVALID],
+        'securityLevel': [f.Type.CODE_WRONG_TYPE],
       },
     )