Begin implementing pydantic validation for OANDA

This commit is contained in:
Mark Veidemanis 2022-10-31 08:58:08 +00:00
parent c15ae379f5
commit 8ee56b0e37
Signed by: m
GPG Key ID: 5ACFCEED46C0904F
4 changed files with 106 additions and 4 deletions

View File

@ -57,7 +57,7 @@ class AlpacaExchange(BaseExchange):
return (True, balance) return (True, balance)
def get_market_value(self, symbol): def get_market_value(self, symbol): # TODO: pydantic
try: try:
position = self.client.get_position(symbol) position = self.client.get_position(symbol)
except APIError as e: except APIError as e:
@ -65,7 +65,7 @@ class AlpacaExchange(BaseExchange):
return False return False
return float(position["market_value"]) return float(position["market_value"])
def post_trade(self, trade): def post_trade(self, trade): # TODO: pydantic
# the trade is not placed yet # the trade is not placed yet
if trade.direction == "buy": if trade.direction == "buy":
direction = OrderSide.BUY direction = OrderSide.BUY

View File

@ -4,10 +4,25 @@ from oandapyV20.endpoints import accounts, orders, positions, trades
from core.exchanges import BaseExchange from core.exchanges import BaseExchange
from core.lib.schemas import oanda_s from core.lib.schemas import oanda_s
OANDA_SCHEMA_MAPPING = {} OANDA_SCHEMA_MAPPING = {"OpenPositions": oanda_s.OpenPositions}
class OANDAExchange(BaseExchange): class OANDAExchange(BaseExchange):
def call(self, method, request):
self.client.request(request)
response = request.response
if isinstance(response, list):
response = {"itemlist": response}
if method not in self.schema:
self.log.error(f"Method cannot be validated: {method}")
self.log.debug(f"Response: {response}")
return (False, f"Method cannot be validated: {method}")
try:
return (True, self.schema[method](**response).dict())
except ValidationError as e:
self.log.error(f"Could not validate response: {e}")
return (False, e)
def set_schema(self): def set_schema(self):
self.schema = OANDA_SCHEMA_MAPPING self.schema = OANDA_SCHEMA_MAPPING
@ -58,5 +73,9 @@ class OANDAExchange(BaseExchange):
def get_all_positions(self): def get_all_positions(self):
r = positions.OpenPositions(accountID=self.account_id) r = positions.OpenPositions(accountID=self.account_id)
self.client.request(r) success, response = self.call("OpenPositions", r)
if not success:
return (success, response)
print("Positions", response)
return (True, []) return (True, [])

View File

@ -1,5 +1,6 @@
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
class Asset(BaseModel): class Asset(BaseModel):
id: str id: str
class_: str = Field(..., alias="class") class_: str = Field(..., alias="class")
@ -17,10 +18,12 @@ class Asset(BaseModel):
min_trade_increment: str min_trade_increment: str
price_increment: str price_increment: str
# get_all_assets # get_all_assets
class GetAllAssets(BaseModel): class GetAllAssets(BaseModel):
itemlist: list[Asset] itemlist: list[Asset]
# get_open_position # get_open_position
class GetOpenPosition(BaseModel): class GetOpenPosition(BaseModel):
asset_id: str asset_id: str
@ -63,10 +66,12 @@ class Position(BaseModel):
change_today: str change_today: str
qty_available: str qty_available: str
# get_all_positions # get_all_positions
class GetAllPositions(BaseModel): class GetAllPositions(BaseModel):
itemlist: list[Position] itemlist: list[Position]
# get_account # get_account
class GetAccount(BaseModel): class GetAccount(BaseModel):
id: str id: str

View File

@ -1 +1,79 @@
from pydantic import BaseModel from pydantic import BaseModel
a = {
"positions": [
{
"instrument": "EUR_USD",
"long": {
"units": "1",
"averagePrice": "0.99361",
"pl": "-0.1014",
"resettablePL": "-0.1014",
"financing": "0.0000",
"dividendAdjustment": "0.0000",
"guaranteedExecutionFees": "0.0000",
"tradeIDs": ["71"],
"unrealizedPL": "-0.0002",
},
"short": {
"units": "0",
"pl": "0.0932",
"resettablePL": "0.0932",
"financing": "0.0000",
"dividendAdjustment": "0.0000",
"guaranteedExecutionFees": "0.0000",
"unrealizedPL": "0.0000",
},
"pl": "-0.0082",
"resettablePL": "-0.0082",
"financing": "0.0000",
"commission": "0.0000",
"dividendAdjustment": "0.0000",
"guaranteedExecutionFees": "0.0000",
"unrealizedPL": "-0.0002",
"marginUsed": "0.0286",
}
],
"lastTransactionID": "71",
}
class PositionLong(BaseModel):
units: str
averagePrice: str
pl: str
resettablePL: str
financing: str
dividendAdjustment: str
guaranteedExecutionFees: str
tradeIDs: list[str]
unrealizedPL: str
class PositionShort(BaseModel):
units: str
pl: str
resettablePL: str
financing: str
dividendAdjustment: str
guaranteedExecutionFees: str
unrealizedPL: str
class Position(BaseModel):
instrument: str
long: PositionLong
short: PositionShort
pl: str
resettablePL: str
financing: str
commission: str
dividendAdjustment: str
guaranteedExecutionFees: str
unrealizedPL: str
marginUsed: str
class OpenPositions(BaseModel):
positions: list[Position]
lastTransactionID: str