@ -3,57 +3,63 @@ import logging
from datetime import datetime
from typing import Any , List , Optional
from freqtrade . persistence . keyvalue import KeyValue
from freqtrade . persistence . keyvalue import CustomData
logger = logging . getLogger ( __name__ )
class KeyValues ( ) :
class CustomDataWrapper ( ) :
"""
KeyValues middleware class
CustomData middleware class
Abstracts the database layer away so it becomes optional - which will be necessary to support
backtesting and hyperopt in the future .
"""
use_db = True
kvals: List [ KeyValue ] = [ ]
custom_data: List [ CustomData ] = [ ]
unserialized_types = [ ' bool ' , ' float ' , ' int ' , ' str ' ]
@staticmethod
def reset_ keyvalues ( ) - > None :
def reset_ custom_data ( ) - > None :
"""
Resets all key - value pairs . Only active for backtesting mode .
"""
if not KeyValues . use_db :
KeyValues. kvals = [ ]
if not CustomDataWrapper . use_db :
CustomDataWrapper. custom_data = [ ]
@staticmethod
def get_kval ( key : Optional [ str ] = None , trade_id : Optional [ int ] = None ) - > List [ KeyValue ] :
def get_custom_data ( key : Optional [ str ] = None ,
trade_id : Optional [ int ] = None ) - > List [ CustomData ] :
if trade_id is None :
trade_id = 0
if KeyValues . use_db :
filtered_ kvals = KeyValue . query_kv ( trade_id = trade_id , key = key ) . all ( )
for index , kval in enumerate ( filtered_kvals ) :
if kval. kv_type not in KeyValues . unserialized_types :
kval. kv_value = json . loads ( kval . kv _value)
filtered_ kvals[ index ] = kval
return filtered_ kvals
if CustomDataWrapper . use_db :
filtered_ custom_data = CustomData . query_cd ( trade_id = trade_id , key = key ) . all ( )
for index , data_entry in enumerate ( filtered_custom_data ) :
if data_entry. cd_type not in CustomDataWrapper . unserialized_types :
data_entry. cd_value = json . loads ( data_entry . cd _value)
filtered_ custom_data[ index ] = data_entry
return filtered_ custom_data
else :
filtered_kvals = [ kval for kval in KeyValues . kvals if ( kval . ft_trade_id == trade_id ) ]
filtered_custom_data = [
data_entry for data_entry in CustomDataWrapper . custom_data
if ( data_entry . ft_trade_id == trade_id )
]
if key is not None :
filtered_kvals = [
kval for kval in filtered_kvals if ( kval . kv_key . casefold ( ) == key . casefold ( ) ) ]
return filtered_kvals
filtered_custom_data = [
data_entry for data_entry in filtered_custom_data
if ( data_entry . cd_key . casefold ( ) == key . casefold ( ) )
]
return filtered_custom_data
@staticmethod
def set_ kval ( key : str , value : Any , trade_id : Optional [ int ] = None ) - > None :
def set_ custom_data ( key : str , value : Any , trade_id : Optional [ int ] = None ) - > None :
value_type = type ( value ) . __name__
value_db = None
if value_type not in KeyValues . unserialized_types :
if value_type not in CustomDataWrapper . unserialized_types :
try :
value_db = json . dumps ( value )
except TypeError as e :
@ -64,44 +70,44 @@ class KeyValues():
if trade_id is None :
trade_id = 0
kvals = KeyValues . get_kval ( key = key , trade_id = trade_id )
if kvals :
kv = kvals [ 0 ]
kv. kv _value = value
kv . updated_at = datetime . utcnow ( )
custom_data = CustomDataWrapper . get_custom_data ( key = key , trade_id = trade_id )
if custom_data :
data_entry = custom_data [ 0 ]
data_entry. cd _value = value
data_entry . updated_at = datetime . utcnow ( )
else :
kv = KeyValue (
ft_trade_id = trade_id ,
kv _key= key ,
kv _type= value_type ,
kv _value= value ,
created_at = datetime . utcnow ( )
data_entry = CustomData (
ft_trade_id = trade_id ,
cd _key= key ,
cd _type= value_type ,
cd _value= value ,
created_at = datetime . utcnow ( )
)
if KeyValues . use_db and value_db is not None :
kv. kv _value = value_db
KeyValue. query . session . add ( kv )
KeyValue . query . session . commit ( )
elif not KeyValues . use_db :
kv _index = - 1
for index , kval in enumerate ( KeyValues . kvals ) :
if kval. ft_trade_id == trade_id and kval . kv _key == key :
kv _index = index
if CustomDataWrapper . use_db and value_db is not None :
data_entry. cd _value = value_db
CustomData. query . session . add ( data_entry )
CustomData . query . session . commit ( )
elif not CustomDataWrapper . use_db :
cd _index = - 1
for index , data_entry in enumerate ( CustomDataWrapper . custom_data ) :
if data_entry. ft_trade_id == trade_id and data_entry . cd _key == key :
cd _index = index
break
if kv _index > = 0 :
kval. kv _type = value_type
kval . value = value
kval . updated_at = datetime . utcnow ( )
if cd _index > = 0 :
data_entry. cd _type = value_type
data_entry . value = value
data_entry . updated_at = datetime . utcnow ( )
KeyValues. kvals [ kv_index ] = kval
CustomDataWrapper. custom_data [ cd_index ] = data_entry
else :
KeyValues. kvals . append ( kv )
CustomDataWrapper. custom_data . append ( data_entry )
@staticmethod
def get_all_ kvals( ) - > List [ KeyValue ] :
def get_all_ custom_data( ) - > List [ CustomData ] :
if KeyValues . use_db :
return KeyValue . query . all ( )
if CustomDataWrapper . use_db :
return CustomData . query . all ( )
else :
return KeyValues. kvals
return CustomDataWrapper. custom_data