diff --git a/BrighterTrading.db b/BrighterTrading.db
new file mode 100644
index 0000000..e69de29
diff --git a/markdown/App.md b/markdown/App.md
deleted file mode 100644
index 6d2114a..0000000
--- a/markdown/App.md
+++ /dev/null
@@ -1,159 +0,0 @@
-## App Flow Charts
-
-### App
-```plantuml
-@startuml
-start
- :Create BrighterTrades object;
- :configuration app;
- :run app;
-stop
-@enduml
-```
-
-### /index
-```plantuml
-@startuml
-start
- :Log in user;
- :Load dynamic data;
- :Render Landing Page;
-stop
-@enduml
-```
-
-### /ws
-```plantuml
-@startuml
-start
- repeat
- :Listen for message;
- if (Contains json?) then (yse)
- :Process_received_json();
- else (no)
- :Display_message();
- endif
- repeatwhile()
-@enduml
-```
-
-### /settings
-```plantuml
-@startuml
-start
- if (Logged in?) then (no)
- :redirect -> "/index";
- stop
- else (yes)
- :get_setting();
- :process_command();
- :redirect -> "/index";
-stop
-@enduml
-```
-
-### /history
-```plantuml
-@startuml
-start
- if (Logged in?) then (no)
- :Return empty data;
- stop
- else (yes)
- :Get current chart view details.;
- :Request price history for the chart view.;
- :Return data;
-stop
-@enduml
-```
-
-### /signup
-```plantuml
-@startuml
- start
- :Return rendered signup page.;
- stop
-@enduml
-```
-
-### /signout
-```plantuml
-@startuml
- start
- :Logout user.;
- :Delete client session var.;
- :redirect -> /index;
- stop
-@enduml
-```
-
-### /login
-```plantuml
-@startuml
- start
- :Get credentials;
- :Log in user.;
- if (success) then (yes)
- :Set the client session var;
- else (no)
- endif
- :Redirect -> /index;
- stop
-@enduml
-```
-
-### /signup_submit
-```plantuml
-@startuml
-
-start
-
-:Receive form data;
-:Extract email, username, and password;
-:Validate email format;
-if (Valid email format?) then (yes)
- :Validate username and password;
- if (Valid username and password?) then (yes)
- :Create new user;
- if (Success) then (yes)
- :Set session user;
- :Redirect to homepage;
- else (no)
- :Flash error message;
- endif
- else (no)
- :Flash error message;
- endif
-else (no)
- :Flash error message;
-endif
-
-stop
-
-@enduml
-```
-### /indictor_init
-```plantuml
-@startuml
-start
-
-if (Check if username is provided) then (yes)
- :Retrieve username from request data;
-else (no)
- :Return error response;
- stop
-endif
-
-if (Check if user is logged in) then (yes)
- :Retrieve chart view for the user;
-else (no)
- :Return error response;
- stop
-endif
-
-:Retrieve indicator data for the user;
-:Return data response;
-stop
-
-@endum
-```
diff --git a/markdown/App/App.md b/markdown/App/App.md
new file mode 100644
index 0000000..980e493
--- /dev/null
+++ b/markdown/App/App.md
@@ -0,0 +1,375 @@
+## App Flow Charts
+
+### App
+```plantuml
+@startuml
+skinparam legendBackgroundColor lightgreen
+skinparam defaultFontColor blue
+skinparam legendAlignment left
+skinparam defaultFontName "Arial Black"
+skinparam legendFontSize 12
+
+skinparam activity {
+ BackgroundColor lightblue
+ BorderColor black
+ FontColor darkblue
+ FontSize 16
+}
+
+legend top
+————————————————————————————————
+=app.py
+————————————————————————————————
+ Initializes the BrighterTrades object, configures the Flask
+ server, defines the endpoints then launches the app.
+end legend
+start
+ :Create BrighterTrades object;
+ :Configure app;
+ :Define endpoints;
+ :Run app;
+stop
+
+
+@enduml
+
+```
+
+### /index
+```plantuml
+@startuml
+skinparam legendBackgroundColor lightgreen
+skinparam defaultFontColor blue
+skinparam legendAlignment left
+skinparam defaultFontName "Arial Black"
+skinparam legendFontSize 12
+
+skinparam activity {
+ BackgroundColor lightblue
+ BorderColor black
+ FontColor darkblue
+ FontSize 16
+}
+
+legend top
+————————————————————————————————
+=/index
+————————————————————————————————
+ Handles the main landing page, logs in the user,
+ loads dynamic data, and renders the landing page.
+end legend
+start
+ :Log in user;
+ :Load dynamic data;
+ :Render Landing Page;
+stop
+@enduml
+
+
+```
+
+### /ws
+```plantuml
+@startuml
+skinparam legendBackgroundColor lightgreen
+skinparam defaultFontColor blue
+skinparam legendAlignment left
+skinparam defaultFontName "Arial Black"
+skinparam legendFontSize 12
+
+skinparam activity {
+ BackgroundColor lightblue
+ BorderColor black
+ FontColor darkblue
+ FontSize 16
+}
+
+legend top
+————————————————————————————————
+=/ws
+————————————————————————————————
+ Handles WebSocket connections, listens for messages,
+ processes JSON data, and displays messages.
+end legend
+start
+repeat
+ :Listen for message;
+ if (Contains JSON?) then (yes)
+ :Process received JSON;
+ else (no)
+ :Display message;
+ endif
+repeat while ()
+@enduml
+
+```
+
+### /settings
+```plantuml
+@startuml
+skinparam legendBackgroundColor lightgreen
+skinparam defaultFontColor blue
+skinparam legendAlignment left
+skinparam defaultFontName "Arial Black"
+skinparam legendFontSize 12
+
+skinparam activity {
+ BackgroundColor lightblue
+ BorderColor black
+ FontColor darkblue
+ FontSize 16
+}
+
+legend top
+————————————————————————————————
+=/settings
+————————————————————————————————
+ Handles settings changes. If user is logged in,
+ processes commands and redirects to index.
+end legend
+start
+if (Logged in?) then (no)
+ :redirect -> "/index";
+ stop
+else (yes)
+ :get_setting();
+ :process_command();
+ :redirect -> "/index";
+endif
+stop
+@enduml
+
+```
+
+### /history
+```plantuml
+@startuml
+skinparam legendBackgroundColor lightgreen
+skinparam defaultFontColor blue
+skinparam legendAlignment left
+skinparam defaultFontName "Arial Black"
+skinparam legendFontSize 12
+
+skinparam activity {
+ BackgroundColor lightblue
+ BorderColor black
+ FontColor darkblue
+ FontSize 16
+}
+
+legend top
+————————————————————————
+=/history
+————————————————————————
+ Fetches candle history for
+ a specific trading pair
+ and timeframe. Returns empty
+ data if user is not logged in.
+end legend
+start
+if (Logged in?) then (no)
+ :Return empty data;
+ stop
+else (yes)
+ :Get current chart view details;
+ :Request price history for the chart view;
+ :Return data;
+endif
+stop
+@enduml
+
+```
+
+### /signup
+```plantuml
+@startuml
+skinparam legendBackgroundColor lightgreen
+skinparam defaultFontColor blue
+skinparam legendAlignment left
+skinparam defaultFontName "Arial Black"
+skinparam legendFontSize 12
+
+skinparam activity {
+ BackgroundColor lightblue
+ BorderColor black
+ FontColor darkblue
+ FontSize 16
+}
+
+legend top
+————————————————————————————————
+=/signup
+————————————————————————————————
+Returns the rendered signup page.
+end legend
+start
+ :Return rendered signup page;
+stop
+@enduml
+
+```
+
+### /signout
+```plantuml
+@startuml
+skinparam legendBackgroundColor lightgreen
+skinparam defaultFontColor blue
+skinparam legendAlignment left
+skinparam defaultFontName "Arial Black"
+skinparam legendFontSize 12
+
+skinparam activity {
+ BackgroundColor lightblue
+ BorderColor black
+ FontColor darkblue
+ FontSize 16
+}
+
+legend top
+————————————————————————————————
+=/signout
+————————————————————————————————
+ Logs out the user, deletes the client
+ session variable, and redirects to index.
+end legend
+start
+ :Logout user;
+ :Delete client session var;
+ :redirect -> "/index";
+stop
+@enduml
+
+
+```
+
+### /login
+```plantuml
+@startuml
+skinparam legendBackgroundColor lightgreen
+skinparam defaultFontColor blue
+skinparam legendAlignment left
+skinparam defaultFontName "Arial Black"
+skinparam legendFontSize 12
+
+skinparam activity {
+ BackgroundColor lightblue
+ BorderColor black
+ FontColor darkblue
+ FontSize 16
+}
+
+legend top
+————————————————————————————————
+=/login
+————————————————————————————————
+ Handles user login by receiving credentials,
+ logging in the user, and redirecting to index.
+end legend
+start
+ :Get credentials;
+ :Log in user;
+ if (success) then (yes)
+ :Set the client session var;
+ else (no)
+ endif
+ :Redirect -> /index;
+stop
+@enduml
+
+
+```
+
+### /signup_submit
+```plantuml
+@startuml
+skinparam legendBackgroundColor lightgreen
+skinparam defaultFontColor blue
+skinparam legendAlignment left
+skinparam defaultFontName "Arial Black"
+skinparam legendFontSize 12
+
+skinparam activity {
+ BackgroundColor lightblue
+ BorderColor black
+ FontColor darkblue
+ FontSize 16
+}
+
+legend top
+————————————————————————————————
+=/signup_submit
+————————————————————————————————
+ Handles user signup by receiving form data,
+ validating email, creating new user,
+ and redirecting to homepage.
+end legend
+start
+ :Receive form data;
+ :Extract email, username, and password;
+ :Validate email format;
+ if (Valid email format?) then (yes)
+ :Validate username and password;
+ if (Valid username and password?) then (yes)
+ :Create new user;
+ if (Success) then (yes)
+ :Set session user;
+ :Redirect to homepage;
+ else (no)
+ :Flash error message;
+ endif
+ else (no)
+ :Flash error message;
+ endif
+ else (no)
+ :Flash error message;
+ endif
+stop
+@enduml
+
+```
+
+### /indictor_init
+```plantuml
+@startuml
+skinparam legendBackgroundColor lightgreen
+skinparam defaultFontColor blue
+skinparam legendAlignment left
+skinparam defaultFontName "Arial Black"
+skinparam legendFontSize 12
+
+skinparam activity {
+ BackgroundColor lightblue
+ BorderColor black
+ FontColor darkblue
+ FontSize 16
+}
+
+legend top
+————————————————————————————————
+=/indicator_init
+————————————————————————————————
+ Initializes the indicators for a given symbol
+ and timeframe, retrieves user and chart view
+ details, and returns data response.
+end legend
+start
+if (Check if username is provided) then (yes)
+ :Retrieve username from request data;
+else (no)
+ :Return error response;
+ stop
+endif
+
+if (Check if user is logged in) then (yes)
+ :Retrieve chart view for the user;
+else (no)
+ :Return error response;
+ stop
+endif
+
+:Retrieve indicator data for the user;
+:Return data response;
+stop
+@enduml
+
+```
diff --git a/markdown/App_Class_Diagram.md b/markdown/App/App_Class_Diagram.md
similarity index 73%
rename from markdown/App_Class_Diagram.md
rename to markdown/App/App_Class_Diagram.md
index ebc0119..f990dfd 100644
--- a/markdown/App_Class_Diagram.md
+++ b/markdown/App/App_Class_Diagram.md
@@ -1,6 +1,16 @@
```plantuml
+@startuml
+scale 1
-class "BrighterTrades" {
+skinparam class {
+ BackgroundColor<> lightblue
+ BackgroundColor<> lightgreen
+ BackgroundColor<> lightyellow
+ BackgroundColor<> lightcoral
+ BackgroundColor<> lightgrey
+}
+
+class "BrighterTrades" <> {
+ config
+ data_cache
+ strategies
@@ -35,30 +45,146 @@ class "BrighterTrades" {
}
class "app" {
- + "index()"
- + "ws(socket_conn)"
- + "settings()"
- + "history()"
- + "signup()"
- + "signout()"
- + "login()"
- + "signup_submit()"
- + "indicator_init()"
+ + index()
+ + ws(socket_conn)
+ + settings()
+ + history()
+ + signup()
+ + signout()
+ + login()
+ + signup_submit()
+ + indicator_init()
}
class "Flask" {
- + "render_template()"
+ + render_template()
}
-"app" --> "index()" : "index()"
-"app" --> "ws(socket_conn)" : "ws(socket_conn)"
-"app" --> "settings()" : "settings()"
-"app" --> "history()" : "history()"
-"app" --> "signup()" : "signup()"
-"app" --> "signout()" : "signout()"
-"app"--> "login()" : "login()"
-"app" --> "signup_submit()" : "signup_submit()"
-"app" --> "indicator_init()" : "indicator_init()"
+class "Users" <> {
+ + data_cache
+}
+
+class "Configuration" <> {
+ + exchanges
+ + indicators
+ + users
+ + __init__(exchanges, indicators, users)
+ + get_exchanges()
+ + get_indicators()
+ + get_users()
+ + add_exchange(exchange)
+ + remove_exchange(exchange)
+ + add_indicator(indicator)
+ + remove_indicator(indicator)
+ + add_user(user)
+ + remove_user(user)
+}
+
+class "Candles" <> {
+ + __init__(exchanges, config_obj, database)
+ + get_last_n_candles(num_candles, asset, timeframe, exchange, user_name)
+ + set_new_candle(cdata)
+ + set_cache(symbol=None, interval=None, exchange_name=None, user_name=None)
+ + get_latestvalues(value_name, symbol, timeframe, exchange, user_name, num_record=1)
+ + convert_candles(candles)
+ + get_candle_history(num_records, symbol=None, interval=None, exchange_name=None, user_name=None)
+}
+
+class "DataCache" <> {
+ + db
+ + get_records_since(key, start_datetime, record_length, ex_details)
+ + cache_exists(key)
+ + update_candle_cache(more_records, key)
+ + get_cached_candles(key)
+ + set_cached_candles(candles, key)
+ + clear_cache()
+ + get_cache_info()
+ + remove_expired_records()
+ + remove_cache(key)
+ + remove_all_caches()
+}
+
+class "Database" <> {
+ + exchanges
+ + __init__(exchanges)
+ + execute_sql(sql)
+ + get_item_where(item_name, table_name, filter_vals)
+ + get_rows_where(table, filter_vals)
+ + insert_dataframe(df, table)
+ + insert_row(table, columns, values)
+ + _table_exists(table_name)
+ + _populate_table(table_name, start_time, ex_details, end_time=None)
+ + _fetch_exchange_id(exchange_name)
+ + _fetch_market_id(symbol, exchange_name)
+ + _insert_candles_into_db(candlesticks, table_name, symbol, exchange_name)
+ + get_records_since(table_name, st, et, rl, ex_details)
+ + _get_records(table_name, st, et=None)
+ + _fetch_candles_from_exchange(symbol, interval, exchange_name, user_name, start_datetime=None, end_datetime=None)
+ + get_from_static_table(item, table, indexes, create_id=False)
+}
+
+class "ExchangeInterface" <> {
+ + exchange_data
+ + available_exchanges
+ --
+ + __init__()
+ + connect_exchange(exchange_name, user_name, api_keys=None)
+ + add_exchange(user_name, _class, arg)
+ + get_exchange(ename, uname)
+ + get_connected_exchanges(user_name)
+ + get_available_exchanges()
+ + get_exchange_balances(name)
+ + get_all_balances(name)
+ + get_order(symbol, order_id, target, user_name)
+ + get_trade_status(trade, user_name)
+ + get_trade_executed_qty(trade, user_name)
+ + get_trade_executed_price(trade, user_name)
+ + get_price(symbol, price_source=None)
+}
+
+class "Indicators" <> {
+ + get_indicators(user_name)
+ + get_indicator_data(user_name, source, start_ts, num_results)
+}
+
+class "Strategies" <> {
+ + get_strategies(user_name)
+ + run_strategy(strategy_name, user_name)
+}
+
+class "Backtester" <> {
+ + run_backtest(strategy_name, user_name)
+}
+
+class "Signals" <> {
+ + generate_signals(strategy_name, user_name)
+}
+
+class "Trades" <> {
+ + execute_trade(trade_details, user_name)
+}
+
+class "HDict" <> {
+}
+
+class "SQLite" <> {
+}
+
+class "shared_utilities" <> {
+}
+
+class "ArrayList" <> {
+}
+
+app --> "index()" : "index()"
+app --> "ws(socket_conn)" : "ws(socket_conn)"
+app --> "settings()" : "settings()"
+app --> "history()" : "history()"
+app --> "signup()" : "signup()"
+app --> "signout()" : "signout()"
+app --> "login()" : "login()"
+app --> "signup_submit()" : "signup_submit()"
+app --> "indicator_init()" : "indicator_init()"
"signup_submit()" --> "BrighterTrades" : "create_new_user()"
"history()" --> "BrighterTrades" : get_user_info()
@@ -90,90 +216,6 @@ class "Flask" {
"BrighterTrades" -- "SQLite"
"BrighterTrades" -- "HDict"
-class "Users" {
- + data_cache
-}
-
-class "Configuration" {
- + exchanges
- + indicators
- + users
- + __init__(exchanges, indicators, users)
- + get_exchanges()
- + get_indicators()
- + get_users()
- + add_exchange(exchange)
- + remove_exchange(exchange)
- + add_indicator(indicator)
- + remove_indicator(indicator)
- + add_user(user)
- + remove_user(user)
-}
-
-class "Candles" {
- + __init__(exchanges, config_obj, database)
- + get_last_n_candles(num_candles, asset, timeframe, exchange, user_name)
- + set_new_candle(cdata)
- + set_cache(symbol=None, interval=None, exchange_name=None, user_name=None)
- + get_latestvalues(value_name, symbol, timeframe, exchange, user_name, num_record=1)
- + convert_candles(candles)
- + get_candle_history(num_records, symbol=None, interval=None, exchange_name=None, user_name=None)
-}
-
-class "DataCache" {
- + db
- + get_records_since(key, start_datetime, record_length, ex_details)
- + cache_exists(key)
- + update_candle_cache(more_records, key)
- + get_cached_candles(key)
- + set_cached_candles(candles, key)
- + clear_cache()
- + get_cache_info()
- + remove_expired_records()
- + remove_cache(key)
- + remove_all_caches()
-}
-
-class "Database" {
- + exchanges
- + __init__(exchanges)
- + execute_sql(sql)
- + get_item_where(item_name, table_name, filter_vals)
- + get_rows_where(table, filter_vals)
- + insert_dataframe(df, table)
- + insert_row(table, columns, values)
- + _table_exists(table_name)
- + _populate_table(table_name, start_time, ex_details, end_time=None)
- + _fetch_exchange_id(exchange_name)
- + _fetch_market_id(symbol, exchange_name)
- + _insert_candles_into_db(candlesticks, table_name, symbol, exchange_name)
- + get_records_since(table_name, st, et, rl, ex_details)
- + _get_records(table_name, st, et=None)
- + _fetch_candles_from_exchange(symbol, interval, exchange_name, user_name, start_datetime=None, end_datetime=None)
- + get_from_static_table(item, table, indexes, create_id=False)
-}
-
-
-class "ExchangeInterface" {
- + exchange_data
- + available_exchanges
- --
- + __init__()
- + connect_exchange(exchange_name, user_name, api_keys=None)
- + add_exchange(user_name, _class, arg)
- + get_exchange(ename, uname)
- + get_connected_exchanges(user_name)
- + get_available_exchanges()
- + get_exchange_balances(name)
- + get_all_balances(name)
- + get_order(symbol, order_id, target, user_name)
- + get_trade_status(trade, user_name)
- + get_trade_executed_qty(trade, user_name)
- + get_trade_executed_price(trade, user_name)
- + get_price(symbol, price_source=None)
-}
-
-
"Configuration" -- "Signals"
"Configuration" -- "Indicators"
"Configuration" -- "Users"
@@ -189,9 +231,8 @@ class "ExchangeInterface" {
"ExchangeInterface" -- "ArrayList"
"ExchangeInterface" -- "DataCache"
-
-
-
@enduml
+
+
```
\ No newline at end of file
diff --git a/markdown/App_UseCase-Seq_Diagrams.md b/markdown/App/App_UseCase-Seq_Diagrams.md
similarity index 77%
rename from markdown/App_UseCase-Seq_Diagrams.md
rename to markdown/App/App_UseCase-Seq_Diagrams.md
index e097e54..1ab5eab 100644
--- a/markdown/App_UseCase-Seq_Diagrams.md
+++ b/markdown/App/App_UseCase-Seq_Diagrams.md
@@ -4,6 +4,14 @@
left to right direction
skinparam packageStyle rectangle
+skinparam usecase {
+ BackgroundColor lightblue
+ BorderColor black
+ FontColor darkblue
+ FontSize 16
+ RoundCorner 20
+}
+title Use Case Low Detail Overview
actor "User Interface" as User
rectangle "Flask App" as App {
@@ -33,6 +41,14 @@ rectangle "Flask App" as App {
left to right direction
skinparam packageStyle rectangle
+skinparam usecase {
+ BackgroundColor lightblue
+ BorderColor black
+ FontColor darkblue
+ FontSize 16
+ RoundCorner 20
+}
+title Use Case Medium Detail Overview
actor "User Interface" as User
rectangle "Flask App" as App {
@@ -73,6 +89,14 @@ rectangle "Flask App" as App {
left to right direction
skinparam packageStyle rectangle
+skinparam usecase {
+ BackgroundColor lightblue
+ BorderColor black
+ FontColor darkblue
+ FontSize 16
+ RoundCorner 20
+}
+title Use Case View Homepage
actor "User Interface" as User
rectangle "Flask App" as App {
@@ -106,16 +130,23 @@ rectangle "Flask App" as App {
@enduml
+
```
### Sequence Request Homepage
```plantuml
@startuml
+skinparam participant {
+ BackgroundColor lightblue
+ BorderColor black
+ FontColor darkblue
+}
+title Sequence Request Homepage
actor "User Interface" as User
-participant App as "Flask App"
-participant BrighterTrades as "BrighterTrades"
-participant Config as "Config"
-participant UserStorage as "User Storage"
+participant "Flask App" as App
+participant "BrighterTrades" as BrighterTrades
+participant "Config" as Config
+participant "User Storage" as UserStorage
User -> App: Request Homepage
App -> BrighterTrades: Create BrighterTrades object
@@ -129,13 +160,27 @@ App --> User: Serve Homepage
@enduml
+
```
### Use Case Change Settings:
```plantuml
@startuml
+title Use Case Change Settings
left to right direction
skinparam packageStyle rectangle
+skinparam usecase {
+ BackgroundColor lightblue
+ BorderColor black
+ FontColor darkblue
+ FontSize 16
+}
+skinparam actor {
+ BackgroundColor lightgreen
+ BorderColor black
+ FontColor darkblue
+ FontSize 16
+}
actor "User Interface" as User
rectangle "Flask App" as App {
@@ -153,10 +198,22 @@ rectangle "Flask App" as App {
@enduml
+
```
### Sequence Change Settings
```plantuml
@startuml
+title Sequence Change Settings
+
+skinparam sequence {
+ ActorBackgroundColor lightgreen
+ ParticipantBackgroundColor lightblue
+ ActorBorderColor black
+ ParticipantBorderColor black
+ ActorFontColor darkblue
+ ParticipantFontColor darkblue
+ FontSize 14
+}
actor "User Interface" as User
participant App as "Flask App"
@@ -171,13 +228,18 @@ App --> User: Redirect to Homepage
@enduml
+
```
### Use Case Fetch Candle History:
```plantuml
@startuml
-
left to right direction
skinparam packageStyle rectangle
+skinparam usecase {
+ BackgroundColor lightblue
+ BorderColor black
+ FontColor darkblue
+}
actor "User Interface" as User
rectangle "Flask App" as App {
@@ -195,10 +257,16 @@ rectangle "Flask App" as App {
@enduml
+
```
### Sequence Request candle history
```plantuml
@startuml
+skinparam participant {
+ BackgroundColor lightblue
+ BorderColor black
+ FontColor darkblue
+}
actor "User Interface" as User
participant App as "Flask App"
@@ -215,31 +283,41 @@ App --> User: Serve Candle History
@enduml
+
```
### Sequence Initialize Indicators:
```plantuml
@startuml
+skinparam participant {
+ BackgroundColor lightblue
+ BorderColor black
+ FontColor darkblue
+}
-actor "User Interface"
+actor "User Interface" as User
-
-"User Interface" -> app: Requests initialized indicators
+User -> app: Requests initialized indicators
activate app #005500
app -> Indicators: initialize indicators
activate Indicators #005500
Indicators -> app: return initialized indicators
deactivate Indicators
-app -> "User Interface": Returns initialized indicators
+app -> User: Returns initialized indicators
deactivate app
@enduml
+
```
### Sequence Sign in:
```plantuml
@startuml
-
+skinparam participant {
+ BackgroundColor lightblue
+ BorderColor black
+ FontColor darkblue
+}
actor "User Interface"
"User Interface" -> app: requests "Sign In"
@@ -259,7 +337,11 @@ deactivate app
### Sequence Sign up:
```plantuml
@startuml
-
+skinparam participant {
+ BackgroundColor lightblue
+ BorderColor black
+ FontColor darkblue
+}
actor "User Interface" as User
User -> app: send "Sign Up" request
@@ -279,7 +361,11 @@ deactivate app
### Sequence Sign out:
```plantuml
@startuml
-
+skinparam participant {
+ BackgroundColor lightblue
+ BorderColor black
+ FontColor darkblue
+}
actor "User Interface" as User
User -> app: send "Sign Out" request
diff --git a/src/app.py b/src/app.py
index 03fa4b1..758de9c 100644
--- a/src/app.py
+++ b/src/app.py
@@ -24,10 +24,19 @@ CORS_HEADERS = 'Content-Type'
app.config.from_object(__name__)
app.secret_key = '1_BAD_secrete_KEY_is_not_2'
-# Enable cross resources.
+# Enable cross-origin resource sharing for specific endpoints
cors = CORS(app, supports_credentials=True,
- resources=[r'/api/history', r'/api/indicator_init'],
- origins=[r'http://127.0.0.1:5000'])
+ resources={
+ r"/api/history": {"origins": ["http://127.0.0.1:5000", "http://localhost:5000"]},
+ r"/api/indicator_init": {"origins": ["http://127.0.0.1:5000", "http://localhost:5000"]}
+ },
+ headers=['Content-Type'])
+
+
+@app.after_request
+def add_cors_headers(response):
+ response.headers['Access-Control-Allow-Credentials'] = 'true'
+ return response
@app.route('/')
@@ -159,29 +168,37 @@ def settings():
@app.route('/api/history', methods=['POST', 'GET'])
-# @cross_origin(supports_credentials=True)
def history():
"""
- Fetches the candle history of a specific trading pair and timeframe.
- Currently, set to last 1000 candles.
- :return: json - price history
+ Fetches the candle history of a specific trading pair and timeframe.
+ Currently, set to last 1000 candles.
+ :return: json - price history
"""
- data = request.get_json()
- username = data.get('user_name')
- # Return if the user is not logged in.
- if not username:
- return {} # redirect('/')
+ try:
+ data = request.get_json()
+ if not data:
+ raise ValueError("No JSON data received")
- print('[RECEIVED PRICE HISTORY REQUEST] - user', username)
+ username = data.get('user_name')
- # Get a dictionary of chart attributes from the user data indexed by user_name.
- chart_view = brighter_trades.get_user_info(user_name=username, info='Chart View')
+ # Return if the user is not logged in.
+ if not username:
+ # redirect('/')
+ return jsonify({'error': 'User not logged in.'}), 401
- payload = brighter_trades.get_market_info(
- info='Candle History', num_records=1000, chart_view=chart_view, user_name=username)
+ print('[RECEIVED PRICE HISTORY REQUEST] - user', username)
- print('[SENDING PRICE HISTORY TO CLIENT]', payload.tail(2))
- return jsonify(payload.to_dict('records'))
+ # Get a dictionary of chart attributes from the user data indexed by user_name.
+ chart_view = brighter_trades.get_user_info(user_name=username, info='Chart View')
+
+ payload = brighter_trades.get_market_info(
+ info='Candle History', num_records=1000, chart_view=chart_view, user_name=username)
+
+ print('[SENDING PRICE HISTORY TO CLIENT]', payload.tail(2))
+ return jsonify(payload.to_dict('records')), 200
+ except Exception as e:
+ print(f'Error in history endpoint: {e}')
+ return jsonify({'error': str(e)}), 500
# @app.route('/saved_data')
diff --git a/src/config.py b/src/config.py
index 10a7ca3..6ca7103 100644
--- a/src/config.py
+++ b/src/config.py
@@ -2,4 +2,4 @@ BINANCE_API_KEY = 'rkp1Xflb5nnwt6jys0PG27KXcqwn0q9lKCLryKcSp4mKW2UOlkPRuAHPg45rQ
BINANCE_API_SECRET = 'DiFhhYhF64nkPe5f3V7TRJX2bSVA7ZQZlozSdX7O7uYmBMdK985eA6Kp2B2zKvbK'
ALPACA_API_KEY = 'PKN0WFYT9VZYUVRBG1HM'
ALPACA_API_SECRET = '0C1I6UcBSR2B0SZrBC3DoKGtcglAny8znorvganx'
-DB_FILE = "C:/Users/Rob/PycharmProjects/BrighterTrading/BrighterTrading.db"
+DB_FILE = "C:/Users/Rob/PycharmProjects/BrighterTrading/data/BrighterTrading.db"
diff --git a/src/database.py b/src/database.py
index 9298383..0f3892b 100644
--- a/src/database.py
+++ b/src/database.py
@@ -427,36 +427,35 @@ class Database:
quote_volume, num_trades, taker_buy_base_volume, taker_buy_quote_volume]
"""
- def fill_data_holes(records):
+ def fill_data_holes(records, interval):
time_span = timeframe_to_minutes(interval)
last_timestamp = None
- # Iterate through the timestamps in all the records.
- for time_stamp in records.open_time:
+ filled_records = []
+
+ for _, row in records.iterrows():
+ time_stamp = row['open_time']
if last_timestamp is None:
- # Record this time_stamp.
last_timestamp = time_stamp
- # Skip the first iteration.
+ filled_records.append(row)
continue
- # Get the time difference between current and last time_stamps in minutes.
delta_ms = time_stamp - last_timestamp
delta_minutes = (delta_ms / 1000) / 60
- # If the difference exceeds the span of a single record.
+
if delta_minutes > time_span:
- # Calculate how many records are missing.
- num_missing_rec = (delta_minutes / time_span)
- # Create the missing records
+ num_missing_rec = int(delta_minutes / time_span)
step = int(delta_ms / num_missing_rec)
- # loop from the last timestamp + step until the current timestamp.
- for ts in range(last_timestamp + step, time_stamp, step):
- # Copy the current row and append it with all the missing timestamps.
- row = records.loc[records['open_time'] == time_stamp]
- row.open_time = ts
- records = records.append(row, ignore_index=True)
- # Remember the time_stamp.
+
+ for ts in range(int(last_timestamp) + step, int(time_stamp), step):
+ new_row = row.copy()
+ new_row['open_time'] = ts
+ filled_records.append(new_row)
+
+ filled_records.append(row)
last_timestamp = time_stamp
- return records
+
+ return pd.DataFrame(filled_records)
# Default start date for fetching from the exchange_name.
if start_datetime is None:
@@ -494,5 +493,5 @@ class Database:
if num_rec_records < estimated_num_records:
# Some records may be missing due to server maintenance periods ect.
# Fill the holes with copies of the last record received before the gap.
- candles = fill_data_holes(candles)
+ candles = fill_data_holes(candles, interval)
return candles
diff --git a/static/Alerts.js b/src/static/Alerts.js
similarity index 100%
rename from static/Alerts.js
rename to src/static/Alerts.js
diff --git a/static/Strategies.js b/src/static/Strategies.js
similarity index 100%
rename from static/Strategies.js
rename to src/static/Strategies.js
diff --git a/static/arrow-down.svg b/src/static/arrow-down.svg
similarity index 100%
rename from static/arrow-down.svg
rename to src/static/arrow-down.svg
diff --git a/static/backtesting.js b/src/static/backtesting.js
similarity index 100%
rename from static/backtesting.js
rename to src/static/backtesting.js
diff --git a/static/blue_img.jpg b/src/static/blue_img.jpg
similarity index 100%
rename from static/blue_img.jpg
rename to src/static/blue_img.jpg
diff --git a/static/brighterStyles.css b/src/static/brighterStyles.css
similarity index 100%
rename from static/brighterStyles.css
rename to src/static/brighterStyles.css
diff --git a/static/charts.js b/src/static/charts.js
similarity index 100%
rename from static/charts.js
rename to src/static/charts.js
diff --git a/static/communication.js b/src/static/communication.js
similarity index 97%
rename from static/communication.js
rename to src/static/communication.js
index e5f5f10..8aaba68 100644
--- a/static/communication.js
+++ b/src/static/communication.js
@@ -58,9 +58,9 @@ class Comms {
* @returns {Promise