Repository: rotki/rotki

Issue:
Offer a way to force save a snapshot of all balances
## Problem Definition

On the Statistics page, selecting a date range and clicking render does not change the graph.  

![no error or feedback](https://user-images.githubusercontent.com/5751289/82474033-0babd480-9a90-11ea-8331-3ce632c7a5ae.png)

At the bottom of the page, the field "Value distribution by asset" is red and says "You have to show at least one asset".  

![at least one](https://user-images.githubusercontent.com/5751289/82474084-25e5b280-9a90-11ea-91d0-5ea517e77480.png)

However, increasing the value to something above zero changes the error to "You cannot show more than 0 assets", which seems nonsensical.  

![no more than 0](https://user-images.githubusercontent.com/5751289/82474147-3b5adc80-9a90-11ea-9f04-0dbcf80cdf8b.png)

Additionally, the "Asset amount and value over time" has "No data available" on the dropdown menu and the Render button is greyed out.

![no data available](https://user-images.githubusercontent.com/5751289/82474207-50d00680-9a90-11ea-9f33-2c2ae9fcaca4.png)



### System Description
Ubuntu 20.04
Linux 5.4.0-31-generic #35-Ubuntu SMP Thu May 7 20:20:34 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux



Discussion:
Hey @ChosunOne thanks for the issue and for getting premium.

This looks like rotki has no data to show.

IS this a new account? The data displayed here is what is saved in your local DB every day you use rotki. What does the top left button with the disk say? When is the last time data were saved?
This is a new account, the save icon states:
```
Balances last saved
20/05/2020 10:33:31 CDT
```

I see data on the main dashboard, but not on the stats page.
> This is a new account, the save icon states:
> I see data on the main dashboard, but not on the stats page.

All right. In this case you should see some data. The netvalue graph is not going to be really useful but the assets distributions should have been there.

All right. I will try to reproduce this with a new account with premium and check back with you later. In the meantime what happens if you exit the app and open it again? Does it work then?
Reopening the app doesn't seem to change anything, I still can't select any assets and I'm getting the same as before.
Okay @ChosunOne thanks for the report. Will have a look when I get to the computer again and come back to you as soon as we find out what the problem is.
### Introduction

All right @ChosunOne I believe I figured out what happened. It's due to the way we keep historical data and the fact that this is a new account.

### Background on how rotki provides the analytics

rotki calculates the analytics data, by analyzing its own snapshot of your balances over everything we are tracking. If we have no snapshots of balances we can't calculate anything.

By default rotki takes a balance snapshot every 24 hours. This is configurable by going to settings and changing the balance saving frequency as seen below.

![Peek 2020-05-20 20-51](https://user-images.githubusercontent.com/1658405/82486244-d9749400-9adc-11ea-9dd7-0b9d0c3deeb7.gif)


### Theory of what happened

- You created a new account
- Balances of zero are saved
- You added exchanges, accounts and whatever else you want to track
- You added the premium key and tried to see the analytics. But since the saved data are the very initial zero data, there is nothing to see here.

### How you can fix it.

- Change the balance frequency setting to 1 hour.
- Restart the application.
-  New balances should now be saved since it's definitely more than 1 hour ago that you opened the app for the first time.
- If you go to statistics you should now be able to see something.

### Things that we can improve

Thank you for this report! Probably never seen this before because our other premium users have all had accounts populated with data so far. Thanks to you we discovered:

- Premium should show the available range of data: https://github.com/rotki/rotki/issues/1017
- If the account is new, then have a grace period for saving the data. Or something like that.
That did the trick!  Any chance a button to manually save a snapshot could be added?  That would ensure that the DB has a snapshot with data.
> That did the trick! Any chance a button to manually save a snapshot could be added? That would ensure that the DB has a snapshot with data.

Yes this sounds like a good approach. We will use this issue to track implementing that.

Resolving patch:
diff --git a/rotkehlchen/api/v1/encoding.py b/rotkehlchen/api/v1/encoding.py
--- a/rotkehlchen/api/v1/encoding.py
+++ b/rotkehlchen/api/v1/encoding.py
@@ -717,7 +717,7 @@ class NewUserSchema(BaseUserSchema):
 
 class AllBalancesQuerySchema(Schema):
     async_query = fields.Boolean(missing=False)
-    save_data = fields.Boolean(missing=True)
+    save_data = fields.Boolean(missing=False)
     ignore_cache = fields.Boolean(missing=False)
 
 
diff --git a/rotkehlchen/rotkehlchen.py b/rotkehlchen/rotkehlchen.py
--- a/rotkehlchen/rotkehlchen.py
+++ b/rotkehlchen/rotkehlchen.py
@@ -506,13 +506,15 @@ def query_fiat_balances(self) -> Dict[Asset, Dict[str, FVal]]:
 
     def query_balances(
             self,
-            requested_save_data: bool = True,
+            requested_save_data: bool = False,
             timestamp: Timestamp = None,
             ignore_cache: bool = False,
     ) -> Dict[str, Any]:
         """Query all balances rotkehlchen can see.
 
-        If requested_save_data is True then the data are saved in the DB.
+        If requested_save_data is True then the data are always saved in the DB,
+        if it is False then data are saved if self.data.should_save_balances()
+        is True.
         If timestamp is None then the current timestamp is used.
         If a timestamp is given then that is the time that the balances are going
         to be saved in the DB
@@ -583,7 +585,8 @@ def query_balances(
 
         result_dict = merge_dicts(combined, stats)
 
-        allowed_to_save = requested_save_data and self.data.should_save_balances()
+        allowed_to_save = requested_save_data or self.data.should_save_balances()
+
         if problem_free and allowed_to_save:
             if not timestamp:
                 timestamp = Timestamp(int(time.time()))


Test patch:
diff --git a/rotkehlchen/tests/api/test_balances.py b/rotkehlchen/tests/api/test_balances.py
--- a/rotkehlchen/tests/api/test_balances.py
+++ b/rotkehlchen/tests/api/test_balances.py
@@ -138,14 +138,14 @@ def test_query_all_balances(
     rotki = rotkehlchen_api_server_with_exchanges.rest_api.rotkehlchen
     rotki.chain_manager.cache_ttl_secs = 0
     setup = setup_balances(rotki, ethereum_accounts, btc_accounts)
-    # Test all balances request by requesting to not save the data
+    # Test that all balances request saves data on a fresh account
     with ExitStack() as stack:
         setup.enter_all_patches(stack)
         response = requests.get(
             api_url_for(
                 rotkehlchen_api_server_with_exchanges,
                 "allbalancesresource",
-            ), json={'save_data': False},
+            ),
         )
 
     assert_proper_response(response)
@@ -153,12 +153,14 @@ def test_query_all_balances(
     assert_all_balances(
         data=json_data,
         db=rotki.data.db,
-        expected_data_in_db=False,
+        expected_data_in_db=True,
         setup=setup,
     )
 
-    # now do the same but save the data in the DB and test it works
-    # Omit the argument to test that default value of save_data is True
+    last_save_timestamp = rotki.data.db.get_last_balance_save_time()
+
+    # now do the same but check to see if the balance save frequency delay works
+    # and thus data will not be saved
     with ExitStack() as stack:
         setup.enter_all_patches(stack)
         response = requests.get(
@@ -168,13 +170,22 @@ def test_query_all_balances(
             ),
         )
     assert_proper_response(response)
-    json_data = response.json()
-    assert_all_balances(
-        data=json_data,
-        db=rotki.data.db,
-        expected_data_in_db=True,
-        setup=setup,
-    )
+    new_save_timestamp = rotki.data.db.get_last_balance_save_time()
+    assert last_save_timestamp == new_save_timestamp
+
+    # now do the same but test that balance are saved since the balance save frequency delay
+    # is overriden via `save_data` = True
+    with ExitStack() as stack:
+        setup.enter_all_patches(stack)
+        response = requests.get(
+            api_url_for(
+                rotkehlchen_api_server_with_exchanges,
+                "allbalancesresource",
+            ), json={'save_data': True},
+        )
+    assert_proper_response(response)
+    new_save_timestamp = rotki.data.db.get_last_balance_save_time()
+    assert last_save_timestamp != new_save_timestamp
 
 
 @pytest.mark.parametrize('number_of_eth_accounts', [2])
@@ -369,7 +380,7 @@ def test_query_all_balances_with_manually_tracked_balances(
         manually_tracked_balances=manually_tracked_balances,
     )
     # now do the same but save the data in the DB and test it works
-    # Omit the argument to test that default value of save_data is True
+    # `save_data` is False by default but data will save since this is a fresh account
     with ExitStack() as stack:
         setup.enter_all_patches(stack)
         response = requests.get(